Esempio n. 1
0
void __fastcall UDPRequestProcess(
	const DNS_PACKET_DATA &Packet, 
	const SOCKET_DATA &LocalSocketData)
{
//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_UDP)
	{
	//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)
		UDPRequestMulti(Packet.Buffer, EDNS_SwitchLength, &LocalSocketData, Packet.Protocol);
//Normal request process
	else 
		UDPRequest(Packet.Buffer, EDNS_SwitchLength, &LocalSocketData, Packet.Protocol);

//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);
	}

//EDNS switching(Part 2)
	if (Parameter.EDNS_Label && !Parameter.EDNS_Switch.EDNS_UDP)
	{
		((dns_hdr *)(Packet.Buffer))->Flags = EDNS_Packet_Flags;
		((dns_hdr *)(Packet.Buffer))->Additional = htons(ntohs(((dns_hdr *)(Packet.Buffer))->Additional) + 1U);
	}

	return;
}
Esempio n. 2
0
//Transmission and reception of SOCKS protocol(UDP)
size_t __fastcall SOCKSUDPRequest(
	const char *OriginalSend, 
	const size_t SendSize, 
	char *OriginalRecv, 
	const size_t RecvSize)
{
//Initialization
	std::shared_ptr<char> SendBuffer(new char[LARGE_PACKET_MAXSIZE]());
	memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
	SOCKET_DATA TCPSocketData = {0}, LocalSocketData = {0}, UDPSocketData = {0};
	memset(OriginalRecv, 0, RecvSize);

//Socket initialization
	if (Parameter.SOCKS_Address_IPv6.Storage.ss_family > 0 && //IPv6
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv6 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 || //IPv6
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 && Parameter.SOCKS_Address_IPv4.Storage.ss_family == 0)) //Non-IPv4
	{
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
		//TCP process
			TCPSocketData.SockAddr.ss_family = AF_INET6;
			((PSOCKADDR_IN6)&TCPSocketData.SockAddr)->sin6_addr = Parameter.SOCKS_Address_IPv6.IPv6.sin6_addr;
			((PSOCKADDR_IN6)&TCPSocketData.SockAddr)->sin6_port = Parameter.SOCKS_Address_IPv6.IPv6.sin6_port;
			TCPSocketData.AddrLen = sizeof(sockaddr_in6);
			TCPSocketData.Socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

		//Local process
			LocalSocketData.SockAddr.ss_family = AF_INET6;
			LocalSocketData.AddrLen = sizeof(sockaddr_in6);
		}

	//UDP process
		UDPSocketData.SockAddr.ss_family = AF_INET6;
		((PSOCKADDR_IN6)&UDPSocketData.SockAddr)->sin6_addr = Parameter.SOCKS_Address_IPv6.IPv6.sin6_addr;
		if (Parameter.SOCKS_UDP_NoHandshake)
			((PSOCKADDR_IN6)&UDPSocketData.SockAddr)->sin6_port = Parameter.SOCKS_Address_IPv6.IPv6.sin6_port;
		UDPSocketData.AddrLen = sizeof(sockaddr_in6);
		UDPSocketData.Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
	}
	else if (Parameter.SOCKS_Address_IPv4.Storage.ss_family > 0 && //IPv4
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv4 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 || //IPv4
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 && Parameter.SOCKS_Address_IPv6.Storage.ss_family == 0)) //Non-IPv6
	{
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
		//TCP process
			TCPSocketData.SockAddr.ss_family = AF_INET;
			((PSOCKADDR_IN)&TCPSocketData.SockAddr)->sin_addr = Parameter.SOCKS_Address_IPv4.IPv4.sin_addr;
			((PSOCKADDR_IN)&TCPSocketData.SockAddr)->sin_port = Parameter.SOCKS_Address_IPv4.IPv4.sin_port;
			TCPSocketData.AddrLen = sizeof(sockaddr_in);
			TCPSocketData.Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

		//Local process
			LocalSocketData.SockAddr.ss_family = AF_INET;
			LocalSocketData.AddrLen = sizeof(sockaddr_in);
		}

	//UDP process
		UDPSocketData.SockAddr.ss_family = AF_INET;
		((PSOCKADDR_IN)&UDPSocketData.SockAddr)->sin_addr = Parameter.SOCKS_Address_IPv4.IPv4.sin_addr;
		if (Parameter.SOCKS_UDP_NoHandshake)
			((PSOCKADDR_IN)&UDPSocketData.SockAddr)->sin_port = Parameter.SOCKS_Address_IPv4.IPv4.sin_port;
		UDPSocketData.AddrLen = sizeof(sockaddr_in);
		UDPSocketData.Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	}
	else {
		return EXIT_FAILURE;
	}

//Socket check and Hop Limits setting
	if (!Parameter.SOCKS_UDP_NoHandshake && !SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr) || 
		TCPSocketData.SockAddr.ss_family == AF_INET6 && !SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_HOP_LIMITS_IPV6, false, nullptr) || 
		TCPSocketData.SockAddr.ss_family == AF_INET && (!SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_HOP_LIMITS_IPV4, false, nullptr) || 
		!SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_DO_NOT_FRAGMENT, true, nullptr)) ||
		!SocketSetting(UDPSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr) || 
		UDPSocketData.SockAddr.ss_family == AF_INET6 && !SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_HOP_LIMITS_IPV6, false, nullptr) || 
		UDPSocketData.SockAddr.ss_family == AF_INET && (!SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_HOP_LIMITS_IPV4, false, nullptr) || 
		!SocketSetting(UDPSocketData.Socket, SOCKET_SETTING_DO_NOT_FRAGMENT, true, nullptr)))
	{
		closesocket(UDPSocketData.Socket);
		if (!Parameter.SOCKS_UDP_NoHandshake)
			closesocket(TCPSocketData.Socket);
		PrintError(LOG_LEVEL_2, LOG_ERROR_NETWORK, L"SOCKS socket initialization error", 0, nullptr, 0);

		return EXIT_FAILURE;
	}

//Non-blocking mode setting
	if (!Parameter.SOCKS_UDP_NoHandshake && !SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_NON_BLOCKING_MODE, true, nullptr) || 
		!SocketSetting(UDPSocketData.Socket, SOCKET_SETTING_NON_BLOCKING_MODE, true, nullptr))
	{
		closesocket(UDPSocketData.Socket);
		if (!Parameter.SOCKS_UDP_NoHandshake)
			closesocket(TCPSocketData.Socket);

		return EXIT_FAILURE;
	}

//Selecting structure setting
	fd_set ReadFDS = {0}, WriteFDS = {0};
	timeval Timeout = {0};

//UDP transmission of standard SOCKS protocol must connect with TCP to server at first.
	if (!Parameter.SOCKS_UDP_NoHandshake)
	{
	//Selection exchange process
		if (!SOCKSSelectionExchange(&TCPSocketData, &ReadFDS, &WriteFDS, &Timeout, SendBuffer.get(), OriginalRecv, RecvSize))
		{
			shutdown(UDPSocketData.Socket, SD_BOTH);
			shutdown(TCPSocketData.Socket, SD_BOTH);
			closesocket(UDPSocketData.Socket);
			closesocket(TCPSocketData.Socket);

			return EXIT_FAILURE;
		}
		else {
			memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
		}

	//UDP connecting and get UDP socket infomation.
		if (SocketConnecting(IPPROTO_UDP, UDPSocketData.Socket, (PSOCKADDR)&UDPSocketData.SockAddr, UDPSocketData.AddrLen, nullptr, 0) == EXIT_FAILURE || 
			getsockname(UDPSocketData.Socket, (PSOCKADDR)&LocalSocketData.SockAddr, &LocalSocketData.AddrLen) == SOCKET_ERROR)
		{
			shutdown(UDPSocketData.Socket, SD_BOTH);
			shutdown(TCPSocketData.Socket, SD_BOTH);
			closesocket(UDPSocketData.Socket);
			closesocket(TCPSocketData.Socket);
			PrintError(LOG_LEVEL_3, LOG_ERROR_NETWORK, L"SOCKS connecting error", 0, nullptr, 0);

			return EXIT_FAILURE;
		}

	//Client command request process
		if (!SOCKSClientCommandRequest(IPPROTO_UDP, TCPSocketData.Socket, &ReadFDS, &WriteFDS, &Timeout, SendBuffer.get(), OriginalRecv, RecvSize, &LocalSocketData))
		{
			shutdown(UDPSocketData.Socket, SD_BOTH);
			shutdown(TCPSocketData.Socket, SD_BOTH);
			closesocket(UDPSocketData.Socket);
			closesocket(TCPSocketData.Socket);

			return EXIT_FAILURE;
		}
		else {
			memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);

		//Copy network infomation from server message.
			if (UDPSocketData.SockAddr.ss_family == AF_INET6)
				((PSOCKADDR_IN6)&UDPSocketData.SockAddr)->sin6_port = ((PSOCKADDR_IN6)&LocalSocketData.SockAddr)->sin6_port;
			else 
				((PSOCKADDR_IN)&UDPSocketData.SockAddr)->sin_port = ((PSOCKADDR_IN)&LocalSocketData.SockAddr)->sin_port;
		}
	}

//UDP connecting again
	if (SocketConnecting(IPPROTO_UDP, UDPSocketData.Socket, (PSOCKADDR)&UDPSocketData.SockAddr, UDPSocketData.AddrLen, nullptr, 0) == EXIT_FAILURE)
	{
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
			shutdown(TCPSocketData.Socket, SD_BOTH);
			closesocket(TCPSocketData.Socket);
		}

		PrintError(LOG_LEVEL_3, LOG_ERROR_NETWORK, L"SOCKS connecting error", 0, nullptr, 0);
		return EXIT_FAILURE;
	}

//SOCKS UDP relay header
	SSIZE_T RecvLen = sizeof(socks_udp_relay_request);
	void *SOCKS_Pointer = SendBuffer.get();
	if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET6) //IPv6
	{
		((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type = SOCKS5_ADDRESS_IPV6;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(in6_addr);
		*(in6_addr *)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv6.sin6_addr;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(uint16_t);
		*(uint16_t *)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv6.sin6_port;
	}
	else if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET) //IPv4
	{
		((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type = SOCKS5_ADDRESS_IPV4;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(in_addr);
		*(in_addr *)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv4.sin_addr;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(uint16_t);
		*(uint16_t *)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv4.sin_port;
	}
	else if (Parameter.SOCKS_TargetDomain != nullptr && !Parameter.SOCKS_TargetDomain->empty()) //Damain
	{
		((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type = SOCKS5_ADDRESS_DOMAIN;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(uint8_t);
		*(uint8_t *)SOCKS_Pointer = (uint8_t)Parameter.SOCKS_TargetDomain->length();
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		memcpy_s(SOCKS_Pointer, (SSIZE_T)LARGE_PACKET_MAXSIZE - ((SSIZE_T)sizeof(socks_udp_relay_request) + RecvLen), Parameter.SOCKS_TargetDomain->c_str(), Parameter.SOCKS_TargetDomain->length());
		RecvLen += (SSIZE_T)Parameter.SOCKS_TargetDomain->length();
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		*(uint16_t *)SOCKS_Pointer = Parameter.SOCKS_TargetDomain_Port;
		RecvLen += (SSIZE_T)sizeof(uint16_t);
	}
	else {
		shutdown(UDPSocketData.Socket, SD_BOTH);
		closesocket(UDPSocketData.Socket);
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
			shutdown(TCPSocketData.Socket, SD_BOTH);
			closesocket(TCPSocketData.Socket);
		}

		return EXIT_FAILURE;
	}

	memcpy_s(SendBuffer.get() + RecvLen, RecvSize, OriginalSend, SendSize);
	RecvLen += (SSIZE_T)SendSize;

//Socket timeout setting
#if defined(PLATFORM_WIN)
	Timeout.tv_sec = Parameter.SOCKS_SocketTimeout_Unreliable / SECOND_TO_MILLISECOND;
	Timeout.tv_usec = Parameter.SOCKS_SocketTimeout_Unreliable % SECOND_TO_MILLISECOND * MICROSECOND_TO_MILLISECOND;
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	Timeout.tv_sec = Parameter.SOCKS_SocketTimeout_Reliable.tv_sec;
	Timeout.tv_usec = Parameter.SOCKS_SocketTimeout_Reliable.tv_usec;
#endif

//Data exchange
	RecvLen = ProxySocketSelecting(UDPSocketData.Socket, &ReadFDS, &WriteFDS, &Timeout, SendBuffer.get(), RecvLen, OriginalRecv, RecvSize, sizeof(socks_udp_relay_request) + DNS_PACKET_MINSIZE, nullptr);
	shutdown(UDPSocketData.Socket, SD_BOTH);
	closesocket(UDPSocketData.Socket);
	if (!Parameter.SOCKS_UDP_NoHandshake)
	{
		shutdown(TCPSocketData.Socket, SD_BOTH);
		closesocket(TCPSocketData.Socket);
	}
	if (RecvLen >= (SSIZE_T)DNS_PACKET_MINSIZE)
	{
		SSIZE_T OriginalRecvLen = RecvLen;

	//Remove SOCKS UDP relay header
		SOCKS_Pointer = OriginalRecv;
		if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET6 && //IPv6
			((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV6 && 
			RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE) && 
			memcmp((in6_addr *)(OriginalRecv + sizeof(socks_udp_relay_request)), &Parameter.SOCKS_TargetServer.IPv6.sin6_addr, sizeof(in6_addr)) == 0 && 
			*(uint16_t *)(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in6_addr)) == Parameter.SOCKS_TargetServer.IPv6.sin6_port)
		{
			memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t)));
			RecvLen -= sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t);
		}
		else if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET && //IPv4
			((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV4 && 
			RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE) && 
			(*(in_addr *)(OriginalRecv + sizeof(socks_udp_relay_request))).s_addr == Parameter.SOCKS_TargetServer.IPv4.sin_addr.s_addr && 
			*(uint16_t *)(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in_addr)) == Parameter.SOCKS_TargetServer.IPv4.sin_port)
		{
			memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t)));
			RecvLen -= sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t);
		}
		else if (Parameter.SOCKS_TargetDomain != nullptr && !Parameter.SOCKS_TargetDomain->empty()) //Domain
/* SOCKS server will reply IPv4/IPv6 address of domain.
			((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_DOMAIN && 
			RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain->length() + sizeof(uint16_t) + DNS_PACKET_MINSIZE) && 
			*(uint8_t *)(OriginalRecv + sizeof(socks_udp_relay_request)) == Parameter.SOCKS_TargetDomain->length() && 
			memcmp(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(uint8_t), Parameter.SOCKS_TargetDomain->c_str(), Parameter.SOCKS_TargetDomain->length()) == 0 && 
			*(uint16_t *)(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain->length()) == Parameter.SOCKS_TargetDomain_Port)
*/
		{
		//IPv6
			if (((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV6 && 
				RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE))
			{
				memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t)));
				RecvLen -= sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t);
			}
		//IPv4
			else if (((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV4 && 
				RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE))
			{
				memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t)));
				RecvLen -= sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t);
			}

/* SOCKS server will reply IPv4/IPv6 address of domain.
			memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain->length() + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain->length() + sizeof(uint16_t)));
			return RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain->length() + sizeof(uint16_t));
*/
		}

	//Server response check
		if (OriginalRecvLen != RecvLen)
		{
		//Responses check
			RecvLen = CheckResponseData(
				REQUEST_PROCESS_SOCKS, 
				OriginalRecv, 
				RecvLen, 
				RecvSize, 
				nullptr);
			if (RecvLen < (SSIZE_T)DNS_PACKET_MINSIZE)
				return EXIT_FAILURE;

		//Mark DNS cache.
			if (Parameter.CacheType > 0)
				MarkDomainCache(OriginalRecv, RecvLen);

			return RecvLen;
		}
	}

	return EXIT_FAILURE;
}
Esempio n. 3
0
//Transmission and reception of SOCKS protocol(TCP)
size_t __fastcall SOCKSTCPRequest(
	const char *OriginalSend, 
	const size_t SendSize, 
	char *OriginalRecv, 
	const size_t RecvSize)
{
//Initialization
	std::shared_ptr<char> SendBuffer(new char[LARGE_PACKET_MAXSIZE]());
	memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
	SOCKET_DATA TCPSocketData = {0};
	memset(OriginalRecv, 0, RecvSize);

//Socket initialization
	if (Parameter.SOCKS_Address_IPv6.Storage.ss_family > 0 && //IPv6
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv6 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 || //IPv6
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 && Parameter.SOCKS_Address_IPv4.Storage.ss_family == 0)) //Non-IPv4
	{
		TCPSocketData.SockAddr.ss_family = AF_INET6;
		((PSOCKADDR_IN6)&TCPSocketData.SockAddr)->sin6_addr = Parameter.SOCKS_Address_IPv6.IPv6.sin6_addr;
		((PSOCKADDR_IN6)&TCPSocketData.SockAddr)->sin6_port = Parameter.SOCKS_Address_IPv6.IPv6.sin6_port;
		TCPSocketData.AddrLen = sizeof(sockaddr_in6);
		TCPSocketData.Socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
	}
	else if (Parameter.SOCKS_Address_IPv4.Storage.ss_family > 0 && //IPv4
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv4 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 || //IPv4
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 && Parameter.SOCKS_Address_IPv6.Storage.ss_family == 0)) //Non-IPv6
	{
		TCPSocketData.SockAddr.ss_family = AF_INET;
		((PSOCKADDR_IN)&TCPSocketData.SockAddr)->sin_addr = Parameter.SOCKS_Address_IPv4.IPv4.sin_addr;
		((PSOCKADDR_IN)&TCPSocketData.SockAddr)->sin_port = Parameter.SOCKS_Address_IPv4.IPv4.sin_port;
		TCPSocketData.AddrLen = sizeof(sockaddr_in);
		TCPSocketData.Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	}
	else {
		return EXIT_FAILURE;
	}

//Socket check 
	if (!SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, false, nullptr))
	{
		PrintError(LOG_LEVEL_2, LOG_ERROR_NETWORK, L"SOCKS socket initialization error", 0, nullptr, 0);
		return EXIT_FAILURE;
	}

//Non-blocking mode setting and Hop Limits setting
	if (!SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_NON_BLOCKING_MODE, true, nullptr) || 
		TCPSocketData.SockAddr.ss_family == AF_INET6 && !SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_HOP_LIMITS_IPV6, true, nullptr) || 
		TCPSocketData.SockAddr.ss_family == AF_INET && (!SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_HOP_LIMITS_IPV4, true, nullptr) || 
		!SocketSetting(TCPSocketData.Socket, SOCKET_SETTING_DO_NOT_FRAGMENT, true, nullptr)))
	{
		shutdown(TCPSocketData.Socket, SD_BOTH);
		closesocket(TCPSocketData.Socket);

		return EXIT_FAILURE;
	}

//Selecting structure setting
	fd_set ReadFDS = {0}, WriteFDS = {0};
	timeval Timeout = {0};

//Selection exchange process
	if (Parameter.SOCKS_Version == SOCKS_VERSION_5)
	{
		if (!SOCKSSelectionExchange(&TCPSocketData, &ReadFDS, &WriteFDS, &Timeout, SendBuffer.get(), OriginalRecv, RecvSize))
		{
			shutdown(TCPSocketData.Socket, SD_BOTH);
			closesocket(TCPSocketData.Socket);

			return EXIT_FAILURE;
		}
		else {
			memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
		}
	}

//Client command request process
	if (!SOCKSClientCommandRequest(IPPROTO_TCP, TCPSocketData.Socket, &ReadFDS, &WriteFDS, &Timeout, SendBuffer.get(), OriginalRecv, RecvSize, &TCPSocketData))
	{
		shutdown(TCPSocketData.Socket, SD_BOTH);
		closesocket(TCPSocketData.Socket);

		return EXIT_FAILURE;
	}
	else {
		memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
	}

//Add length of request packet(It must be written in header when transpot with TCP protocol).
	memcpy_s(SendBuffer.get(), RecvSize, OriginalSend, SendSize);
	SSIZE_T RecvLen = AddLengthDataToHeader(SendBuffer.get(), SendSize, RecvSize);
	if (RecvLen < (SSIZE_T)DNS_PACKET_MINSIZE)
	{
		shutdown(TCPSocketData.Socket, SD_BOTH);
		closesocket(TCPSocketData.Socket);

		return EXIT_FAILURE;
	}

//Socket timeout setting
#if defined(PLATFORM_WIN)
	Timeout.tv_sec = Parameter.SOCKS_SocketTimeout_Reliable / SECOND_TO_MILLISECOND;
	Timeout.tv_usec = Parameter.SOCKS_SocketTimeout_Reliable % SECOND_TO_MILLISECOND * MICROSECOND_TO_MILLISECOND;
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	Timeout.tv_sec = Parameter.SOCKS_SocketTimeout_Reliable.tv_sec;
	Timeout.tv_usec = Parameter.SOCKS_SocketTimeout_Reliable.tv_usec;
#endif

//Data exchange
	RecvLen = ProxySocketSelecting(TCPSocketData.Socket, &ReadFDS, &WriteFDS, &Timeout, SendBuffer.get(), RecvLen, OriginalRecv, RecvSize, DNS_PACKET_MINSIZE, nullptr);
	shutdown(TCPSocketData.Socket, SD_BOTH);
	closesocket(TCPSocketData.Socket);

//Server response check
	if (RecvLen >= (SSIZE_T)DNS_PACKET_MINSIZE && ntohs(((uint16_t *)OriginalRecv)[0]) >= DNS_PACKET_MINSIZE && 
		RecvLen >= ntohs(((uint16_t *)OriginalRecv)[0]))
	{
		RecvLen = ntohs(((uint16_t *)OriginalRecv)[0]);
		memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(uint16_t), RecvLen);

	//Responses check
		RecvLen = CheckResponseData(
			REQUEST_PROCESS_SOCKS, 
			OriginalRecv, 
			RecvLen, 
			RecvSize, 
			nullptr);
		if (RecvLen < (SSIZE_T)DNS_PACKET_MINSIZE)
			return EXIT_FAILURE;

	//Mark DNS cache.
		if (Parameter.CacheType > 0)
			MarkDomainCache(OriginalRecv, RecvLen);

		return RecvLen;
	}

	return EXIT_FAILURE;
}
Esempio n. 4
0
//Transmission and reception of HTTP protocol
size_t __fastcall HTTPRequest(
	const char *OriginalSend, 
	const size_t SendSize, 
	char *OriginalRecv, 
	const size_t RecvSize)
{
//Initialization
	SOCKET_DATA HTTPSocketData = {0};
	memset(OriginalRecv, 0, RecvSize);

//Socket initialization
	if (Parameter.HTTP_Address_IPv6.Storage.ss_family > 0 && //IPv6
		(Parameter.HTTP_Protocol == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv6 || //Auto select
		Parameter.HTTP_Protocol == REQUEST_MODE_IPV6 || //IPv6
		Parameter.HTTP_Protocol == REQUEST_MODE_IPV4 && Parameter.HTTP_Address_IPv4.Storage.ss_family == 0)) //Non-IPv4
	{
		HTTPSocketData.SockAddr.ss_family = AF_INET6;
		((PSOCKADDR_IN6)&HTTPSocketData.SockAddr)->sin6_addr = Parameter.HTTP_Address_IPv6.IPv6.sin6_addr;
		((PSOCKADDR_IN6)&HTTPSocketData.SockAddr)->sin6_port = Parameter.HTTP_Address_IPv6.IPv6.sin6_port;
		HTTPSocketData.AddrLen = sizeof(sockaddr_in6);
		HTTPSocketData.Socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
	}
	else if (Parameter.HTTP_Address_IPv4.Storage.ss_family > 0 && //IPv4
		(Parameter.HTTP_Protocol == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv4 || //Auto select
		Parameter.HTTP_Protocol == REQUEST_MODE_IPV4 || //IPv4
		Parameter.HTTP_Protocol == REQUEST_MODE_IPV6 && Parameter.HTTP_Address_IPv6.Storage.ss_family == 0)) //Non-IPv6
	{
		HTTPSocketData.SockAddr.ss_family = AF_INET;
		((PSOCKADDR_IN)&HTTPSocketData.SockAddr)->sin_addr = Parameter.HTTP_Address_IPv4.IPv4.sin_addr;
		((PSOCKADDR_IN)&HTTPSocketData.SockAddr)->sin_port = Parameter.HTTP_Address_IPv4.IPv4.sin_port;
		HTTPSocketData.AddrLen = sizeof(sockaddr_in);
		HTTPSocketData.Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	}
	else {
		return EXIT_FAILURE;
	}

//Socket check 
	if (!SocketSetting(HTTPSocketData.Socket, SOCKET_SETTING_INVALID_CHECK, nullptr))
	{
		PrintError(LOG_ERROR_NETWORK, L"HTTP socket initialization error", 0, nullptr, 0);
		return EXIT_FAILURE;
	}

//Non-blocking mode setting
	if (!SocketSetting(HTTPSocketData.Socket, SOCKET_SETTING_NON_BLOCKING_MODE, nullptr))
	{
		shutdown(HTTPSocketData.Socket, SD_BOTH);
		closesocket(HTTPSocketData.Socket);
		PrintError(LOG_ERROR_NETWORK, L"Socket non-blocking mode setting error", 0, nullptr, 0);

		return EXIT_FAILURE;
	}

//Selecting structure setting
	fd_set ReadFDS = {0}, WriteFDS = {0};
	timeval Timeout = {0};

//HTTP CONNECT request
	if (Parameter.HTTP_TargetDomain == nullptr || Parameter.HTTP_Version == nullptr || 
		!HTTP_CONNECTRequest(&HTTPSocketData, &ReadFDS, &WriteFDS, &Timeout, OriginalRecv, RecvSize))
	{
		shutdown(HTTPSocketData.Socket, SD_BOTH);
		closesocket(HTTPSocketData.Socket);

		return EXIT_FAILURE;
	}

//Add length of request packet(It must be written in header when transpot with TCP protocol).
	std::shared_ptr<char> SendBuffer(new char[LARGE_PACKET_MAXSIZE]());
	memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
	memcpy_s(SendBuffer.get(), RecvSize, OriginalSend, SendSize);
	SSIZE_T RecvLen = AddLengthDataToHeader(SendBuffer.get(), SendSize, RecvSize);
	if (RecvLen < (SSIZE_T)DNS_PACKET_MINSIZE)
	{
		shutdown(HTTPSocketData.Socket, SD_BOTH);
		closesocket(HTTPSocketData.Socket);

		return EXIT_FAILURE;
	}

//Socket timeout setting
#if defined(PLATFORM_WIN)
	Timeout.tv_sec = Parameter.HTTP_SocketTimeout / SECOND_TO_MILLISECOND;
	Timeout.tv_usec = Parameter.HTTP_SocketTimeout % SECOND_TO_MILLISECOND * MICROSECOND_TO_MILLISECOND;
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	Timeout.tv_sec = Parameter.HTTP_SocketTimeout.tv_sec;
	Timeout.tv_usec = Parameter.HTTP_SocketTimeout.tv_usec;
#endif

//Data exchange
	RecvLen = ProxySocketSelecting(HTTPSocketData.Socket, &ReadFDS, &WriteFDS, &Timeout, SendBuffer.get(), RecvLen, OriginalRecv, RecvSize, DNS_PACKET_MINSIZE, nullptr);
	shutdown(HTTPSocketData.Socket, SD_BOTH);
	closesocket(HTTPSocketData.Socket);

//Server response check
	if (RecvLen >= (SSIZE_T)DNS_PACKET_MINSIZE && ntohs(((uint16_t *)OriginalRecv)[0]) >= DNS_PACKET_MINSIZE && 
		RecvLen >= ntohs(((uint16_t *)OriginalRecv)[0]))
	{
		RecvLen = ntohs(((uint16_t *)OriginalRecv)[0]);
		memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(uint16_t), RecvLen);

	//Responses check
		RecvLen = CheckResponseData(
			REQUEST_PROCESS_HTTP, 
			OriginalRecv, 
			RecvLen, 
			RecvSize, 
			nullptr);
		if (RecvLen < (SSIZE_T)DNS_PACKET_MINSIZE)
			return EXIT_FAILURE;

	//Mark DNS cache.
		if (Parameter.CacheType > 0)
			MarkDomainCache(OriginalRecv, RecvLen);

		return RecvLen;
	}

	return EXIT_FAILURE;
}
Esempio n. 5
0
//Transmission of DNSCurve UDP protocol(Multiple threading)
size_t DNSCurve_UDP_RequestMultiple(
	const uint8_t * const OriginalSend, 
	const size_t SendSize, 
	uint8_t * const OriginalRecv, 
	const size_t RecvSize, 
	const uint16_t QueryType, 
	const SOCKET_DATA &LocalSocketData)
{
//Key initialization
	uint8_t *PrecomputationKey = nullptr, *Alternate_PrecomputationKey = nullptr;
	DNSCURVE_HEAP_BUFFER_TABLE<uint8_t> PrecomputationKeyBuffer, Alternate_PrecomputationKeyBuffer;
	if (DNSCurveParameter.IsEncryption && DNSCurveParameter.IsClientEphemeralKey)
	{
		DNSCURVE_HEAP_BUFFER_TABLE<uint8_t> PrecomputationKeyBufferTemp(crypto_box_BEFORENMBYTES), Alternate_PrecomputationKeyBufferTemp(crypto_box_BEFORENMBYTES);

	//Main
		PrecomputationKeyBufferTemp.Swap(PrecomputationKeyBuffer);
		PrecomputationKey = PrecomputationKeyBuffer.Buffer;

	//Alternate
		Alternate_PrecomputationKeyBufferTemp.Swap(Alternate_PrecomputationKeyBuffer);
		Alternate_PrecomputationKey = Alternate_PrecomputationKeyBuffer.Buffer;
	}

//Initialization(Part 1)
	std::vector<SOCKET_DATA> UDPSocketDataList;
	std::vector<DNSCURVE_SOCKET_SELECTING_TABLE> UDPSocketSelectingDataList;
	std::unique_ptr<uint8_t[]> SendBuffer(nullptr);
	std::unique_ptr<uint8_t[]> Alternate_SendBuffer(nullptr);
	DNSCURVE_SERVER_DATA *PacketTarget = nullptr;
	size_t DataLength = 0, Alternate_DataLength = 0;
	memset(OriginalRecv, 0, RecvSize);

//Socket precomputation
	DNSCurve_SocketPrecomputation(IPPROTO_UDP, OriginalSend, SendSize, RecvSize, &PrecomputationKey, &Alternate_PrecomputationKey, &PacketTarget, 
		UDPSocketDataList, UDPSocketSelectingDataList, QueryType, LocalSocketData, SendBuffer, DataLength, Alternate_SendBuffer, Alternate_DataLength);
	if (UDPSocketDataList.empty() || UDPSocketDataList.size() != UDPSocketSelectingDataList.size())
		return EXIT_FAILURE;

//Socket selecting structure initialization
	for (auto &SocketSelectingItem:UDPSocketSelectingDataList)
	{
	//Encryption mode
		if (DNSCurveParameter.IsEncryption)
		{
			DNSCurve_PacketTargetSetting(SocketSelectingItem.ServerType, &PacketTarget);
			SocketSelectingItem.ReceiveMagicNumber = PacketTarget->ReceiveMagicNumber;

		//Alternate
			if (SocketSelectingItem.ServerType == DNSCURVE_SERVER_TYPE::ALTERNATE_IPV6 || SocketSelectingItem.ServerType == DNSCURVE_SERVER_TYPE::ALTERNATE_IPV4)
			{
				SocketSelectingItem.PrecomputationKey = Alternate_PrecomputationKey;
				SocketSelectingItem.SendBuffer = Alternate_SendBuffer.get();
				SocketSelectingItem.SendSize = Alternate_DataLength;
			}
		//Main
			else {
				SocketSelectingItem.PrecomputationKey = PrecomputationKey;
				SocketSelectingItem.SendBuffer = SendBuffer.get();
				SocketSelectingItem.SendSize = DataLength;
			}
		}
	//Normal mode
		else {
			SocketSelectingItem.SendBuffer = const_cast<uint8_t *>(OriginalSend);
			SocketSelectingItem.SendSize = SendSize;
		}

		SocketSelectingItem.RecvLen = 0;
		SocketSelectingItem.IsPacketDone = false;
	}

//Socket selecting
	ssize_t ErrorCode = 0;
	const auto RecvLen = SocketSelectingOnce(REQUEST_PROCESS_TYPE::DNSCURVE_MAIN, IPPROTO_UDP, UDPSocketDataList, &UDPSocketSelectingDataList, nullptr, 0, OriginalRecv, RecvSize, &ErrorCode, &LocalSocketData);
	if (ErrorCode == WSAETIMEDOUT && !Parameter.AlternateMultipleRequest) //Mark timeout.
	{
		if (UDPSocketDataList.front().AddrLen == sizeof(sockaddr_in6))
			++AlternateSwapList.TimeoutTimes.at(ALTERNATE_SWAP_TYPE_DNSCURVE_UDP_IPV6);
		else if (UDPSocketDataList.front().AddrLen == sizeof(sockaddr_in))
			++AlternateSwapList.TimeoutTimes.at(ALTERNATE_SWAP_TYPE_DNSCURVE_UDP_IPV4);
	}

//Close all sockets.
	for (auto &SocketItem:UDPSocketDataList)
	{
		if (SocketSetting(SocketItem.Socket, SOCKET_SETTING_TYPE::INVALID_CHECK, false, nullptr))
			SocketSetting(SocketItem.Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);
	}

	return RecvLen;
}
Esempio n. 6
0
//Transmission of DNSCurve UDP protocol
size_t DNSCurve_UDP_RequestSingle(
	const uint8_t * const OriginalSend, 
	const size_t SendSize, 
	uint8_t * const OriginalRecv, 
	const size_t RecvSize, 
	const uint16_t QueryType, 
	const SOCKET_DATA &LocalSocketData)
{
//Initialization
	std::vector<SOCKET_DATA> UDPSocketDataList(1U);
	memset(&UDPSocketDataList.front(), 0, sizeof(UDPSocketDataList.front()));
	UDPSocketDataList.front().Socket = INVALID_SOCKET;
	DNSCURVE_SOCKET_SELECTING_TABLE UDPSocketSelectingData;
	DNSCURVE_SERVER_DATA *PacketTarget = nullptr;
	bool *IsAlternate = nullptr;
	size_t *AlternateTimeoutTimes = nullptr;
	memset(OriginalRecv, 0, RecvSize);
	const auto SendBuffer = OriginalRecv;

//Socket initialization
	ssize_t RecvLen = SelectTargetSocketSingle(REQUEST_PROCESS_TYPE::DNSCURVE_MAIN, IPPROTO_UDP, QueryType, &LocalSocketData, &UDPSocketDataList.front(), &IsAlternate, &AlternateTimeoutTimes, nullptr, &UDPSocketSelectingData.ServerType, reinterpret_cast<void **>(&PacketTarget));
	if (RecvLen == EXIT_FAILURE || UDPSocketSelectingData.ServerType == DNSCURVE_SERVER_TYPE::NONE)
	{
		SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);
		PrintError(LOG_LEVEL_TYPE::LEVEL_2, LOG_ERROR_TYPE::NETWORK, L"DNSCurve UDP socket initialization error", 0, nullptr, 0);

		return EXIT_FAILURE;
	}

//Make Precomputation Key between client and server.
	uint8_t *Client_PublicKey = nullptr, *PrecomputationKey = nullptr;
	std::unique_ptr<uint8_t[]> Client_PublicKey_Buffer(nullptr);
	std::unique_ptr<uint8_t[]> PrecomputationKeyBuffer(nullptr);
	if (DNSCurveParameter.IsEncryption && DNSCurveParameter.IsClientEphemeralKey)
	{
		auto Client_PublicKey_BufferTemp = std::make_unique<uint8_t[]>(crypto_box_PUBLICKEYBYTES);
		auto PrecomputationKeyBufferTemp = std::make_unique<uint8_t[]>(crypto_box_BEFORENMBYTES);
		std::swap(Client_PublicKey_Buffer, Client_PublicKey_BufferTemp);
		std::swap(PrecomputationKeyBuffer, PrecomputationKeyBufferTemp);
		Client_PublicKey = Client_PublicKey_Buffer.get();
		PrecomputationKey = PrecomputationKeyBuffer.get();
		if (!DNSCurve_PrecomputationKeySetting(PrecomputationKey, Client_PublicKey, PacketTarget->ServerFingerprint))
		{
			SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);
			return EXIT_FAILURE;
		}
	}
	else {
		PrecomputationKey = PacketTarget->PrecomputationKey;
		Client_PublicKey = DNSCurveParameter.Client_PublicKey;
	}

//Socket attribute setting(Timeout) and UDP connecting
	if (!SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::TIMEOUT, true, &DNSCurveParameter.DNSCurve_SocketTimeout_Unreliable) || 
		SocketConnecting(IPPROTO_UDP, UDPSocketDataList.front().Socket, reinterpret_cast<const sockaddr *>(&UDPSocketDataList.front().SockAddr), UDPSocketDataList.front().AddrLen, nullptr, 0) == EXIT_FAILURE)
	{
		SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);
		return EXIT_FAILURE;
	}

//Make encryption or normal packet.
	RecvLen = DNSCurve_PacketEncryption(IPPROTO_UDP, PacketTarget->SendMagicNumber, Client_PublicKey, PrecomputationKey, OriginalSend, SendSize, SendBuffer, RecvSize);
	if (RecvLen < static_cast<const ssize_t>(DNS_PACKET_MINSIZE))
	{
		SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);
		return EXIT_FAILURE;
	}

//Socket selecting structure initialization
	std::vector<DNSCURVE_SOCKET_SELECTING_TABLE> UDPSocketSelectingDataList;
	if (DNSCurveParameter.IsEncryption) //Encryption mode
	{
		UDPSocketSelectingData.PrecomputationKey = PrecomputationKey;
		UDPSocketSelectingData.ReceiveMagicNumber = PacketTarget->ReceiveMagicNumber;
		UDPSocketSelectingData.SendBuffer = SendBuffer;
		UDPSocketSelectingData.SendSize = RecvLen;
	}
	else { //Normal mode
		UDPSocketSelectingData.SendBuffer = const_cast<uint8_t *>(OriginalSend);
		UDPSocketSelectingData.SendSize = SendSize;
	}

	UDPSocketSelectingData.RecvLen = 0;
	UDPSocketSelectingData.IsPacketDone = false;
	UDPSocketSelectingDataList.push_back(std::move(UDPSocketSelectingData));

//Socket selecting
	ssize_t ErrorCode = 0;
	RecvLen = SocketSelectingOnce(REQUEST_PROCESS_TYPE::DNSCURVE_MAIN, IPPROTO_UDP, UDPSocketDataList, &UDPSocketSelectingDataList, nullptr, 0, OriginalRecv, RecvSize, &ErrorCode, &LocalSocketData);
	if (ErrorCode == WSAETIMEDOUT && !Parameter.AlternateMultipleRequest) //Mark timeout.
	{
		if (UDPSocketDataList.front().AddrLen == sizeof(sockaddr_in6))
			++AlternateSwapList.TimeoutTimes.at(ALTERNATE_SWAP_TYPE_DNSCURVE_UDP_IPV6);
		else if (UDPSocketDataList.front().AddrLen == sizeof(sockaddr_in))
			++AlternateSwapList.TimeoutTimes.at(ALTERNATE_SWAP_TYPE_DNSCURVE_UDP_IPV4);
	}

//Close all sockets.
	if (SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::INVALID_CHECK, false, nullptr))
		SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);

	return RecvLen;
}
Esempio n. 7
0
//Get signature data from server via UDP request
bool DNSCurve_SignatureRequest_UDP(
	const uint16_t Protocol, 
	const bool IsAlternate)
{
//Initialization
	const auto SendBuffer = std::make_unique<uint8_t[]>(PACKET_NORMAL_MAXSIZE + MEMORY_RESERVED_BYTES);
	const auto RecvBuffer = std::make_unique<uint8_t[]>(PACKET_NORMAL_MAXSIZE + MEMORY_RESERVED_BYTES);
	memset(SendBuffer.get(), 0, PACKET_NORMAL_MAXSIZE + MEMORY_RESERVED_BYTES);
	memset(RecvBuffer.get(), 0, PACKET_NORMAL_MAXSIZE + MEMORY_RESERVED_BYTES);
	std::vector<SOCKET_DATA> UDPSocketDataList(1U);
	memset(&UDPSocketDataList.front(), 0, sizeof(UDPSocketDataList.front()));
	UDPSocketDataList.front().Socket = INVALID_SOCKET;

//Make packet data(Part 1).
	const auto DNS_Header = reinterpret_cast<dns_hdr *>(SendBuffer.get());
	auto DataLength = sizeof(dns_hdr);
#if defined(ENABLE_PCAP)
	DNS_Header->ID = Parameter.DomainTest_ID;
#else
	GenerateRandomBuffer(&DNS_Header->ID, sizeof(DNS_Header->ID), nullptr, 0, 0);
#endif
	DNS_Header->Flags = hton16(DNS_FLAG_REQUEST_STANDARD);
	DNS_Header->Question = hton16(UINT16_NUM_ONE);
	if (Protocol == AF_INET6)
	{
		if (IsAlternate)
			DataLength += StringToPacketQuery(DNSCurveParameter.DNSCurve_Target_Server_Alternate_IPv6.ProviderName, SendBuffer.get() + DataLength, PACKET_NORMAL_MAXSIZE - DataLength);
		else //Main
			DataLength += StringToPacketQuery(DNSCurveParameter.DNSCurve_Target_Server_Main_IPv6.ProviderName, SendBuffer.get() + DataLength, PACKET_NORMAL_MAXSIZE - DataLength);
	}
	else if (Protocol == AF_INET)
	{
		if (IsAlternate)
			DataLength += StringToPacketQuery(DNSCurveParameter.DNSCurve_Target_Server_Alternate_IPv4.ProviderName, SendBuffer.get() + DataLength, PACKET_NORMAL_MAXSIZE - DataLength);
		else //Main
			DataLength += StringToPacketQuery(DNSCurveParameter.DNSCurve_Target_Server_Main_IPv4.ProviderName, SendBuffer.get() + DataLength, PACKET_NORMAL_MAXSIZE - DataLength);
	}
	else {
		return false;
	}
	reinterpret_cast<dns_qry *>(SendBuffer.get() + DataLength)->Type = hton16(DNS_TYPE_TEXT);
	reinterpret_cast<dns_qry *>(SendBuffer.get() + DataLength)->Classes = hton16(DNS_CLASS_INTERNET);
	DataLength += sizeof(dns_qry);

//EDNS Label
	DataLength = Add_EDNS_LabelToPacket(SendBuffer.get(), DataLength, PACKET_NORMAL_MAXSIZE, nullptr);

//Socket initialization(Part 1)
	std::wstring Message;
	size_t TotalSleepTime = 0;
	ssize_t RecvLen = 0;
	auto FileModifiedTime = GlobalRunningStatus.ConfigFileModifiedTime;
	auto ServerType = DNSCURVE_SERVER_TYPE::NONE;
	const auto PacketTarget = DNSCurve_SelectSignatureTargetSocket(Protocol, IsAlternate, ServerType, UDPSocketDataList);
	if (PacketTarget == nullptr)
	{
		SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);
		PrintError(LOG_LEVEL_TYPE::LEVEL_2, LOG_ERROR_TYPE::SYSTEM, L"DNSCurve UDP Signature Request module Monitor terminated", 0, nullptr, 0);

		return false;
	}

//Send request.
	while (!GlobalRunningStatus.IsNeedExit)
	{
	//Sleep time controller
		if (TotalSleepTime > 0)
		{
		//Configuration files have been changed.
			if (FileModifiedTime != GlobalRunningStatus.ConfigFileModifiedTime)
			{
				FileModifiedTime = GlobalRunningStatus.ConfigFileModifiedTime;
				TotalSleepTime = 0;
			}
		//Interval time is not enough.
			else if (TotalSleepTime < DNSCurveParameter.KeyRecheckTime)
			{
				TotalSleepTime += Parameter.FileRefreshTime;

			//Next loop
				Sleep(Parameter.FileRefreshTime);
				continue;
			}
		//Interval time is enough, next recheck time.
			else {
				TotalSleepTime = 0;
			}
		}

	//Socket initialization(Part 2)
		if (Protocol == AF_INET6)
			UDPSocketDataList.front().Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
		else if (Protocol == AF_INET)
			UDPSocketDataList.front().Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		else 
			goto JumpTo_Restart;
		if (!SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::INVALID_CHECK, true, nullptr) || 
			!SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::NON_BLOCKING_MODE, true, nullptr) || 
			(Protocol == AF_INET6 && !SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::HOP_LIMITS_IPV6, true, nullptr)) || 
			(Protocol == AF_INET && (!SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::HOP_LIMITS_IPV4, true, nullptr) || 
			!SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::DO_NOT_FRAGMENT, true, nullptr))))
				goto JumpTo_Restart;

	//Socket selecting
		RecvLen = SocketSelectingOnce(REQUEST_PROCESS_TYPE::DNSCURVE_SIGN, IPPROTO_UDP, UDPSocketDataList, nullptr, SendBuffer.get(), DataLength, RecvBuffer.get(), PACKET_NORMAL_MAXSIZE, nullptr, nullptr);
		if (RecvLen < static_cast<const ssize_t>(DNS_PACKET_MINSIZE))
		{
			goto JumpTo_Restart;
		}
		else {
		//Check signature.
			if (!DNSCruve_GetSignatureData(RecvBuffer.get() + DNS_PACKET_RR_LOCATE(RecvBuffer.get(), PACKET_NORMAL_MAXSIZE), ServerType) || 
				CheckEmptyBuffer(PacketTarget->ServerFingerprint, crypto_box_PUBLICKEYBYTES) || 
				CheckEmptyBuffer(PacketTarget->SendMagicNumber, DNSCURVE_MAGIC_QUERY_LEN))
					goto JumpTo_Restart;
		}

	//Wait for sending again.
		TotalSleepTime += Parameter.FileRefreshTime;
		continue;

	//Jump here to restart.
	JumpTo_Restart:
		SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);

	//Print error log.
		PrintLog_DNSCurve(ServerType, Message);
		if (!Message.empty())
		{
			Message.append(L"UDP get signature data error");
			PrintError(LOG_LEVEL_TYPE::LEVEL_3, LOG_ERROR_TYPE::DNSCURVE, Message.c_str(), 0, nullptr, 0);
		}
		else {
			PrintError(LOG_LEVEL_TYPE::LEVEL_3, LOG_ERROR_TYPE::DNSCURVE, L"UDP get signature data error", 0, nullptr, 0);
		}

	//Send request again.
		memset(RecvBuffer.get(), 0, PACKET_NORMAL_MAXSIZE + MEMORY_RESERVED_BYTES);
		if (!Parameter.AlternateMultipleRequest)
		{
			if (ServerType == DNSCURVE_SERVER_TYPE::MAIN_IPV6)
				++AlternateSwapList.TimeoutTimes.at(ALTERNATE_SWAP_TYPE_DNSCURVE_UDP_IPV6);
			else if (ServerType == DNSCURVE_SERVER_TYPE::MAIN_IPV4)
				++AlternateSwapList.TimeoutTimes.at(ALTERNATE_SWAP_TYPE_DNSCURVE_UDP_IPV4);
		}

	//Next loop
		Sleep(SENDING_INTERVAL_TIME);
	}

//Loop terminated
	SocketSetting(UDPSocketDataList.front().Socket, SOCKET_SETTING_TYPE::CLOSE, false, nullptr);
	if (!GlobalRunningStatus.IsNeedExit)
		PrintError(LOG_LEVEL_TYPE::LEVEL_2, LOG_ERROR_TYPE::SYSTEM, L"DNSCurve UDP Signature Request module Monitor terminated", 0, nullptr, 0);
	return true;
}
Esempio n. 8
0
//Transmission and reception of SOCKS protocol(UDP)
size_t __fastcall SOCKSUDPRequest(
	const char *OriginalSend, 
	const size_t SendSize, 
	PSTR OriginalRecv, 
	const size_t RecvSize)
{
//Initialization
	std::shared_ptr<char> SendBuffer(new char[LARGE_PACKET_MAXSIZE]());
	std::shared_ptr<SOCKET_DATA> TCPSocketData, UDPSocketData(new SOCKET_DATA()), LocalSocketData;
	memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
	memset(UDPSocketData.get(), 0, sizeof(SOCKET_DATA));
	if (!Parameter.SOCKS_UDP_NoHandshake)
	{
		std::shared_ptr<SOCKET_DATA> TCPSocketDataTemp(new SOCKET_DATA()), LocalSocketDataTemp(new SOCKET_DATA());
		TCPSocketDataTemp.swap(TCPSocketData);
		LocalSocketDataTemp.swap(LocalSocketData);
		memset(TCPSocketData.get(), 0, sizeof(SOCKET_DATA));
		memset(LocalSocketData.get(), 0, sizeof(SOCKET_DATA));
	}

//Socket initialization
	if (Parameter.SOCKS_Address_IPv6.Storage.ss_family > 0 && //IPv6
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv6 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 || //IPv6
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 && Parameter.SOCKS_Address_IPv4.Storage.ss_family == 0)) //Non-IPv4
	{
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
		//TCP process
			TCPSocketData->SockAddr.ss_family = AF_INET6;
			((PSOCKADDR_IN6)&TCPSocketData->SockAddr)->sin6_addr = Parameter.SOCKS_Address_IPv6.IPv6.sin6_addr;
			((PSOCKADDR_IN6)&TCPSocketData->SockAddr)->sin6_port = Parameter.SOCKS_Address_IPv6.IPv6.sin6_port;
			TCPSocketData->AddrLen = sizeof(sockaddr_in6);
			TCPSocketData->Socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

		//Local process
			LocalSocketData->SockAddr.ss_family = AF_INET6;
			LocalSocketData->AddrLen = sizeof(sockaddr_in6);
		}

	//UDP process
		UDPSocketData->SockAddr.ss_family = AF_INET6;
		((PSOCKADDR_IN6)&UDPSocketData->SockAddr)->sin6_addr = Parameter.SOCKS_Address_IPv6.IPv6.sin6_addr;
		if (Parameter.SOCKS_UDP_NoHandshake)
			((PSOCKADDR_IN6)&UDPSocketData->SockAddr)->sin6_port = Parameter.SOCKS_Address_IPv6.IPv6.sin6_port;
		UDPSocketData->AddrLen = sizeof(sockaddr_in6);
		UDPSocketData->Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
	}
	else if (Parameter.SOCKS_Address_IPv4.Storage.ss_family > 0 && //IPv4
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv4 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 || //IPv4
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 && Parameter.SOCKS_Address_IPv6.Storage.ss_family == 0)) //Non-IPv6
	{
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
		//TCP process
			TCPSocketData->SockAddr.ss_family = AF_INET;
			((PSOCKADDR_IN)&TCPSocketData->SockAddr)->sin_addr = Parameter.SOCKS_Address_IPv4.IPv4.sin_addr;
			((PSOCKADDR_IN)&TCPSocketData->SockAddr)->sin_port = Parameter.SOCKS_Address_IPv4.IPv4.sin_port;
			TCPSocketData->AddrLen = sizeof(sockaddr_in);
			TCPSocketData->Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

		//Local process
			LocalSocketData->SockAddr.ss_family = AF_INET;
			LocalSocketData->AddrLen = sizeof(sockaddr_in);
		}

	//UDP process
		UDPSocketData->SockAddr.ss_family = AF_INET;
		((PSOCKADDR_IN)&UDPSocketData->SockAddr)->sin_addr = Parameter.SOCKS_Address_IPv4.IPv4.sin_addr;
		if (Parameter.SOCKS_UDP_NoHandshake)
			((PSOCKADDR_IN)&UDPSocketData->SockAddr)->sin_port = Parameter.SOCKS_Address_IPv4.IPv4.sin_port;
		UDPSocketData->AddrLen = sizeof(sockaddr_in);
		UDPSocketData->Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	}
	else {
		return EXIT_FAILURE;
	}

//Socket check 
	if (!Parameter.SOCKS_UDP_NoHandshake && !SocketSetting(TCPSocketData->Socket, SOCKET_SETTING_INVALID_CHECK, nullptr) || 
		!SocketSetting(UDPSocketData->Socket, SOCKET_SETTING_INVALID_CHECK, nullptr))
	{
		closesocket(UDPSocketData->Socket);
		if (!Parameter.SOCKS_UDP_NoHandshake)
			closesocket(TCPSocketData->Socket);
		PrintError(LOG_ERROR_NETWORK, L"SOCKS socket initialization error", 0, nullptr, 0);

		return EXIT_FAILURE;
	}

//Non-blocking mode setting
	if (!Parameter.SOCKS_UDP_NoHandshake && !SocketSetting(TCPSocketData->Socket, SOCKET_SETTING_NON_BLOCKING_MODE, nullptr) || 
		!SocketSetting(UDPSocketData->Socket, SOCKET_SETTING_NON_BLOCKING_MODE, nullptr))
	{
		closesocket(UDPSocketData->Socket);
		if (!Parameter.SOCKS_UDP_NoHandshake)
			closesocket(TCPSocketData->Socket);
		PrintError(LOG_ERROR_NETWORK, L"Socket non-blocking mode setting error", 0, nullptr, 0);

		return EXIT_FAILURE;
	}

//Selecting structure setting
	std::shared_ptr<fd_set> ReadFDS(new fd_set()), WriteFDS(new fd_set());
	std::shared_ptr<timeval> Timeout(new timeval());
	memset(ReadFDS.get(), 0, sizeof(fd_set));
	memset(WriteFDS.get(), 0, sizeof(fd_set));
	memset(Timeout.get(), 0, sizeof(timeval));

//UDP transmission of standard SOCKS protocol must connect with TCP to server first.
	if (!Parameter.SOCKS_UDP_NoHandshake)
	{
	//Selection exchange process
		if (!SOCKSSelectionExchange(TCPSocketData.get(), ReadFDS.get(), WriteFDS.get(), Timeout.get(), SendBuffer.get(), OriginalRecv, RecvSize))
		{
			shutdown(UDPSocketData->Socket, SD_BOTH);
			shutdown(TCPSocketData->Socket, SD_BOTH);
			closesocket(UDPSocketData->Socket);
			closesocket(TCPSocketData->Socket);

			return EXIT_FAILURE;
		}
		else {
			memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
		}

	//UDP connecting and get UDP socket infomation.
		if (SocketConnecting(IPPROTO_UDP, UDPSocketData->Socket, (PSOCKADDR)&UDPSocketData->SockAddr, UDPSocketData->AddrLen, nullptr, 0) == EXIT_FAILURE || 
			getsockname(UDPSocketData->Socket, (PSOCKADDR)&LocalSocketData->SockAddr, &LocalSocketData->AddrLen) == SOCKET_ERROR)
		{
			shutdown(UDPSocketData->Socket, SD_BOTH);
			shutdown(TCPSocketData->Socket, SD_BOTH);
			closesocket(UDPSocketData->Socket);
			closesocket(TCPSocketData->Socket);
			PrintError(LOG_ERROR_NETWORK, L"SOCKS connecting error", 0, nullptr, 0);

			return EXIT_FAILURE;
		}

	//Client command request process
		if (!SOCKSClientCommandRequest(IPPROTO_UDP, TCPSocketData->Socket, ReadFDS.get(), WriteFDS.get(), Timeout.get(), SendBuffer.get(), OriginalRecv, RecvSize, LocalSocketData.get()))
		{
			shutdown(UDPSocketData->Socket, SD_BOTH);
			shutdown(TCPSocketData->Socket, SD_BOTH);
			closesocket(UDPSocketData->Socket);
			closesocket(TCPSocketData->Socket);

			return EXIT_FAILURE;
		}
		else {
			memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);

		//Copy network infomation from server message.
			if (UDPSocketData->SockAddr.ss_family == AF_INET6)
				((PSOCKADDR_IN6)&UDPSocketData->SockAddr)->sin6_port = ((PSOCKADDR_IN6)&LocalSocketData->SockAddr)->sin6_port;
			else 
				((PSOCKADDR_IN)&UDPSocketData->SockAddr)->sin_port = ((PSOCKADDR_IN)&LocalSocketData->SockAddr)->sin_port;
		}
	}

//UDP connecting again
	if (SocketConnecting(IPPROTO_UDP, UDPSocketData->Socket, (PSOCKADDR)&UDPSocketData->SockAddr, UDPSocketData->AddrLen, nullptr, 0) == EXIT_FAILURE)
	{
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
			shutdown(TCPSocketData->Socket, SD_BOTH);
			closesocket(TCPSocketData->Socket);
		}

		PrintError(LOG_ERROR_NETWORK, L"SOCKS connecting error", 0, nullptr, 0);
		return EXIT_FAILURE;
	}

//SOCKS UDP relay header
	SSIZE_T RecvLen = sizeof(socks_udp_relay_request);
	void *SOCKS_Pointer = SendBuffer.get();
	if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET6) //IPv6
	{
		((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type = SOCKS5_ADDRESS_IPV6;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(in6_addr);
		*(in6_addr *)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv6.sin6_addr;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(uint16_t);
		*(PUINT16)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv6.sin6_port;
	}
	else if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET) //IPv4
	{
		((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type = SOCKS5_ADDRESS_IPV4;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(in_addr);
		*(in_addr *)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv4.sin_addr;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(uint16_t);
		*(PUINT16)SOCKS_Pointer = Parameter.SOCKS_TargetServer.IPv4.sin_port;
	}
	else if (Parameter.SOCKS_TargetDomain != nullptr && Parameter.SOCKS_TargetDomain_Length > 0) //Damain
	{
		((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type = SOCKS5_ADDRESS_DOMAIN;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		RecvLen += (SSIZE_T)sizeof(uint8_t);
		*(PUINT8)SOCKS_Pointer = (uint8_t)Parameter.SOCKS_TargetDomain_Length;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		memcpy_s(SOCKS_Pointer, (SSIZE_T)LARGE_PACKET_MAXSIZE - ((SSIZE_T)sizeof(socks_udp_relay_request) + RecvLen), Parameter.SOCKS_TargetDomain, Parameter.SOCKS_TargetDomain_Length);
		RecvLen += (SSIZE_T)Parameter.SOCKS_TargetDomain_Length;
		SOCKS_Pointer = SendBuffer.get() + RecvLen;
		*(PUINT16)SOCKS_Pointer = Parameter.SOCKS_TargetDomain_Port;
		RecvLen += (SSIZE_T)sizeof(uint16_t);
	}
	else {
		shutdown(UDPSocketData->Socket, SD_BOTH);
		closesocket(UDPSocketData->Socket);
		if (!Parameter.SOCKS_UDP_NoHandshake)
		{
			shutdown(TCPSocketData->Socket, SD_BOTH);
			closesocket(TCPSocketData->Socket);
		}

		return EXIT_FAILURE;
	}

	memcpy_s(SendBuffer.get() + RecvLen, RecvSize, OriginalSend, SendSize);
	RecvLen += (SSIZE_T)SendSize;

//Data exchange
	RecvLen = SOCKSSocketSelecting(UDPSocketData->Socket, ReadFDS.get(), WriteFDS.get(), Timeout.get(), SendBuffer.get(), RecvLen, OriginalRecv, RecvSize, sizeof(socks_udp_relay_request) + DNS_PACKET_MINSIZE);
	shutdown(UDPSocketData->Socket, SD_BOTH);
	closesocket(UDPSocketData->Socket);
	if (!Parameter.SOCKS_UDP_NoHandshake)
	{
		shutdown(TCPSocketData->Socket, SD_BOTH);
		closesocket(TCPSocketData->Socket);
	}
	if (RecvLen >= (SSIZE_T)DNS_PACKET_MINSIZE)
	{
	//Remove SOCKS UDP relay header
		SOCKS_Pointer = OriginalRecv;
		if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET6 && //IPv6
			((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV6 && 
			RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE) && 
			memcmp((in6_addr *)(OriginalRecv + sizeof(socks_udp_relay_request)), &Parameter.SOCKS_TargetServer.IPv6.sin6_addr, sizeof(in6_addr)) == EXIT_SUCCESS && 
			*(uint16_t *)(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in6_addr)) == Parameter.SOCKS_TargetServer.IPv6.sin6_port)
		{
			memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t)));
			return RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t));
		}
		else if (Parameter.SOCKS_TargetServer.Storage.ss_family == AF_INET && //IPv4
			((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV4 && 
			RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE) && 
			(*(in_addr *)(OriginalRecv + sizeof(socks_udp_relay_request))).S_un.S_addr == Parameter.SOCKS_TargetServer.IPv4.sin_addr.S_un.S_addr && 
			*(uint16_t *)(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in_addr)) == Parameter.SOCKS_TargetServer.IPv4.sin_port)
		{
			memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t)));
			return RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t));
		}
		else if (Parameter.SOCKS_TargetDomain != nullptr && Parameter.SOCKS_TargetDomain_Length > 0) //Domain
/* SOCKS server will reply IPv4/IPv6 address of domain.
			((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_DOMAIN && 
			RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain_Length + sizeof(uint16_t) + DNS_PACKET_MINSIZE) && 
			*(uint8_t *)(OriginalRecv + sizeof(socks_udp_relay_request)) == Parameter.SOCKS_TargetDomain_Length && 
			memcmp(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(uint8_t), Parameter.SOCKS_TargetDomain, Parameter.SOCKS_TargetDomain_Length) == EXIT_SUCCESS && 
			*(uint16_t *)(OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain_Length) == Parameter.SOCKS_TargetDomain_Port)
*/
		{
		//IPv6
			if (((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV6 && 
				RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE))
			{
				memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t)));
				return RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in6_addr) + sizeof(uint16_t));
			}
		//IPv4
			else if (((psocks_udp_relay_request)SOCKS_Pointer)->Address_Type == SOCKS5_ADDRESS_IPV4 && 
				RecvLen >= (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t) + DNS_PACKET_MINSIZE))
			{
				memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t)));
				return RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(in_addr) + sizeof(uint16_t));
			}

//			memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain_Length + sizeof(uint16_t), RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain_Length + sizeof(uint16_t)));
//			return RecvLen - (SSIZE_T)(sizeof(socks_udp_relay_request) + sizeof(uint8_t) + Parameter.SOCKS_TargetDomain_Length + sizeof(uint16_t));
		}
	}

	return EXIT_FAILURE;
}
Esempio n. 9
0
//Transmission and reception of SOCKS protocol(TCP)
size_t __fastcall SOCKSTCPRequest(
	const char *OriginalSend, 
	const size_t SendSize, 
	PSTR OriginalRecv, 
	const size_t RecvSize)
{
//Initialization
	std::shared_ptr<char> SendBuffer(new char[LARGE_PACKET_MAXSIZE]());
	std::shared_ptr<SOCKET_DATA> TCPSocketData(new SOCKET_DATA());
	memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
	memset(TCPSocketData.get(), 0, sizeof(SOCKET_DATA));

//Socket initialization
	if (Parameter.SOCKS_Address_IPv6.Storage.ss_family > 0 && //IPv6
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv6 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 || //IPv6
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 && Parameter.SOCKS_Address_IPv4.Storage.ss_family == 0)) //Non-IPv4
	{
		TCPSocketData->SockAddr.ss_family = AF_INET6;
		((PSOCKADDR_IN6)&TCPSocketData->SockAddr)->sin6_addr = Parameter.SOCKS_Address_IPv6.IPv6.sin6_addr;
		((PSOCKADDR_IN6)&TCPSocketData->SockAddr)->sin6_port = Parameter.SOCKS_Address_IPv6.IPv6.sin6_port;
		TCPSocketData->AddrLen = sizeof(sockaddr_in6);
		TCPSocketData->Socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
	}
	else if (Parameter.SOCKS_Address_IPv4.Storage.ss_family > 0 && //IPv4
		(Parameter.SOCKS_Protocol_Network == REQUEST_MODE_NETWORK_BOTH && GlobalRunningStatus.GatewayAvailable_IPv4 || //Auto select
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV4 || //IPv4
		Parameter.SOCKS_Protocol_Network == REQUEST_MODE_IPV6 && Parameter.SOCKS_Address_IPv6.Storage.ss_family == 0)) //Non-IPv6
	{
		TCPSocketData->SockAddr.ss_family = AF_INET;
		((PSOCKADDR_IN)&TCPSocketData->SockAddr)->sin_addr = Parameter.SOCKS_Address_IPv4.IPv4.sin_addr;
		((PSOCKADDR_IN)&TCPSocketData->SockAddr)->sin_port = Parameter.SOCKS_Address_IPv4.IPv4.sin_port;
		TCPSocketData->AddrLen = sizeof(sockaddr_in);
		TCPSocketData->Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	}
	else {
		return EXIT_FAILURE;
	}

//Socket check 
	if (!SocketSetting(TCPSocketData->Socket, SOCKET_SETTING_INVALID_CHECK, nullptr))
	{
		PrintError(LOG_ERROR_NETWORK, L"SOCKS socket initialization error", 0, nullptr, 0);
		return EXIT_FAILURE;
	}

//Non-blocking mode setting
	if (!SocketSetting(TCPSocketData->Socket, SOCKET_SETTING_NON_BLOCKING_MODE, nullptr))
	{
		shutdown(TCPSocketData->Socket, SD_BOTH);
		closesocket(TCPSocketData->Socket);
		PrintError(LOG_ERROR_NETWORK, L"Socket non-blocking mode setting error", 0, nullptr, 0);

		return EXIT_FAILURE;
	}

//Selecting structure setting
	std::shared_ptr<fd_set> ReadFDS(new fd_set()), WriteFDS(new fd_set());
	std::shared_ptr<timeval> Timeout(new timeval());
	memset(ReadFDS.get(), 0, sizeof(fd_set));
	memset(WriteFDS.get(), 0, sizeof(fd_set));
	memset(Timeout.get(), 0, sizeof(timeval));

//Selection exchange process
	if (Parameter.SOCKS_Version == SOCKS_VERSION_5)
	{
		if (!SOCKSSelectionExchange(TCPSocketData.get(), ReadFDS.get(), WriteFDS.get(), Timeout.get(), SendBuffer.get(), OriginalRecv, RecvSize))
		{
			shutdown(TCPSocketData->Socket, SD_BOTH);
			closesocket(TCPSocketData->Socket);

			return EXIT_FAILURE;
		}
		else {
			memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
		}
	}

//Client command request process
	if (!SOCKSClientCommandRequest(IPPROTO_TCP, TCPSocketData->Socket, ReadFDS.get(), WriteFDS.get(), Timeout.get(), SendBuffer.get(), OriginalRecv, RecvSize, TCPSocketData.get()))
	{
		shutdown(TCPSocketData->Socket, SD_BOTH);
		closesocket(TCPSocketData->Socket);

		return EXIT_FAILURE;
	}
	else {
		memset(SendBuffer.get(), 0, LARGE_PACKET_MAXSIZE);
	}

//Add length of request packet(It must be written in header when transpot with TCP protocol).
	memcpy_s(SendBuffer.get(), RecvSize, OriginalSend, SendSize);
	SSIZE_T RecvLen = AddLengthDataToHeader(SendBuffer.get(), SendSize, RecvSize);
	if (RecvLen < (SSIZE_T)DNS_PACKET_MINSIZE)
	{
		shutdown(TCPSocketData->Socket, SD_BOTH);
		closesocket(TCPSocketData->Socket);

		return EXIT_FAILURE;
	}

//Data exchange
	RecvLen = SOCKSSocketSelecting(TCPSocketData->Socket, ReadFDS.get(), WriteFDS.get(), Timeout.get(), SendBuffer.get(), RecvLen, OriginalRecv, RecvSize, DNS_PACKET_MINSIZE);
	shutdown(TCPSocketData->Socket, SD_BOTH);
	closesocket(TCPSocketData->Socket);
	if (RecvLen >= (SSIZE_T)DNS_PACKET_MINSIZE)
	{
		memmove_s(OriginalRecv, RecvSize, OriginalRecv + sizeof(uint16_t), RecvLen);
		return RecvLen;
	}

	return EXIT_FAILURE;
}
Esempio n. 10
0
//Windows Firewall Test
bool __fastcall FirewallTest(
	const uint16_t Protocol)
{
//Initialization
	std::shared_ptr<sockaddr_storage> SockAddr(new sockaddr_storage());
	memset(SockAddr.get(), 0, sizeof(sockaddr_storage));
	SYSTEM_SOCKET FirewallSocket = 0;

//Ramdom number distribution initialization
	std::uniform_int_distribution<int> RamdomDistribution(DYNAMIC_MIN_PORT, UINT16_MAX - 1U);

//IPv6
	if (Protocol == AF_INET6)
	{
		((PSOCKADDR_IN6)SockAddr.get())->sin6_addr = in6addr_any;
		((PSOCKADDR_IN6)SockAddr.get())->sin6_port = htons((uint16_t)RamdomDistribution(*GlobalRunningStatus.RamdomEngine));
		SockAddr->ss_family = AF_INET6;
		FirewallSocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);

	//Bind local socket.
		if (!SocketSetting(FirewallSocket, SOCKET_SETTING_INVALID_CHECK, nullptr))
		{
			return false;
		}
		else if (bind(FirewallSocket, (PSOCKADDR)SockAddr.get(), sizeof(sockaddr_in6)) == SOCKET_ERROR)
		{
			((PSOCKADDR_IN6)SockAddr.get())->sin6_port = htons((uint16_t)RamdomDistribution(*GlobalRunningStatus.RamdomEngine));
			size_t Index = 0;
			while (bind(FirewallSocket, (PSOCKADDR)SockAddr.get(), sizeof(sockaddr_in6)) == SOCKET_ERROR)
			{
				if (Index < LOOP_MAX_TIMES && WSAGetLastError() == WSAEADDRINUSE)
				{
					((PSOCKADDR_IN6)SockAddr.get())->sin6_port = htons((uint16_t)RamdomDistribution(*GlobalRunningStatus.RamdomEngine));

					++Index;
					continue;
				}
				else {
					closesocket(FirewallSocket);
					return false;
				}
			}
		}
	}
//IPv4
	else {
		((PSOCKADDR_IN)SockAddr.get())->sin_addr.s_addr = INADDR_ANY;
		((PSOCKADDR_IN)SockAddr.get())->sin_port = htons((uint16_t)RamdomDistribution(*GlobalRunningStatus.RamdomEngine));
		SockAddr->ss_family = AF_INET;
		FirewallSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	//Bind local socket.
		if (!SocketSetting(FirewallSocket, SOCKET_SETTING_INVALID_CHECK, nullptr))
		{
			return false;
		}
		else if (bind(FirewallSocket, (PSOCKADDR)SockAddr.get(), sizeof(sockaddr_in)) == SOCKET_ERROR)
		{
			((PSOCKADDR_IN)SockAddr.get())->sin_port = htons((uint16_t)RamdomDistribution(*GlobalRunningStatus.RamdomEngine));
			size_t Index = 0;
			while (bind(FirewallSocket, (PSOCKADDR)SockAddr.get(), sizeof(sockaddr_in)) == SOCKET_ERROR)
			{
				if (Index < LOOP_MAX_TIMES && WSAGetLastError() == WSAEADDRINUSE)
				{
					((PSOCKADDR_IN)SockAddr.get())->sin_port = htons((uint16_t)RamdomDistribution(*GlobalRunningStatus.RamdomEngine));

					++Index;
					continue;
				}
				else {
					closesocket(FirewallSocket);
					return false;
				}
			}
		}
	}

	closesocket(FirewallSocket);
	return true;
}
Esempio n. 11
0
//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
}