Exemplo n.º 1
0
// Load a description packet from a specified file
bool DescriptionPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header)
{
  // Is the packet big enough
  if (header.length <= sizeof(FILEDESCRIPTIONPACKET))
  {
    return false;
  }

  // Is the packet too large (what is the longest permissible filename)
  if (header.length - sizeof(FILEDESCRIPTIONPACKET) > 100000)
  {
    return false;
  }

  // Allocate the packet (with a little extra so we will have NULLs after the filename)
  FILEDESCRIPTIONPACKET *packet = (FILEDESCRIPTIONPACKET *)AllocatePacket((size_t)header.length, 4);

  packet->header = header;

  // Read the rest of the packet from disk
  if (!diskfile->Read(offset + sizeof(PACKET_HEADER), 
                      &packet->fileid, 
                      (size_t)packet->header.length - sizeof(PACKET_HEADER)))
    return false;

  // Are the file and 16k hashes consistent
  if (packet->length <= 16384 && packet->hash16k != packet->hashfull)
  {
    return false;
  }

  return true;
}
Exemplo n.º 2
0
bool MainPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header)
{
  // Is the packet large enough
  if (header.length < sizeof(MAINPACKET))
  {
    return false;
  }

  // Is there a whole number of fileid values
  if (0 < (header.length - sizeof(MAINPACKET)) % sizeof(MD5Hash))
  {
    return false;
  }

  // Is the packet too large
  if (header.length > sizeof(MAINPACKET) + 32768 * sizeof(MD5Hash))
  {
    return false;
  }

  // Compute the total number of entries in the fileid array
  totalfilecount = (u32)(((size_t)header.length - sizeof(MAINPACKET)) / sizeof(MD5Hash));

  MAINPACKET *packet = (MAINPACKET *)AllocatePacket((size_t)header.length);

  packet->header = header;

  // Read the rest of the packet from disk
  if (!diskfile->Read(offset + sizeof(PACKET_HEADER), 
                      &packet->blocksize, 
                     (size_t)packet->header.length - sizeof(PACKET_HEADER)))
    return false;

  // Does the packet have enough fileid values
  recoverablefilecount = packet->recoverablefilecount;
  if (recoverablefilecount > totalfilecount)
  {
    return false;
  }

  // Is the block size valid
  blocksize = packet->blocksize;
  if (blocksize == 0 || (blocksize & 3) != 0)
  {
    return false;
  }

  return true;
}
Exemplo n.º 3
0
bool MainPacket::Create(vector<Par2CreatorSourceFile*> &sourcefiles, u64 _blocksize)
{
  recoverablefilecount = totalfilecount =(u32)sourcefiles.size();
  blocksize = _blocksize;

  // Allocate memory for the main packet with enough fileid entries
  MAINPACKET *packet = (MAINPACKET *)AllocatePacket(sizeof(MAINPACKET) + totalfilecount * sizeof(MD5Hash));

  // Record the details we already know in the packet
  packet->header.magic         = packet_magic;
  packet->header.length        = packetlength;
  //packet->header.hash;         // Compute shortly
  //packet->header.setid;        // Compute shortly
  packet->header.type          = mainpacket_type;

  packet->blocksize            = _blocksize;
  packet->recoverablefilecount = totalfilecount;
  //packet->fileid;              // Compute shortly

  // Sort the source files according to their fileid values
  if (totalfilecount > 1)
  {
    sort(sourcefiles.begin(), sourcefiles.end(), Par2CreatorSourceFile::CompareLess);
  }

  // Store the fileid values in the main packet
  vector<Par2CreatorSourceFile*>::const_iterator sourcefile;
  MD5Hash *hash;
  for ((sourcefile=sourcefiles.begin()),(hash=packet->fileid);
       sourcefile!=sourcefiles.end();
       ++sourcefile, ++hash)
  {
    *hash = (*sourcefile)->FileId();
  }

  // Compute the set_id_hash
  MD5Context setidcontext;
  setidcontext.Update(&packet->blocksize, packetlength - offsetof(MAINPACKET, blocksize));
  setidcontext.Final(packet->header.setid);

  // Compute the packet_hash
  MD5Context packetcontext;
  packetcontext.Update(&packet->header.setid, packetlength - offsetof(MAINPACKET, header.setid));
  packetcontext.Final(packet->header.hash);

  return true;
}
Exemplo n.º 4
0
bool DescriptionPacket::Create(string filename, u64 filesize)
{
  // Allocate some extra bytes for the packet in memory so that strlen() can
  // be used on the filename. The extra bytes do not get written to disk.
  FILEDESCRIPTIONPACKET *packet = (FILEDESCRIPTIONPACKET *)AllocatePacket(sizeof(*packet) + (~3 & (3 + (u32)filename.size())), 4);

  // Store everything that is currently known in the packet.

  packet->header.magic  = packet_magic;
  packet->header.length = packetlength;
  //packet->header.hash;  // Not known yet
  //packet->header.setid; // Not known yet
  packet->header.type   = filedescriptionpacket_type;

  //packet->fileid;       // Not known yet
  //packet->hashfull;     // Not known yet
  //packet->hash16k;      // Not known yet
  packet->length        = filesize;

  memcpy(packet->name, filename.c_str(), filename.size());

  return true;
}
Exemplo n.º 5
0
bool CreatorPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header)
{
  // Is the packet long enough
  if (header.length <= sizeof(CREATORPACKET))
  {
    return false;
  }

  // Is the packet too large (what is the longest reasonable creator description)
  if (header.length - sizeof(CREATORPACKET) > 100000)
  {
    return false;
  }

  // Allocate the packet (with a little extra so we will have NULLs after the description)
  CREATORPACKET *packet = (CREATORPACKET *)AllocatePacket((size_t)header.length, 4);
  packet->header = header;

  // Load the rest of the packet from disk
  return diskfile->Read(offset + sizeof(PACKET_HEADER), 
                        packet->client, 
                        (size_t)packet->header.length - sizeof(PACKET_HEADER));
}
Exemplo n.º 6
0
bool CreatorPacket::Create(const MD5Hash &setid)
{
  string creator = "Created by " PACKAGE " version " VERSION ".";

  // Allocate a packet just large enough for creator name
  CREATORPACKET *packet = (CREATORPACKET *)AllocatePacket(sizeof(*packet) + (~3 & (3+(u32)creator.size())));

  // Fill in the details the we know
  packet->header.magic = packet_magic;
  packet->header.length = packetlength;
  //packet->header.hash;  // Compute shortly
  packet->header.setid = setid;
  packet->header.type = creatorpacket_type;

  // Copy the creator description into the packet
  memcpy(packet->client, creator.c_str(), creator.size());

  // Compute the packet hash
  MD5Context packetcontext;
  packetcontext.Update(&packet->header.setid, packetlength - offsetof(PACKET_HEADER, setid));
  packetcontext.Final(packet->header.hash);

  return true;
}
Exemplo n.º 7
0
AmDemuxerError CDemuxerAac::GetPacket(CPacket*& packet)
{
  AmDemuxerError ret = AM_DEMUXER_OK;
  packet = NULL;
  while (NULL == packet) {
    if (AM_UNLIKELY(NULL == mMedia)) {
      mNeedToRead = true;
      mAvailSize = 0;
      mSentSize = 0;
      mIsNewFile = (NULL != (mMedia = GetNewFile()));
      if (AM_UNLIKELY(!mMedia)) {
        ret = AM_DEMUXER_NO_FILE;
        break;
      } else {
        mRemainSize = mFileSize;
      }
    }

    if (AM_LIKELY(mMedia && mMedia->open(AmFile::AM_FILE_READONLY))) {
      AdtsHeader *adts = NULL;
      if (AM_LIKELY(mNeedToRead)) {
        ssize_t readSize = mMedia->read(mBuffer, FILE_BUFFER_SIZE);
        if (AM_UNLIKELY(readSize <= 0)) {
          if (readSize < 0) {
            ERROR("%s: %s! Skip!", mMedia->name(), strerror(errno));
          } else {
            INFO("%s EOF", mMedia->name());
          }
          delete mMedia;
          mMedia = NULL;
          continue;
        } else {
          mSentSize = 0;
          mAvailSize = readSize;
          mNeedToRead = false;
        }
      }
      adts = (AdtsHeader*)&mBuffer[mSentSize];
      if (AM_LIKELY(adts->IsSyncWordOk() &&
                    (mAvailSize > sizeof(AdtsHeader)) &&
                    (mAvailSize >= adts->FrameLength()))) {
        if (AM_LIKELY(AllocatePacket(packet))) {
          packet->SetAttr(CPacket::AM_PAYLOAD_ATTR_AUDIO);
          packet->SetFrameType(AM_AUDIO_CODEC_AAC);
          packet->SetStreamId(mStreamId);
          packet->SetPTS(0);
          if (AM_UNLIKELY(mIsNewFile)) {
            AM_AUDIO_INFO *audioInfo = ((AM_AUDIO_INFO*)packet->GetDataPtr());
            audioInfo->channels = adts->AacChannelConf();
            audioInfo->sampleRate = index_to_freq[adts->AacFrequencyIndex()];
            packet->SetType(CPacket::AM_PAYLOAD_TYPE_INFO);
            packet->SetDataSize(sizeof(AM_AUDIO_INFO));
            mIsNewFile = false;
          } else {
            AM_U16 framelen = adts->FrameLength();
            memcpy(packet->GetDataPtr(), &mBuffer[mSentSize], framelen);
            mSentSize += framelen;
            mAvailSize -= framelen;
            mRemainSize -= framelen;
            packet->SetType(CPacket::AM_PAYLOAD_TYPE_DATA);
            packet->SetDataSize(framelen);
            packet->SetDataOffset(0);
            mNeedToRead = (mAvailSize == 0);
          }
        } else {
          ret = AM_DEMUXER_NO_PACKET;
          break;
        }
      } else if (AM_LIKELY(adts->IsSyncWordOk())) {
        if (AM_UNLIKELY(mRemainSize < adts->FrameLength())) {
          WARN("%s is incomplete, the last ADTS reports length is %u bytes, "
               "but available file length is %llu bytes!",
               mMedia->name(), adts->FrameLength(), mRemainSize);
          delete mMedia;
          mMedia = NULL;
          continue;
        } else {
          mMedia->seek(-mAvailSize, AmFile::AM_FILE_SEEK_CUR);
          mNeedToRead = true;
        }
      } else {
        while ((mAvailSize >= sizeof(AdtsHeader)) && !adts->IsSyncWordOk()) {
          -- mAvailSize;
          -- mRemainSize;
          ++ mSentSize;
          adts = (AdtsHeader*)&mBuffer[mSentSize];
        }
        ERROR("Invalid ADTS, %u bytes data skipped!", mSentSize);
        if (AM_UNLIKELY(mRemainSize <= sizeof(AdtsHeader))) {
          delete mMedia;
          mMedia = NULL;
          continue;
        } else {
          mMedia->seek(-mAvailSize, AmFile::AM_FILE_SEEK_CUR);
          mNeedToRead = true;
        }
      }
    }
  }

  return ret;
}
Exemplo n.º 8
0
int Init_Networking(uint16_t port)
{
    if (proxyInit == true) {
        return BH_SRVR_FAILURE;
    }

    //
    // Create a socket using reliable bi-directional communication.
    // This translates down to a TCP-based socket over ipv4.
    int socket_descriptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (-1 == socket_descriptor) {
        printf("Failed creating socket.\n");
        return BH_SRVR_FAILURE;
    }

    // 
    // Socket options
    int yes = 1;
    if (no_delay) {
        int sockopt_res = setsockopt(socket_descriptor, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(int));
        if (sockopt_res < 0) {
            fprintf(stderr,
                    "Setsockopt(TCP_NODELAY) failed with error: %s\n",
                    strerror(errno));
            return BH_ERROR;
        }
    }
    if (reuse_addr) {
        int sockopt_res = setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof(int));
        if (sockopt_res < 0) {
            fprintf(stderr,
                    "Setsockopt(SO_REUSEADDR) failed with error: %s\n",
                    strerror(errno));
            return BH_ERROR;
        }   
    }

    //
    // Setup data-structure for binding on the socket
    struct sockaddr_in server_addr;
    memset(&server_addr, '0', sizeof(server_addr));
    server_addr.sin_family         = AF_INET;
    server_addr.sin_addr.s_addr    = htonl(INADDR_ANY);
    server_addr.sin_port           = htons(port);

    int bind_res = bind(
        socket_descriptor, 
        (struct sockaddr*)&server_addr,
        sizeof(server_addr)
    );
    if (-1 == bind_res) {
        close(socket_descriptor);
        printf("Bind failed with error: [%s], exiting.\n", strerror(errno));
        return BH_SRVR_SOCKET_BIND;
    }

    //
    // Start listening for connections on the socket
    int listen_res = listen(socket_descriptor, 1);
    if (-1 == listen_res) {
        printf("Listen failed with error: %s\n", strerror(errno));
        return BH_SRVR_LISTEN;
    }

    #ifdef PROXY_DEBUG
    printf("Server waiting for client to connect...\n");
    #endif

    //
    // Block until a client connects
    proxyfd = accept(socket_descriptor, 0, 0);
    if (-1 == proxyfd) {
        printf("Accept failed with error: [%s]\n", strerror(errno));
        return BH_SRVR_ACCEPT_ERR;
    }

    //
    // Now close the socket since we only use a single incoming connection
    // in our lifetime...
    int close_res = close(socket_descriptor);
    if (-1 == close_res) {
        printf("Closing socket file descriptor failed with error: [%s]\n", strerror(errno));
        return BH_ERROR;
    }

    //
    // Start the "bohrium-proxy-protocol" handshake with client.
    int handshake_res = PerformServerHandshake(proxyfd);
    if (BH_SRVR_SUCCESS != handshake_res) {
        return handshake_res;
    }

    //
    // What is this?
    recPack = AllocatePacket(DEFAULT_DATABUFFER_LENGTH);

    // What is this? init functions?
    ArrayMan_init();

    #ifdef PROXY_DEBUG
    printf("***Proxy initialization completed***\n\n");
    #endif

    proxyInit = true;
    return BH_SUCCESS;
}