diff --git a/Redirector/Based.cpp b/Redirector/Based.cpp index 6a187502..ca408d7a 100644 --- a/Redirector/Based.cpp +++ b/Redirector/Based.cpp @@ -10,6 +10,8 @@ bool filterDNS = true; DWORD icmping = 0; +bool dnsOnly = false; +bool dnsProx = true; string dnsHost = "1.1.1.1"; USHORT dnsPort = 53; diff --git a/Redirector/Based.h b/Redirector/Based.h index 24db84af..3f56c676 100644 --- a/Redirector/Based.h +++ b/Redirector/Based.h @@ -36,6 +36,8 @@ typedef enum _AIO_TYPE { AIO_ICMPING, + AIO_DNSONLY, + AIO_DNSPROX, AIO_DNSHOST, AIO_DNSPORT, diff --git a/Redirector/DNSHandler.cpp b/Redirector/DNSHandler.cpp index 48e390f8..7f20327a 100644 --- a/Redirector/DNSHandler.cpp +++ b/Redirector/DNSHandler.cpp @@ -2,12 +2,58 @@ #include "SocksHelper.h" +extern bool dnsProx; extern string dnsHost; extern USHORT dnsPort; SOCKADDR_IN6 dnsAddr; -void HandleDNS(ENDPOINT_ID id, PSOCKADDR_IN6 target, char* packet, int length, PNF_UDP_OPTIONS option) +void HandleClientDNS(ENDPOINT_ID id, PSOCKADDR_IN6 target, char* packet, int length, PNF_UDP_OPTIONS option) +{ + auto remote = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (remote != INVALID_SOCKET) + { + int v6only = 0; + + if (setsockopt(remote, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&v6only, sizeof(v6only)) != SOCKET_ERROR) + { + SOCKADDR_IN6 addr; + IN6ADDR_SETANY(&addr); + + if (bind(remote, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN6)) != SOCKET_ERROR) + { + if (sendto(remote, packet, length, 0, (PSOCKADDR)&dnsAddr, (dnsAddr.sin6_family == AF_INET ? sizeof(SOCKADDR_IN) : sizeof(SOCKADDR_IN6))) == length) + { + timeval timeout{}; + timeout.tv_sec = 4; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(remote, &fds); + + int size = select(NULL, &fds, NULL, NULL, &timeout); + if (size != 0 && size != SOCKET_ERROR) + { + char buffer[1024]; + + size = recvfrom(remote, buffer, sizeof(buffer), 0, NULL, NULL); + if (size != 0 && size != SOCKET_ERROR) + nf_udpPostReceive(id, (PBYTE)target, buffer, size, option); + } + } + } + } + } + + if (remote != INVALID_SOCKET) + closesocket(remote); + + delete target; + delete[] packet; + delete[] option; +} + +void HandleRemoteDNS(ENDPOINT_ID id, PSOCKADDR_IN6 target, char* packet, int length, PNF_UDP_OPTIONS option) { auto remote = new SocksHelper::UDP(); if (remote->Associate()) @@ -23,7 +69,7 @@ void HandleDNS(ENDPOINT_ID id, PSOCKADDR_IN6 target, char* packet, int length, P int size = remote->Read(NULL, buffer, sizeof(buffer), &timeout); if (size != 0 && size != SOCKET_ERROR) - nf_udpPostReceive(id, (unsigned char*)target, buffer, size, option); + nf_udpPostReceive(id, (PBYTE)target, buffer, size, option); } } } @@ -60,13 +106,9 @@ bool DNSHandler::INIT() bool DNSHandler::IsDNS(PSOCKADDR_IN6 target) { if (target->sin6_family == AF_INET) - { return ((PSOCKADDR_IN)target)->sin_port == htons(53); - } else - { return target->sin6_port == htons(53); - } } void DNSHandler::CreateHandler(ENDPOINT_ID id, PSOCKADDR_IN6 target, const char* packet, int length, PNF_UDP_OPTIONS options) @@ -79,5 +121,8 @@ void DNSHandler::CreateHandler(ENDPOINT_ID id, PSOCKADDR_IN6 target, const char* memcpy(buffer, packet, length); memcpy(option, options, sizeof(NF_UDP_OPTIONS) + options->optionsLength - 1); - thread(HandleDNS, id, remote, buffer, length, option).detach(); + if (!dnsProx) + thread(HandleClientDNS, id, remote, buffer, length, option).detach(); + else + thread(HandleRemoteDNS, id, remote, buffer, length, option).detach(); } diff --git a/Redirector/EventHandler.cpp b/Redirector/EventHandler.cpp index a8f155bf..00c39030 100644 --- a/Redirector/EventHandler.cpp +++ b/Redirector/EventHandler.cpp @@ -8,6 +8,8 @@ extern bool filterTCP; extern bool filterUDP; extern bool filterDNS; +extern bool dnsOnly; + extern vector bypassList; extern vector handleList; @@ -279,18 +281,24 @@ void udpCreated(ENDPOINT_ID id, PNF_UDP_CONN_INFO info) if (!filterUDP) { + if (!filterDNS) nf_udpDisableFiltering(id); + wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!filterUDP] " << GetProcessName(info->processId) << endl; return; } if (checkBypassName(info->processId)) { + if (dnsOnly) nf_udpDisableFiltering(id); + wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][checkBypassName] " << GetProcessName(info->processId) << endl; return; } if (!checkHandleName(info->processId)) { + if (dnsOnly) nf_udpDisableFiltering(id); + wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!checkHandleName] " << GetProcessName(info->processId) << endl; return; } diff --git a/Redirector/README.md b/Redirector/README.md index c85198c3..34c79378 100644 --- a/Redirector/README.md +++ b/Redirector/README.md @@ -11,6 +11,8 @@ typedef enum _AIO_TYPE { AIO_ICMPING, + AIO_DNSONLY, + AIO_DNSPROX, AIO_DNSHOST, AIO_DNSPORT, @@ -46,6 +48,8 @@ private enum NameList : int AIO_ICMPING, + AIO_DNSONLY, + AIO_DNSPROX, AIO_DNSHOST, AIO_DNSPORT, diff --git a/Redirector/Redirector.cpp b/Redirector/Redirector.cpp index 94a3129e..b83958e4 100644 --- a/Redirector/Redirector.cpp +++ b/Redirector/Redirector.cpp @@ -13,6 +13,8 @@ extern bool filterDNS; extern DWORD icmping; +extern bool dnsOnly; +extern bool dnsProx; extern string dnsHost; extern USHORT dnsPort; @@ -113,6 +115,12 @@ extern "C" { case AIO_ICMPING: icmping = atoi(ws2s(value).c_str()); break; + case AIO_DNSONLY: + dnsOnly = (wstring(value).find(L"false") == string::npos); + break; + case AIO_DNSPROX: + dnsProx = (wstring(value).find(L"false") == string::npos); + break; case AIO_DNSHOST: dnsHost = ws2s(value); break; diff --git a/Redirector/SocksHelper.cpp b/Redirector/SocksHelper.cpp index fe1b5543..55b6253b 100644 --- a/Redirector/SocksHelper.cpp +++ b/Redirector/SocksHelper.cpp @@ -197,7 +197,7 @@ bool SocksHelper::TCP::Connect(PSOCKADDR_IN6 target) /* Connect Request */ if (target->sin6_family == AF_INET) { - char buffer[10]; + char buffer[10]{}; buffer[0] = 0x05; buffer[1] = 0x01; buffer[2] = 0x00; @@ -215,7 +215,7 @@ bool SocksHelper::TCP::Connect(PSOCKADDR_IN6 target) } else { - char buffer[22]; + char buffer[22]{}; buffer[0] = 0x05; buffer[1] = 0x01; buffer[2] = 0x00;