// 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; }
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; }
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; }
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; }
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)); }
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; }
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; }
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; }