Update Redirector

This commit is contained in:
Netch
2021-09-11 20:59:35 +08:00
parent 87fe315c71
commit 5c9faa3fe9
12 changed files with 103 additions and 675 deletions

View File

@@ -1,15 +1,9 @@
#include "Based.h"
BOOL filterLoopback = FALSE;
BOOL filterIntranet = FALSE;
BOOL filterICMP = TRUE;
BOOL filterTCP = TRUE;
BOOL filterUDP = TRUE;
USHORT tcpPort = 0;
USHORT udpPort = 0;
vector<wstring> bypassList;
vector<wstring> handleList;
mutex tcpLock;
mutex udpLock;
map<ENDPOINT_ID, PTCPINFO> tcpContext;
map<ENDPOINT_ID, PUDPINFO> udpContext;

View File

@@ -1,7 +1,6 @@
#pragma once
#ifndef BASED_H
#define BASED_H
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#include <stdio.h>
#include <map>
@@ -12,7 +11,6 @@
#include <string>
#include <vector>
#include <thread>
#include <codecvt>
#include <iostream>
#include <WinSock2.h>
@@ -26,27 +24,14 @@ using namespace std;
typedef enum _AIO_TYPE {
AIO_FILTERLOOPBACK,
AIO_FILTERINTRANET,
AIO_FILTERICMP,
AIO_FILTERTCP,
AIO_FILTERUDP,
AIO_CLRNAME,
AIO_ADDNAME,
AIO_BYPNAME,
AIO_TCPPORT,
AIO_UDPPORT
AIO_BYPNAME
} AIO_TYPE;
typedef struct _TCPINFO {
DWORD PID;
PBYTE Client[NF_MAX_ADDRESS_LENGTH];
PBYTE Target[NF_MAX_ADDRESS_LENGTH];
} TCPINFO, * PTCPINFO;
typedef struct _UDPINFO {
DWORD PID;
SOCKET Socket;
} UDPINFO, * PUDPINFO;
#endif

View File

@@ -1,38 +1,28 @@
#include "EventHandler.h"
#include "TCPHandler.h"
extern BOOL filterTCP;
extern BOOL filterUDP;
extern USHORT udpPort;
extern vector<wstring> bypassList;
extern vector<wstring> handleList;
extern mutex tcpLock;
extern mutex udpLock;
extern map<ENDPOINT_ID, PTCPINFO> tcpContext;
extern map<ENDPOINT_ID, PUDPINFO> udpContext;
PTCPHandler tcpHandler = NULL;
wstring getAddrString(PSOCKADDR addr)
wstring ConvertIP(PSOCKADDR addr)
{
WCHAR buffer[MAX_PATH] = L"";
DWORD bufferLength = MAX_PATH;
if (addr->sa_family == AF_INET)
{
WSAAddressToString(addr, sizeof(SOCKADDR_IN), NULL, buffer, &bufferLength);
WSAAddressToStringW(addr, sizeof(SOCKADDR_IN), NULL, buffer, &bufferLength);
}
else
{
WSAAddressToString(addr, sizeof(SOCKADDR_IN6), NULL, buffer, &bufferLength);
WSAAddressToStringW(addr, sizeof(SOCKADDR_IN6), NULL, buffer, &bufferLength);
}
return buffer;
}
wstring getProcessName(DWORD id)
wstring GetProcessName(DWORD id)
{
if (id == 0)
{
@@ -64,7 +54,7 @@ wstring getProcessName(DWORD id)
BOOL checkBypassName(DWORD id)
{
auto name = getProcessName(id);
auto name = GetProcessName(id);
for (size_t i = 0; i < bypassList.size(); i++)
{
@@ -79,7 +69,7 @@ BOOL checkBypassName(DWORD id)
BOOL checkHandleName(DWORD id)
{
auto name = getProcessName(id);
auto name = GetProcessName(id);
for (size_t i = 0; i < handleList.size(); i++)
{
@@ -94,52 +84,12 @@ BOOL checkHandleName(DWORD id)
BOOL eh_init()
{
tcpHandler = new TCPHandler();
if (!tcpHandler->init())
{
return FALSE;
}
return TRUE;
}
void eh_free()
{
{
lock_guard<mutex> lg(tcpLock);
for (auto& [k, v] : tcpContext)
{
delete v;
continue;
}
tcpContext.clear();
if (tcpHandler)
{
tcpHandler->free();
delete tcpHandler;
tcpHandler = NULL;
}
}
{
lock_guard<mutex> lg(udpLock);
for (auto& [k, v] : udpContext)
{
if (v->Socket)
{
closesocket(v->Socket);
v->Socket = NULL;
}
delete v;
continue;
}
udpContext.clear();
}
}
void threadStart()
@@ -158,7 +108,7 @@ void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
{
nf_tcpDisableFiltering(id);
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!filterTCP] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!filterTCP] " << GetProcessName(info->processId) << endl;
return;
}
@@ -166,7 +116,7 @@ void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
{
nf_tcpDisableFiltering(id);
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][checkBypassName] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][checkBypassName] " << GetProcessName(info->processId) << endl;
return;
}
@@ -174,7 +124,7 @@ void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
{
nf_tcpDisableFiltering(id);
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!checkHandleName] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!checkHandleName] " << GetProcessName(info->processId) << endl;
return;
}
@@ -182,32 +132,14 @@ void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
{
nf_tcpDisableFiltering(id);
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!IPv4 && !IPv6] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!IPv4 && !IPv6] " << GetProcessName(info->processId) << endl;
return;
}
tcpHandler->Create(id, info);
wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][" << getAddrString((PSOCKADDR)info->remoteAddress) << "] " << getProcessName(info->processId) << endl;
if (info->ip_family == AF_INET)
{
auto target = (PSOCKADDR_IN)info->remoteAddress;
target->sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
target->sin_port = htons(tcpHandler->ListenIPv4);
}
if (info->ip_family == AF_INET6)
{
auto target = (PSOCKADDR_IN6)info->remoteAddress;
memset(target->sin6_addr.u.Byte, 0, 16);
target->sin6_addr.u.Byte[15] = 0x01;
target->sin6_port = htons(tcpHandler->ListenIPv6);
}
}
void tcpConnected(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
{
wcout << "[Redirector][EventHandler][tcpConnected][" << id << "][" << info->processId << "][" << getAddrString((PSOCKADDR)info->remoteAddress) << "] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][tcpConnected][" << id << "][" << info->processId << "][" << ConvertIP((PSOCKADDR)info->remoteAddress) << "] " << GetProcessName(info->processId) << endl;
}
void tcpCanSend(ENDPOINT_ID id)
@@ -232,8 +164,6 @@ void tcpReceive(ENDPOINT_ID id, const char* buffer, int length)
void tcpClosed(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
{
tcpHandler->Delete(id);
printf("[Redirector][EventHandler][tcpClosed][%llu][%lu]\n", id, info->processId);
}
@@ -243,7 +173,7 @@ void udpCreated(ENDPOINT_ID id, PNF_UDP_CONN_INFO info)
{
nf_udpDisableFiltering(id);
wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!filterUDP] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!filterUDP] " << GetProcessName(info->processId) << endl;
return;
}
@@ -251,7 +181,7 @@ void udpCreated(ENDPOINT_ID id, PNF_UDP_CONN_INFO info)
{
nf_udpDisableFiltering(id);
wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][checkBypassName] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][checkBypassName] " << GetProcessName(info->processId) << endl;
return;
}
@@ -259,13 +189,9 @@ void udpCreated(ENDPOINT_ID id, PNF_UDP_CONN_INFO info)
{
nf_udpDisableFiltering(id);
wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!checkHandleName] " << getProcessName(info->processId) << endl;
wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!checkHandleName] " << GetProcessName(info->processId) << endl;
return;
}
lock_guard<mutex> lg(udpLock);
udpContext[id] = new UDPINFO();
udpContext[id]->PID = info->processId;
}
void udpConnectRequest(ENDPOINT_ID id, PNF_UDP_CONN_REQUEST info)
@@ -281,96 +207,7 @@ void udpCanSend(ENDPOINT_ID id)
void udpSend(ENDPOINT_ID id, const unsigned char* target, const char* buffer, int length, PNF_UDP_OPTIONS options)
{
lock_guard<mutex> lg(udpLock);
if (udpContext.find(id) == udpContext.end())
{
nf_udpPostSend(id, target, buffer, length, options);
return;
}
if (!udpContext[id]->Socket)
{
auto client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (!client)
{
printf("[Redirector][EventHandler][udpSend][%llu] Create socket failed: %d\n", id, WSAGetLastError());
return;
}
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 0;
if (bind(client, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
closesocket(client);
printf("[Redirector][EventHandler][udpSend][%llu] Bind socket failed: %d\n", id, WSAGetLastError());
return;
}
addr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(udpPort);
if (sendto(client, (PCHAR)&udpContext[id]->PID, 4, 0, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
closesocket(client);
printf("[Redirector][EventHandler][udpSend][%llu] Send initial data failed: %d\n", id, WSAGetLastError());
return;
}
udpContext[id]->Socket = client;
auto data = new BYTE[sizeof(NF_UDP_OPTIONS) + options->optionsLength - 1]();
memcpy(data, options, sizeof(NF_UDP_OPTIONS) + options->optionsLength - 1);
thread(&udpBeginReceive, id, client, data).detach();
}
char* data = NULL;
int dataLength = 0;
if (((PSOCKADDR)target)->sa_family == AF_INET)
{
dataLength = length + 7;
data = new char[dataLength]();
data[0] = 0x01;
auto addr = (PSOCKADDR_IN)target;
memcpy(data + 1, &addr->sin_addr, 4);
memcpy(data + 5, &addr->sin_port, 2);
memcpy(data + 7, buffer, length);
}
else if (((PSOCKADDR)target)->sa_family == AF_INET6)
{
dataLength = length + 19;
data = new char[dataLength]();
data[0] = 0x04;
auto addr = (PSOCKADDR_IN6)target;
memcpy(data + 1, &addr->sin6_addr, 16);
memcpy(data + 17, &addr->sin6_port, 2);
memcpy(data + 19, buffer, length);
}
else
{
nf_udpPostSend(id, target, buffer, length, options);
return;
}
if (data)
{
SOCKADDR_IN remote;
remote.sin_family = AF_INET;
remote.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
remote.sin_port = htons(udpPort);
if (sendto(udpContext[id]->Socket, data, dataLength, 0, (PSOCKADDR)&remote, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
printf("[Redirector][EventHandler][udpSend][%llu] Send data failed: %d\n", id, WSAGetLastError());
}
delete[] data;
}
nf_udpPostSend(id, target, buffer, length, options);
}
void udpCanReceive(ENDPOINT_ID id)
@@ -385,74 +222,6 @@ void udpReceive(ENDPOINT_ID id, const unsigned char* target, const char* buffer,
void udpClosed(ENDPOINT_ID id, PNF_UDP_CONN_INFO info)
{
UNREFERENCED_PARAMETER(id);
UNREFERENCED_PARAMETER(info);
lock_guard<mutex> lg(udpLock);
if (udpContext.find(id) != udpContext.end())
{
if (udpContext[id]->Socket != NULL)
{
closesocket(udpContext[id]->Socket);
udpContext[id]->Socket = NULL;
}
udpContext.erase(id);
}
printf("[Redirector][EventHandler][udpClosed][%llu]\n", id);
}
void udpBeginReceive(ENDPOINT_ID id, SOCKET client, PBYTE data)
{
auto buffer = new char[NF_TCP_PACKET_BUF_SIZE]();
while (true)
{
SOCKADDR_IN remote;
int remoteLength = sizeof(SOCKADDR_IN);
int length = recvfrom(client, buffer, NF_TCP_PACKET_BUF_SIZE, 0, (PSOCKADDR)&remote, &remoteLength);
if (length == 0)
{
break;
}
if (length == SOCKET_ERROR)
{
int last = WSAGetLastError();
if (last == 10004)
{
continue;
}
else if (last == 10038)
{
break;
}
printf("[Redirector][udpBeginReceive][%llu] Receive failed: %d\n", id, last);
break;
}
if (buffer[0] == 0x01 && length > 7)
{
SOCKADDR_IN target;
target.sin_family = AF_INET;
memcpy(&target.sin_addr, buffer + 1, 4);
memcpy(&target.sin_port, buffer + 5, 2);
nf_udpPostReceive(id, (PBYTE)&target, buffer + 7, length - 7, (PNF_UDP_OPTIONS)data);
}
else if (buffer[0] == 0x04 && length > 19)
{
SOCKADDR_IN6 target;
target.sin6_family = AF_INET6;
memcpy(&target.sin6_addr, buffer + 1, 16);
memcpy(&target.sin6_port, buffer + 17, 2);
nf_udpPostReceive(id, (PBYTE)&target, buffer + 19, length - 19, (PNF_UDP_OPTIONS)data);
}
}
delete[] data;
delete[] buffer;
}

View File

@@ -22,6 +22,5 @@ void udpSend(ENDPOINT_ID id, const unsigned char* target, const char* buffer, in
void udpCanReceive(ENDPOINT_ID id);
void udpReceive(ENDPOINT_ID id, const unsigned char* target, const char* buffer, int length, PNF_UDP_OPTIONS options);
void udpClosed(ENDPOINT_ID id, PNF_UDP_CONN_INFO info);
void udpBeginReceive(ENDPOINT_ID id, SOCKET client, PBYTE data);
#endif

View File

@@ -1,45 +0,0 @@
All address use SOCKS5 format
/* TCP */
First Packet
+--------+-----+
| Target | PID |
+--------+-----+
| ?????? | 4 |
+--------+-----+
Send
+------+
| Data |
+------+
| ???? |
+------+
Receive
+------+
| Data |
+------+
| ???? |
+------+
/* UDP */
First Packet
+-----+
| PID |
+-----+
| 4 |
+-----+
Send
+--------+------+
| Target | Data |
+--------+------+
| ?????? | ???? |
+--------+------+
Receive
+--------+------+
| Source | Data |
+--------+------+
| ?????? | ???? |
+--------+------+

1
Redirector/README.md Normal file
View File

@@ -0,0 +1 @@
# Redirector

View File

@@ -4,11 +4,10 @@
#include "Utils.h"
extern BOOL filterLoopback;
extern BOOL filterIntranet;
extern BOOL filterICMP;
extern BOOL filterTCP;
extern BOOL filterUDP;
extern USHORT tcpPort;
extern USHORT udpPort;
extern vector<wstring> bypassList;
extern vector<wstring> handleList;
@@ -53,6 +52,9 @@ extern "C" {
case AIO_FILTERLOOPBACK:
filterLoopback = (wstring(value).find(L"false") == string::npos);
break;
case AIO_FILTERINTRANET:
filterIntranet = (wstring(value).find(L"false") == string::npos);
break;
case AIO_FILTERICMP:
filterICMP = (wstring(value).find(L"false") == string::npos);
break;
@@ -88,12 +90,6 @@ extern "C" {
handleList.emplace_back(value);
break;
case AIO_TCPPORT:
tcpPort = (USHORT)atoi(ws2s(value).c_str());
break;
case AIO_UDPPORT:
udpPort = (USHORT)atoi(ws2s(value).c_str());
break;
default:
return FALSE;
}
@@ -141,6 +137,65 @@ extern "C" {
nf_addRule(&rule, FALSE);
}
if (!filterIntranet)
{
/* 10.0.0.0/8 */
memset(&rule, 0, sizeof(NF_RULE));
rule.ip_family = AF_INET;
inet_pton(AF_INET, "10.0.0.0", rule.remoteIpAddress);
inet_pton(AF_INET, "255.0.0.0", rule.remoteIpAddressMask);
rule.filteringFlag = NF_ALLOW;
nf_addRule(&rule, FALSE);
/* 100.64.0.0/10 */
memset(&rule, 0, sizeof(NF_RULE));
rule.ip_family = AF_INET;
inet_pton(AF_INET, "100.64.0.0", rule.remoteIpAddress);
inet_pton(AF_INET, "255.192.0.0", rule.remoteIpAddressMask);
rule.filteringFlag = NF_ALLOW;
nf_addRule(&rule, FALSE);
/* 169.254.0.0/16 */
memset(&rule, 0, sizeof(NF_RULE));
rule.ip_family = AF_INET;
inet_pton(AF_INET, "169.254.0.0", rule.remoteIpAddress);
inet_pton(AF_INET, "255.255.0.0", rule.remoteIpAddressMask);
rule.filteringFlag = NF_ALLOW;
nf_addRule(&rule, FALSE);
/* 172.16.0.0/12 */
memset(&rule, 0, sizeof(NF_RULE));
rule.ip_family = AF_INET;
inet_pton(AF_INET, "100.64.0.0", rule.remoteIpAddress);
inet_pton(AF_INET, "255.240.0.0", rule.remoteIpAddressMask);
rule.filteringFlag = NF_ALLOW;
nf_addRule(&rule, FALSE);
/* 192.0.0.0/24 */
memset(&rule, 0, sizeof(NF_RULE));
rule.ip_family = AF_INET;
inet_pton(AF_INET, "192.0.0.0", rule.remoteIpAddress);
inet_pton(AF_INET, "255.255.255.0", rule.remoteIpAddressMask);
rule.filteringFlag = NF_ALLOW;
nf_addRule(&rule, FALSE);
/* 192.168.0.0/16 */
memset(&rule, 0, sizeof(NF_RULE));
rule.ip_family = AF_INET;
inet_pton(AF_INET, "192.168.0.0", rule.remoteIpAddress);
inet_pton(AF_INET, "255.255.0.0", rule.remoteIpAddressMask);
rule.filteringFlag = NF_ALLOW;
nf_addRule(&rule, FALSE);
/* 198.18.0.0/15 */
memset(&rule, 0, sizeof(NF_RULE));
rule.ip_family = AF_INET;
inet_pton(AF_INET, "198.18.0.0", rule.remoteIpAddress);
inet_pton(AF_INET, "255.254.0.0", rule.remoteIpAddressMask);
rule.filteringFlag = NF_ALLOW;
nf_addRule(&rule, FALSE);
}
if (filterICMP)
{
nf_setIPEventHandler(&IPEventHandler);

View File

@@ -100,19 +100,14 @@
<ClCompile Include="EventHandler.cpp" />
<ClCompile Include="IPEventHandler.cpp" />
<ClCompile Include="Redirector.cpp" />
<ClCompile Include="TCPHandler.cpp" />
<ClCompile Include="Utils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="EventHandler.h" />
<ClInclude Include="IPEventHandler.h" />
<ClInclude Include="Based.h" />
<ClInclude Include="TCPHandler.h" />
<ClInclude Include="Utils.h" />
</ItemGroup>
<ItemGroup>
<Text Include="PROTOCOL.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@@ -20,9 +20,6 @@
<ClCompile Include="IPEventHandler.cpp">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="TCPHandler.cpp">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="Based.cpp">
<Filter>Source</Filter>
</ClCompile>
@@ -37,9 +34,6 @@
<ClInclude Include="IPEventHandler.h">
<Filter>Header</Filter>
</ClInclude>
<ClInclude Include="TCPHandler.h">
<Filter>Header</Filter>
</ClInclude>
<ClInclude Include="Based.h">
<Filter>Header</Filter>
</ClInclude>
@@ -47,7 +41,4 @@
<Filter>Header</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="PROTOCOL.txt" />
</ItemGroup>
</Project>

View File

@@ -1,305 +0,0 @@
#include "TCPHandler.h"
extern USHORT tcpPort;
extern mutex tcpLock;
extern map<ENDPOINT_ID, PTCPINFO> tcpContext;
void IoConn(SOCKET client, SOCKET remote)
{
auto buffer = new char[NF_TCP_PACKET_BUF_SIZE]();
while (true)
{
auto length = recv(client, buffer, NF_TCP_PACKET_BUF_SIZE, 0);
if (!length)
{
if (length == SOCKET_ERROR)
{
printf("[Redirector][TCPHandler][IoConn] Receive failed: %d\n", WSAGetLastError());
break;
}
continue;
}
auto sended = send(remote, buffer, length, 0);
if (!sended && sended != length)
{
printf("[Redirector][TCPHandler][IoConn] Send failed: %d\n", WSAGetLastError());
break;
}
}
delete[] buffer;
}
BOOL TCPHandler::init()
{
{
this->SocketIPv4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (!this->SocketIPv4)
{
printf("[Redirector][TCPHandler::init][IPv4] Create socket failed: %d\n", WSAGetLastError());
return FALSE;
}
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = 0;
if (bind(this->SocketIPv4, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
printf("[Redirector][TCPHandler::init][IPv4] Bind socket failed: %d\n", WSAGetLastError());
return FALSE;
}
if (listen(this->SocketIPv4, 1024) == SOCKET_ERROR)
{
printf("[Redirector][TCPHandler::init][IPv4] Listen socket failed: %d\n", WSAGetLastError());
return FALSE;
}
int addrLength = 0;
if (getsockname(this->SocketIPv4, (PSOCKADDR)&addr, &addrLength) != NO_ERROR)
{
printf("[Redirector][TCPHandler::init][IPv4] Get local address failed: %d\n", WSAGetLastError());
return FALSE;
}
this->ListenIPv4 = addr.sin_port;
}
{
this->SocketIPv6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (!this->SocketIPv6)
{
printf("[Redirector][TCPHandler::init][IPv6] Create socket failed: %d\n", WSAGetLastError());
return FALSE;
}
SOCKADDR_IN6 addr;
addr.sin6_family = AF_INET6;
addr.sin6_addr.u.Byte[15] = 1;
addr.sin6_port = 0;
if (bind(this->SocketIPv6, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN6)) == SOCKET_ERROR)
{
printf("[Redirector][TCPHandler::init][IPv6] Bind socket failed: %d\n", WSAGetLastError());
return FALSE;
}
if (listen(this->SocketIPv6, 1024) == SOCKET_ERROR)
{
printf("[Redirector][TCPHandler::init][IPv6] Listen socket failed: %d\n", WSAGetLastError());
return FALSE;
}
int addrLength = 0;
if (getsockname(this->SocketIPv6, (PSOCKADDR)&addr, &addrLength) != NO_ERROR)
{
printf("[Redirector][TCPHandler::init][IPv6] Get local address failed: %d\n", WSAGetLastError());
return FALSE;
}
this->ListenIPv6 = addr.sin6_port;
}
thread(&TCPHandler::IPv4, this).detach();
thread(&TCPHandler::IPv6, this).detach();
return TRUE;
}
void TCPHandler::free()
{
lock_guard<mutex> lg(this->Lock);
if (this->SocketIPv4)
{
closesocket(this->SocketIPv4);
this->SocketIPv4 = NULL;
}
if (this->SocketIPv6)
{
closesocket(this->SocketIPv6);
this->SocketIPv6 = NULL;
}
this->Context.clear();
}
void TCPHandler::Create(ENDPOINT_ID id, PNF_TCP_CONN_INFO info)
{
auto uid = (info->ip_family == AF_INET) ? ((PSOCKADDR_IN)info->localAddress)->sin_port : ((PSOCKADDR_IN6)info->localAddress)->sin6_port;
auto data = new TCPINFO();
data->PID = info->processId;
memcpy(data->Client, info->localAddress, NF_MAX_ADDRESS_LENGTH);
memcpy(data->Target, info->remoteAddress, NF_MAX_ADDRESS_LENGTH);
lock_guard<mutex> lga(tcpLock);
lock_guard<mutex> lgb(this->Lock);
tcpContext[id] = data;
this->Context[uid] = id;
}
void TCPHandler::Delete(ENDPOINT_ID id)
{
lock_guard<mutex> lga(tcpLock);
lock_guard<mutex> lgb(this->Lock);
if (tcpContext.find(id) != tcpContext.end())
{
delete tcpContext[id];
tcpContext.erase(id);
}
USHORT uid = 0;
for (auto i = this->Context.begin(); i != this->Context.end(); i++)
{
if (i->second == id)
{
uid = i->first;
break;
}
}
if (uid)
{
this->Context.erase(uid);
}
}
void TCPHandler::IPv4()
{
SOCKADDR_IN addr;
int addrLength = 0;
while (this->SocketIPv4)
{
auto client = accept(this->SocketIPv4, (PSOCKADDR)&addr, &addrLength);
if (!client)
{
printf("[Redirector][TCPHandler::IPv4] Accept client failed: %d\n", WSAGetLastError());
return;
}
{
lock_guard<mutex> lg(this->Lock);
if (this->Context.find(addr.sin_port) == this->Context.end())
{
closesocket(client);
continue;
}
}
thread(&TCPHandler::Handle, this, client, addr.sin_port).detach();
}
}
void TCPHandler::IPv6()
{
SOCKADDR_IN6 addr;
int addrLength = 0;
while (this->SocketIPv6)
{
auto client = accept(this->SocketIPv6, (PSOCKADDR)&addr, &addrLength);
if (!client)
{
printf("[Redirector][TCPHandler::IPv6] Accept client failed: %d\n", WSAGetLastError());
return;
}
{
lock_guard<mutex> lg(this->Lock);
if (this->Context.find(addr.sin6_port) == this->Context.end())
{
closesocket(client);
continue;
}
}
thread(&TCPHandler::Handle, this, client, addr.sin6_port).detach();
}
}
void TCPHandler::Handle(SOCKET client, USHORT side)
{
tcpLock.lock();
this->Lock.lock();
PTCPINFO data = tcpContext[this->Context[side]];
this->Lock.unlock();
tcpLock.unlock();
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(tcpPort);
auto remote = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (!remote)
{
printf("[Redirector][TCPHandler::Handle] Create socket failed: %d\n", WSAGetLastError());
closesocket(client);
return;
}
if (connect(remote, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) != NO_ERROR)
{
printf("[Redirector][TCPHandler::Handle] Connect to remote failed: %d\n", WSAGetLastError());
closesocket(client);
closesocket(remote);
return;
}
if (((PSOCKADDR)data->Target)->sa_family == AF_INET)
{
auto target = (PSOCKADDR_IN)data->Target;
char buffer[11];
buffer[0] = 0x01;
memcpy(buffer + 1, &target->sin_addr.S_un.S_addr, 4);
memcpy(buffer + 5, &target->sin_port, 2);
memcpy(buffer + 7, &data->PID, 4);
if (send(remote, buffer, 11, 0) == SOCKET_ERROR)
{
printf("[Redirector][TCPHandler::Handle] Send request failed: %d\n", WSAGetLastError());
closesocket(client);
closesocket(remote);
return;
}
}
else
{
auto target = (PSOCKADDR_IN6)data->Target;
char buffer[23];
buffer[0] = 0x04;
memcpy(buffer + 1, target->sin6_addr.u.Byte, 16);
memcpy(buffer + 17, &target->sin6_port, 2);
memcpy(buffer + 19, &data->PID, 4);
if (send(remote, buffer, 23, 0) == SOCKET_ERROR)
{
printf("[Redirector][TCPHandler::Handle] Send request failed: %d\n", WSAGetLastError());
closesocket(client);
closesocket(remote);
return;
}
}
thread(IoConn, client, remote).detach();
IoConn(remote, client);
closesocket(client);
closesocket(remote);
}

View File

@@ -1,29 +0,0 @@
#pragma once
#ifndef TCPHANDLER_H
#define TCPHANDLER_H
#include "Based.h"
typedef class TCPHandler
{
public:
BOOL init();
void free();
void Create(ENDPOINT_ID id, PNF_TCP_CONN_INFO info);
void Delete(ENDPOINT_ID id);
USHORT ListenIPv4 = 0;
USHORT ListenIPv6 = 0;
private:
void IPv4();
void IPv6();
void Handle(SOCKET client, USHORT side);
mutex Lock;
map<USHORT, ENDPOINT_ID> Context;
SOCKET SocketIPv4 = NULL;
SOCKET SocketIPv6 = NULL;
} *PTCPHandler;
#endif

View File

@@ -2,10 +2,28 @@
string ws2s(const wstring str)
{
return wstring_convert<codecvt_utf8<wchar_t>, wchar_t>().to_bytes(str);
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
if (WideCharToMultiByte(CP_ACP, 0, str.c_str(), (int)str.length(), NULL, 0, NULL, NULL) > 1024)
{
return "Convert Failed";
}
WideCharToMultiByte(CP_ACP, 0, str.c_str(), (int)str.length(), buffer, 1024, NULL, NULL);
return buffer;
}
wstring s2ws(const string str)
{
return wstring_convert<codecvt_utf8<wchar_t>, wchar_t>().from_bytes(str);
wchar_t buffer[1024];
memset(buffer, 0, sizeof(buffer));
if (MultiByteToWideChar(CP_ACP, 0, str.c_str(), (int)str.length(), NULL, 0) > 1024)
{
return L"Convert Failed";
}
MultiByteToWideChar(CP_ACP, 0, str.c_str(), (int)str.length(), buffer, 1024);
return buffer;
}