📄 packets.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include <zlib/zlib.h>
#include "Packets.h"
#include "OtherFunctions.h"
#include "SafeFile.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#pragma pack(1)
struct Header_Struct{
uint8 eDonkeyID;
uint32 packetlength;
uint8 command;
};
#pragma pack()
#pragma pack(1)
struct UDP_Header_Struct{
uint8 eDonkeyID;
uint8 command;
};
#pragma pack()
Packet::Packet(uint8 protocol){
m_bSplitted = false;
m_bLastSplitted = false;
m_bFromPF = false;
size = 0;
pBuffer = 0;
completebuffer = 0;
tempbuffer = 0;
opcode = 0x00;
prot = protocol;
m_bPacked = false;
}
Packet::Packet(char* header){
m_bSplitted = false;
m_bPacked = false;
m_bLastSplitted = false;
m_bFromPF = false;
tempbuffer = 0;
pBuffer = 0;
completebuffer = 0;
Header_Struct* head = (Header_Struct*) header;
size = head->packetlength-1;
opcode = head->command;
prot = head->eDonkeyID;
}
Packet::Packet(char* pPacketPart, uint32 nSize, bool bLast, bool bFromPartFile){// only used for splitted packets!
m_bFromPF = bFromPartFile;
m_bSplitted = true;
m_bPacked = false;
m_bLastSplitted = bLast;
tempbuffer = 0;
pBuffer = 0;
completebuffer = pPacketPart;
size = nSize-6;
opcode = 0x00;
prot = 0x00;
}
Packet::Packet(uint8 in_opcode, uint32 in_size, uint8 protocol, bool bFromPartFile){
m_bFromPF = bFromPartFile;
m_bSplitted = false;
m_bPacked = false;
m_bLastSplitted = false;
tempbuffer = 0;
if (in_size){
completebuffer = new char[in_size+10];
pBuffer = completebuffer+6;
memset(completebuffer,0,in_size+10);
}
else{
pBuffer = 0;
completebuffer = 0;
}
opcode = in_opcode;
size = in_size;
prot = protocol;
}
Packet::Packet(CMemFile* datafile, uint8 protocol, uint8 ucOpcode){
m_bSplitted = false;
m_bPacked = false;
m_bLastSplitted = false;
m_bFromPF = false;
size = datafile->GetLength();
completebuffer = new char[datafile->GetLength()+10];
pBuffer = completebuffer+6;
BYTE* tmp = datafile->Detach();
memcpy(pBuffer,tmp,size);
free(tmp);
tempbuffer = 0;
opcode = ucOpcode;
prot = protocol;
}
Packet::Packet(const CStringA& str, uint8 ucProtocol, uint8 ucOpcode){
m_bSplitted = false;
m_bPacked = false;
m_bLastSplitted = false;
m_bFromPF = false;
size = str.GetLength();
completebuffer = new char[size+10];
pBuffer = completebuffer+6;
memcpy(pBuffer,(LPCSTR)str,size);
tempbuffer = 0;
opcode = ucOpcode;
prot = ucProtocol;
}
Packet::~Packet(){
if (completebuffer)
delete[] completebuffer;
else
delete [] pBuffer;
delete[] tempbuffer;
}
char* Packet::GetPacket(){
if (completebuffer){
if (!m_bSplitted)
memcpy(completebuffer,GetHeader(),6);
return completebuffer;
}
else{
if (tempbuffer){
delete[] tempbuffer;
tempbuffer = NULL; // 'new' may throw an exception
}
tempbuffer = new char[size+10];
memcpy(tempbuffer,GetHeader(),6);
memcpy(tempbuffer+6,pBuffer,size);
return tempbuffer;
}
}
char* Packet::DetachPacket(){
if (completebuffer){
if (!m_bSplitted)
memcpy(completebuffer,GetHeader(),6);
char* result = completebuffer;
completebuffer = 0;
pBuffer = 0;
return result;
}
else{
if (tempbuffer){
delete[] tempbuffer;
tempbuffer = NULL; // 'new' may throw an exception
}
tempbuffer = new char[size+10];
memcpy(tempbuffer,GetHeader(),6);
memcpy(tempbuffer+6,pBuffer,size);
char* result = tempbuffer;
tempbuffer = 0;
return result;
}
}
char* Packet::GetHeader(){
ASSERT ( !m_bSplitted );
Header_Struct* header = (Header_Struct*) head;
header->command = opcode;
header->eDonkeyID = prot;
header->packetlength = size+1;
return head;
}
char* Packet::GetUDPHeader(){
ASSERT ( !m_bSplitted );
UDP_Header_Struct* header = (UDP_Header_Struct*) head;
header->command = opcode;
header->eDonkeyID = prot;
return head;
}
void Packet::PackPacket(){
ASSERT (!m_bSplitted);
uLongf newsize = size+300;
BYTE* output = new BYTE[newsize];
uint16 result = compress2(output,&newsize,(BYTE*)pBuffer,size,Z_BEST_COMPRESSION);
if (result != Z_OK || size <= newsize){
delete[] output;
return;
}
if( prot == OP_KADEMLIAHEADER )
prot = OP_KADEMLIAPACKEDPROT;
else
prot = OP_PACKEDPROT;
memcpy(pBuffer,output,newsize);
size = newsize;
delete[] output;
m_bPacked = true;
}
bool Packet::UnPackPacket(UINT uMaxDecompressedSize){
ASSERT ( prot == OP_PACKEDPROT || prot == OP_KADEMLIAPACKEDPROT);
uint32 nNewSize = size*10+300;
if (nNewSize > uMaxDecompressedSize){
//ASSERT(0);
nNewSize = uMaxDecompressedSize;
}
BYTE* unpack = new BYTE[nNewSize];
uLongf unpackedsize = nNewSize;
uint16 result = uncompress(unpack,&unpackedsize,(BYTE*)pBuffer,size);
if (result == Z_OK){
ASSERT ( completebuffer == NULL );
ASSERT ( pBuffer != NULL );
size = unpackedsize;
delete[] pBuffer;
pBuffer = (char*)unpack;
if( prot == OP_KADEMLIAPACKEDPROT )
prot = OP_KADEMLIAHEADER;
else
prot = OP_EMULEPROT;
return true;
}
delete[] unpack;
return false;
}
///////////////////////////////////////////////////////////////////////////////
// CRawPacket
CRawPacket::CRawPacket(const CStringA& rstr)
{
ASSERT( opcode == 0 );
ASSERT( !m_bSplitted );
ASSERT( !m_bLastSplitted );
ASSERT( !m_bPacked );
ASSERT( !m_bFromPF );
ASSERT( completebuffer == NULL );
ASSERT( tempbuffer == NULL );
prot = 0x00;
size = rstr.GetLength();
pBuffer = new char[size];
memcpy(pBuffer, (LPCSTR)rstr, size);
}
CRawPacket::CRawPacket(const char* pcData, UINT uSize, bool bFromPartFile)
{
ASSERT( opcode == 0 );
ASSERT( !m_bSplitted );
ASSERT( !m_bLastSplitted );
ASSERT( !m_bPacked );
ASSERT( !m_bFromPF );
ASSERT( completebuffer == NULL );
ASSERT( tempbuffer == NULL );
prot = 0x00;
size = uSize;
pBuffer = new char[size];
memcpy(pBuffer, pcData, size);
m_bFromPF = bFromPartFile;
}
CRawPacket::~CRawPacket()
{
ASSERT( completebuffer == NULL );
}
char* CRawPacket::GetHeader()
{
ASSERT(0);
return NULL;
}
char* CRawPacket::GetUDPHeader()
{
ASSERT(0);
return NULL;
}
void CRawPacket::AttachPacket(char* pPacketData, UINT uPacketSize, bool bFromPartFile)
{
ASSERT( pBuffer == NULL );
pBuffer = pPacketData;
size = uPacketSize;
m_bFromPF = bFromPartFile;
}
char* CRawPacket::DetachPacket()
{
char* pResult = pBuffer;
pBuffer = NULL;
return pResult;
}
///////////////////////////////////////////////////////////////////////////////
// STag
STag::STag()
{
type = 0;
tagname = NULL;
stringvalue = NULL;
intvalue = 0;
specialtag = 0;
}
STag::STag(const STag& in)
{
type = in.type;
tagname = in.tagname!=NULL ? nstrdup(in.tagname) : NULL;
if (in.type == TAGTYPE_STRING)
stringvalue = in.stringvalue!=NULL ? nstrdup(in.stringvalue) : NULL;
else if (in.type == TAGTYPE_UINT32)
intvalue = in.intvalue;
else if (in.type == TAGTYPE_FLOAT32)
floatvalue = in.floatvalue;
else{
ASSERT(0);
intvalue = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -