mirror of
https://github.com/netchx/netch.git
synced 2026-03-14 17:43:18 +08:00
[Redirector] Update TCPHandler
This commit is contained in:
@@ -29,6 +29,11 @@ typedef enum _AIO_TYPE {
|
||||
AIO_FILTERTCP,
|
||||
AIO_FILTERUDP,
|
||||
|
||||
AIO_TGTHOST,
|
||||
AIO_TGTPORT,
|
||||
AIO_TGTUSER,
|
||||
AIO_TGTPASS,
|
||||
|
||||
AIO_CLRNAME,
|
||||
AIO_ADDNAME,
|
||||
AIO_BYPNAME
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include "EventHandler.h"
|
||||
|
||||
#include "SocksHelper.h"
|
||||
#include "TCPHandler.h"
|
||||
|
||||
extern BOOL filterTCP;
|
||||
extern BOOL filterUDP;
|
||||
extern vector<wstring> bypassList;
|
||||
extern vector<wstring> handleList;
|
||||
|
||||
extern USHORT tcpListen;
|
||||
|
||||
wstring ConvertIP(PSOCKADDR addr)
|
||||
{
|
||||
WCHAR buffer[MAX_PATH] = L"";
|
||||
@@ -84,14 +86,14 @@ BOOL checkHandleName(DWORD id)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL eh_init()
|
||||
bool eh_init()
|
||||
{
|
||||
return TRUE;
|
||||
return TCPHandler::Init();
|
||||
}
|
||||
|
||||
void eh_free()
|
||||
{
|
||||
|
||||
TCPHandler::Free();
|
||||
}
|
||||
|
||||
void threadStart()
|
||||
@@ -137,6 +139,31 @@ void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
|
||||
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!IPv4 && !IPv6] " << GetProcessName(info->processId) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
SOCKADDR_IN6 client;
|
||||
memcpy(&client, info->localAddress, sizeof(SOCKADDR_IN6));
|
||||
|
||||
SOCKADDR_IN6 remote;
|
||||
memcpy(&remote, info->remoteAddress, sizeof(SOCKADDR_IN6));
|
||||
|
||||
if (info->ip_family == AF_INET)
|
||||
{
|
||||
auto addr = (PSOCKADDR_IN)info->remoteAddress;
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
|
||||
addr->sin_port = htons(tcpListen);
|
||||
}
|
||||
|
||||
if (info->ip_family == AF_INET6)
|
||||
{
|
||||
auto addr = (PSOCKADDR_IN6)info->remoteAddress;
|
||||
IN6ADDR_SETLOOPBACK(addr);
|
||||
addr->sin6_port = htons(tcpListen);
|
||||
}
|
||||
|
||||
TCPHandler::CreateHandler(client, remote);
|
||||
|
||||
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "] " << ConvertIP((PSOCKADDR)&client) << " -> " << ConvertIP((PSOCKADDR)&remote) << endl;
|
||||
}
|
||||
|
||||
void tcpConnected(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
|
||||
@@ -166,6 +193,11 @@ void tcpReceive(ENDPOINT_ID id, const char* buffer, int length)
|
||||
|
||||
void tcpClosed(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
|
||||
{
|
||||
SOCKADDR_IN6 client;
|
||||
memcpy(&client, info->localAddress, sizeof(SOCKADDR_IN6));
|
||||
|
||||
TCPHandler::DeleteHandler(client);
|
||||
|
||||
printf("[Redirector][EventHandler][tcpClosed][%llu][%lu]\n", id, info->processId);
|
||||
}
|
||||
|
||||
@@ -194,6 +226,8 @@ void udpCreated(ENDPOINT_ID id, PNF_UDP_CONN_INFO info)
|
||||
wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!checkHandleName] " << GetProcessName(info->processId) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
nf_udpDisableFiltering(id);
|
||||
}
|
||||
|
||||
void udpConnectRequest(ENDPOINT_ID id, PNF_UDP_CONN_REQUEST info)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define EVENTHANDLER_H
|
||||
#include "Based.h"
|
||||
|
||||
BOOL eh_init();
|
||||
bool eh_init();
|
||||
void eh_free();
|
||||
|
||||
void threadStart();
|
||||
|
||||
@@ -8,6 +8,10 @@ extern BOOL filterIntranet;
|
||||
extern BOOL filterICMP;
|
||||
extern BOOL filterTCP;
|
||||
extern BOOL filterUDP;
|
||||
extern wstring tgtHost;
|
||||
extern wstring tgtPort;
|
||||
extern string tgtUsername;
|
||||
extern string tgtPassword;
|
||||
extern vector<wstring> bypassList;
|
||||
extern vector<wstring> handleList;
|
||||
|
||||
@@ -68,6 +72,18 @@ extern "C" {
|
||||
bypassList.clear();
|
||||
handleList.clear();
|
||||
break;
|
||||
case AIO_TGTHOST:
|
||||
tgtHost = wstring(value);
|
||||
break;
|
||||
case AIO_TGTPORT:
|
||||
tgtPort = wstring(value);
|
||||
break;
|
||||
case AIO_TGTUSER:
|
||||
tgtUsername = ws2s(value);
|
||||
break;
|
||||
case AIO_TGTPASS:
|
||||
tgtPassword = ws2s(value);
|
||||
break;
|
||||
case AIO_BYPNAME:
|
||||
try
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace SocksHelper
|
||||
bool ReadAddr(SOCKET client, char type, PSOCKADDR addr);
|
||||
}
|
||||
|
||||
class TCP
|
||||
typedef class TCP
|
||||
{
|
||||
public:
|
||||
TCP();
|
||||
@@ -26,9 +26,9 @@ namespace SocksHelper
|
||||
int Read(char* buffer, int length);
|
||||
|
||||
SOCKET tcpSocket = NULL;
|
||||
};
|
||||
} *PTCP;
|
||||
|
||||
class UDP
|
||||
typedef class UDP
|
||||
{
|
||||
public:
|
||||
UDP();
|
||||
@@ -48,7 +48,7 @@ namespace SocksHelper
|
||||
|
||||
thread tcpThread;
|
||||
SOCKADDR_IN6 address = { 0 };
|
||||
};
|
||||
} *PUDP;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1 +1,227 @@
|
||||
#include "TCPHandler.h"
|
||||
|
||||
SOCKET tcpSocket = NULL;
|
||||
USHORT tcpListen = 0;
|
||||
|
||||
mutex tcpLock;
|
||||
map<USHORT, SOCKADDR_IN6> tcpContext;
|
||||
|
||||
bool TCPHandler::Init()
|
||||
{
|
||||
auto lg = lock_guard<mutex>(tcpLock);
|
||||
|
||||
if (tcpSocket)
|
||||
{
|
||||
closesocket(tcpSocket);
|
||||
tcpSocket = NULL;
|
||||
}
|
||||
|
||||
auto client = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (!client)
|
||||
{
|
||||
printf("[Redirector][TCPHandler::Init] Create socket failed: %d\n", WSAGetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
int v6only = 0;
|
||||
if (setsockopt(client, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&v6only, sizeof(v6only)) == SOCKET_ERROR)
|
||||
{
|
||||
printf("[Redirector][TCPHandler::Init] Set socket option failed: %d\n", WSAGetLastError());
|
||||
|
||||
closesocket(client);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
SOCKADDR_IN6 addr;
|
||||
IN6ADDR_SETANY(&addr);
|
||||
|
||||
if (bind(client, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN6)) == SOCKET_ERROR)
|
||||
{
|
||||
printf("[Redirector][TCPHandler::Init] Bind socket failed: %d\n", WSAGetLastError());
|
||||
|
||||
closesocket(client);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (listen(client, 1024) == SOCKET_ERROR)
|
||||
{
|
||||
printf("[Redirector][TCPHandler::Init] Listen socket failed: %d\n", WSAGetLastError());
|
||||
|
||||
closesocket(client);
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
SOCKADDR_IN6 addr;
|
||||
int addrLength = 0;
|
||||
if (getsockname(client, (PSOCKADDR)&addr, &addrLength) == SOCKET_ERROR)
|
||||
{
|
||||
printf("[Redirector][TCPHandler::Init] Get listen address failed: %d\n", WSAGetLastError());
|
||||
|
||||
closesocket(client);
|
||||
return false;
|
||||
}
|
||||
|
||||
tcpListen = (addr.sin6_family == AF_INET6) ? addr.sin6_port : ((PSOCKADDR_IN)&addr)->sin_port;
|
||||
}
|
||||
|
||||
tcpSocket = client;
|
||||
|
||||
thread(TCPHandler::Accept).detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TCPHandler::Free()
|
||||
{
|
||||
auto lg = lock_guard<mutex>(tcpLock);
|
||||
|
||||
if (tcpSocket)
|
||||
{
|
||||
closesocket(tcpSocket);
|
||||
tcpSocket = NULL;
|
||||
}
|
||||
tcpListen = 0;
|
||||
|
||||
tcpContext.clear();
|
||||
}
|
||||
|
||||
void TCPHandler::CreateHandler(SOCKADDR_IN6 client, SOCKADDR_IN6 remote)
|
||||
{
|
||||
auto lg = lock_guard<mutex>(tcpLock);
|
||||
|
||||
auto id = (client.sin6_family == AF_INET6) ? client.sin6_port : ((PSOCKADDR_IN)&client)->sin_port;
|
||||
if (tcpContext.find(id) != tcpContext.end())
|
||||
{
|
||||
tcpContext.erase(id);
|
||||
}
|
||||
|
||||
tcpContext[id] = remote;
|
||||
}
|
||||
|
||||
void TCPHandler::DeleteHandler(SOCKADDR_IN6 client)
|
||||
{
|
||||
auto lg = lock_guard<mutex>(tcpLock);
|
||||
|
||||
auto id = (client.sin6_family == AF_INET6) ? client.sin6_port : ((PSOCKADDR_IN)&client)->sin_port;
|
||||
if (tcpContext.find(id) != tcpContext.end())
|
||||
{
|
||||
tcpContext.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
void TCPHandler::Accept()
|
||||
{
|
||||
SOCKADDR_IN6 addr;
|
||||
int addrLength = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto client = accept(tcpSocket, (PSOCKADDR)&addr, &addrLength);
|
||||
if (!client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
thread(TCPHandler::Handle, client).detach();
|
||||
}
|
||||
}
|
||||
|
||||
void TCPHandler::Handle(SOCKET client)
|
||||
{
|
||||
USHORT id = 0;
|
||||
{
|
||||
SOCKADDR_IN6 addr;
|
||||
int addrLength = 0;
|
||||
if (getpeername(client, (PSOCKADDR)&addr, &addrLength) == SOCKET_ERROR)
|
||||
{
|
||||
closesocket(client);
|
||||
return;
|
||||
}
|
||||
|
||||
id = (addr.sin6_family == AF_INET6) ? addr.sin6_port : ((PSOCKADDR_IN)&addr)->sin_port;
|
||||
}
|
||||
|
||||
auto remote = SocksHelper::Utils::Connect();
|
||||
if (!remote)
|
||||
{
|
||||
closesocket(client);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SocksHelper::Utils::Handshake(remote))
|
||||
{
|
||||
closesocket(client);
|
||||
closesocket(remote);
|
||||
return;
|
||||
}
|
||||
|
||||
tcpLock.lock();
|
||||
if (tcpContext.find(id) == tcpContext.end())
|
||||
{
|
||||
tcpLock.unlock();
|
||||
|
||||
closesocket(client);
|
||||
return;
|
||||
}
|
||||
|
||||
auto target = tcpContext[id];
|
||||
tcpLock.unlock();
|
||||
|
||||
auto conn = new SocksHelper::TCP(remote);
|
||||
if (!conn->Connect((PSOCKADDR)&target))
|
||||
{
|
||||
delete conn;
|
||||
|
||||
closesocket(client);
|
||||
return;
|
||||
}
|
||||
|
||||
thread(TCPHandler::Send, client, conn).detach();
|
||||
TCPHandler::Read(client, conn);
|
||||
|
||||
closesocket(client);
|
||||
closesocket(remote);
|
||||
delete conn;
|
||||
}
|
||||
|
||||
void TCPHandler::Read(SOCKET client, SocksHelper::PTCP remote)
|
||||
{
|
||||
char buffer[1446];
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto length = remote->Read(buffer, 1446);
|
||||
if (!length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (send(client, buffer, length, 0) != length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TCPHandler::Send(SOCKET client, SocksHelper::PTCP remote)
|
||||
{
|
||||
char buffer[1446];
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto length = recv(client, buffer, 1446, 0);
|
||||
if (!length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (remote->Send(buffer, length) != length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
#pragma once
|
||||
#ifndef TCPHANDLER_H
|
||||
#define TCPHANDLER_H
|
||||
#include "Based.h"
|
||||
|
||||
#include "SocksHelper.h"
|
||||
|
||||
namespace TCPHandler
|
||||
{
|
||||
bool Init();
|
||||
void Free();
|
||||
|
||||
void CreateHandler(SOCKADDR_IN6 client, SOCKADDR_IN6 remote);
|
||||
void DeleteHandler(SOCKADDR_IN6 client);
|
||||
|
||||
void Accept();
|
||||
void Handle(SOCKET client);
|
||||
|
||||
void Read(SOCKET client, SocksHelper::PTCP remote);
|
||||
void Send(SOCKET client, SocksHelper::PTCP remote);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user