//Request Process(Local part) bool __fastcall LocalRequestProcess(const char *OriginalSend, const size_t SendSize, PSTR OriginalRecv, const uint16_t Protocol, const SOCKET_DATA &LocalSocketData) { size_t DataLength = 0; //TCP Mode if (Parameter.RequestMode_Transport == REQUEST_MODE_TCP || Protocol == IPPROTO_TCP) { DataLength = TCPRequest(OriginalSend, SendSize, OriginalRecv, LARGE_PACKET_MAXSIZE, true); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < LARGE_PACKET_MAXSIZE) { SendToRequester(OriginalRecv, DataLength, Protocol, LocalSocketData); return true; } } //UDP Mode(REQUEST_MODE_UDP) if (Protocol == IPPROTO_TCP) //TCP requesting DataLength = LARGE_PACKET_MAXSIZE; //UDP requesting else DataLength = PACKET_MAXSIZE; DataLength = UDPCompleteRequest(OriginalSend, SendSize, OriginalRecv, DataLength, true); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && (DataLength < PACKET_MAXSIZE || Protocol == IPPROTO_TCP && DataLength < LARGE_PACKET_MAXSIZE)) { SendToRequester(OriginalRecv, DataLength, Protocol, LocalSocketData); return true; } return false; }
//Request Process(Direct connections part) bool __fastcall DirectRequestProcess( const char *OriginalSend, const size_t SendSize, PSTR OriginalRecv, const uint16_t Protocol, const bool DirectRequest, const SOCKET_DATA &LocalSocketData) { size_t DataLength = 0; //Direct Request mode check DataLength = SelectNetworkProtocol(); if (DirectRequest && (DataLength == AF_INET6 && Parameter.DirectRequest == DIRECT_REQUEST_MODE_IPV4 || //IPv6 DataLength == AF_INET && Parameter.DirectRequest == DIRECT_REQUEST_MODE_IPV6)) //IPv4 return false; //TCP Mode if (Parameter.RequestMode_Transport == REQUEST_MODE_TCP || Protocol == IPPROTO_TCP) { //Multi requesting. if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) DataLength = TCPRequestMulti(OriginalSend, SendSize, OriginalRecv, LARGE_PACKET_MAXSIZE); //Normal requesting else DataLength = TCPRequest(OriginalSend, SendSize, OriginalRecv, LARGE_PACKET_MAXSIZE, false); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < LARGE_PACKET_MAXSIZE) { SendToRequester(OriginalRecv, DataLength, Protocol, LocalSocketData); return true; } } //UDP Mode(REQUEST_MODE_UDP) if (Protocol == IPPROTO_TCP) //TCP requesting DataLength = LARGE_PACKET_MAXSIZE; else //UDP requesting DataLength = PACKET_MAXSIZE; //Multi requesting. if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) DataLength = UDPCompleteRequestMulti(OriginalSend, SendSize, OriginalRecv, DataLength); //Normal requesting else DataLength = UDPCompleteRequest(OriginalSend, SendSize, OriginalRecv, DataLength, false); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && (DataLength < PACKET_MAXSIZE || Protocol == IPPROTO_TCP && DataLength < LARGE_PACKET_MAXSIZE)) { SendToRequester(OriginalRecv, DataLength, Protocol, LocalSocketData); return true; } return false; }
//Request Process(SOCKS part) bool __fastcall SOCKSRequestProcess( const DNS_PACKET_DATA &Packet, char *OriginalRecv, const size_t RecvSize, const SOCKET_DATA &LocalSocketData) { size_t DataLength = 0; memset(OriginalRecv, 0, RecvSize); //EDNS switching(Part 1) size_t EDNS_SwitchLength = Packet.Length; uint16_t EDNS_Packet_Flags = ((dns_hdr *)(Packet.Buffer))->Flags; if (Parameter.EDNS_Label && !Parameter.EDNS_Switch.EDNS_SOCKS) { //Reset EDNS flags, resource record counts and packet length. ((dns_hdr *)(Packet.Buffer))->Flags = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Flags) & (~DNS_GET_BIT_AD)); ((dns_hdr *)(Packet.Buffer))->Flags = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Flags) & (~DNS_GET_BIT_CD)); if (((dns_hdr *)(Packet.Buffer))->Additional > 0) ((dns_hdr *)(Packet.Buffer))->Additional = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Additional) - 1U); EDNS_SwitchLength -= Packet.EDNS_Record; } //UDP request if (Parameter.SOCKS_Version == SOCKS_VERSION_5 && Parameter.SOCKS_Protocol_Transport == REQUEST_MODE_UDP) { //UDP request process DataLength = SOCKSUDPRequest(Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < RecvSize) { SendToRequester(OriginalRecv, DataLength, RecvSize, Packet.Protocol, LocalSocketData); return true; } } //TCP request DataLength = SOCKSTCPRequest(Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < RecvSize) { SendToRequester(OriginalRecv, DataLength, RecvSize, Packet.Protocol, LocalSocketData); return true; } //EDNS switching(Part 2) if (Parameter.EDNS_Label && !Parameter.EDNS_Switch.EDNS_SOCKS) { ((dns_hdr *)(Packet.Buffer))->Flags = EDNS_Packet_Flags; ((dns_hdr *)(Packet.Buffer))->Additional = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Additional) + 1U); } return false; }
bool __fastcall DNSCurveRequestProcess( const char *OriginalSend, const size_t SendSize, PSTR OriginalRecv, const uint16_t Protocol, const SOCKET_DATA &LocalSocketData) { size_t DataLength = 0; //TCP requesting if (DNSCurveParameter.DNSCurveProtocol_Transport == REQUEST_MODE_TCP || Protocol == IPPROTO_TCP) { //Multi requesting. if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) DataLength = DNSCurveTCPRequestMulti(OriginalSend, SendSize, OriginalRecv, LARGE_PACKET_MAXSIZE); //Normal requesting else DataLength = DNSCurveTCPRequest(OriginalSend, SendSize, OriginalRecv, LARGE_PACKET_MAXSIZE); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < LARGE_PACKET_MAXSIZE) { SendToRequester(OriginalRecv, DataLength, Protocol, LocalSocketData); return true; } } //UDP Mode(REQUEST_MODE_UDP) if (Protocol == IPPROTO_TCP) //TCP requesting DataLength = LARGE_PACKET_MAXSIZE; else //UDP requesting DataLength = PACKET_MAXSIZE; //Multi requesting. if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) DataLength = DNSCurveUDPRequestMulti(OriginalSend, SendSize, OriginalRecv, DataLength); //Normal requesting else DataLength = DNSCurveUDPRequest(OriginalSend, SendSize, OriginalRecv, DataLength); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && (DataLength < PACKET_MAXSIZE || Protocol == IPPROTO_TCP && DataLength < LARGE_PACKET_MAXSIZE)) { SendToRequester(OriginalRecv, DataLength, Protocol, LocalSocketData); return true; } return false; }
//Request Process(TCP part) bool __fastcall TCPRequestProcess( const char *OriginalSend, const size_t SendSize, PSTR OriginalRecv, const uint16_t Protocol, const SOCKET_DATA &LocalSocketData) { size_t DataLength = 0; //Multi requesting. if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) DataLength = TCPRequestMulti(OriginalSend, SendSize, OriginalRecv, LARGE_PACKET_MAXSIZE); //Normal requesting else DataLength = TCPRequest(OriginalSend, SendSize, OriginalRecv, LARGE_PACKET_MAXSIZE, false); //Send response. if (DataLength >= sizeof(uint16_t) + DNS_PACKET_MINSIZE && DataLength < LARGE_PACKET_MAXSIZE) { SendToRequester(OriginalRecv, DataLength, Protocol, LocalSocketData); return true; } return false; }
//Request Process(TCP part) bool __fastcall TCPRequestProcess( const DNS_PACKET_DATA &Packet, char *OriginalRecv, const size_t RecvSize, const SOCKET_DATA &LocalSocketData) { size_t DataLength = 0; memset(OriginalRecv, 0, RecvSize); //EDNS switching(Part 1) size_t EDNS_SwitchLength = Packet.Length; uint16_t EDNS_Packet_Flags = ((dns_hdr *)(Packet.Buffer))->Flags; if (Parameter.EDNS_Label && !Parameter.EDNS_Switch.EDNS_TCP) { //Reset EDNS flags, resource record counts and packet length. ((dns_hdr *)(Packet.Buffer))->Flags = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Flags) & (~DNS_GET_BIT_AD)); ((dns_hdr *)(Packet.Buffer))->Flags = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Flags) & (~DNS_GET_BIT_CD)); if (((dns_hdr *)(Packet.Buffer))->Additional > 0) ((dns_hdr *)(Packet.Buffer))->Additional = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Additional) - 1U); EDNS_SwitchLength -= Packet.EDNS_Record; } //Multi request process if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) DataLength = TCPRequestMulti(REQUEST_PROCESS_TCP, Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); //Normal request process else DataLength = TCPRequest(REQUEST_PROCESS_TCP, Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < RecvSize) { SendToRequester(OriginalRecv, DataLength, RecvSize, Packet.Protocol, LocalSocketData); return true; } //EDNS switching(Part 2) if (Parameter.EDNS_Label && !Parameter.EDNS_Switch.EDNS_TCP) { ((dns_hdr *)(Packet.Buffer))->Flags = EDNS_Packet_Flags; ((dns_hdr *)(Packet.Buffer))->Additional = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Additional) + 1U); } return false; }
//Request Process(Direct connections part) bool __fastcall DirectRequestProcess( const DNS_PACKET_DATA &Packet, char *OriginalRecv, const size_t RecvSize, const bool DirectRequest, const SOCKET_DATA &LocalSocketData) { size_t DataLength = 0; memset(OriginalRecv, 0, RecvSize); //Direct Request mode check DataLength = SelectNetworkProtocol(); if (DirectRequest && (DataLength == AF_INET6 && Parameter.DirectRequest == DIRECT_REQUEST_MODE_IPV4 || //IPv6 DataLength == AF_INET && Parameter.DirectRequest == DIRECT_REQUEST_MODE_IPV6)) //IPv4 return false; //EDNS switching(Part 1) size_t EDNS_SwitchLength = Packet.Length; uint16_t EDNS_Packet_Flags = ((dns_hdr *)(Packet.Buffer))->Flags; if (Parameter.EDNS_Label && !Parameter.EDNS_Switch.EDNS_Direct) { //Reset EDNS flags, resource record counts and packet length. ((dns_hdr *)(Packet.Buffer))->Flags = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Flags) & (~DNS_GET_BIT_AD)); ((dns_hdr *)(Packet.Buffer))->Flags = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Flags) & (~DNS_GET_BIT_CD)); if (((dns_hdr *)(Packet.Buffer))->Additional > 0) ((dns_hdr *)(Packet.Buffer))->Additional = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Additional) - 1U); EDNS_SwitchLength -= Packet.EDNS_Record; } //TCP request if (Parameter.RequestMode_Transport == REQUEST_MODE_TCP || Packet.Protocol == IPPROTO_TCP) { //Multi request process if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) DataLength = TCPRequestMulti(REQUEST_PROCESS_DIRECT, Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); //Normal request process else DataLength = TCPRequest(REQUEST_PROCESS_DIRECT, Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < RecvSize) { SendToRequester(OriginalRecv, DataLength, RecvSize, Packet.Protocol, LocalSocketData); return true; } } //UDP request if (Parameter.AlternateMultiRequest || Parameter.MultiRequestTimes > 1U) //Multi request process DataLength = UDPCompleteRequestMulti(REQUEST_PROCESS_DIRECT, Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); else //Normal request process DataLength = UDPCompleteRequest(REQUEST_PROCESS_DIRECT, Packet.Buffer, EDNS_SwitchLength, OriginalRecv, RecvSize); //Send response. if (DataLength >= DNS_PACKET_MINSIZE && DataLength < RecvSize) { SendToRequester(OriginalRecv, DataLength, RecvSize, Packet.Protocol, LocalSocketData); return true; } //EDNS switching(Part 2) if (Parameter.EDNS_Label && !Parameter.EDNS_Switch.EDNS_Direct) { ((dns_hdr *)(Packet.Buffer))->Flags = EDNS_Packet_Flags; ((dns_hdr *)(Packet.Buffer))->Additional = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Additional) + 1U); } return false; }
//Match port of responses and send responses to system sockets process bool __fastcall MatchPortToSend(const char *Buffer, const size_t Length, const uint16_t Protocol, const uint16_t Port) { //Initialization std::shared_ptr<SOCKET_DATA> SocketData_Input(new SOCKET_DATA()); memset(SocketData_Input.get(), 0, sizeof(SOCKET_DATA)); uint16_t SystemProtocol = 0; size_t ReceiveIndex = 0; //Match port. std::unique_lock<std::mutex> OutputPacketListMutex(OutputPacketListLock); for (auto &PortTableIter:OutputPacketList) { for (auto &SocketDataIter:PortTableIter.SocketData_Output) { if (PortTableIter.ClearPortTime > 0 && //Do not scan timeout data. Protocol == AF_INET6 && SocketDataIter.AddrLen == sizeof(sockaddr_in6) && SocketDataIter.SockAddr.ss_family == AF_INET6 && Port == ((PSOCKADDR_IN6)&SocketDataIter.SockAddr)->sin6_port || //IPv6 Protocol == AF_INET && SocketDataIter.AddrLen == sizeof(sockaddr_in) && SocketDataIter.SockAddr.ss_family == AF_INET && Port == ((PSOCKADDR_IN)&SocketDataIter.SockAddr)->sin_port) //IPv4 { if (Parameter.ReceiveWaiting > 0) { ++PortTableIter.ReceiveIndex; ReceiveIndex = PortTableIter.ReceiveIndex; OutputPacketListLock.unlock(); goto StopLoop; } else { *SocketData_Input = PortTableIter.SocketData_Input; SystemProtocol = PortTableIter.Protocol_Network; PortTableIter.ClearPortTime = 0; goto ClearOutputPacketListData; } } } } goto ClearOutputPacketListData; //Stop loop, wait receiving and match port again. StopLoop: Sleep(Parameter.ReceiveWaiting); OutputPacketListLock.lock(); for (auto &PortTableIter:OutputPacketList) { for (auto &SocketDataIter:PortTableIter.SocketData_Output) { if (PortTableIter.ClearPortTime > 0 && //Do not scan timeout data. Protocol == AF_INET6 && SocketDataIter.AddrLen == sizeof(sockaddr_in6) && SocketDataIter.SockAddr.ss_family == AF_INET6 && Port == ((PSOCKADDR_IN6)&SocketDataIter.SockAddr)->sin6_port || //IPv6 Protocol == AF_INET && SocketDataIter.AddrLen == sizeof(sockaddr_in) && SocketDataIter.SockAddr.ss_family == AF_INET && Port == ((PSOCKADDR_IN)&SocketDataIter.SockAddr)->sin_port) //IPv4 { if (PortTableIter.ReceiveIndex == ReceiveIndex) { *SocketData_Input = PortTableIter.SocketData_Input; SystemProtocol = PortTableIter.Protocol_Network; PortTableIter.ClearPortTime = 0; } else { return false; } goto ClearOutputPacketListData; } } } //Stop loop and clear timeout data. ClearOutputPacketListData: //Minimum supported system of GetTickCount64() is Windows Vista(Windows XP with SP3 support). #if (defined(PLATFORM_WIN32) && !defined(PLATFORM_WIN64)) if (Parameter.FunctionPTR_GetTickCount64 != nullptr) { while (!OutputPacketList.empty() && OutputPacketList.front().ClearPortTime <= (size_t)((*Parameter.FunctionPTR_GetTickCount64)())) { //Mark timeout. if (OutputPacketList.front().ClearPortTime > 0) { if (OutputPacketList.front().Protocol_Network == AF_INET6) //IPv6 { if (OutputPacketList.front().Protocol_Transport == IPPROTO_TCP) //TCP ++AlternateSwapList.TimeoutTimes[0]; else //UDP ++AlternateSwapList.TimeoutTimes[2U]; } else if (OutputPacketList.front().Protocol_Network == AF_INET) //IPv4 { if (OutputPacketList.front().Protocol_Transport == IPPROTO_TCP) //TCP ++AlternateSwapList.TimeoutTimes[1U]; else //UDP ++AlternateSwapList.TimeoutTimes[3U]; } } OutputPacketList.pop_front(); } } else { while (!OutputPacketList.empty() && OutputPacketList.front().ClearPortTime <= GetTickCount()) { //Mark timeout. if (OutputPacketList.front().ClearPortTime > 0) { if (OutputPacketList.front().Protocol_Network == AF_INET6) //IPv6 { if (OutputPacketList.front().Protocol_Transport == IPPROTO_TCP) //TCP ++AlternateSwapList.TimeoutTimes[0]; else //UDP ++AlternateSwapList.TimeoutTimes[2U]; } else if (OutputPacketList.front().Protocol_Network == AF_INET) //IPv4 { if (OutputPacketList.front().Protocol_Transport == IPPROTO_TCP) //TCP ++AlternateSwapList.TimeoutTimes[1U]; else //UDP ++AlternateSwapList.TimeoutTimes[3U]; } } OutputPacketList.pop_front(); } } #else while (!OutputPacketList.empty() && OutputPacketList.front().ClearPortTime <= GetTickCount64()) { //Mark timeout. if (OutputPacketList.front().ClearPortTime > 0) { if (OutputPacketList.front().Protocol_Network == AF_INET6) //IPv6 { if (OutputPacketList.front().Protocol_Transport == IPPROTO_TCP) //TCP ++AlternateSwapList.TimeoutTimes[0]; else //UDP ++AlternateSwapList.TimeoutTimes[2U]; } else if (OutputPacketList.front().Protocol_Network == AF_INET) //IPv4 { if (OutputPacketList.front().Protocol_Transport == IPPROTO_TCP) //TCP ++AlternateSwapList.TimeoutTimes[1U]; else //UDP ++AlternateSwapList.TimeoutTimes[3U]; } } OutputPacketList.pop_front(); } #endif OutputPacketListMutex.unlock(); //Drop resopnses which not in OutputPacketList. if (SocketData_Input->Socket == 0 || SocketData_Input->AddrLen == 0 || SocketData_Input->SockAddr.ss_family == 0 || SystemProtocol == 0) return false; //Mark DNS Cache. if (Parameter.CacheType > 0) MarkDomainCache(Buffer, Length); //Send to localhost. SendToRequester((PSTR)Buffer, Length, SystemProtocol, *SocketData_Input); if (SystemProtocol == IPPROTO_TCP) return true; //Check global sockets. if (Parameter.LocalSocket != nullptr && !Parameter.LocalSocket->empty()) { for (auto SocketIter:*Parameter.LocalSocket) { if (SocketIter == SocketData_Input->Socket) return true; } } shutdown(SocketData_Input->Socket, SD_BOTH); closesocket(SocketData_Input->Socket); return true; }