static int QueryDNSListenTCP(void *Unused)
{
	static ThreadHandle	Unused2;
	RecvInfo			*Info = NULL;
	CompatibleAddr		*Peer;
	socklen_t			AddrLen;

	while(TRUE){

		Info = SafeMalloc(sizeof(RecvInfo));

		Peer = &(Info -> Peer);
		memset(Info, 0, sizeof(CompatibleAddr));

		if( Family == AF_INET )
		{
			AddrLen = sizeof(struct sockaddr);
			Info -> Socket = accept(ListenSocketTCP, (struct sockaddr *)&(Peer -> Addr4), (socklen_t *)&AddrLen);
		} else {
			AddrLen = sizeof(struct sockaddr_in6);
			Info -> Socket = accept(ListenSocketTCP, (struct sockaddr *)&(Peer -> Addr6), (socklen_t *)&AddrLen);
		}

		if(Info -> Socket == INVALID_SOCKET)
		{
			SafeFree(Info);
			continue;
		}

		SetSocketWait(Info -> Socket, TRUE);
		SetSocketRecvTimeLimit(Info -> Socket, 2000);

		if( Family == AF_INET )
		{
			INFO("Established TCP connection to %s:%d\n", inet_ntoa(Peer -> Addr4.sin_addr), Peer -> Addr4.sin_port);
		} else {
			char Addr[LENGTH_OF_IPV6_ADDRESS_ASCII] = {0};

			IPv6AddressToAsc(&(Peer -> Addr6.sin6_addr), Addr);

			INFO("Established TCP connection to %s:%d\n", Addr, Peer -> Addr6.sin6_port);
		}

		CREATE_THREAD(TCPRecv, (void *)Info, Unused2);
#ifdef WIN32
		CloseHandle(Unused2);
#endif /* WIN32 */
	}
	CLOSE_SOCKET(ListenSocketTCP);
	return 0;
}
Beispiel #2
0
static int QueryDNSListenUDP(void *ID){
	socklen_t			AddrLen;

	CompatibleAddr		ClientAddr;

	int					State;

	ThreadContext		Context;

	char				RequestEntity[1024];

	InitContext(&Context, RequestEntity);

	/* Listen and accept requests */
	while(TRUE)
	{
		memset(&ClientAddr, 0, sizeof(ClientAddr));

		GET_MUTEX(ListenMutex);

		if( Family == AF_INET )
		{
			AddrLen = sizeof(struct sockaddr);
			State = recvfrom(ListenSocketUDP,
							 RequestEntity,
							 sizeof(RequestEntity),
							 0,
							 (struct sockaddr *)&(ClientAddr.Addr4),
							 &AddrLen
							 );

		} else {
			AddrLen = sizeof(struct sockaddr_in6);
			State = recvfrom(ListenSocketUDP,
							 RequestEntity,
							 sizeof(RequestEntity),
							 0,
							 (struct sockaddr *)&(ClientAddr.Addr6),
							 &AddrLen
							 );

		}
		RELEASE_MUTEX(ListenMutex);

		if(State < 1)
		{
			if( ErrorMessages == TRUE )
			{
				int		ErrorNum = GET_LAST_ERROR();
				char	ErrorMessage[320];

				ErrorMessage[0] ='\0';

				GetErrorMsg(ErrorNum, ErrorMessage, sizeof(ErrorMessage));
				if( Family == AF_INET )
				{
					printf("An error occured while receiving from %s : %d : %s .\n",
						   inet_ntoa(ClientAddr.Addr4.sin_addr),
						   ErrorNum,
						   ErrorMessage
						   );
				} else {
					char Addr[LENGTH_OF_IPV6_ADDRESS_ASCII] = {0};

					IPv6AddressToAsc(&(ClientAddr.Addr6.sin6_addr), Addr);

					printf("An error occured while receiving from %s : %d : %s .\n",
						   Addr,
						   ErrorNum,
						   ErrorMessage
						   );

				}
			}
			continue;
		}

		Context.RequestLength = State;

		Query(&Context, &ClientAddr);
		ExtendableBuffer_Reset(Context.ResponseBuffer);

	}

	return 0;
}
Beispiel #3
0
static int Query(ThreadContext *Context, CompatibleAddr *ClientAddr)
{
	int		State;

	char	RequestingDomain[256];

	char	ClientIP[LENGTH_OF_IPV6_ADDRESS_ASCII + 1];

	if( Family == AF_INET )
	{
		strcpy(ClientIP, inet_ntoa(ClientAddr -> Addr4.sin_addr));
	} else {
		IPv6AddressToAsc(&(ClientAddr -> Addr6.sin6_addr), ClientIP);
	}

	Context -> ClientIP = ClientIP;

	RequestingDomain[0] = '\0';
	DNSGetHostName(Context -> RequestEntity,
				   DNSJumpHeader(Context -> RequestEntity),
				   RequestingDomain
				   );

	StrToLower(RequestingDomain);

	Context -> RequestingDomain = RequestingDomain;

	Context -> RequestingType =
		(DNSRecordType)DNSGetRecordType(DNSJumpHeader(Context -> RequestEntity));

	Context -> RequestingDomainHashValue = ELFHash(RequestingDomain, 0);

	Context -> CurrentTime = time(NULL);

	State = QueryBase(Context);

	switch( State )
	{
		case QUERY_RESULT_DISABLE:
			((DNSHeader *)(Context -> RequestEntity)) -> Flags.Direction = 1;
			((DNSHeader *)(Context -> RequestEntity)) -> Flags.RecursionAvailable = 1;
			((DNSHeader *)(Context -> RequestEntity)) -> Flags.ResponseCode = RefusingResponseCode;
			if( Family == AF_INET )
			{
				_SendTo(ListenSocketUDP,
						Context -> RequestEntity,
						Context -> RequestLength,
						0,
						(struct sockaddr *)&(ClientAddr -> Addr4),
						sizeof(struct sockaddr)
						);
			} else {
				_SendTo(ListenSocketUDP,
						Context -> RequestEntity,
						Context -> RequestLength,
						0,
						(struct sockaddr *)&(ClientAddr -> Addr6),
						sizeof(struct sockaddr_in6)
						);
			}
			return -1;
			break;

		case QUERY_RESULT_ERROR:
			((DNSHeader *)(Context -> RequestEntity)) -> Flags.Direction = 1;
			((DNSHeader *)(Context -> RequestEntity)) -> Flags.RecursionAvailable = 1;
			((DNSHeader *)(Context -> RequestEntity)) -> Flags.ResponseCode = 2;
			if( Family == AF_INET )
			{
				_SendTo(ListenSocketUDP,
						Context -> RequestEntity,
						Context -> RequestLength,
						0,
						(struct sockaddr *)&(ClientAddr -> Addr4),
						sizeof(struct sockaddr)
						);
			} else {
				_SendTo(ListenSocketUDP,
						Context -> RequestEntity,
						Context -> RequestLength,
						0,
						(struct sockaddr *)&(ClientAddr -> Addr6),
						sizeof(struct sockaddr_in6)
						);
			}
			return -1;
			break;

		default: /* Succeed */
			if(State > MaximumMessageSize)
			{
				State = MaximumMessageSize;
				((DNSHeader *)(ExtendableBuffer_GetData(Context -> ResponseBuffer))) -> Flags.TrunCation = 1;
			}

			if( Family == AF_INET )
			{
				_SendTo(ListenSocketUDP,
						ExtendableBuffer_GetData(Context -> ResponseBuffer),
						State,
						0,
						(struct sockaddr *)&(ClientAddr -> Addr4),
						sizeof(struct sockaddr)
						);
			} else {
				_SendTo(ListenSocketUDP,
						ExtendableBuffer_GetData(Context -> ResponseBuffer),
						State,
						0,
						(struct sockaddr *)&(ClientAddr -> Addr6),
						sizeof(struct sockaddr_in6)
						);
			}
			return 0;
	}
}
static int TCPRecv(RecvInfo *Info)
{
	SOCKET				Socket	=	Info -> Socket;
	CompatibleAddr		Peer	=	Info -> Peer;
	int					state;
	char				ResultBuffer[1024];
	ExtendableBuffer	Buffer;

	/* Sockets to server */
	SOCKET				TCPSocket = INVALID_SOCKET;
	SOCKET				UDPSocket = INVALID_SOCKET;
	SOCKET				*PrimarySocketPtr;
	SOCKET				*SecondarySocketPtr;
	DNSQuaryProtocol	PrimaryProtocol;

	char				ProtocolStr[8] = {0};

	strncpy(ProtocolStr, ConfigGetString(&ConfigInfo, "PrimaryServer"), 3);
	StrToLower(ProtocolStr);

	if( strcmp(ProtocolStr, "tcp") == 0 )
	{
		PrimaryProtocol = DNS_QUARY_PROTOCOL_TCP;
		PrimarySocketPtr = &TCPSocket;

		if( ConfigGetString(&ConfigInfo, "UDPServer") != NULL )
			SecondarySocketPtr = &UDPSocket;
		else
			SecondarySocketPtr = NULL;

	} else {
		PrimaryProtocol = DNS_QUARY_PROTOCOL_UDP;
		PrimarySocketPtr = &UDPSocket;

		if( ConfigGetString(&ConfigInfo, "TCPServer") != NULL )
			SecondarySocketPtr = &TCPSocket;
		else
			SecondarySocketPtr = NULL;
	}

	ExtendableBuffer_Init(&Buffer, 512, 10240);

	while(TRUE){
		state = recv(Socket, ResultBuffer, sizeof(ResultBuffer), MSG_NOSIGNAL);
		if(GET_LAST_ERROR() == TCP_TIME_OUT)
		{
			break;
		}

		if( state < 1 )
		{
			break;
		}

		Query(PrimarySocketPtr, SecondarySocketPtr, PrimaryProtocol, ResultBuffer, state, &Socket, &Peer, &Buffer);
		ExtendableBuffer_Reset(&Buffer);

	}

	CLOSE_SOCKET(TCPSocket);
	CLOSE_SOCKET(UDPSocket);

	CLOSE_SOCKET(Socket);

	if( Family == AF_INET )
	{
		INFO("Closed TCP connection to %s:%d\n", inet_ntoa(Peer.Addr4.sin_addr), Peer.Addr4.sin_port);
	} else {
		char Addr[LENGTH_OF_IPV6_ADDRESS_ASCII] = {0};

		IPv6AddressToAsc(&(Peer.Addr6.sin6_addr), Addr);

		INFO("Closed TCP connection to %s:%d\n", Addr, Peer.Addr6.sin6_port);
	}

	SafeFree(Info);

	EXIT_THREAD(0);
}
static int Query(	SOCKET				*PrimarySocket,
					SOCKET				*SecondarySocket,
					DNSQuaryProtocol	PrimaryProtocol,
					char				*QueryContent,
					int					QueryContentLength,

					SOCKET				*ClientSocket,
					CompatibleAddr		*ClientAddr,
					ExtendableBuffer	*Buffer
					)
{
	int					State;

	DNSRecordType		SourceType;
	char				*DNSBody = DNSGetDNSBody(QueryContent);

	char				ProtocolCharacter = ' ';

	char				QueryDomain[256];

	char				DateAndTime[32];

	QueryContext		Context;

	GetCurDateAndTime(DateAndTime, sizeof(DateAndTime));

	QueryDomain[0] = '\0';
	DNSGetHostName(DNSBody, DNSJumpHeader(DNSBody), QueryDomain);

	SourceType = (DNSRecordType)DNSGetRecordType(DNSJumpHeader(DNSBody));

	Context.PrimarySocket = PrimarySocket;
	Context.SecondarySocket = SecondarySocket;
	Context.PrimaryProtocolToServer = PrimaryProtocol;
	Context.ProtocolToSrc = DNS_QUARY_PROTOCOL_TCP;
	Context.Compress = TRUE;

	State = QueryBase(&Context,

					  QueryContent,
					  QueryContentLength,

					  Buffer,
					  QueryDomain,
					  SourceType,
					  &ProtocolCharacter
					  );

	switch( State )
	{
		case QUERY_RESULT_DISABLE:
			((DNSHeader *)DNSBody) -> Flags.Direction = 1;
			((DNSHeader *)DNSBody) -> Flags.ResponseCode = 5;
			send(*ClientSocket, QueryContent, QueryContentLength, 0);
			if( Family == AF_INET )
			{
				PRINT("%s[R][%s:%d][%s][%s] Refused.\n", DateAndTime, inet_ntoa(ClientAddr -> Addr4.sin_addr), ClientAddr -> Addr4.sin_port, DNSGetTypeName(SourceType), QueryDomain);
			} else {
				char Addr[LENGTH_OF_IPV6_ADDRESS_ASCII] = {0};

				IPv6AddressToAsc(&(ClientAddr -> Addr6.sin6_addr), Addr);

				PRINT("%s[R][%s:%d][%s][%s] Refused.\n", DateAndTime, Addr, ClientAddr -> Addr6.sin6_port, DNSGetTypeName(SourceType), QueryDomain);

			}
			return -1;
			break;

		case QUERY_RESULT_ERROR:
			if( ErrorMessages == TRUE )
			{
				int		ErrorNum = GET_LAST_ERROR();
				char	ErrorMessage[320];

				ErrorMessage[0] ='\0';

				GetErrorMsg(ErrorNum, ErrorMessage, sizeof(ErrorMessage));
				if( Family == AF_INET )
				{
					printf("%s[%c][%s][%s][%s] Error occured : %d : %s .\n",
						   DateAndTime,
						   ProtocolCharacter,
						   inet_ntoa(ClientAddr -> Addr4.sin_addr),
						   DNSGetTypeName(SourceType),
						   QueryDomain,
						   ErrorNum,
						   ErrorMessage
						   );
				} else {
					char Addr[LENGTH_OF_IPV6_ADDRESS_ASCII] = {0};

					IPv6AddressToAsc(&(ClientAddr -> Addr6.sin6_addr), Addr);

					printf("%s[%c][%s][%s][%s] Error occured : %d : %s .\n",
						   DateAndTime,
						   ProtocolCharacter,
						   Addr,
						   DNSGetTypeName(SourceType),
						   QueryDomain,
						   ErrorNum,
						   ErrorMessage
						   );
				}
			}
			return -1;
			break;

		default: /* Succeed */
			send(*ClientSocket, ExtendableBuffer_GetData(Buffer), State, 0);

			if( ShowMassages == TRUE )
			{
				char InfoBuffer[3072];
				InfoBuffer[0] = '\0';
				GetAllAnswers(DNSGetDNSBody(ExtendableBuffer_GetData(Buffer)), InfoBuffer);

				if( Family == AF_INET )
				{
					PRINT("%s[%c][%s][%s][%s] :\n%s", DateAndTime, ProtocolCharacter, inet_ntoa(ClientAddr ->Addr4.sin_addr), DNSGetTypeName(SourceType), QueryDomain, InfoBuffer);
				} else {
					char Addr[LENGTH_OF_IPV6_ADDRESS_ASCII] = {0};

					IPv6AddressToAsc(&(ClientAddr -> Addr6.sin6_addr), Addr);

					PRINT("%s[%c][%s][%s][%s] :\n%s", DateAndTime, ProtocolCharacter, Addr, DNSGetTypeName(SourceType), QueryDomain, InfoBuffer);
				}
			}
			return 0;
			break;

	}
}