Reduced code size.
Combined recent changes from darconeous... - Refactor to decrease minimum code footprint. - Added `RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION`. ...with a few additional changes to reduce code size.
This commit is contained in:
parent
d8862bd243
commit
46cb6013ae
|
@ -139,6 +139,28 @@ strcasecmp(const char *s1, const char *s2)
|
||||||
#define RESOLV_CONF_MAX_DOMAIN_NAME_SIZE 32
|
#define RESOLV_CONF_MAX_DOMAIN_NAME_SIZE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RESOLV_CONF_AUTO_REMOVE_TRAILING_DOTS
|
||||||
|
#define RESOLV_AUTO_REMOVE_TRAILING_DOTS RESOLV_CONF_AUTO_REMOVE_TRAILING_DOTS
|
||||||
|
#else
|
||||||
|
#define RESOLV_AUTO_REMOVE_TRAILING_DOTS RESOLV_CONF_SUPPORTS_MDNS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RESOLV_CONF_VERIFY_ANSWER_NAMES
|
||||||
|
#define RESOLV_VERIFY_ANSWER_NAMES RESOLV_CONF_VERIFY_ANSWER_NAMES
|
||||||
|
#else
|
||||||
|
#define RESOLV_VERIFY_ANSWER_NAMES RESOLV_CONF_SUPPORTS_MDNS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION
|
||||||
|
#define RESOLV_SUPPORTS_RECORD_EXPIRATION RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION
|
||||||
|
#else
|
||||||
|
#define RESOLV_SUPPORTS_RECORD_EXPIRATION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RESOLV_CONF_SUPPORTS_MDNS && !RESOLV_VERIFY_ANSWER_NAMES
|
||||||
|
#error RESOLV_CONF_SUPPORTS_MDNS cannot be set without RESOLV_CONF_VERIFY_ANSWER_NAMES
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(CONTIKI_TARGET_NAME) && defined(BOARD)
|
#if !defined(CONTIKI_TARGET_NAME) && defined(BOARD)
|
||||||
#define stringy2(x) #x
|
#define stringy2(x) #x
|
||||||
#define stringy(x) stringy2(x)
|
#define stringy(x) stringy2(x)
|
||||||
|
@ -163,6 +185,12 @@ strcasecmp(const char *s1, const char *s2)
|
||||||
#define DNS_TYPE_ANY 255
|
#define DNS_TYPE_ANY 255
|
||||||
#define DNS_TYPE_NSEC 47
|
#define DNS_TYPE_NSEC 47
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6
|
||||||
|
#define NATIVE_DNS_TYPE DNS_TYPE_AAAA /* IPv6 */
|
||||||
|
#else
|
||||||
|
#define NATIVE_DNS_TYPE DNS_TYPE_A /* IPv4 */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DNS_CLASS_IN 1
|
#define DNS_CLASS_IN 1
|
||||||
#define DNS_CLASS_ANY 255
|
#define DNS_CLASS_ANY 255
|
||||||
|
|
||||||
|
@ -238,12 +266,14 @@ struct namemap {
|
||||||
uint8_t tmr;
|
uint8_t tmr;
|
||||||
uint8_t retries;
|
uint8_t retries;
|
||||||
uint8_t seqno;
|
uint8_t seqno;
|
||||||
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
unsigned long expiration;
|
unsigned long expiration;
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
|
uip_ipaddr_t ipaddr;
|
||||||
uint8_t err;
|
uint8_t err;
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
uint8_t is_mdns:1, is_probe:1;
|
uint8_t is_mdns:1, is_probe:1;
|
||||||
#endif
|
#endif
|
||||||
uip_ipaddr_t ipaddr;
|
|
||||||
char name[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
|
char name[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -271,12 +301,13 @@ enum {
|
||||||
EVENT_NEW_SERVER = 0
|
EVENT_NEW_SERVER = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
|
||||||
/** \internal The DNS question message structure. */
|
/** \internal The DNS question message structure. */
|
||||||
struct dns_question {
|
struct dns_question {
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
uint16_t class;
|
uint16_t class;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
static char resolv_hostname[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
|
static char resolv_hostname[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -300,11 +331,13 @@ static int mdns_needs_host_announce;
|
||||||
PROCESS(mdns_probe_process, "mDNS probe");
|
PROCESS(mdns_probe_process, "mDNS probe");
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
|
|
||||||
|
#if RESOLV_AUTO_REMOVE_TRAILING_DOTS
|
||||||
/* For removing trailing dots in resolv_query() and resolve_lookup2(). */
|
/* For removing trailing dots in resolv_query() and resolve_lookup2(). */
|
||||||
static char dns_name_without_dots[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
|
static char dns_name_without_dots[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
|
||||||
|
#endif /* RESOLV_AUTO_REMOVE_TRAILING_DOTS */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS || VERBOSE_DEBUG
|
#if RESOLV_VERIFY_ANSWER_NAMES || VERBOSE_DEBUG
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief Decodes a DNS name from the DNS format into the given string.
|
* \brief Decodes a DNS name from the DNS format into the given string.
|
||||||
* \return 1 upon success, 0 if the size of the name would be too large.
|
* \return 1 upon success, 0 if the size of the name would be too large.
|
||||||
|
@ -312,7 +345,7 @@ static char dns_name_without_dots[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
|
||||||
* \note `dest` must point to a buffer with at least
|
* \note `dest` must point to a buffer with at least
|
||||||
* `RESOLV_CONF_MAX_DOMAIN_NAME_SIZE+1` bytes large.
|
* `RESOLV_CONF_MAX_DOMAIN_NAME_SIZE+1` bytes large.
|
||||||
*/
|
*/
|
||||||
static int
|
static uint8_t
|
||||||
decode_name(const unsigned char *query, char *dest,
|
decode_name(const unsigned char *query, char *dest,
|
||||||
const unsigned char *packet)
|
const unsigned char *packet)
|
||||||
{
|
{
|
||||||
|
@ -334,7 +367,7 @@ decode_name(const unsigned char *query, char *dest,
|
||||||
if(!n)
|
if(!n)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for(; n; n--) {
|
for(; n; --n) {
|
||||||
//DEBUG_PRINTF("%c",*query);
|
//DEBUG_PRINTF("%c",*query);
|
||||||
|
|
||||||
*dest++ = *query++;
|
*dest++ = *query++;
|
||||||
|
@ -358,11 +391,10 @@ decode_name(const unsigned char *query, char *dest,
|
||||||
*dest = 0;
|
*dest = 0;
|
||||||
return len != 0;
|
return len != 0;
|
||||||
}
|
}
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS || VERBOSE_DEBUG */
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \internal
|
/** \internal
|
||||||
*/
|
*/
|
||||||
static int
|
static uint8_t
|
||||||
dns_name_isequal(const unsigned char *queryptr, const char *name,
|
dns_name_isequal(const unsigned char *queryptr, const char *name,
|
||||||
const unsigned char *packet)
|
const unsigned char *packet)
|
||||||
{
|
{
|
||||||
|
@ -399,6 +431,7 @@ dns_name_isequal(const unsigned char *queryptr, const char *name,
|
||||||
|
|
||||||
return name[0] == 0;
|
return name[0] == 0;
|
||||||
}
|
}
|
||||||
|
#endif /* RESOLV_VERIFY_ANSWER_NAMES */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \internal
|
/** \internal
|
||||||
*/
|
*/
|
||||||
|
@ -496,13 +529,14 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
|
||||||
if(!*count) {
|
if(!*count) {
|
||||||
queryptr = encode_name(queryptr, resolv_hostname);
|
queryptr = encode_name(queryptr, resolv_hostname);
|
||||||
} else {
|
} else {
|
||||||
|
/* Use name compression to refer back to the first name */
|
||||||
*queryptr++ = 0xc0;
|
*queryptr++ = 0xc0;
|
||||||
*queryptr++ = sizeof(struct dns_hdr);
|
*queryptr++ = sizeof(struct dns_hdr);
|
||||||
}
|
}
|
||||||
ans = (struct dns_answer *)queryptr;
|
ans = (struct dns_answer *)queryptr;
|
||||||
|
|
||||||
*queryptr++ = (uint8_t) ((DNS_TYPE_AAAA) >> 8);
|
*queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE) >> 8);
|
||||||
*queryptr++ = (uint8_t) ((DNS_TYPE_AAAA));
|
*queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE));
|
||||||
|
|
||||||
*queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000) >> 8);
|
*queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000) >> 8);
|
||||||
*queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000));
|
*queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000));
|
||||||
|
@ -515,8 +549,7 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
|
||||||
*queryptr++ = 0;
|
*queryptr++ = 0;
|
||||||
*queryptr++ = sizeof(uip_ipaddr_t);
|
*queryptr++ = sizeof(uip_ipaddr_t);
|
||||||
|
|
||||||
uip_ipaddr_copy((uip_ipaddr_t *) queryptr,
|
uip_ipaddr_copy((uip_ipaddr_t*)queryptr, &uip_ds6_if.addr_list[i].ipaddr);
|
||||||
&uip_ds6_if.addr_list[i].ipaddr);
|
|
||||||
queryptr += sizeof(uip_ipaddr_t);
|
queryptr += sizeof(uip_ipaddr_t);
|
||||||
++(*count);
|
++(*count);
|
||||||
}
|
}
|
||||||
|
@ -524,7 +557,7 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
|
||||||
#else /* UIP_CONF_IPV6 */
|
#else /* UIP_CONF_IPV6 */
|
||||||
queryptr = encode_name(queryptr, resolv_hostname);
|
queryptr = encode_name(queryptr, resolv_hostname);
|
||||||
ans = (struct dns_answer *)queryptr;
|
ans = (struct dns_answer *)queryptr;
|
||||||
ans->type = UIP_HTONS(DNS_TYPE_A);
|
ans->type = UIP_HTONS(NATIVE_DNS_TYPE);
|
||||||
ans->class = UIP_HTONS(DNS_CLASS_IN | 0x8000);
|
ans->class = UIP_HTONS(DNS_CLASS_IN | 0x8000);
|
||||||
ans->ttl[0] = 0;
|
ans->ttl[0] = 0;
|
||||||
ans->ttl[1] = UIP_HTONS(120);
|
ans->ttl[1] = UIP_HTONS(120);
|
||||||
|
@ -632,8 +665,10 @@ check_entries(void)
|
||||||
/* STATE_ERROR basically means "not found". */
|
/* STATE_ERROR basically means "not found". */
|
||||||
namemapptr->state = STATE_ERROR;
|
namemapptr->state = STATE_ERROR;
|
||||||
|
|
||||||
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
/* Keep the "not found" error valid for 30 seconds */
|
/* Keep the "not found" error valid for 30 seconds */
|
||||||
namemapptr->expiration = clock_seconds() + 30;
|
namemapptr->expiration = clock_seconds() + 30;
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
|
|
||||||
resolv_found(namemapptr->name, NULL);
|
resolv_found(namemapptr->name, NULL);
|
||||||
continue;
|
continue;
|
||||||
|
@ -671,7 +706,7 @@ check_entries(void)
|
||||||
hdr->flags1 = DNS_FLAG1_RD;
|
hdr->flags1 = DNS_FLAG1_RD;
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
hdr->numquestions = UIP_HTONS(1);
|
hdr->numquestions = UIP_HTONS(1);
|
||||||
query = (char *)uip_appdata + sizeof(*hdr);
|
query = (unsigned char *)uip_appdata + sizeof(*hdr);
|
||||||
query = encode_name(query, namemapptr->name);
|
query = encode_name(query, namemapptr->name);
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
if(namemapptr->is_probe) {
|
if(namemapptr->is_probe) {
|
||||||
|
@ -680,19 +715,13 @@ check_entries(void)
|
||||||
} else
|
} else
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
{
|
{
|
||||||
#if UIP_CONF_IPV6
|
*query++ = (uint8_t) ((NATIVE_DNS_TYPE) >> 8);
|
||||||
*query++ = (uint8_t) ((DNS_TYPE_AAAA) >> 8);
|
*query++ = (uint8_t) ((NATIVE_DNS_TYPE));
|
||||||
*query++ = (uint8_t) ((DNS_TYPE_AAAA));
|
|
||||||
#else /* UIP_CONF_IPV6 */
|
|
||||||
*query++ = (uint8_t) ((DNS_TYPE_A) >> 8);
|
|
||||||
*query++ = (uint8_t) ((DNS_TYPE_A));
|
|
||||||
#endif /* UIP_CONF_IPV6 */
|
|
||||||
}
|
}
|
||||||
*query++ = (uint8_t) ((DNS_CLASS_IN) >> 8);
|
*query++ = (uint8_t) ((DNS_CLASS_IN) >> 8);
|
||||||
*query++ = (uint8_t) ((DNS_CLASS_IN));
|
*query++ = (uint8_t) ((DNS_CLASS_IN));
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
if(namemapptr->is_mdns) {
|
if(namemapptr->is_mdns) {
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
|
||||||
if(namemapptr->is_probe) {
|
if(namemapptr->is_probe) {
|
||||||
/* This is our conflict detection request.
|
/* This is our conflict detection request.
|
||||||
* In order to be in compliance with the MDNS
|
* In order to be in compliance with the MDNS
|
||||||
|
@ -704,13 +733,12 @@ check_entries(void)
|
||||||
query = mdns_write_announce_records(query, &count);
|
query = mdns_write_announce_records(query, &count);
|
||||||
hdr->numauthrr = UIP_HTONS(count);
|
hdr->numauthrr = UIP_HTONS(count);
|
||||||
}
|
}
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
|
||||||
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||||
(query - (uint8_t *) uip_appdata),
|
(query - (uint8_t *) uip_appdata),
|
||||||
&resolv_mdns_addr, UIP_HTONS(MDNS_PORT));
|
&resolv_mdns_addr, UIP_HTONS(MDNS_PORT));
|
||||||
|
|
||||||
PRINTF("resolver: (i=%d) Sent MDNS request for \"%s\".\n", i,
|
PRINTF("resolver: (i=%d) Sent MDNS %s for \"%s\".\n", i,
|
||||||
namemapptr->name);
|
namemapptr->is_probe?"probe":"request",namemapptr->name);
|
||||||
} else {
|
} else {
|
||||||
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||||
(query - (uint8_t *) uip_appdata),
|
(query - (uint8_t *) uip_appdata),
|
||||||
|
@ -737,17 +765,19 @@ check_entries(void)
|
||||||
static void
|
static void
|
||||||
newdata(void)
|
newdata(void)
|
||||||
{
|
{
|
||||||
struct dns_answer *ans;
|
static uint8_t nquestions, nanswers, nauthrr;
|
||||||
|
|
||||||
struct dns_hdr const *hdr = (struct dns_hdr *)uip_appdata;
|
static int8_t i;
|
||||||
|
|
||||||
unsigned char *queryptr = (unsigned char *)hdr + sizeof(*hdr);
|
|
||||||
|
|
||||||
register struct namemap *namemapptr;
|
register struct namemap *namemapptr;
|
||||||
|
|
||||||
static uint8_t nquestions, nanswers, nauthrr = 0;
|
struct dns_answer *ans;
|
||||||
|
|
||||||
static int8_t i;
|
register struct dns_hdr const *hdr = (struct dns_hdr *)uip_appdata;
|
||||||
|
|
||||||
|
unsigned char *queryptr = (unsigned char *)hdr + sizeof(*hdr);
|
||||||
|
|
||||||
|
const uint8_t is_request = ((hdr->flags1 & ~1) == 0) && (hdr->flags2 == 0);
|
||||||
|
|
||||||
/* We only care about the question(s) and the answers. The authrr
|
/* We only care about the question(s) and the answers. The authrr
|
||||||
* and the extrarr are simply discarded.
|
* and the extrarr are simply discarded.
|
||||||
|
@ -755,48 +785,52 @@ newdata(void)
|
||||||
nquestions = (uint8_t) uip_ntohs(hdr->numquestions);
|
nquestions = (uint8_t) uip_ntohs(hdr->numquestions);
|
||||||
nanswers = (uint8_t) uip_ntohs(hdr->numanswers);
|
nanswers = (uint8_t) uip_ntohs(hdr->numanswers);
|
||||||
|
|
||||||
|
queryptr = (unsigned char *)hdr + sizeof(*hdr);
|
||||||
|
i = 0;
|
||||||
|
|
||||||
DEBUG_PRINTF
|
DEBUG_PRINTF
|
||||||
("resolver: flags1=0x%02X flags2=0x%02X nquestions=%d, nanswers=%d, nauthrr=%d, nextrarr=%d\n",
|
("resolver: flags1=0x%02X flags2=0x%02X nquestions=%d, nanswers=%d, nauthrr=%d, nextrarr=%d\n",
|
||||||
hdr->flags1, hdr->flags2, (uint8_t) nquestions, (uint8_t) nanswers,
|
hdr->flags1, hdr->flags2, (uint8_t) nquestions, (uint8_t) nanswers,
|
||||||
(uint8_t) uip_ntohs(hdr->numauthrr),
|
(uint8_t) uip_ntohs(hdr->numauthrr),
|
||||||
(uint8_t) uip_ntohs(hdr->numextrarr));
|
(uint8_t) uip_ntohs(hdr->numextrarr));
|
||||||
|
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
if(is_request && (nquestions == 0)) {
|
||||||
/** QUESTION HANDLING SECTION ************************************************/
|
|
||||||
|
|
||||||
if(((hdr->flags1 & ~1) == 0) && (hdr->flags2 == 0)) {
|
|
||||||
/* This is an DNS request! */
|
|
||||||
|
|
||||||
/* Skip requests with no questions. */
|
/* Skip requests with no questions. */
|
||||||
if(!nquestions) {
|
DEBUG_PRINTF("resolver: Skipping request with no questions.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryptr = (unsigned char *)hdr + sizeof(*hdr);
|
/** QUESTION HANDLING SECTION ************************************************/
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for(; nquestions > 0;
|
for(; nquestions > 0;
|
||||||
queryptr = skip_name(queryptr) + sizeof(struct dns_question),
|
queryptr = skip_name(queryptr) + sizeof(struct dns_question),
|
||||||
nquestions--) {
|
--nquestions
|
||||||
struct dns_question *question =
|
) {
|
||||||
(struct dns_question *)skip_name(queryptr);
|
|
||||||
|
|
||||||
#if __ARM__
|
if(!is_request) {
|
||||||
|
/* If this isn't a request, we don't need to bother
|
||||||
|
* looking at the individual questions. For the most
|
||||||
|
* part, this loop to just used to skip past them.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
|
{
|
||||||
|
struct dns_question *question = (struct dns_question *)skip_name(queryptr);
|
||||||
|
|
||||||
|
#if !ARCH_DOESNT_NEED_ALIGNED_STRUCTS
|
||||||
static struct dns_question aligned;
|
static struct dns_question aligned;
|
||||||
|
|
||||||
memcpy(&aligned, question, sizeof(aligned));
|
memcpy(&aligned, question, sizeof(aligned));
|
||||||
question = &aligned;
|
question = &aligned;
|
||||||
#endif /* __ARM__ */
|
#endif /* !ARCH_DOESNT_NEED_ALIGNED_STRUCTS */
|
||||||
|
|
||||||
DEBUG_PRINTF("resolver: Question %d: type=%d class=%d\n", ++i,
|
DEBUG_PRINTF("resolver: Question %d: type=%d class=%d\n", ++i,
|
||||||
uip_htons(question->type), uip_htons(question->class));
|
uip_htons(question->type), uip_htons(question->class));
|
||||||
|
|
||||||
if(((uip_ntohs(question->class) & 0x7FFF) != DNS_CLASS_IN)
|
if(((uip_ntohs(question->class) & 0x7FFF) != DNS_CLASS_IN) ||
|
||||||
|| ((question->type != UIP_HTONS(DNS_TYPE_ANY))
|
((question->type != UIP_HTONS(DNS_TYPE_ANY)) &&
|
||||||
&& (question->type != UIP_HTONS(DNS_TYPE_AAAA))
|
(question->type != UIP_HTONS(NATIVE_DNS_TYPE)))) {
|
||||||
&& (question->type != UIP_HTONS(DNS_TYPE_A))
|
|
||||||
)) {
|
|
||||||
/* Skip unrecognised records. */
|
/* Skip unrecognised records. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -826,7 +860,7 @@ newdata(void)
|
||||||
* probe race condition check here and make sure
|
* probe race condition check here and make sure
|
||||||
* we don't need to delay probing for a second.
|
* we don't need to delay probing for a second.
|
||||||
*/
|
*/
|
||||||
nauthrr = (uint8_t) uip_ntohs(hdr->numauthrr);
|
nauthrr = (uint8_t)uip_ntohs(hdr->numauthrr);
|
||||||
|
|
||||||
/* For now, we will always restart the collision check if
|
/* For now, we will always restart the collision check if
|
||||||
* there are *any* authority records present.
|
* there are *any* authority records present.
|
||||||
|
@ -834,23 +868,23 @@ newdata(void)
|
||||||
* but this should eventually converge to something reasonable.
|
* but this should eventually converge to something reasonable.
|
||||||
*/
|
*/
|
||||||
if(nauthrr) {
|
if(nauthrr) {
|
||||||
start_name_collision_check(CLOCK_SECOND * 1.5);
|
start_name_collision_check(CLOCK_SECOND);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
|
}
|
||||||
|
|
||||||
/** ANSWER HANDLING SECTION **************************************************/
|
/** ANSWER HANDLING SECTION **************************************************/
|
||||||
|
|
||||||
if(!nanswers) {
|
if(nanswers == 0) {
|
||||||
DEBUG_PRINTF("resolver: Skipping request/response with no answers.\n");
|
/* Skip responses with no answers. */
|
||||||
/* We demand answers! */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
if(UIP_UDP_BUF->srcport == UIP_HTONS(MDNS_PORT)
|
if(UIP_UDP_BUF->srcport == UIP_HTONS(MDNS_PORT) &&
|
||||||
&& hdr->id == 0) {
|
hdr->id == 0) {
|
||||||
/* OK, this was from MDNS. Things get a little weird here,
|
/* OK, this was from MDNS. Things get a little weird here,
|
||||||
* because we can't use the `id` field. We will look up the
|
* because we can't use the `id` field. We will look up the
|
||||||
* appropriate request in a later step. */
|
* appropriate request in a later step. */
|
||||||
|
@ -866,8 +900,7 @@ newdata(void)
|
||||||
namemapptr = &names[i];
|
namemapptr = &names[i];
|
||||||
|
|
||||||
if(i >= RESOLV_ENTRIES || i < 0 || namemapptr->state != STATE_ASKING) {
|
if(i >= RESOLV_ENTRIES || i < 0 || namemapptr->state != STATE_ASKING) {
|
||||||
PRINTF("resolver: Bad ID (%04X) on incoming DNS response\n",
|
PRINTF("resolver: DNS response has bad ID (%04X) \n", uip_ntohs(hdr->id));
|
||||||
uip_ntohs(hdr->id));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,10 +908,13 @@ newdata(void)
|
||||||
|
|
||||||
/* We'll change this to DONE when we find the record. */
|
/* We'll change this to DONE when we find the record. */
|
||||||
namemapptr->state = STATE_ERROR;
|
namemapptr->state = STATE_ERROR;
|
||||||
|
|
||||||
namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
|
namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
|
||||||
|
|
||||||
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
/* If we remain in the error state, keep it cached for 30 seconds. */
|
/* If we remain in the error state, keep it cached for 30 seconds. */
|
||||||
namemapptr->expiration = clock_seconds() + 30;
|
namemapptr->expiration = clock_seconds() + 30;
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
|
|
||||||
/* Check for error. If so, call callback to inform. */
|
/* Check for error. If so, call callback to inform. */
|
||||||
if(namemapptr->err != 0) {
|
if(namemapptr->err != 0) {
|
||||||
|
@ -888,32 +924,23 @@ newdata(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Discard all remaining questions */
|
i = 0;
|
||||||
for(; nquestions > 0; queryptr += 4, --nquestions) {
|
|
||||||
if(namemapptr && dns_name_isequal(queryptr, namemapptr->name, uip_appdata) != 0) {
|
|
||||||
DEBUG_PRINTF("resolver: Question name doesn't look familiar...!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
queryptr = skip_name(queryptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Answer parsing loop */
|
/* Answer parsing loop */
|
||||||
while(nanswers > 0) {
|
while(nanswers > 0) {
|
||||||
ans = (struct dns_answer *)skip_name(queryptr);
|
ans = (struct dns_answer *)skip_name(queryptr);
|
||||||
|
|
||||||
#if __ARM__
|
#if !ARCH_DOESNT_NEED_ALIGNED_STRUCTS
|
||||||
static struct dns_answer aligned;
|
static struct dns_answer aligned;
|
||||||
|
|
||||||
memcpy(&aligned, ans, sizeof(aligned));
|
memcpy(&aligned, ans, sizeof(aligned));
|
||||||
ans = &aligned;
|
ans = &aligned;
|
||||||
#endif /* __ARM__ */
|
#endif /* !ARCH_DOESNT_NEED_ALIGNED_STRUCTS */
|
||||||
|
|
||||||
#if VERBOSE_DEBUG
|
#if VERBOSE_DEBUG
|
||||||
static char debug_name[40];
|
static char debug_name[40];
|
||||||
|
|
||||||
decode_name(queryptr, debug_name, uip_appdata);
|
decode_name(queryptr, debug_name, uip_appdata);
|
||||||
DEBUG_PRINTF("resolver: \"%s\", type %d, class %d, ttl %d, length %d\n",
|
DEBUG_PRINTF("resolver: Answer %d: \"%s\", type %d, class %d, ttl %d, length %d\n",
|
||||||
debug_name, uip_ntohs(ans->type),
|
++i, debug_name, uip_ntohs(ans->type),
|
||||||
uip_ntohs(ans->class) & 0x7FFF,
|
uip_ntohs(ans->class) & 0x7FFF,
|
||||||
(int)((uint32_t) uip_ntohs(ans->ttl[0]) << 16) | (uint32_t)
|
(int)((uint32_t) uip_ntohs(ans->ttl[0]) << 16) | (uint32_t)
|
||||||
uip_ntohs(ans->ttl[1]), uip_ntohs(ans->len));
|
uip_ntohs(ans->ttl[1]), uip_ntohs(ans->len));
|
||||||
|
@ -927,15 +954,9 @@ newdata(void)
|
||||||
goto skip_to_next_answer;
|
goto skip_to_next_answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UIP_CONF_IPV6
|
if(ans->type != UIP_HTONS(NATIVE_DNS_TYPE)) {
|
||||||
if(ans->type != UIP_HTONS(DNS_TYPE_AAAA)) {
|
|
||||||
goto skip_to_next_answer;
|
goto skip_to_next_answer;
|
||||||
}
|
}
|
||||||
#else /* UIP_CONF_IPV6 */
|
|
||||||
if(ans->type != UIP_HTONS(DNS_TYPE_A)) {
|
|
||||||
goto skip_to_next_answer;
|
|
||||||
}
|
|
||||||
#endif /* UIP_CONF_IPV6 */
|
|
||||||
|
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
if(UIP_UDP_BUF->srcport == UIP_HTONS(MDNS_PORT) &&
|
if(UIP_UDP_BUF->srcport == UIP_HTONS(MDNS_PORT) &&
|
||||||
|
@ -952,9 +973,11 @@ newdata(void)
|
||||||
if(dns_name_isequal(queryptr, namemapptr->name, uip_appdata)) {
|
if(dns_name_isequal(queryptr, namemapptr->name, uip_appdata)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if((namemapptr->state == STATE_UNUSED) ||
|
if((namemapptr->state == STATE_UNUSED)
|
||||||
(namemapptr->state == STATE_DONE &&
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
clock_seconds() > namemapptr->expiration)) {
|
|| (namemapptr->state == STATE_DONE && clock_seconds() > namemapptr->expiration)
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
|
) {
|
||||||
available_i = i;
|
available_i = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -988,17 +1011,22 @@ newdata(void)
|
||||||
nanswers = 1;
|
nanswers = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(namemapptr && !dns_name_isequal(queryptr, namemapptr->name, uip_appdata)) {
|
#if RESOLV_VERIFY_ANSWER_NAMES
|
||||||
|
if(namemapptr &&
|
||||||
|
!dns_name_isequal(queryptr, namemapptr->name, uip_appdata)) {
|
||||||
DEBUG_PRINTF("resolver: Answer name doesn't match question...!\n");
|
DEBUG_PRINTF("resolver: Answer name doesn't match question...!\n");
|
||||||
goto skip_to_next_answer;
|
goto skip_to_next_answer;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUG_PRINTF("resolver: Answer for \"%s\" is usable.\n",
|
DEBUG_PRINTF("resolver: Answer for \"%s\" is usable.\n",
|
||||||
namemapptr->name);
|
namemapptr->name);
|
||||||
|
|
||||||
namemapptr->state = STATE_DONE;
|
namemapptr->state = STATE_DONE;
|
||||||
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
namemapptr->expiration = ans->ttl[1] + (ans->ttl[0] << 8);
|
namemapptr->expiration = ans->ttl[1] + (ans->ttl[0] << 8);
|
||||||
namemapptr->expiration += clock_seconds();
|
namemapptr->expiration += clock_seconds();
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
|
|
||||||
uip_ipaddr_copy(&namemapptr->ipaddr, (uip_ipaddr_t *) ans->ipaddr);
|
uip_ipaddr_copy(&namemapptr->ipaddr, (uip_ipaddr_t *) ans->ipaddr);
|
||||||
|
|
||||||
|
@ -1100,15 +1128,13 @@ PROCESS_THREAD(resolv_process, ev, data)
|
||||||
resolv_conn->rport = 0;
|
resolv_conn->rport = 0;
|
||||||
|
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
PRINTF("resolver: Supports MDNS name resolution.\n");
|
PRINTF("resolver: Supports MDNS.\n");
|
||||||
#endif
|
|
||||||
|
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
|
||||||
PRINTF("resolver: Supports MDNS responder.\n");
|
|
||||||
uip_udp_bind(resolv_conn, UIP_HTONS(MDNS_PORT));
|
uip_udp_bind(resolv_conn, UIP_HTONS(MDNS_PORT));
|
||||||
|
|
||||||
#if UIP_CONF_IPV6
|
#if UIP_CONF_IPV6
|
||||||
uip_ds6_maddr_add(&resolv_mdns_addr);
|
uip_ds6_maddr_add(&resolv_mdns_addr);
|
||||||
|
#else
|
||||||
|
/* TODO: Is there anything we need to do here for IPv4 multicast? */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
resolv_set_hostname(CONTIKI_CONF_DEFAULT_HOSTNAME);
|
resolv_set_hostname(CONTIKI_CONF_DEFAULT_HOSTNAME);
|
||||||
|
@ -1164,6 +1190,24 @@ PROCESS_THREAD(resolv_process, ev, data)
|
||||||
PROCESS_END();
|
PROCESS_END();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if RESOLV_AUTO_REMOVE_TRAILING_DOTS
|
||||||
|
static const char *
|
||||||
|
remove_trailing_dots(const char *name) {
|
||||||
|
size_t len = strlen(name);
|
||||||
|
|
||||||
|
if(name[len - 1] == '.') {
|
||||||
|
strncpy(dns_name_without_dots, name, sizeof(dns_name_without_dots));
|
||||||
|
while(len && (dns_name_without_dots[len - 1] == '.')) {
|
||||||
|
dns_name_without_dots[--len] = 0;
|
||||||
|
}
|
||||||
|
name = dns_name_without_dots;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
#else /* RESOLV_AUTO_REMOVE_TRAILING_DOTS */
|
||||||
|
#define remove_trailing_dots(x) (x)
|
||||||
|
#endif /* RESOLV_AUTO_REMOVE_TRAILING_DOTS */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* Queues a name so that a question for the name will be sent out.
|
* Queues a name so that a question for the name will be sent out.
|
||||||
*
|
*
|
||||||
|
@ -1181,26 +1225,18 @@ resolv_query(const char *name)
|
||||||
lseq = lseqi = 0;
|
lseq = lseqi = 0;
|
||||||
|
|
||||||
/* Remove trailing dots, if present. */
|
/* Remove trailing dots, if present. */
|
||||||
{
|
name = remove_trailing_dots(name);
|
||||||
size_t len = strlen(name);
|
|
||||||
|
|
||||||
if(name[len - 1] == '.') {
|
|
||||||
strncpy(dns_name_without_dots, name, sizeof(dns_name_without_dots));
|
|
||||||
while(len && (dns_name_without_dots[len - 1] == '.')) {
|
|
||||||
dns_name_without_dots[--len] = 0;
|
|
||||||
}
|
|
||||||
name = dns_name_without_dots;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < RESOLV_ENTRIES; ++i) {
|
for(i = 0; i < RESOLV_ENTRIES; ++i) {
|
||||||
nameptr = &names[i];
|
nameptr = &names[i];
|
||||||
if(strcasecmp(nameptr->name, name) == 0) {
|
if(0 == strcasecmp(nameptr->name, name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if((nameptr->state == STATE_UNUSED) ||
|
if((nameptr->state == STATE_UNUSED)
|
||||||
(nameptr->state == STATE_DONE &&
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
clock_seconds() > nameptr->expiration)) {
|
|| (nameptr->state == STATE_DONE && clock_seconds() > nameptr->expiration)
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
|
) {
|
||||||
lseqi = i;
|
lseqi = i;
|
||||||
lseq = 255;
|
lseq = 255;
|
||||||
} else if(seqno - nameptr->seqno > lseq) {
|
} else if(seqno - nameptr->seqno > lseq) {
|
||||||
|
@ -1230,7 +1266,7 @@ resolv_query(const char *name)
|
||||||
static const char local_suffix[] = "local";
|
static const char local_suffix[] = "local";
|
||||||
|
|
||||||
if((name_len > (sizeof(local_suffix) - 1)) &&
|
if((name_len > (sizeof(local_suffix) - 1)) &&
|
||||||
(strcasecmp(name + name_len - (sizeof(local_suffix) - 1), local_suffix) == 0)) {
|
(0 == strcasecmp(name + name_len - (sizeof(local_suffix) - 1), local_suffix))) {
|
||||||
PRINTF("resolver: Using MDNS to look up \"%s\".\n", name);
|
PRINTF("resolver: Using MDNS to look up \"%s\".\n", name);
|
||||||
nameptr->is_mdns = 1;
|
nameptr->is_mdns = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1238,7 +1274,7 @@ resolv_query(const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nameptr->is_probe = (mdns_state == MDNS_STATE_PROBING) &&
|
nameptr->is_probe = (mdns_state == MDNS_STATE_PROBING) &&
|
||||||
(strcmp(nameptr->name, resolv_hostname) == 0);
|
(0 == strcmp(nameptr->name, resolv_hostname));
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
|
|
||||||
/* Force check_entires() to run on our process. */
|
/* Force check_entires() to run on our process. */
|
||||||
|
@ -1255,7 +1291,7 @@ resolv_query(const char *name)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
resolv_status_t
|
resolv_status_t
|
||||||
resolv_lookup(const char *name, uip_ipaddr_t **ipaddr)
|
resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr)
|
||||||
{
|
{
|
||||||
resolv_status_t ret = RESOLV_STATUS_UNCACHED;
|
resolv_status_t ret = RESOLV_STATUS_UNCACHED;
|
||||||
|
|
||||||
|
@ -1264,17 +1300,7 @@ resolv_lookup(const char *name, uip_ipaddr_t **ipaddr)
|
||||||
struct namemap *nameptr;
|
struct namemap *nameptr;
|
||||||
|
|
||||||
/* Remove trailing dots, if present. */
|
/* Remove trailing dots, if present. */
|
||||||
{
|
name = remove_trailing_dots(name);
|
||||||
size_t len = strlen(name);
|
|
||||||
|
|
||||||
if(name[len - 1] == '.') {
|
|
||||||
strncpy(dns_name_without_dots, name, sizeof(dns_name_without_dots) - 1);
|
|
||||||
name = dns_name_without_dots;
|
|
||||||
while(len && (dns_name_without_dots[len - 1] == '.')) {
|
|
||||||
dns_name_without_dots[--len] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UIP_CONF_LOOPBACK_INTERFACE
|
#if UIP_CONF_LOOPBACK_INTERFACE
|
||||||
if(strcmp(name, "localhost")) {
|
if(strcmp(name, "localhost")) {
|
||||||
|
@ -1299,11 +1325,12 @@ resolv_lookup(const char *name, uip_ipaddr_t **ipaddr)
|
||||||
if(strcasecmp(name, nameptr->name) == 0) {
|
if(strcasecmp(name, nameptr->name) == 0) {
|
||||||
switch (nameptr->state) {
|
switch (nameptr->state) {
|
||||||
case STATE_DONE:
|
case STATE_DONE:
|
||||||
|
ret = RESOLV_STATUS_CACHED;
|
||||||
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
if(clock_seconds() > nameptr->expiration) {
|
if(clock_seconds() > nameptr->expiration) {
|
||||||
ret = RESOLV_STATUS_EXPIRED;
|
ret = RESOLV_STATUS_EXPIRED;
|
||||||
} else {
|
|
||||||
ret = RESOLV_STATUS_CACHED;
|
|
||||||
}
|
}
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
break;
|
break;
|
||||||
case STATE_NEW:
|
case STATE_NEW:
|
||||||
case STATE_ASKING:
|
case STATE_ASKING:
|
||||||
|
@ -1311,9 +1338,12 @@ resolv_lookup(const char *name, uip_ipaddr_t **ipaddr)
|
||||||
break;
|
break;
|
||||||
/* Almost certainly a not-found error from server */
|
/* Almost certainly a not-found error from server */
|
||||||
case STATE_ERROR:
|
case STATE_ERROR:
|
||||||
if(clock_seconds() >= nameptr->expiration) {
|
|
||||||
ret = RESOLV_STATUS_NOT_FOUND;
|
ret = RESOLV_STATUS_NOT_FOUND;
|
||||||
|
#if RESOLV_SUPPORTS_RECORD_EXPIRATION
|
||||||
|
if(clock_seconds() > nameptr->expiration) {
|
||||||
|
ret = RESOLV_STATUS_UNCACHED;
|
||||||
}
|
}
|
||||||
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1372,7 +1402,7 @@ resolv_getserver(void)
|
||||||
* address of the DNS server to be configured.
|
* address of the DNS server to be configured.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
resolv_conf(const uip_ipaddr_t *dnsserver)
|
resolv_conf(const uip_ipaddr_t * dnsserver)
|
||||||
{
|
{
|
||||||
uip_ipaddr_copy(&resolv_default_dns_server, dnsserver);
|
uip_ipaddr_copy(&resolv_default_dns_server, dnsserver);
|
||||||
process_post(&resolv_process, EVENT_NEW_SERVER, &resolv_default_dns_server);
|
process_post(&resolv_process, EVENT_NEW_SERVER, &resolv_default_dns_server);
|
||||||
|
@ -1383,11 +1413,11 @@ resolv_conf(const uip_ipaddr_t *dnsserver)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
resolv_found(char *name, uip_ipaddr_t *ipaddr)
|
resolv_found(char *name, uip_ipaddr_t * ipaddr)
|
||||||
{
|
{
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0
|
if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 &&
|
||||||
&& ipaddr
|
ipaddr
|
||||||
#if UIP_CONF_IPV6
|
#if UIP_CONF_IPV6
|
||||||
&& !uip_ds6_is_my_addr(ipaddr)
|
&& !uip_ds6_is_my_addr(ipaddr)
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in a new issue