diff --git a/CHANGELOG b/CHANGELOG index 45b96d1e..174bb2bb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ HISTORY ++ New features: + 2015-09-03: Simon Goldschmidt + * opt.h, dns.h/.c: DNS/IPv6: added support for AAAA records + 2015-09-01: Simon Goldschmidt * task #12178: hardware checksum capabilities can be configured per netif (use NETIF_SET_CHECKSUM_CTRL() in your netif's init function) @@ -25,7 +28,7 @@ HISTORY 2015-04-24: Simon Goldschmidt * dhcp.h/c, autoip.h/.c: added functions dhcp/autoip_supplied_address() to - check for the source of address assignemnt (replacement for NETIF_FLAG_DHCP) + check for the source of address assignment (replacement for NETIF_FLAG_DHCP) 2015-04-10: Simon Goldschmidt * many files: task #13480: added LWIP_IPV4 define - IPv4 can be disabled, diff --git a/src/core/dns.c b/src/core/dns.c index c11b08a5..e3c27cd4 100644 --- a/src/core/dns.c +++ b/src/core/dns.c @@ -161,6 +161,23 @@ static u16_t dns_txid; #define DNS_MAX_SOURCE_PORTS 1 #endif +#if LWIP_IPV4 && LWIP_IPV6 +#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) (((t) == LWIP_DNS_ADDRTYPE_IPV6_IPV4) || ((t) == LWIP_DNS_ADDRTYPE_IPV6)) +#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) (IP_IS_V6_VAL(ip) ? LWIP_DNS_ADDRTYPE_IS_IPV6(t) : (!LWIP_DNS_ADDRTYPE_IS_IPV6(t))) +#define LWIP_DNS_ADDRTYPE_ARG(x) , x +#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) x +#define LWIP_DNS_SET_ADDRTYPE(x, y) do { x = y; } while(0) +#else +#if LWIP_IPV6 +#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 1 +#else +#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 0 +#endif +#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) 1 +#define LWIP_DNS_ADDRTYPE_ARG(x) +#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) 0 +#define LWIP_DNS_SET_ADDRTYPE(x, y) +#endif /* LWIP_IPV4 && LWIP_IPV6 */ /* DNS protocol flags */ #define DNS_FLAG1_RESPONSE 0x80 @@ -239,6 +256,9 @@ struct dns_table_entry { u8_t pcb_idx; #endif char name[DNS_MAX_NAME_LENGTH]; +#if LWIP_IPV4 && LWIP_IPV6 + u8_t reqaddrtype; +#endif /* LWIP_IPV4 && LWIP_IPV6 */ }; /** DNS request table entry: used when dns_gehostbyname cannot answer the @@ -251,6 +271,9 @@ struct dns_req_entry { #if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) u8_t dns_table_idx; #endif +#if LWIP_IPV4 && LWIP_IPV6 + u8_t reqaddrtype; +#endif /* LWIP_IPV4 && LWIP_IPV6 */ }; #if DNS_LOCAL_HOSTLIST @@ -459,12 +482,13 @@ dns_init_local(void) * @return ERR_OK if found, ERR_ARG if not found */ static err_t -dns_lookup_local(const char *hostname, ip_addr_t *addr) +dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) { #if DNS_LOCAL_HOSTLIST_IS_DYNAMIC struct local_hostlist_entry *entry = local_hostlist_dynamic; while(entry != NULL) { - if (LWIP_DNS_STRICMP(entry->name, hostname) == 0) { + if ((LWIP_DNS_STRICMP(entry->name, hostname) == 0) && + LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, entry->addr)) { if (addr) { ip_addr_copy(*addr, entry->addr); } @@ -475,7 +499,8 @@ dns_lookup_local(const char *hostname, ip_addr_t *addr) #else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ int i; for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) { - if (LWIP_DNS_STRICMP(local_hostlist_static[i].name, hostname) == 0) { + if ((LWIP_DNS_STRICMP(local_hostlist_static[i].name, hostname) == 0) && + LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, local_hostlist_static[i].addr)) { if (addr) { ip_addr_copy(*addr, local_hostlist_static[i].addr); } @@ -568,26 +593,27 @@ dns_local_addhost(const char *hostname, const ip_addr_t *addr) * @return ERR_OK if found, ERR_ARG if not found */ static err_t -dns_lookup(const char *name, ip_addr_t *addr) +dns_lookup(const char *name, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) { u8_t i; #if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) #endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ #if DNS_LOCAL_HOSTLIST - if (dns_lookup_local(name, addr) == ERR_OK) { + if (dns_lookup_local(name, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) { return ERR_OK; } #endif /* DNS_LOCAL_HOSTLIST */ #ifdef DNS_LOOKUP_LOCAL_EXTERN - if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) { - return addr; + if (DNS_LOOKUP_LOCAL_EXTERN(name, addr, LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(dns_addrtype))) { + return ERR_OK; } #endif /* DNS_LOOKUP_LOCAL_EXTERN */ /* Walk through name list, return entry if found. If not, return NULL. */ for (i = 0; i < DNS_TABLE_SIZE; ++i) { if ((dns_table[i].state == DNS_STATE_DONE) && - (LWIP_DNS_STRICMP(name, dns_table[i].name) == 0)) { + (LWIP_DNS_STRICMP(name, dns_table[i].name) == 0) && + LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, dns_table[i].ipaddr)) { LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); LWIP_DEBUGF(DNS_DEBUG, ("\n")); @@ -698,7 +724,7 @@ dns_send(u8_t idx) /* call specified callback function if provided */ dns_call_found(idx, NULL); /* flush this entry */ - entry->state = DNS_STATE_UNUSED; + entry->state = DNS_STATE_UNUSED; return ERR_OK; } @@ -732,7 +758,11 @@ dns_send(u8_t idx) query_idx++; /* fill dns query */ - qry.type = PP_HTONS(DNS_RRTYPE_A); + if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) { + qry.type = PP_HTONS(DNS_RRTYPE_AAAA); + } else { + qry.type = PP_HTONS(DNS_RRTYPE_A); + } qry.cls = PP_HTONS(DNS_RRCLASS_IN); pbuf_take_at(p, &qry, SIZEOF_DNS_QUERY, query_idx); @@ -840,6 +870,19 @@ dns_call_found(u8_t idx, ip_addr_t* addr) u8_t i; #endif +#if LWIP_IPV4 && LWIP_IPV6 + if (addr != NULL) { + /* check that address type matches the request and adapt the table entry */ + if (IP_IS_V6_VAL(*addr)) { + LWIP_ASSERT("invalid response", LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype)); + dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6; + } else { + LWIP_ASSERT("invalid response", !LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype)); + dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4; + } + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + #if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) for (i = 0; i < DNS_MAX_REQUESTS; i++) { if (dns_requests[i].found && (dns_requests[i].dns_table_idx == idx)) { @@ -1068,7 +1111,9 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, /* check if "question" part matches the request */ pbuf_copy_partial(p, &qry, SIZEOF_DNS_QUERY, res_idx); - if((qry.type != PP_HTONS(DNS_RRTYPE_A)) || (qry.cls != PP_HTONS(DNS_RRCLASS_IN))) { + if((qry.cls != PP_HTONS(DNS_RRCLASS_IN)) || + (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_AAAA))) || + (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_A)))) { LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); /* call callback to indicate error, clean up memory and return */ goto responseerr; @@ -1082,39 +1127,94 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, /* Check for IP address type and Internet class. Others are discarded. */ pbuf_copy_partial(p, &ans, SIZEOF_DNS_ANSWER, res_idx); + if (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) { #if LWIP_IPV4 - if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) && - (ans.len == PP_HTONS(sizeof(ip4_addr_t))) ) { - res_idx += SIZEOF_DNS_ANSWER; - /* read the answer resource record's TTL, and maximize it if needed */ - entry->ttl = ntohl(ans.ttl); - if (entry->ttl > DNS_MAX_TTL) { - entry->ttl = DNS_MAX_TTL; + if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.len == PP_HTONS(sizeof(ip4_addr_t)))) { +#if LWIP_IPV4 && LWIP_IPV6 + if (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + { + ip4_addr_t ip4addr; + res_idx += SIZEOF_DNS_ANSWER; + /* read the answer resource record's TTL, and maximize it if needed */ + entry->ttl = ntohl(ans.ttl); + if (entry->ttl > DNS_MAX_TTL) { + entry->ttl = DNS_MAX_TTL; + } + /* read the IP address after answer resource record's header */ + pbuf_copy_partial(p, &ip4addr, sizeof(ip4_addr_t), res_idx); + ip_addr_copy_from_ip4(entry->ipaddr, ip4addr); + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", entry->name)); + ip_addr_debug_print(DNS_DEBUG, (&(entry->ipaddr))); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + /* call specified callback function if provided */ + dns_call_found(entry_idx, &entry->ipaddr); + if (entry->ttl == 0) { + /* RFC 883, page 29: "Zero values are + interpreted to mean that the RR can only be used for the + transaction in progress, and should not be cached." + -> flush this entry now */ + goto flushentry; + } + /* deallocate memory and return */ + goto memerr; + } } - /* read the IP address after answer resource record's header */ - pbuf_copy_partial(p, &(entry->ipaddr), sizeof(entry->ipaddr), res_idx); - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", entry->name)); - ip_addr_debug_print(DNS_DEBUG, (&(entry->ipaddr))); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - /* call specified callback function if provided */ - dns_call_found(entry_idx, &entry->ipaddr); - if (entry->ttl == 0) { - /* RFC 883, page 29: "Zero values are - interpreted to mean that the RR can only be used for the - transaction in progress, and should not be cached." - -> flush this entry now */ - goto flushentry; - } - /* deallocate memory and return */ - goto memerr; - } else #endif /* LWIP_IPV4 */ - { - /* @todo: parse IPv6 answers */ - res_idx += SIZEOF_DNS_ANSWER + htons(ans.len); +#if LWIP_IPV6 + if((ans.type == PP_HTONS(DNS_RRTYPE_AAAA)) && (ans.len == PP_HTONS(sizeof(ip6_addr_t)))) { +#if LWIP_IPV4 && LWIP_IPV6 + if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + { + ip6_addr_t ip6addr; + res_idx += SIZEOF_DNS_ANSWER; + /* read the answer resource record's TTL, and maximize it if needed */ + entry->ttl = ntohl(ans.ttl); + if (entry->ttl > DNS_MAX_TTL) { + entry->ttl = DNS_MAX_TTL; + } + /* read the IP address after answer resource record's header */ + pbuf_copy_partial(p, &ip6addr, sizeof(ip6_addr_t), res_idx); + ip_addr_copy_from_ip6(entry->ipaddr, ip6addr); + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", entry->name)); + ip_addr_debug_print(DNS_DEBUG, (&(entry->ipaddr))); + LWIP_DEBUGF(DNS_DEBUG, (" AAAA\n")); + /* call specified callback function if provided */ + dns_call_found(entry_idx, &entry->ipaddr); + if (entry->ttl == 0) { + /* RFC 883, page 29: "Zero values are + interpreted to mean that the RR can only be used for the + transaction in progress, and should not be cached." + -> flush this entry now */ + goto flushentry; + } + /* deallocate memory and return */ + goto memerr; + } + } +#endif /* LWIP_IPV6 */ } + /* skip this answer */ + res_idx += SIZEOF_DNS_ANSWER + htons(ans.len); --nanswers; } +#if LWIP_IPV4 && LWIP_IPV6 + if ((entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || + (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) { + if (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) { + /* IPv4 failed, try IPv6 */ + entry->reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6; + } else { + /* IPv6 failed, try IPv4 */ + entry->reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4; + } + pbuf_free(p); + entry->state = DNS_STATE_NEW; + dns_check_entry(entry_idx); + return; + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", entry->name)); /* call callback to indicate error, clean up memory and return */ goto responseerr; @@ -1128,9 +1228,7 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, responseerr: /* ERROR: call specified callback function with NULL as name to indicate an error */ dns_call_found(entry_idx, NULL); -#if LWIP_IPV4 flushentry: -#endif /* LWIP_IPV4 */ /* flush this entry */ dns_table[entry_idx].state = DNS_STATE_UNUSED; @@ -1151,7 +1249,7 @@ memerr: */ static err_t dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found, - void *callback_arg) + void *callback_arg LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) { u8_t i; u8_t lseq, lseqi; @@ -1165,12 +1263,21 @@ dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found, for (i = 0; i < DNS_TABLE_SIZE; i++) { if ((dns_table[i].state == DNS_STATE_ASKING) && (LWIP_DNS_STRICMP(name, dns_table[i].name) == 0)) { +#if LWIP_IPV4 && LWIP_IPV6 + if (dns_table[i].reqaddrtype != dns_addrtype) { + /* requested address types don't match + this can lead to 2 concurrent requests, but mixing the address types + for the same host should not be that common */ + continue; + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ /* this is a duplicate entry, find a free request entry */ for (r = 0; r < DNS_MAX_REQUESTS; r++) { if (dns_requests[r].found == 0) { dns_requests[r].found = found; dns_requests[r].arg = callback_arg; dns_requests[r].dns_table_idx = i; + LWIP_DNS_SET_ADDRTYPE(dns_requests[r].reqaddrtype, dns_addrtype); LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": duplicate request\n", name)); return ERR_INPROGRESS; } @@ -1237,6 +1344,8 @@ dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found, /* fill the entry */ entry->state = DNS_STATE_NEW; entry->seqno = dns_seqno; + LWIP_DNS_SET_ADDRTYPE(entry->reqaddrtype, dns_addrtype); + LWIP_DNS_SET_ADDRTYPE(req->reqaddrtype, dns_addrtype); req->found = found; req->arg = callback_arg; namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH-1); @@ -1287,6 +1396,21 @@ err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg) { +#if LWIP_IPV4 && LWIP_IPV6 + return dns_gethostbyname_addrtype(hostname, addr, found, callback_arg, LWIP_DNS_ADDRTYPE_IPV4_IPV6); +} + +/** Like dns_gethostbyname, but returned address type can be controlled: + * @param dns_addrtype: - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 first, try IPv6 if IPv4 fails only + * - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 first, try IPv4 if IPv6 fails only + * - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only + * - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only + */ +err_t +dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found, + void *callback_arg, u8_t dns_addrtype) +{ +#endif /* LWIP_IPV4 && LWIP_IPV6 */ size_t hostnamelen; /* not initialized or no valid server yet, or invalid addr pointer * or invalid hostname or invalid hostname length */ @@ -1308,8 +1432,7 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun #if LWIP_HAVE_LOOPIF if (strcmp(hostname, "localhost") == 0) { - /* @todo: IPv6 support... */ - ip_addr_set_loopback(0, addr); + ip_addr_set_loopback(LWIP_DNS_ADDRTYPE_IS_IPV6(dns_addrtype), addr); return ERR_OK; } #endif /* LWIP_HAVE_LOOPIF */ @@ -1319,12 +1442,26 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun return ERR_OK; } /* already have this address cached? */ - if(dns_lookup(hostname, addr) == ERR_OK) { + if(dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) { return ERR_OK; } +#if LWIP_IPV4 && LWIP_IPV6 + if ((dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6)) { + /* fallback to 2nd IP type and try again to lookup */ + u8_t fallback; + if (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) { + fallback = LWIP_DNS_ADDRTYPE_IPV6; + } else { + fallback = LWIP_DNS_ADDRTYPE_IPV4; + } + if(dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) { + return ERR_OK; + } + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ /* queue query with specified callback */ - return dns_enqueue(hostname, hostnamelen, found, callback_arg); + return dns_enqueue(hostname, hostnamelen, found, callback_arg LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)); } #endif /* LWIP_DNS */ diff --git a/src/include/lwip/dns.h b/src/include/lwip/dns.h index afe4b129..67ac3206 100644 --- a/src/include/lwip/dns.h +++ b/src/include/lwip/dns.h @@ -62,6 +62,7 @@ extern "C" { #define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ #define DNS_RRTYPE_MX 15 /* mail exchange */ #define DNS_RRTYPE_TXT 16 /* text strings */ +#define DNS_RRTYPE_AAAA 28 /* IPv6 address */ /** DNS field CLASS used for "Resource Records" */ #define DNS_RRCLASS_IN 1 /* the Internet */ @@ -70,6 +71,12 @@ extern "C" { #define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ #define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ +/* DNS resolve types: */ +#define LWIP_DNS_ADDRTYPE_IPV4_IPV6 0 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */ +#define LWIP_DNS_ADDRTYPE_IPV6_IPV4 0xFF /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */ +#define LWIP_DNS_ADDRTYPE_IPV4 DNS_RRTYPE_A +#define LWIP_DNS_ADDRTYPE_IPV6 DNS_RRTYPE_AAAA + #if DNS_LOCAL_HOSTLIST /** struct used for local host-list */ struct local_hostlist_entry { @@ -102,6 +109,15 @@ void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); ip_addr_t dns_getserver(u8_t numdns); err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg); +#if LWIP_IPV4 && LWIP_IPV6 +err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, + dns_found_callback found, void *callback_arg, + u8_t dns_addrtype); +#else /* LWIP_IPV4 && LWIP_IPV6 */ +#define dns_gethostbyname_addrtype(hostname, addr, found, callback_arg, dns_addrtype) \ + dns_gethostbyname(hostname, addr, found, callback_arg) +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + #if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC int dns_local_removehost(const char *hostname, const ip_addr_t *addr); diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 4dbf143f..0852fe63 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1027,8 +1027,9 @@ * byte order). * * Instead, you can also use an external function: - * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) - * that returns the IP address or INADDR_NONE if not found. + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern int my_lookup_function(const char *name, ip_addr_t* result, u8_t reqtype) + * that provides the IP address, returns 1 if found or 0 if not found and gets + * the type of the requested address passed (see LWIP_DNS_ADDRTYPE_*) */ #ifndef DNS_LOCAL_HOSTLIST #define DNS_LOCAL_HOSTLIST 0