Minor changes on DNS client. Note that "compressed answers are fixed".

This commit is contained in:
fbernon 2007-11-18 15:01:45 +00:00
parent edc46281a4
commit 92401faa72

View File

@ -59,17 +59,17 @@
* must be implemented by the module that uses the resolver). * must be implemented by the module that uses the resolver).
*/ */
/** @todo: define good default values (rfc compliance) */
/** @todo: secondary server support */
/** @todo: compressed answer support */
/** @todo: improve answer parsing, more checkings... */
/** @todo: possible alignment problems to access to dns_answer fields? */
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
* RFC 1035 - Domain names - implementation and specification * RFC 1035 - Domain names - implementation and specification
* RFC 2181 - Clarifications to the DNS Specification * RFC 2181 - Clarifications to the DNS Specification
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
/** @todo: define good default values (rfc compliance) */
/** @todo: secondary server support */
/** @todo: pbuf chain not yet supported */
/** @todo: improve answer parsing, more checkings... */
/** @todo: possible alignment problems to access to dns_answer fields? */
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
* Includes * Includes
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
@ -350,11 +350,17 @@ dns_parse_name(unsigned char *query)
do { do {
n = *query++; n = *query++;
/** @see RFC 1035 - 4.1.4. Message compression */
while(n > 0) { if ((n & 0xc0)==0xc0) {
++query; /* Compressed name */
--n; break;
}; } else {
/* Not compressed name */
while(n > 0) {
++query;
--n;
};
}
} while(*query != 0); } while(*query != 0);
return query + 1; return query + 1;
@ -490,6 +496,8 @@ dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16
hdr = (struct dns_hdr *)p->payload; hdr = (struct dns_hdr *)p->payload;
/** @todo: check RFC1035 - 7.3. Processing responses */
/* The ID in the DNS header should be our entry into the name table. */ /* The ID in the DNS header should be our entry into the name table. */
i = htons(hdr->id); i = htons(hdr->id);
pEntry = &dns_table[i]; pEntry = &dns_table[i];
@ -499,8 +507,13 @@ dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16
pEntry->ttl = DNS_TTL_ENTRY; pEntry->ttl = DNS_TTL_ENTRY;
pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
/* We only care about the question(s) and the answers. The authrr
and the extrarr are simply discarded. */
nquestions = htons(hdr->numquestions);
nanswers = htons(hdr->numanswers);
/* Check for error. If so, call callback to inform. */ /* Check for error. If so, call callback to inform. */
if(pEntry->err != 0) { if ((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 specified callback function if provided */
if (pEntry->found) if (pEntry->found)
@ -511,25 +524,13 @@ dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16
return; return;
} }
/* We only care about the question(s) and the answers. The authrr
and the extrarr are simply discarded. */
nquestions = htons(hdr->numquestions);
nanswers = htons(hdr->numanswers);
/* Skip the name in the "question" part. This should really be checked /* Skip the name in the "question" part. This should really be checked
agains the name in the question, to be sure that they match. */ agains the name in the question, to be sure that they match. */
pHostname = (char *) dns_parse_name((unsigned char *)p->payload + sizeof(struct dns_hdr)) + 4/*type(2)+class(2)*/; pHostname = (char *) dns_parse_name((unsigned char *)p->payload + sizeof(struct dns_hdr)) + 4/*type(2)+class(2)*/;
while(nanswers > 0) { while(nanswers > 0) {
/* The first byte in the answer resource record determines if it /* skip answer resource record's host name */
is a compressed record or a normal one. */ pHostname = (char *) dns_parse_name((unsigned char *)pHostname);
if(*pHostname & 0xc0) {
/* Compressed name. */
pHostname +=2;
} else {
/* Not compressed name. */
pHostname = (char *) dns_parse_name((unsigned char *)pHostname);
}
/* TODO: isn't it any problem to access to dns_answer fields since pHostname's length can be unaligned? */ /* TODO: isn't it any problem to access to dns_answer fields since pHostname's length can be unaligned? */
ans = (struct dns_answer *)pHostname; ans = (struct dns_answer *)pHostname;