Index: lwip/lwip/src/core/dns.c =================================================================== --- lwip/lwip/src/core/dns.c (revision 6302) +++ lwip/lwip/src/core/dns.c (revision 6303) @@ -135,6 +135,11 @@ #define DNS_MAX_REQUESTS DNS_TABLE_SIZE #endif +/** DNS maximum number of addresses to remember */ +#ifndef DNS_MAX_ADDRESSES_PER_ENTRY +#define DNS_MAX_ADDRESSES_PER_ENTRY 4 +#endif + /* The number of UDP source ports used in parallel */ #if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) #ifndef DNS_MAX_SOURCE_PORTS @@ -257,7 +262,7 @@ /** DNS table entry */ struct dns_table_entry { u32_t ttl; - ip_addr_t ipaddr; + ip_addr_t ipaddr[DNS_MAX_ADDRESSES_PER_ENTRY]; u16_t txid; u8_t state; u8_t server_idx; @@ -267,6 +272,7 @@ #if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) u8_t pcb_idx; #endif + u8_t num_addr; // number of addresses in ipaddr array char name[DNS_MAX_NAME_LENGTH]; #if LWIP_IPV4 && LWIP_IPV6 u8_t reqaddrtype; @@ -641,7 +647,8 @@ ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); LWIP_DEBUGF(DNS_DEBUG, ("\n")); if (addr) { - ip_addr_copy(*addr, dns_table[i].ipaddr); + // select a random address to return + ip_addr_copy(*addr, dns_table[i].ipaddr[LWIP_RAND() % dns_table[i].num_addr]); } return ERR_OK; } @@ -1080,7 +1087,8 @@ if (entry->ttl > DNS_MAX_TTL) { entry->ttl = DNS_MAX_TTL; } - dns_call_found(idx, &entry->ipaddr); + // call found callback with random ip + dns_call_found(idx, &entry->ipaddr[LWIP_RAND() % entry->num_addr]); if (entry->ttl == 0) { /* RFC 883, page 29: "Zero values are @@ -1108,6 +1116,8 @@ struct dns_answer ans; struct dns_query qry; u16_t nquestions, nanswers; + u8_t num_addr; + u32_t ttl; LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(pcb); @@ -1173,6 +1183,8 @@ if (hdr.flags2 & DNS_FLAG2_ERR_MASK) { LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", entry->name)); } else { + num_addr = 0; // initialize counter to number of addresses extracted + ttl = DNS_MAX_TTL; // initialize ttl to maximum values, we'll use minimum of all entries found while ((nanswers > 0) && (res_idx < p->tot_len)) { /* skip answer resource record's host name */ res_idx = dns_parse_name(p, res_idx); @@ -1187,14 +1199,15 @@ if (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) #endif /* LWIP_IPV4 && LWIP_IPV6 */ { - ip4_addr_t ip4addr; - /* 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(dns_table[i].ipaddr, ip4addr); - pbuf_free(p); - /* handle correct response */ - dns_correct_response(i, ntohl(ans.ttl)); - return; + if (num_addr < DNS_MAX_ADDRESSES_PER_ENTRY) + { + ip4_addr_t ip4addr; + /* 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(dns_table[i].ipaddr[num_addr++], ip4addr); + if (ttl > ntohl(ans.ttl)) + ttl = ntohl(ans.ttl); + } } } #endif /* LWIP_IPV4 */ @@ -1204,14 +1217,15 @@ if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) #endif /* LWIP_IPV4 && LWIP_IPV6 */ { - ip6_addr_t ip6addr; - /* 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(dns_table[i].ipaddr, ip6addr); - pbuf_free(p); - /* handle correct response */ - dns_correct_response(i, ntohl(ans.ttl)); - return; + if (num_addr < DNS_MAX_ADDRESSES_PER_ENTRY) + { + ip6_addr_t ip6addr; + /* 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(dns_table[i].ipaddr[num_addr++], ip6addr); + if (ttl > ntohl(ans.ttl)) + ttl = ntohl(ans.ttl); + } } } #endif /* LWIP_IPV6 */ @@ -1220,6 +1234,17 @@ res_idx += htons(ans.len); --nanswers; } + // remember number of addresses extracted + dns_table[i].num_addr = num_addr; + // finish good entries + if (num_addr > 0) + { + pbuf_free(p); + /* handle correct response */ + dns_correct_response(i, ttl); + return; + } + #if LWIP_IPV4 && LWIP_IPV6 if ((entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) {