//Independent request process bool __fastcall EnterRequestProcess(const char *OriginalSend, const size_t Length, const SOCKET_DATA LocalSocketData, const uint16_t Protocol, const bool IsLocal) { //Initialization(Send buffer part) std::shared_ptr<char> SendBuffer, RecvBuffer; if (Parameter.CompressionPointerMutation) { if (Parameter.CPM_PointerToAdditional) { std::shared_ptr<char> SendBufferTemp(new char[Length + 2U + sizeof(dns_record_aaaa) + sizeof(uint16_t)]()); memset(SendBufferTemp.get(), 0, Length + 2U + sizeof(dns_record_aaaa) + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); } else if (Parameter.CPM_PointerToRR) { std::shared_ptr<char> SendBufferTemp(new char[Length + 2U + sizeof(uint16_t)]()); memset(SendBufferTemp.get(), 0, Length + 2U + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); } else { //Pointer to header std::shared_ptr<char> SendBufferTemp(new char[Length + 1U + sizeof(uint16_t)]()); memset(SendBufferTemp.get(), 0, Length + 1U + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); } } else { std::shared_ptr<char> SendBufferTemp(new char[Length + sizeof(uint16_t)]()); //Reserved 2 bytes for TCP header length. memset(SendBufferTemp.get(), 0, Length + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); } memcpy_s(SendBuffer.get(), Length, OriginalSend, Length); //Initialization(Receive buffer part) #if defined(ENABLE_LIBSODIUM) if (Parameter.RequestMode_Transport == REQUEST_MODE_TCP || Parameter.DNSCurve && DNSCurveParameter.DNSCurveMode == DNSCURVE_REQUEST_MODE_TCP || Protocol == IPPROTO_TCP) #else if (Parameter.RequestMode_Transport == REQUEST_MODE_TCP || Protocol == IPPROTO_TCP) #endif { std::shared_ptr<char> TCPRecvBuffer(new char[LARGE_PACKET_MAXSIZE + sizeof(uint16_t)]()); memset(TCPRecvBuffer.get(), 0, LARGE_PACKET_MAXSIZE + sizeof(uint16_t)); RecvBuffer.swap(TCPRecvBuffer); } else { //UDP std::shared_ptr<char> UDPRecvBuffer(new char[PACKET_MAXSIZE + sizeof(uint16_t)]()); memset(UDPRecvBuffer.get(), 0, PACKET_MAXSIZE + sizeof(uint16_t)); RecvBuffer.swap(UDPRecvBuffer); } size_t DataLength = 0; //Local server requesting if ((Parameter.LocalMain || IsLocal) && LocalRequestProcess(SendBuffer.get(), Length, RecvBuffer.get(), Protocol, LocalSocketData)) { //Fin TCP request connection. if (Protocol == IPPROTO_TCP && LocalSocketData.Socket != INVALID_SOCKET) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } auto DNS_Header = (pdns_hdr)SendBuffer.get(); DataLength = Length; //Compression Pointer Mutation if (Parameter.CompressionPointerMutation && DNS_Header->Additional == 0) { DataLength = MakeCompressionPointerMutation(SendBuffer.get(), Length); if (DataLength < Length) DataLength = Length; } //Direct Request requesting if (Parameter.DirectRequest > DIRECT_REQUEST_MODE_NONE && DirectRequestProcess(SendBuffer.get(), DataLength, RecvBuffer.get(), Protocol, true, LocalSocketData)) { //Fin TCP request connection. if (Protocol == IPPROTO_TCP && LocalSocketData.Socket != INVALID_SOCKET) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } //DNSCurve requesting #if defined(ENABLE_LIBSODIUM) if (Parameter.DNSCurve) { if (DNSCurveParameter.IsEncryption && //Send Length check (DataLength > DNSCurveParameter.DNSCurvePayloadSize + crypto_box_BOXZEROBYTES - (DNSCURVE_MAGIC_QUERY_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES) || //Receive Size check(TCP Mode) (Parameter.RequestMode_Transport == REQUEST_MODE_TCP || DNSCurveParameter.DNSCurveMode == DNSCURVE_REQUEST_MODE_TCP || Protocol == IPPROTO_TCP) && DNSCurveParameter.DNSCurvePayloadSize >= LARGE_PACKET_MAXSIZE && crypto_box_ZEROBYTES + DNSCURVE_MAGIC_QUERY_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + DataLength >= LARGE_PACKET_MAXSIZE || //Receive Size check(UDP Mode) Parameter.RequestMode_Transport != REQUEST_MODE_TCP && DNSCurveParameter.DNSCurveMode != DNSCURVE_REQUEST_MODE_TCP && Protocol != IPPROTO_TCP && DNSCurveParameter.DNSCurvePayloadSize >= PACKET_MAXSIZE && crypto_box_ZEROBYTES + DNSCURVE_MAGIC_QUERY_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + DataLength >= PACKET_MAXSIZE)) goto SkipDNSCurve; //DNSCurve requesting if (DNSCurveRequestProcess(SendBuffer.get(), DataLength, RecvBuffer.get(), Protocol, LocalSocketData)) return true; //DNSCurve Encryption Only mode if (DNSCurveParameter.IsEncryptionOnly) { //Fin TCP request connection. if (Protocol == IPPROTO_TCP && LocalSocketData.Socket != INVALID_SOCKET) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } } SkipDNSCurve: #endif //TCP requesting if ((Protocol == IPPROTO_TCP || Parameter.RequestMode_Transport == REQUEST_MODE_TCP) && TCPRequestProcess(SendBuffer.get(), DataLength, RecvBuffer.get(), Protocol, LocalSocketData)) return true; //Direct requesting when Pcap Capture module is turn OFF. #if defined(ENABLE_PCAP) if (!Parameter.PcapCapture) { #endif DirectRequestProcess(SendBuffer.get(), DataLength, RecvBuffer.get(), Protocol, false, LocalSocketData); //Fin TCP request connection. if (Protocol == IPPROTO_TCP && LocalSocketData.Socket != INVALID_SOCKET) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; #if defined(ENABLE_PCAP) } //UDP requesting RecvBuffer.reset(); UDPRequestProcess(SendBuffer.get(), DataLength, LocalSocketData, Protocol); return true; #endif }
//Independent request process bool __fastcall EnterRequestProcess( DNS_PACKET_DATA Packet, const SOCKET_DATA LocalSocketData) { //Initialization(Send buffer part) std::shared_ptr<char> SendBuffer; if (Packet.Protocol == IPPROTO_UDP) { if (Parameter.CompressionPointerMutation) { if (Parameter.CPM_PointerToAdditional) { std::shared_ptr<char> SendBufferTemp(new char[Packet.Length + 2U + sizeof(dns_record_aaaa) + sizeof(uint16_t)]()); memset(SendBufferTemp.get(), 0, Packet.Length + 2U + sizeof(dns_record_aaaa) + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); Packet.BufferSize = Packet.Length + 2U + sizeof(dns_record_aaaa) + sizeof(uint16_t); } else if (Parameter.CPM_PointerToRR) { std::shared_ptr<char> SendBufferTemp(new char[Packet.Length + 2U + sizeof(uint16_t)]()); memset(SendBufferTemp.get(), 0, Packet.Length + 2U + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); Packet.BufferSize = Packet.Length + 2U + sizeof(uint16_t); } else { //Pointer to header std::shared_ptr<char> SendBufferTemp(new char[Packet.Length + 1U + sizeof(uint16_t)]()); memset(SendBufferTemp.get(), 0, Packet.Length + 1U + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); Packet.BufferSize = Packet.Length + 1U + sizeof(uint16_t); } } else { std::shared_ptr<char> SendBufferTemp(new char[Packet.Length + sizeof(uint16_t)]()); //Reserved 2 bytes for TCP header length. memset(SendBufferTemp.get(), 0, Packet.Length + sizeof(uint16_t)); SendBufferTemp.swap(SendBuffer); Packet.BufferSize = Packet.Length + sizeof(uint16_t); } memcpy_s(SendBuffer.get(), Packet.BufferSize, Packet.Buffer, Packet.Length); Packet.Buffer = SendBuffer.get(); } //Initialization(Receive buffer part) std::shared_ptr<char> RecvBuffer; size_t RecvSize = 0; if (Parameter.RequestMode_Transport == REQUEST_MODE_TCP || Packet.Protocol == IPPROTO_TCP || //TCP request Parameter.LocalProtocol_Transport == REQUEST_MODE_TCP || //Local request Parameter.SOCKS_Proxy && Parameter.SOCKS_Protocol_Transport == REQUEST_MODE_TCP || //SOCKS TCP request Parameter.HTTP_Proxy //HTTP Proxy request #if defined(ENABLE_LIBSODIUM) || Parameter.DNSCurve && DNSCurveParameter.DNSCurveProtocol_Transport == REQUEST_MODE_TCP //DNSCurve TCP request #endif ) //TCP { std::shared_ptr<char> TCPRecvBuffer(new char[LARGE_PACKET_MAXSIZE + sizeof(uint16_t)]()); memset(TCPRecvBuffer.get(), 0, LARGE_PACKET_MAXSIZE + sizeof(uint16_t)); RecvBuffer.swap(TCPRecvBuffer); RecvSize = LARGE_PACKET_MAXSIZE; } else { //UDP std::shared_ptr<char> UDPRecvBuffer(new char[PACKET_MAXSIZE + sizeof(uint16_t)]()); memset(UDPRecvBuffer.get(), 0, PACKET_MAXSIZE + sizeof(uint16_t)); RecvBuffer.swap(UDPRecvBuffer); RecvSize = PACKET_MAXSIZE; } //Local request process if (Packet.IsLocal && LocalRequestProcess(Packet, RecvBuffer.get(), RecvSize, LocalSocketData)) { //Fin TCP request connection. if (Packet.Protocol == IPPROTO_TCP && SocketSetting(LocalSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr)) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } //Compression Pointer Mutation if (Parameter.CompressionPointerMutation && ((pdns_hdr)Packet.Buffer)->Additional == 0) { auto DataLength = MakeCompressionPointerMutation(Packet.Buffer, Packet.Length); if (DataLength > Packet.Length) Packet.Length = DataLength; } //SOCKS proxy request process if (Parameter.SOCKS_Proxy) { //SOCKS request if (SOCKSRequestProcess(Packet, RecvBuffer.get(), RecvSize, LocalSocketData)) return true; //SOCKS Proxy Only mode if (Parameter.SOCKS_Only) { //Fin TCP request connection. if (Packet.Protocol == IPPROTO_TCP && SocketSetting(LocalSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr)) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } } //HTTP proxy request process if (Parameter.HTTP_Proxy) { //HTTP request if (HTTPRequestProcess(Packet, RecvBuffer.get(), RecvSize, LocalSocketData)) return true; //HTTP Proxy Only mode if (Parameter.HTTP_Only) { //Fin TCP request connection. if (Packet.Protocol == IPPROTO_TCP && SocketSetting(LocalSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr)) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } } //Direct Request request process if (Parameter.DirectRequest > DIRECT_REQUEST_MODE_NONE && DirectRequestProcess(Packet, RecvBuffer.get(), RecvSize, true, LocalSocketData)) { //Fin TCP request connection. if (Packet.Protocol == IPPROTO_TCP && SocketSetting(LocalSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr)) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } //DNSCurve request process #if defined(ENABLE_LIBSODIUM) if (Parameter.DNSCurve) { //DNSCurve check if (DNSCurveParameter.IsEncryption && Packet.Length + DNSCRYPT_BUFFER_RESERVE_LEN > DNSCurveParameter.DNSCurvePayloadSize) goto SkipDNSCurve; //DNSCurve request if (DNSCurveRequestProcess(Packet, RecvBuffer.get(), RecvSize, LocalSocketData)) return true; //DNSCurve Encryption Only mode if (DNSCurveParameter.IsEncryptionOnly) { //Fin TCP request connection. if (Packet.Protocol == IPPROTO_TCP && SocketSetting(LocalSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr)) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; } } //Jump here to skip DNSCurve process. SkipDNSCurve: #endif //TCP request process if ((Parameter.RequestMode_Transport == REQUEST_MODE_TCP || Packet.Protocol == IPPROTO_TCP) && TCPRequestProcess(Packet, RecvBuffer.get(), RecvSize, LocalSocketData)) return true; //Direct request when Pcap Capture module is not available. #if defined(ENABLE_PCAP) if (!Parameter.PcapCapture) { #endif DirectRequestProcess(Packet, RecvBuffer.get(), RecvSize, false, LocalSocketData); //Fin TCP request connection. if (Packet.Protocol == IPPROTO_TCP && SocketSetting(LocalSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr)) { shutdown(LocalSocketData.Socket, SD_BOTH); closesocket(LocalSocketData.Socket); } return true; #if defined(ENABLE_PCAP) } //UDP request RecvBuffer.reset(); UDPRequestProcess(Packet, LocalSocketData); return true; #endif }