mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-02-06 18:41:30 +00:00
Added function documentation to dns.c, removed function documentation from dns.h (functions should be documented where they are implemented!), dns_table_entry doesn't have to be packed (slower, bigger code for most machines), converted dns_init to return void, dns_table is implicitly initialized to zero, dns_lookup can be static, dns_send returns correct error values, added some asserts, compacted dns_recv using some (ugly) gotos, compacted dns_gethostbyname by combining the same return value
This commit is contained in:
parent
f58515b51e
commit
b3c52f574a
273
src/core/dns.c
273
src/core/dns.c
@ -190,10 +190,6 @@ PACK_STRUCT_END
|
|||||||
# include "arch/epstruct.h"
|
# include "arch/epstruct.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
/** DNS table entry */
|
/** DNS table entry */
|
||||||
struct dns_table_entry {
|
struct dns_table_entry {
|
||||||
u8_t state;
|
u8_t state;
|
||||||
@ -205,13 +201,11 @@ struct dns_table_entry {
|
|||||||
u32_t ttl;
|
u32_t ttl;
|
||||||
char name[DNS_MAX_NAME_LENGTH];
|
char name[DNS_MAX_NAME_LENGTH];
|
||||||
struct ip_addr ipaddr;
|
struct ip_addr ipaddr;
|
||||||
void (* found)(const char *name, struct ip_addr *ipaddr, void *arg); /* pointer to callback on DNS query done */
|
/* pointer to callback on DNS query done */
|
||||||
|
dns_found_callback found;
|
||||||
void *arg;
|
void *arg;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
|
static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
|
||||||
@ -232,15 +226,12 @@ static u8_t dns_payload[DNS_MSG_SIZE];
|
|||||||
#endif /* (DNS_USES_STATIC_BUF == 1) */
|
#endif /* (DNS_USES_STATIC_BUF == 1) */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the resolver and configure which DNS server to use for queries.
|
* Initialize the resolver: set up the UDP pcb and configure the default server
|
||||||
*
|
* (DNS_SERVER_ADDRESS).
|
||||||
* param dnsserver A pointer to a 4-byte representation of the IP
|
|
||||||
* address of the DNS server to be configured.
|
|
||||||
*/
|
*/
|
||||||
err_t
|
void
|
||||||
dns_init()
|
dns_init()
|
||||||
{
|
{
|
||||||
u8_t i;
|
|
||||||
struct ip_addr dnsserver = {DNS_SERVER_ADDRESS};
|
struct ip_addr dnsserver = {DNS_SERVER_ADDRESS};
|
||||||
|
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n"));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n"));
|
||||||
@ -250,11 +241,10 @@ dns_init()
|
|||||||
dns_pcb = udp_new();
|
dns_pcb = udp_new();
|
||||||
|
|
||||||
if (dns_pcb != NULL) {
|
if (dns_pcb != NULL) {
|
||||||
/* initialize DNS table */
|
/* initialize DNS table not needed (initialized to zero since it is a
|
||||||
for (i=0; i<DNS_TABLE_SIZE; ++i) {
|
* global variable) */
|
||||||
dns_table[i].state = DNS_STATE_UNUSED;
|
LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0",
|
||||||
dns_table[i].found = NULL;
|
DNS_STATE_UNUSED == 0);
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize DNS client */
|
/* initialize DNS client */
|
||||||
udp_bind(dns_pcb, IP_ADDR_ANY, 0);
|
udp_bind(dns_pcb, IP_ADDR_ANY, 0);
|
||||||
@ -264,33 +254,43 @@ dns_init()
|
|||||||
dns_setserver(0, &dnsserver);
|
dns_setserver(0, &dnsserver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize one if the DNS server.
|
* Initialize one of the DNS servers.
|
||||||
|
*
|
||||||
|
* @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS
|
||||||
|
* @param dnsserver IP address of the DNS server to set
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dns_setserver(u8_t numdns, struct ip_addr *dnsserver)
|
dns_setserver(u8_t numdns, struct ip_addr *dnsserver)
|
||||||
{
|
{
|
||||||
if ((numdns<DNS_MAX_SERVERS) && (dns_pcb != NULL) && (dnsserver != NULL) && (dnsserver->addr !=0 )) {
|
if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) &&
|
||||||
|
(dnsserver != NULL) && (dnsserver->addr !=0 )) {
|
||||||
dns_servers[numdns] = (*dnsserver);
|
dns_servers[numdns] = (*dnsserver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain one of the currently configured DNS server.
|
* Obtain one of the currently configured DNS server.
|
||||||
* return IP address of one of the currently configured DNS server or "ip_addr_any"
|
*
|
||||||
* if the DNS server has not been configured.
|
* @param numdns the index of the DNS server
|
||||||
|
* @return IP address of the indexed DNS server or "ip_addr_any" if the DNS
|
||||||
|
* server has not been configured.
|
||||||
*/
|
*/
|
||||||
struct ip_addr
|
struct ip_addr
|
||||||
dns_getserver(u8_t numdns)
|
dns_getserver(u8_t numdns)
|
||||||
{
|
{
|
||||||
return (((numdns<DNS_MAX_SERVERS) && (dns_pcb != NULL))?dns_servers[numdns]:(*IP_ADDR_ANY));
|
if (numdns < DNS_MAX_SERVERS) {
|
||||||
|
return dns_servers[numdns];
|
||||||
|
} else {
|
||||||
|
return *IP_ADDR_ANY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The DNS resolver client timer - handle retries and timeouts
|
* The DNS resolver client timer - handle retries and timeouts and should
|
||||||
|
* be called every DNS_TMR_INTERVAL miliseconds (every second by default).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dns_tmr(void)
|
dns_tmr(void)
|
||||||
@ -304,25 +304,27 @@ dns_tmr(void)
|
|||||||
/**
|
/**
|
||||||
* Look up a hostname in the array of known hostnames.
|
* Look up a hostname in the array of known hostnames.
|
||||||
*
|
*
|
||||||
* \note This function only looks in the internal array of known
|
* @note This function only looks in the internal array of known
|
||||||
* hostnames, it does not send out a query for the hostname if none
|
* hostnames, it does not send out a query for the hostname if none
|
||||||
* was found. The function dns_query() can be used to send a query
|
* was found. The function dns_enqueue() can be used to send a query
|
||||||
* for a hostname.
|
* for a hostname.
|
||||||
*
|
*
|
||||||
* return A pointer to a 4-byte representation of the hostname's IP
|
* @param name the hostname to look up
|
||||||
* address, or NULL if the hostname was not found in the array of
|
* @return the hostname's IP address, as u32_t (instead of struct ip_addr to
|
||||||
* hostnames.
|
* better check for failure: != 0) or 0 if the hostname was not found
|
||||||
|
* in the cached dns_table.
|
||||||
*/
|
*/
|
||||||
u32_t
|
static u32_t
|
||||||
dns_lookup(const char *name)
|
dns_lookup(const char *name)
|
||||||
{
|
{
|
||||||
u8_t i;
|
u8_t i;
|
||||||
|
|
||||||
/* Walk through name list, return entry if found. If not, return NULL. */
|
/* Walk through name list, return entry if found. If not, return NULL. */
|
||||||
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
|
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
|
||||||
if ( (dns_table[i].state==DNS_STATE_DONE) && (strcmp(name, dns_table[i].name)==0) ) {
|
if ((dns_table[i].state == DNS_STATE_DONE) &&
|
||||||
|
(strcmp(name, dns_table[i].name) == 0)) {
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
|
||||||
ip_addr_debug_print(DNS_DEBUG, (&(dns_table[i].ipaddr)));
|
ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr));
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
|
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
|
||||||
return dns_table[i].ipaddr.addr;
|
return dns_table[i].ipaddr.addr;
|
||||||
}
|
}
|
||||||
@ -333,8 +335,14 @@ dns_lookup(const char *name)
|
|||||||
|
|
||||||
#if DNS_DOES_NAME_CHECK
|
#if DNS_DOES_NAME_CHECK
|
||||||
/**
|
/**
|
||||||
* dns_compare_name: compare the "dotted" name "query" with the
|
* Compare the "dotted" name "query" with the encoded name "response"
|
||||||
* encoded name "response"
|
* to make sure an answer from the DNS server matches the current dns_table
|
||||||
|
* entry (otherwise, answers might arrive late for hostname not on the list
|
||||||
|
* any more).
|
||||||
|
*
|
||||||
|
* @param query hostname (not encoded) from the dns_table
|
||||||
|
* @param response encoded hostname in the DNS response
|
||||||
|
* @return 0: names equal; 1: names differ
|
||||||
*/
|
*/
|
||||||
static u8_t
|
static u8_t
|
||||||
dns_compare_name(unsigned char *query, unsigned char *response)
|
dns_compare_name(unsigned char *query, unsigned char *response)
|
||||||
@ -366,8 +374,10 @@ dns_compare_name(unsigned char *query, unsigned char *response)
|
|||||||
#endif /* DNS_DOES_NAME_CHECK */
|
#endif /* DNS_DOES_NAME_CHECK */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dns_parse_name() - walk through a compact encoded DNS name and return the end
|
* Walk through a compact encoded DNS name and return the end of the name.
|
||||||
* of the name.
|
*
|
||||||
|
* @param query encoded DNS name in the DNS server response
|
||||||
|
* @return end of the name
|
||||||
*/
|
*/
|
||||||
static unsigned char *
|
static unsigned char *
|
||||||
dns_parse_name(unsigned char *query)
|
dns_parse_name(unsigned char *query)
|
||||||
@ -393,11 +403,18 @@ dns_parse_name(unsigned char *query)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dns_send
|
* Send a DNS query packet.
|
||||||
|
*
|
||||||
|
* @param numdns index of the DNS server in the dns_servers table
|
||||||
|
* @param name hostname to query
|
||||||
|
* @param id index of the hostname in dns_table, used as transaction ID in the
|
||||||
|
* DNS query packet
|
||||||
|
* @return ERR_OK if packet is sent; an err_t indicating the problem otherwise
|
||||||
*/
|
*/
|
||||||
static err_t
|
static err_t
|
||||||
dns_send(u8_t numdns, const char* name, u8_t id)
|
dns_send(u8_t numdns, const char* name, u8_t id)
|
||||||
{
|
{
|
||||||
|
err_t err;
|
||||||
struct dns_hdr *hdr;
|
struct dns_hdr *hdr;
|
||||||
struct dns_query *qry;
|
struct dns_query *qry;
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
@ -405,11 +422,16 @@ dns_send(u8_t numdns, const char* name, u8_t id)
|
|||||||
const char *pHostname;
|
const char *pHostname;
|
||||||
u8_t n;
|
u8_t n;
|
||||||
|
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", (u16_t)(numdns), name));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
|
||||||
|
(u16_t)(numdns), name));
|
||||||
|
LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS);
|
||||||
|
LWIP_ASSERT("dns server has no IP address set", dns_servers[numdns].addr != 0);
|
||||||
|
|
||||||
/* if here, we have either a new query or a retry on a previous query to process */
|
/* if here, we have either a new query or a retry on a previous query to process */
|
||||||
p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dns_hdr)+DNS_MAX_NAME_LENGTH+sizeof(struct dns_query), PBUF_RAM);
|
p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dns_hdr) + DNS_MAX_NAME_LENGTH +
|
||||||
if (p) {
|
sizeof(struct dns_query), PBUF_RAM);
|
||||||
|
if (p != NULL) {
|
||||||
|
LWIP_ASSERT("pbuf must be in one piece", p->next == NULL);
|
||||||
/* fill dns header */
|
/* fill dns header */
|
||||||
hdr = (struct dns_hdr*)p->payload;
|
hdr = (struct dns_hdr*)p->payload;
|
||||||
memset(hdr, 0, sizeof(struct dns_hdr));
|
memset(hdr, 0, sizeof(struct dns_hdr));
|
||||||
@ -443,25 +465,33 @@ dns_send(u8_t numdns, const char* name, u8_t id)
|
|||||||
pbuf_realloc(p, (query + sizeof(struct dns_query)) - ((char*)(p->payload)));
|
pbuf_realloc(p, (query + sizeof(struct dns_query)) - ((char*)(p->payload)));
|
||||||
|
|
||||||
/* send dns packet */
|
/* send dns packet */
|
||||||
udp_sendto(dns_pcb, p, dns_servers+numdns, DNS_SERVER_PORT);
|
err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT);
|
||||||
|
|
||||||
/* free pbuf */
|
/* free pbuf */
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
} else {
|
||||||
return ERR_OK;
|
err = ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_BUF;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query.
|
* dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query.
|
||||||
|
* Check an entry in the dns_table:
|
||||||
|
* - send out query for new entries
|
||||||
|
* - retry old pending entries on timeout (also with different servers)
|
||||||
|
* - remove completed entries from the table if their TTL has expired
|
||||||
|
*
|
||||||
|
* @param i index of the dns_table entry to check
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dns_check_entry(u8_t i)
|
dns_check_entry(u8_t i)
|
||||||
{
|
{
|
||||||
struct dns_table_entry *pEntry = &dns_table[i];
|
struct dns_table_entry *pEntry = &dns_table[i];
|
||||||
|
|
||||||
|
LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE);
|
||||||
|
|
||||||
switch(pEntry->state) {
|
switch(pEntry->state) {
|
||||||
|
|
||||||
case DNS_STATE_NEW: {
|
case DNS_STATE_NEW: {
|
||||||
@ -516,12 +546,17 @@ dns_check_entry(u8_t i)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DNS_STATE_UNUSED:
|
||||||
|
/* nothing to do */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_ASSERT("unknown dns_table entry state:", 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dns_check_entries() - Runs through the list of names to see if there are any
|
* Call dns_check_entry for each entry in dns_table - check all entries.
|
||||||
* that have not yet been queried and, if so, sends out a query.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dns_check_entries(void)
|
dns_check_entries(void)
|
||||||
@ -534,7 +569,9 @@ dns_check_entries(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for DNS responses
|
* Receive input function for DNS response packets arriving for the dns UDP pcb.
|
||||||
|
*
|
||||||
|
* @params see udp.h
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
|
dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
|
||||||
@ -555,23 +592,23 @@ dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16
|
|||||||
/* is the dns message too big ? */
|
/* is the dns message too big ? */
|
||||||
if (p->tot_len > DNS_MSG_SIZE) {
|
if (p->tot_len > DNS_MSG_SIZE) {
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n"));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n"));
|
||||||
pbuf_free(p);
|
/* free pbuf and return */
|
||||||
return;
|
goto memerr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is the dns message big enought ? */
|
/* is the dns message big enough ? */
|
||||||
if (p->tot_len < (sizeof(struct dns_hdr) + sizeof(struct dns_query) + sizeof(struct dns_answer))) {
|
if (p->tot_len < (sizeof(struct dns_hdr) + sizeof(struct dns_query) + sizeof(struct dns_answer))) {
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n"));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n"));
|
||||||
pbuf_free(p);
|
/* free pbuf and return */
|
||||||
return;
|
goto memerr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (DNS_USES_STATIC_BUF == 2)
|
#if (DNS_USES_STATIC_BUF == 2)
|
||||||
dns_payload = mem_malloc(p->tot_len);
|
dns_payload = mem_malloc(p->tot_len);
|
||||||
if (dns_payload == NULL) {
|
if (dns_payload == NULL) {
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: mem_malloc error\n"));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: mem_malloc error\n"));
|
||||||
pbuf_free(p);
|
/* free pbuf and return */
|
||||||
return;
|
goto memerr1;
|
||||||
}
|
}
|
||||||
#endif /* (DNS_USES_STATIC_BUF == 2) */
|
#endif /* (DNS_USES_STATIC_BUF == 2) */
|
||||||
|
|
||||||
@ -595,38 +632,16 @@ dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16
|
|||||||
/* Check for error. If so, call callback to inform. */
|
/* Check for error. If so, call callback to inform. */
|
||||||
if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) {
|
if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) {
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name));
|
||||||
/* call specified callback function if provided */
|
/* call callback to indicate error, clean up memory and return */
|
||||||
if (pEntry->found)
|
goto responseerr;
|
||||||
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
|
|
||||||
/* flush this entry */
|
|
||||||
pEntry->state = DNS_STATE_UNUSED;
|
|
||||||
pEntry->found = NULL;
|
|
||||||
/* free pbuf */
|
|
||||||
pbuf_free(p);
|
|
||||||
#if (DNS_USES_STATIC_BUF == 2)
|
|
||||||
/* free dns buffer */
|
|
||||||
mem_free(dns_payload);
|
|
||||||
#endif /* (DNS_USES_STATIC_BUF == 2) */
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DNS_DOES_NAME_CHECK
|
#if DNS_DOES_NAME_CHECK
|
||||||
/* Check if the name in the "question" part match with the name in the entry. */
|
/* Check if the name in the "question" part match with the name in the entry. */
|
||||||
if (dns_compare_name(pEntry->name, (unsigned char *)dns_payload + sizeof(struct dns_hdr)) != 0) {
|
if (dns_compare_name(pEntry->name, (unsigned char *)dns_payload + sizeof(struct dns_hdr)) != 0) {
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name));
|
||||||
/* call specified callback function if provided */
|
/* call callback to indicate error, clean up memory and return */
|
||||||
if (pEntry->found)
|
goto responseerr;
|
||||||
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
|
|
||||||
/* flush this entry */
|
|
||||||
pEntry->state = DNS_STATE_UNUSED;
|
|
||||||
pEntry->found = NULL;
|
|
||||||
/* free pbuf */
|
|
||||||
pbuf_free(p);
|
|
||||||
#if (DNS_USES_STATIC_BUF == 2)
|
|
||||||
/* free dns buffer */
|
|
||||||
mem_free(dns_payload);
|
|
||||||
#endif /* (DNS_USES_STATIC_BUF == 2) */
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif /* DNS_DOES_NAME_CHECK */
|
#endif /* DNS_DOES_NAME_CHECK */
|
||||||
|
|
||||||
@ -651,15 +666,11 @@ dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16
|
|||||||
ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr)));
|
ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr)));
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
|
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
|
||||||
/* call specified callback function if provided */
|
/* call specified callback function if provided */
|
||||||
if (pEntry->found)
|
if (pEntry->found) {
|
||||||
(*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg);
|
(*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg);
|
||||||
/* free pbuf */
|
}
|
||||||
pbuf_free(p);
|
/* deallocate memory and return */
|
||||||
#if (DNS_USES_STATIC_BUF == 2)
|
goto memerr2;
|
||||||
/* free dns buffer */
|
|
||||||
mem_free(dns_payload);
|
|
||||||
#endif /* (DNS_USES_STATIC_BUF == 2) */
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
pHostname = pHostname + sizeof(struct dns_answer) + htons(ans->len);
|
pHostname = pHostname + sizeof(struct dns_answer) + htons(ans->len);
|
||||||
}
|
}
|
||||||
@ -669,17 +680,34 @@ dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* free pbuf */
|
memerr2:
|
||||||
pbuf_free(p);
|
|
||||||
#if (DNS_USES_STATIC_BUF == 2)
|
#if (DNS_USES_STATIC_BUF == 2)
|
||||||
/* free dns buffer */
|
/* free dns buffer */
|
||||||
mem_free(dns_payload);
|
mem_free(dns_payload);
|
||||||
#endif /* (DNS_USES_STATIC_BUF == 2) */
|
#endif /* (DNS_USES_STATIC_BUF == 2) */
|
||||||
|
memerr1:
|
||||||
|
/* free pbuf */
|
||||||
|
pbuf_free(p);
|
||||||
|
return;
|
||||||
|
responseerr:
|
||||||
|
/* ERROR: call specified callback function with NULL as name to indicate an error */
|
||||||
|
if (pEntry->found) {
|
||||||
|
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
|
||||||
|
}
|
||||||
|
/* flush this entry */
|
||||||
|
pEntry->state = DNS_STATE_UNUSED;
|
||||||
|
pEntry->found = NULL;
|
||||||
|
/* deallocate memory and return */
|
||||||
|
goto memerr2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues a name so that a question for the name will be sent out.
|
* Queues a new hostname to resolve and sends out a DNS query for that hostname
|
||||||
* param name - The hostname that is to be queried.
|
*
|
||||||
|
* @param name the hostname that is to be queried
|
||||||
|
* @param found a callback founction to be called on success, failure or timeout
|
||||||
|
* @param arg argument to pass to the callback function
|
||||||
|
* @return a DNS_RESULT (@see DNS_RESULT, @see enum dns_result)
|
||||||
*/
|
*/
|
||||||
static DNS_RESULT
|
static DNS_RESULT
|
||||||
dns_enqueue(const char *name, void (*found)(const char *name, struct ip_addr *addr, void *arg), void *arg)
|
dns_enqueue(const char *name, void (*found)(const char *name, struct ip_addr *addr, void *arg), void *arg)
|
||||||
@ -698,7 +726,7 @@ dns_enqueue(const char *name, void (*found)(const char *name, struct ip_addr *ad
|
|||||||
|
|
||||||
/* check if this is the oldest completed entry */
|
/* check if this is the oldest completed entry */
|
||||||
if (pEntry->state == DNS_STATE_DONE) {
|
if (pEntry->state == DNS_STATE_DONE) {
|
||||||
if (dns_seqno - pEntry->seqno > lseq) {
|
if ((dns_seqno - pEntry->seqno) > lseq) {
|
||||||
lseq = dns_seqno - pEntry->seqno;
|
lseq = dns_seqno - pEntry->seqno;
|
||||||
lseqi = i;
|
lseqi = i;
|
||||||
}
|
}
|
||||||
@ -736,35 +764,42 @@ dns_enqueue(const char *name, void (*found)(const char *name, struct ip_addr *ad
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NON-BLOCKING callback version for use with raw API
|
* Resolve a hostname (string) into an IP address.
|
||||||
|
* NON-BLOCKING callback version for use with raw API!!!
|
||||||
|
*
|
||||||
|
* Returns immediately with one of DNS_RESULT return codes:
|
||||||
|
* - DNS_COMPLETE if hostname is a valid IP address string or the host
|
||||||
|
* name is already in the local names table.
|
||||||
|
* - DNS_REQUEST_QUEUED and queues a request to be sent to the DNS server
|
||||||
|
* for resolution if no errors are present.
|
||||||
|
*
|
||||||
|
* @param name the hostname that is to be queried
|
||||||
|
* @param addr pointer to a struct ip_addr where to store the address if it is already
|
||||||
|
* cached in the dns_table (only valid if DNS_COMPLETE is returned!)
|
||||||
|
* @param found a callback founction to be called on success, failure or timeout (only if
|
||||||
|
* DNS_QUERY_QUEUED is returned!)
|
||||||
|
* @param arg argument to pass to the callback function
|
||||||
|
* @return a DNS_RESULT (@see DNS_RESULT, @see enum dns_result)
|
||||||
*/
|
*/
|
||||||
DNS_RESULT dns_gethostbyname(const char *hostname, struct ip_addr *addr,
|
DNS_RESULT dns_gethostbyname(const char *hostname, struct ip_addr *addr, dns_found_callback found,
|
||||||
void (*found)(const char *name, struct ip_addr *ipaddr, void *arg),
|
void *callback_arg)
|
||||||
void *arg
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* not initialized or no valid server yet, or invalid addr pointer */
|
/* not initialized or no valid server yet, or invalid addr pointer
|
||||||
if ((dns_pcb == NULL) || (addr == NULL))
|
* or invalid hostname or invalid hostname length */
|
||||||
|
if ((dns_pcb == NULL) || (addr == NULL) || (!hostname) || (!hostname[0]) ||
|
||||||
|
(strlen(hostname) >= DNS_MAX_NAME_LENGTH)) {
|
||||||
return DNS_QUERY_INVALID;
|
return DNS_QUERY_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
/* invalid hostname */
|
/* host name already in octet notation? set ip addr and return COMPLETE
|
||||||
if ((!hostname) || (!hostname[0]))
|
* already have this address cached? */
|
||||||
return DNS_QUERY_INVALID;
|
if (((addr->addr = inet_addr(hostname)) != INADDR_NONE) ||
|
||||||
|
((addr->addr = dns_lookup(hostname)) != 0)) {
|
||||||
/* invalid hostname length */
|
|
||||||
if (strlen(hostname) >= DNS_MAX_NAME_LENGTH)
|
|
||||||
return DNS_QUERY_INVALID;
|
|
||||||
|
|
||||||
/* host name already in octet notation? set ip addr and return COMPLETE */
|
|
||||||
if ((addr->addr = inet_addr(hostname)) != INADDR_NONE)
|
|
||||||
return DNS_COMPLETE;
|
|
||||||
|
|
||||||
/* already have this address cached? */
|
|
||||||
if ((addr->addr = dns_lookup(hostname)) != 0)
|
|
||||||
return DNS_COMPLETE;
|
return DNS_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
/* queue query with specified callback */
|
/* queue query with specified callback */
|
||||||
return dns_enqueue(hostname, found, arg);
|
return dns_enqueue(hostname, found, callback_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* LWIP_DNS */
|
#endif /* LWIP_DNS */
|
||||||
|
@ -79,46 +79,36 @@
|
|||||||
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
||||||
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
||||||
|
|
||||||
/* enumerated list of possible result values returned by dns_gethostname() */
|
/** enumerated list of possible result values returned by dns_gethostname() */
|
||||||
typedef enum dns_result {
|
typedef enum dns_result {
|
||||||
|
/** dns_table is filled with queries, try again later */
|
||||||
DNS_ERR_MEM,
|
DNS_ERR_MEM,
|
||||||
|
/** invalid hostname, hostname too long,
|
||||||
|
* invalid arguments or dns module not initialized */
|
||||||
DNS_QUERY_INVALID,
|
DNS_QUERY_INVALID,
|
||||||
|
/** the hostname was enqueued for query,
|
||||||
|
* found callback will be called when resolved */
|
||||||
DNS_QUERY_QUEUED,
|
DNS_QUERY_QUEUED,
|
||||||
|
/** the hostname was found in the cache and was directly returned,
|
||||||
|
* found callback will not be called */
|
||||||
DNS_COMPLETE
|
DNS_COMPLETE
|
||||||
} DNS_RESULT;
|
} DNS_RESULT;
|
||||||
|
|
||||||
|
/** Callback which is invoked when a hostname is found.
|
||||||
|
* A function of this type must be implemented by the application using the DNS resolver.
|
||||||
|
* @param name pointer to the name that was looked up.
|
||||||
|
* @param ipaddr pointer to a struct ip_addr containing the IP address of the hostname,
|
||||||
|
* or NULL if the name could not be found (or on any other error).
|
||||||
|
* @param a user-specified callback argument passed to dns_gethostbyname
|
||||||
|
*/
|
||||||
|
typedef void (*dns_found_callback)(const char *name, struct ip_addr *ipaddr, void *arg);
|
||||||
|
|
||||||
/* initializes the resolver */
|
void dns_init(void);
|
||||||
err_t dns_init(void);
|
|
||||||
|
|
||||||
/* handles requests, retries and timeouts - call every DNS_TMR_INTERVAL tick */
|
|
||||||
void dns_tmr(void);
|
void dns_tmr(void);
|
||||||
|
|
||||||
/* initializes DNS server IP address */
|
|
||||||
void dns_setserver(u8_t numdns, struct ip_addr *dnsserver);
|
void dns_setserver(u8_t numdns, struct ip_addr *dnsserver);
|
||||||
|
|
||||||
/* returns configured DNS server IP address */
|
|
||||||
struct ip_addr dns_getserver(u8_t numdns);
|
struct ip_addr dns_getserver(u8_t numdns);
|
||||||
|
DNS_RESULT dns_gethostbyname(const char *hostname, struct ip_addr *addr,
|
||||||
/* resolves a host 'name' in ip address */
|
dns_found_callback found, void *callback_arg);
|
||||||
DNS_RESULT dns_gethostbyname(const char *hostName, struct ip_addr *addr,
|
|
||||||
void (*found)(const char *name, struct ip_addr *ipaddr, void *arg),
|
|
||||||
void *arg);
|
|
||||||
|
|
||||||
/* dns_gethostbyname() - Returns immediately with one of DNS_RESULT return codes
|
|
||||||
* Return value will be DNS_COMPLETE if hostName is a valid
|
|
||||||
* IP address string or the host name is already in the local
|
|
||||||
* names table. Returns DNS_REQUEST_QUEUED and queues a
|
|
||||||
* request to be sent to the DNS server for resolution if no
|
|
||||||
* errors are present.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* dns_found_func() - Callback which is invoked when a hostname is found.
|
|
||||||
* This function should be implemented by the application using the DNS resolver.
|
|
||||||
* param 'name' - pointer to the name that was looked up.
|
|
||||||
* param 'ipaddr' - pointer to a struct ip_addr containing the IP address of the
|
|
||||||
* hostname, or NULL if the name could not be found.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* LWIP_DNS */
|
#endif /* LWIP_DNS */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user