From 8b98df81e5730b331c681de7aef8672f80dae847 Mon Sep 17 00:00:00 2001 From: Connection Refused Date: Tue, 21 Sep 2021 16:39:07 +0800 Subject: [PATCH] [Redirector] Update TCPHandler --- Redirector/Based.h | 5 + Redirector/EventHandler.cpp | 42 ++++++- Redirector/EventHandler.h | 2 +- Redirector/Redirector.cpp | 16 +++ Redirector/SocksHelper.h | 8 +- Redirector/TCPHandler.cpp | 226 ++++++++++++++++++++++++++++++++++++ Redirector/TCPHandler.h | 18 +++ 7 files changed, 308 insertions(+), 9 deletions(-) diff --git a/Redirector/Based.h b/Redirector/Based.h index 534c3853..b7ab994a 100644 --- a/Redirector/Based.h +++ b/Redirector/Based.h @@ -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 diff --git a/Redirector/EventHandler.cpp b/Redirector/EventHandler.cpp index ed9d8046..d35c074a 100644 --- a/Redirector/EventHandler.cpp +++ b/Redirector/EventHandler.cpp @@ -1,12 +1,14 @@ #include "EventHandler.h" -#include "SocksHelper.h" +#include "TCPHandler.h" extern BOOL filterTCP; extern BOOL filterUDP; extern vector bypassList; extern vector 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) diff --git a/Redirector/EventHandler.h b/Redirector/EventHandler.h index c37c167e..7932b5d5 100644 --- a/Redirector/EventHandler.h +++ b/Redirector/EventHandler.h @@ -3,7 +3,7 @@ #define EVENTHANDLER_H #include "Based.h" -BOOL eh_init(); +bool eh_init(); void eh_free(); void threadStart(); diff --git a/Redirector/Redirector.cpp b/Redirector/Redirector.cpp index 7f0d2abf..93064c16 100644 --- a/Redirector/Redirector.cpp +++ b/Redirector/Redirector.cpp @@ -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 bypassList; extern vector 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 { diff --git a/Redirector/SocksHelper.h b/Redirector/SocksHelper.h index 42822bf7..0f01129f 100644 --- a/Redirector/SocksHelper.h +++ b/Redirector/SocksHelper.h @@ -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 diff --git a/Redirector/TCPHandler.cpp b/Redirector/TCPHandler.cpp index 0f5578dc..ee99d10d 100644 --- a/Redirector/TCPHandler.cpp +++ b/Redirector/TCPHandler.cpp @@ -1 +1,227 @@ #include "TCPHandler.h" + +SOCKET tcpSocket = NULL; +USHORT tcpListen = 0; + +mutex tcpLock; +map tcpContext; + +bool TCPHandler::Init() +{ + auto lg = lock_guard(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(tcpLock); + + if (tcpSocket) + { + closesocket(tcpSocket); + tcpSocket = NULL; + } + tcpListen = 0; + + tcpContext.clear(); +} + +void TCPHandler::CreateHandler(SOCKADDR_IN6 client, SOCKADDR_IN6 remote) +{ + auto lg = lock_guard(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(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; + } + } +} diff --git a/Redirector/TCPHandler.h b/Redirector/TCPHandler.h index 49e3412a..8536f7da 100644 --- a/Redirector/TCPHandler.h +++ b/Redirector/TCPHandler.h @@ -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