567 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			567 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
//*****************************************************************************
 | 
						|
//
 | 
						|
//! \file dns.c
 | 
						|
//! \brief DNS APIs Implement file.
 | 
						|
//! \details Send DNS query & Receive DNS reponse.  \n
 | 
						|
//!          It depends on stdlib.h & string.h in ansi-c library
 | 
						|
//! \version 1.1.0
 | 
						|
//! \date 2013/11/18
 | 
						|
//! \par  Revision history
 | 
						|
//!       <2013/10/21> 1st Release
 | 
						|
//!       <2013/12/20> V1.1.0
 | 
						|
//!         1. Remove secondary DNS server in DNS_run
 | 
						|
//!            If 1st DNS_run failed, call DNS_run with 2nd DNS again
 | 
						|
//!         2. DNS_timerHandler -> DNS_time_handler
 | 
						|
//!         3. Remove the unused define
 | 
						|
//!         4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c
 | 
						|
//!       <2013/12/20> V1.1.0
 | 
						|
//!
 | 
						|
//! \author Eric Jung & MidnightCow
 | 
						|
//! \copyright
 | 
						|
//!
 | 
						|
//! Copyright (c)  2013, WIZnet Co., LTD.
 | 
						|
//! All rights reserved.
 | 
						|
//! 
 | 
						|
//! Redistribution and use in source and binary forms, with or without 
 | 
						|
//! modification, are permitted provided that the following conditions 
 | 
						|
//! are met: 
 | 
						|
//! 
 | 
						|
//!     * Redistributions of source code must retain the above copyright 
 | 
						|
//! notice, this list of conditions and the following disclaimer. 
 | 
						|
//!     * Redistributions in binary form must reproduce the above copyright
 | 
						|
//! notice, this list of conditions and the following disclaimer in the
 | 
						|
//! documentation and/or other materials provided with the distribution. 
 | 
						|
//!     * Neither the name of the <ORGANIZATION> nor the names of its 
 | 
						|
//! contributors may be used to endorse or promote products derived 
 | 
						|
//! from this software without specific prior written permission. 
 | 
						|
//! 
 | 
						|
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
						|
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 | 
						|
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
						|
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 | 
						|
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 | 
						|
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 | 
						|
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
						|
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 | 
						|
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 | 
						|
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 | 
						|
//! THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
//
 | 
						|
//*****************************************************************************
 | 
						|
 | 
						|
#include <string.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
#include "socket.h"
 | 
						|
#include "dns.h"
 | 
						|
 | 
						|
#ifdef _DNS_DEBUG_
 | 
						|
   #include <stdio.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#define	INITRTT		2000L	/* Initial smoothed response time */
 | 
						|
#define	MAXCNAME	   (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1))	   /* Maximum amount of cname recursion */
 | 
						|
 | 
						|
#define	TYPE_A		1	   /* Host address */
 | 
						|
#define	TYPE_NS		2	   /* Name server */
 | 
						|
#define	TYPE_MD		3	   /* Mail destination (obsolete) */
 | 
						|
#define	TYPE_MF		4	   /* Mail forwarder (obsolete) */
 | 
						|
#define	TYPE_CNAME	5	   /* Canonical name */
 | 
						|
#define	TYPE_SOA	   6	   /* Start of Authority */
 | 
						|
#define	TYPE_MB		7	   /* Mailbox name (experimental) */
 | 
						|
#define	TYPE_MG		8	   /* Mail group member (experimental) */
 | 
						|
#define	TYPE_MR		9	   /* Mail rename name (experimental) */
 | 
						|
#define	TYPE_NULL	10	   /* Null (experimental) */
 | 
						|
#define	TYPE_WKS	   11	   /* Well-known sockets */
 | 
						|
#define	TYPE_PTR	   12	   /* Pointer record */
 | 
						|
#define	TYPE_HINFO	13	   /* Host information */
 | 
						|
#define	TYPE_MINFO	14	   /* Mailbox information (experimental)*/
 | 
						|
#define	TYPE_MX		15	   /* Mail exchanger */
 | 
						|
#define	TYPE_TXT	   16	   /* Text strings */
 | 
						|
#define	TYPE_ANY	   255	/* Matches any type */
 | 
						|
 | 
						|
#define	CLASS_IN	   1	   /* The ARPA Internet */
 | 
						|
 | 
						|
/* Round trip timing parameters */
 | 
						|
#define	AGAIN	      8     /* Average RTT gain = 1/8 */
 | 
						|
#define	LAGAIN      3     /* Log2(AGAIN) */
 | 
						|
#define	DGAIN       4     /* Mean deviation gain = 1/4 */
 | 
						|
#define	LDGAIN      2     /* log2(DGAIN) */
 | 
						|
 | 
						|
/* Header for all domain messages */
 | 
						|
struct dhdr
 | 
						|
{
 | 
						|
	uint16_t id;   /* Identification */
 | 
						|
	uint8_t	qr;      /* Query/Response */
 | 
						|
#define	QUERY    0
 | 
						|
#define	RESPONSE 1
 | 
						|
	uint8_t	opcode;
 | 
						|
#define	IQUERY   1
 | 
						|
	uint8_t	aa;      /* Authoratative answer */
 | 
						|
	uint8_t	tc;      /* Truncation */
 | 
						|
	uint8_t	rd;      /* Recursion desired */
 | 
						|
	uint8_t	ra;      /* Recursion available */
 | 
						|
	uint8_t	rcode;   /* Response code */
 | 
						|
#define	NO_ERROR       0
 | 
						|
#define	FORMAT_ERROR   1
 | 
						|
#define	SERVER_FAIL    2
 | 
						|
#define	NAME_ERROR     3
 | 
						|
#define	NOT_IMPL       4
 | 
						|
#define	REFUSED        5
 | 
						|
	uint16_t qdcount;	/* Question count */
 | 
						|
	uint16_t ancount;	/* Answer count */
 | 
						|
	uint16_t nscount;	/* Authority (name server) count */
 | 
						|
	uint16_t arcount;	/* Additional record count */
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
uint8_t* pDNSMSG;       // DNS message buffer
 | 
						|
uint8_t  DNS_SOCKET;    // SOCKET number for DNS
 | 
						|
uint16_t DNS_MSGID;     // DNS message ID
 | 
						|
 | 
						|
uint32_t dns_1s_tick;   // for timout of DNS processing
 | 
						|
static uint8_t retry_count;
 | 
						|
 | 
						|
/* converts uint16_t from network buffer to a host byte order integer. */
 | 
						|
uint16_t get16(uint8_t * s)
 | 
						|
{
 | 
						|
	uint16_t i;
 | 
						|
	i = *s++ << 8;
 | 
						|
	i = i + *s;
 | 
						|
	return i;
 | 
						|
}
 | 
						|
 | 
						|
/* copies uint16_t to the network buffer with network byte order. */
 | 
						|
uint8_t * put16(uint8_t * s, uint16_t i)
 | 
						|
{
 | 
						|
	*s++ = i >> 8;
 | 
						|
	*s++ = i;
 | 
						|
	return s;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *              CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM
 | 
						|
 *
 | 
						|
 * Description : This function converts a compressed domain name to the human-readable form
 | 
						|
 * Arguments   : msg        - is a pointer to the reply message
 | 
						|
 *               compressed - is a pointer to the domain name in reply message.
 | 
						|
 *               buf        - is a pointer to the buffer for the human-readable form name.
 | 
						|
 *               len        - is the MAX. size of buffer.
 | 
						|
 * Returns     : the length of compressed message
 | 
						|
 */
 | 
						|
int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len)
 | 
						|
{
 | 
						|
	uint16_t slen;		/* Length of current segment */
 | 
						|
	uint8_t * cp;
 | 
						|
	int clen = 0;		/* Total length of compressed name */
 | 
						|
	int indirect = 0;	/* Set if indirection encountered */
 | 
						|
	int nseg = 0;		/* Total number of segments in name */
 | 
						|
 | 
						|
	cp = compressed;
 | 
						|
 | 
						|
	for (;;)
 | 
						|
	{
 | 
						|
		slen = *cp++;	/* Length of this segment */
 | 
						|
 | 
						|
		if (!indirect) clen++;
 | 
						|
 | 
						|
		if ((slen & 0xc0) == 0xc0)
 | 
						|
		{
 | 
						|
			if (!indirect)
 | 
						|
				clen++;
 | 
						|
			indirect = 1;
 | 
						|
			/* Follow indirection */
 | 
						|
			cp = &msg[((slen & 0x3f)<<8) + *cp];
 | 
						|
			slen = *cp++;
 | 
						|
		}
 | 
						|
 | 
						|
		if (slen == 0)	/* zero length == all done */
 | 
						|
			break;
 | 
						|
 | 
						|
		len -= slen + 1;
 | 
						|
 | 
						|
		if (len < 0) return -1;
 | 
						|
 | 
						|
		if (!indirect) clen += slen;
 | 
						|
 | 
						|
		while (slen-- != 0) *buf++ = (char)*cp++;
 | 
						|
		*buf++ = '.';
 | 
						|
		nseg++;
 | 
						|
	}
 | 
						|
 | 
						|
	if (nseg == 0)
 | 
						|
	{
 | 
						|
		/* Root name; represent as single dot */
 | 
						|
		*buf++ = '.';
 | 
						|
		len--;
 | 
						|
	}
 | 
						|
 | 
						|
	*buf++ = '\0';
 | 
						|
	len--;
 | 
						|
 | 
						|
	return clen;	/* Length of compressed message */
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 *              PARSE QUESTION SECTION
 | 
						|
 *
 | 
						|
 * Description : This function parses the qeustion record of the reply message.
 | 
						|
 * Arguments   : msg - is a pointer to the reply message
 | 
						|
 *               cp  - is a pointer to the qeustion record.
 | 
						|
 * Returns     : a pointer the to next record.
 | 
						|
 */
 | 
						|
uint8_t * dns_question(uint8_t * msg, uint8_t * cp)
 | 
						|
{
 | 
						|
	int len;
 | 
						|
	char name[MAXCNAME];
 | 
						|
 | 
						|
	len = parse_name(msg, cp, name, MAXCNAME);
 | 
						|
 | 
						|
 | 
						|
	if (len == -1) return 0;
 | 
						|
 | 
						|
	cp += len;
 | 
						|
	cp += 2;		/* type */
 | 
						|
	cp += 2;		/* class */
 | 
						|
 | 
						|
	return cp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *              PARSE ANSER SECTION
 | 
						|
 *
 | 
						|
 * Description : This function parses the answer record of the reply message.
 | 
						|
 * Arguments   : msg - is a pointer to the reply message
 | 
						|
 *               cp  - is a pointer to the answer record.
 | 
						|
 * Returns     : a pointer the to next record.
 | 
						|
 */
 | 
						|
uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns)
 | 
						|
{
 | 
						|
	int len, type;
 | 
						|
	char name[MAXCNAME];
 | 
						|
 | 
						|
	len = parse_name(msg, cp, name, MAXCNAME);
 | 
						|
 | 
						|
	if (len == -1) return 0;
 | 
						|
 | 
						|
	cp += len;
 | 
						|
	type = get16(cp);
 | 
						|
	cp += 2;		/* type */
 | 
						|
	cp += 2;		/* class */
 | 
						|
	cp += 4;		/* ttl */
 | 
						|
	cp += 2;		/* len */
 | 
						|
 | 
						|
 | 
						|
	switch (type)
 | 
						|
	{
 | 
						|
	case TYPE_A:
 | 
						|
		/* Just read the address directly into the structure */
 | 
						|
		ip_from_dns[0] = *cp++;
 | 
						|
		ip_from_dns[1] = *cp++;
 | 
						|
		ip_from_dns[2] = *cp++;
 | 
						|
		ip_from_dns[3] = *cp++;
 | 
						|
		break;
 | 
						|
	case TYPE_CNAME:
 | 
						|
	case TYPE_MB:
 | 
						|
	case TYPE_MG:
 | 
						|
	case TYPE_MR:
 | 
						|
	case TYPE_NS:
 | 
						|
	case TYPE_PTR:
 | 
						|
		/* These types all consist of a single domain name */
 | 
						|
		/* convert it to ascii format */
 | 
						|
		len = parse_name(msg, cp, name, MAXCNAME);
 | 
						|
		if (len == -1) return 0;
 | 
						|
 | 
						|
		cp += len;
 | 
						|
		break;
 | 
						|
	case TYPE_HINFO:
 | 
						|
		len = *cp++;
 | 
						|
		cp += len;
 | 
						|
 | 
						|
		len = *cp++;
 | 
						|
		cp += len;
 | 
						|
		break;
 | 
						|
	case TYPE_MX:
 | 
						|
		cp += 2;
 | 
						|
		/* Get domain name of exchanger */
 | 
						|
		len = parse_name(msg, cp, name, MAXCNAME);
 | 
						|
		if (len == -1) return 0;
 | 
						|
 | 
						|
		cp += len;
 | 
						|
		break;
 | 
						|
	case TYPE_SOA:
 | 
						|
		/* Get domain name of name server */
 | 
						|
		len = parse_name(msg, cp, name, MAXCNAME);
 | 
						|
		if (len == -1) return 0;
 | 
						|
 | 
						|
		cp += len;
 | 
						|
 | 
						|
		/* Get domain name of responsible person */
 | 
						|
		len = parse_name(msg, cp, name, MAXCNAME);
 | 
						|
		if (len == -1) return 0;
 | 
						|
 | 
						|
		cp += len;
 | 
						|
 | 
						|
		cp += 4;
 | 
						|
		cp += 4;
 | 
						|
		cp += 4;
 | 
						|
		cp += 4;
 | 
						|
		cp += 4;
 | 
						|
		break;
 | 
						|
	case TYPE_TXT:
 | 
						|
		/* Just stash */
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		/* Ignore */
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return cp;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 *              PARSE THE DNS REPLY
 | 
						|
 *
 | 
						|
 * Description : This function parses the reply message from DNS server.
 | 
						|
 * Arguments   : dhdr - is a pointer to the header for DNS message
 | 
						|
 *               buf  - is a pointer to the reply message.
 | 
						|
 *               len  - is the size of reply message.
 | 
						|
 * Returns     : -1 - Domain name lenght is too big 
 | 
						|
 *                0 - Fail (Timout or parse error)
 | 
						|
 *                1 - Success, 
 | 
						|
 */
 | 
						|
int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns)
 | 
						|
{
 | 
						|
	uint16_t tmp;
 | 
						|
	uint16_t i;
 | 
						|
	uint8_t * msg;
 | 
						|
	uint8_t * cp;
 | 
						|
 | 
						|
	msg = pbuf;
 | 
						|
	memset(pdhdr, 0, sizeof(*pdhdr));
 | 
						|
 | 
						|
	pdhdr->id = get16(&msg[0]);
 | 
						|
	tmp = get16(&msg[2]);
 | 
						|
	if (tmp & 0x8000) pdhdr->qr = 1;
 | 
						|
 | 
						|
	pdhdr->opcode = (tmp >> 11) & 0xf;
 | 
						|
 | 
						|
	if (tmp & 0x0400) pdhdr->aa = 1;
 | 
						|
	if (tmp & 0x0200) pdhdr->tc = 1;
 | 
						|
	if (tmp & 0x0100) pdhdr->rd = 1;
 | 
						|
	if (tmp & 0x0080) pdhdr->ra = 1;
 | 
						|
 | 
						|
	pdhdr->rcode = tmp & 0xf;
 | 
						|
	pdhdr->qdcount = get16(&msg[4]);
 | 
						|
	pdhdr->ancount = get16(&msg[6]);
 | 
						|
	pdhdr->nscount = get16(&msg[8]);
 | 
						|
	pdhdr->arcount = get16(&msg[10]);
 | 
						|
 | 
						|
 | 
						|
	/* Now parse the variable length sections */
 | 
						|
	cp = &msg[12];
 | 
						|
 | 
						|
	/* Question section */
 | 
						|
	for (i = 0; i < pdhdr->qdcount; i++)
 | 
						|
	{
 | 
						|
		cp = dns_question(msg, cp);
 | 
						|
   #ifdef _DNS_DEUBG_
 | 
						|
      printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h"
 | 
						|
   #endif
 | 
						|
		if(!cp) return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Answer section */
 | 
						|
	for (i = 0; i < pdhdr->ancount; i++)
 | 
						|
	{
 | 
						|
		cp = dns_answer(msg, cp, ip_from_dns);
 | 
						|
   #ifdef _DNS_DEUBG_
 | 
						|
      printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h"
 | 
						|
   #endif
 | 
						|
		if(!cp) return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Name server (authority) section */
 | 
						|
	for (i = 0; i < pdhdr->nscount; i++)
 | 
						|
	{
 | 
						|
		;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Additional section */
 | 
						|
	for (i = 0; i < pdhdr->arcount; i++)
 | 
						|
	{
 | 
						|
		;
 | 
						|
	}
 | 
						|
 | 
						|
	if(pdhdr->rcode == 0) return 1;		// No error
 | 
						|
	else return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *              MAKE DNS QUERY MESSAGE
 | 
						|
 *
 | 
						|
 * Description : This function makes DNS query message.
 | 
						|
 * Arguments   : op   - Recursion desired
 | 
						|
 *               name - is a pointer to the domain name.
 | 
						|
 *               buf  - is a pointer to the buffer for DNS message.
 | 
						|
 *               len  - is the MAX. size of buffer.
 | 
						|
 * Returns     : the pointer to the DNS message.
 | 
						|
 */
 | 
						|
int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len)
 | 
						|
{
 | 
						|
	uint8_t *cp;
 | 
						|
	char *cp1;
 | 
						|
	char sname[MAXCNAME];
 | 
						|
	char *dname;
 | 
						|
	uint16_t p;
 | 
						|
	uint16_t dlen;
 | 
						|
 | 
						|
	cp = buf;
 | 
						|
 | 
						|
	DNS_MSGID++;
 | 
						|
	cp = put16(cp, DNS_MSGID);
 | 
						|
	p = (op << 11) | 0x0100;			/* Recursion desired */
 | 
						|
	cp = put16(cp, p);
 | 
						|
	cp = put16(cp, 1);
 | 
						|
	cp = put16(cp, 0);
 | 
						|
	cp = put16(cp, 0);
 | 
						|
	cp = put16(cp, 0);
 | 
						|
 | 
						|
	strcpy(sname, name);
 | 
						|
	dname = sname;
 | 
						|
	dlen = strlen(dname);
 | 
						|
	for (;;)
 | 
						|
	{
 | 
						|
		/* Look for next dot */
 | 
						|
		cp1 = strchr(dname, '.');
 | 
						|
 | 
						|
		if (cp1 != NULL) len = cp1 - dname;	/* More to come */
 | 
						|
		else len = dlen;			/* Last component */
 | 
						|
 | 
						|
		*cp++ = len;				/* Write length of component */
 | 
						|
		if (len == 0) break;
 | 
						|
 | 
						|
		/* Copy component up to (but not including) dot */
 | 
						|
		strncpy((char *)cp, dname, len);
 | 
						|
		cp += len;
 | 
						|
		if (cp1 == NULL)
 | 
						|
		{
 | 
						|
			*cp++ = 0;			/* Last one; write null and finish */
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		dname += len+1;
 | 
						|
		dlen -= len+1;
 | 
						|
	}
 | 
						|
 | 
						|
	cp = put16(cp, 0x0001);				/* type */
 | 
						|
	cp = put16(cp, 0x0001);				/* class */
 | 
						|
 | 
						|
	return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf)));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 *              CHECK DNS TIMEOUT
 | 
						|
 *
 | 
						|
 * Description : This function check the DNS timeout
 | 
						|
 * Arguments   : None.
 | 
						|
 * Returns     : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur
 | 
						|
 * Note        : timeout : retry count and timer both over.
 | 
						|
 */
 | 
						|
 | 
						|
int8_t check_DNS_timeout(void)
 | 
						|
{
 | 
						|
 | 
						|
	if(dns_1s_tick >= DNS_WAIT_TIME)
 | 
						|
	{
 | 
						|
		dns_1s_tick = 0;
 | 
						|
		if(retry_count >= MAX_DNS_RETRY) {
 | 
						|
			retry_count = 0;
 | 
						|
			return -1; // timeout occurred
 | 
						|
		}
 | 
						|
		retry_count++;
 | 
						|
		return 0; // timer over, but no timeout
 | 
						|
	}
 | 
						|
 | 
						|
	return 1; // no timer over, no timeout occur
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/* DNS CLIENT INIT */
 | 
						|
void DNS_init(uint8_t s, uint8_t * buf)
 | 
						|
{
 | 
						|
	DNS_SOCKET = s; // SOCK_DNS
 | 
						|
	pDNSMSG = buf; // User's shared buffer
 | 
						|
	DNS_MSGID = DNS_MSG_ID;
 | 
						|
}
 | 
						|
 | 
						|
/* DNS CLIENT RUN */
 | 
						|
int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns)
 | 
						|
{
 | 
						|
	int8_t ret;
 | 
						|
	struct dhdr dhp;
 | 
						|
	uint8_t ip[4];
 | 
						|
	uint16_t len, port;
 | 
						|
	int8_t ret_check_timeout;
 | 
						|
 | 
						|
	retry_count = 0;
 | 
						|
	dns_1s_tick = 0;
 | 
						|
   
 | 
						|
   // Socket open
 | 
						|
   socket(DNS_SOCKET, Sn_MR_UDP, 0, 0);
 | 
						|
 | 
						|
#ifdef _DNS_DEBUG_
 | 
						|
	printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
 | 
						|
#endif
 | 
						|
   
 | 
						|
	len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE);
 | 
						|
	sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
 | 
						|
 | 
						|
	while (1)
 | 
						|
	{
 | 
						|
		if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0)
 | 
						|
		{
 | 
						|
			if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE;
 | 
						|
			len = recvfrom(DNS_SOCKET, pDNSMSG, len, ip, &port);
 | 
						|
      #ifdef _DNS_DEBUG_
 | 
						|
	      printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len);
 | 
						|
      #endif
 | 
						|
         ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns);
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		// Check Timeout
 | 
						|
		ret_check_timeout = check_DNS_timeout();
 | 
						|
		if (ret_check_timeout < 0) {
 | 
						|
 | 
						|
#ifdef _DNS_DEBUG_
 | 
						|
			printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
 | 
						|
#endif
 | 
						|
			return 0; // timeout occurred
 | 
						|
		}
 | 
						|
		else if (ret_check_timeout == 0) {
 | 
						|
 | 
						|
#ifdef _DNS_DEBUG_
 | 
						|
			printf("> DNS Timeout\r\n");
 | 
						|
#endif
 | 
						|
			sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	close(DNS_SOCKET);
 | 
						|
	// Return value
 | 
						|
	// 0 > :  failed / 1 - success
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* DNS TIMER HANDLER */
 | 
						|
void DNS_time_handler(void)
 | 
						|
{
 | 
						|
	dns_1s_tick++;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 |