From 771421c863192544eba62cdf28853e23cdf3622a Mon Sep 17 00:00:00 2001 From: xueyunfei Date: Fri, 21 Jun 2019 18:55:33 +0800 Subject: [PATCH] dns: Support for fallback DNS server This adds support for list of DNS servers, that could contain manually configured server that won't be rewritten. Also if some of the servers in the list is NULL, the algorithm continues searching with other configured servers up to DNS_MAX_SERVERS. Ref IDF-4839 --- .github/workflows/ci-linux.yml | 2 +- src/core/dns.c | 42 +++++++++++++++++++++++++++++++++- src/core/ipv4/dhcp.c | 5 ++++ src/include/lwip/dns.h | 4 +++- test/unit/lwipopts.h | 2 ++ 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 75a87c61..491a330d 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -48,7 +48,7 @@ jobs: run: | cp ${CONTRIB}/examples/example_app/lwipcfg.h.example ${CONTRIB}/examples/example_app/lwipcfg.h cd ${CONTRIB}/ports/unix/example_app - export CFLAGS="-DESP_LWIP=LWIP_NETCONN_FULLDUPLEX -DESP_LWIP_IGMP_TIMERS_ONDEMAND=ESP_LWIP -DESP_LWIP_MLD6_TIMERS_ONDEMAND=ESP_LWIP" + export CFLAGS="-DESP_LWIP=LWIP_NETCONN_FULLDUPLEX -DESP_LWIP_IGMP_TIMERS_ONDEMAND=ESP_LWIP -DESP_LWIP_MLD6_TIMERS_ONDEMAND=ESP_LWIP -DESP_DNS=ESP_LWIP" export LWIPDIR=../../../../src/ chmod +x iteropts.sh && ./iteropts.sh diff --git a/src/core/dns.c b/src/core/dns.c index 9d2f61ed..583ed138 100644 --- a/src/core/dns.c +++ b/src/core/dns.c @@ -314,12 +314,25 @@ const ip_addr_t dns_mquery_v6group = DNS_MQUERY_IPV6_GROUP_INIT; void dns_init(void) { +#if ESP_DNS +#ifdef FALLBACK_DNS_SERVER_ADDRESS + /* initialize fallback dns DNS server address */ + ip_addr_t dnsserver; + FALLBACK_DNS_SERVER_ADDRESS(&dnsserver); + dnsserver.type = IPADDR_TYPE_V4; + dns_setserver(DNS_FALLBACK_SERVER_INDEX, &dnsserver); +#endif /* FALLBACK_DNS_SERVER_ADDRESS */ + +#else + + #ifdef DNS_SERVER_ADDRESS /* initialize default DNS server address */ ip_addr_t dnsserver; DNS_SERVER_ADDRESS(&dnsserver); dns_setserver(0, &dnsserver); #endif /* DNS_SERVER_ADDRESS */ +#endif LWIP_ASSERT("sanity check SIZEOF_DNS_QUERY", sizeof(struct dns_query) == SIZEOF_DNS_QUERY); @@ -1059,7 +1072,11 @@ dns_check_entry(u8_t i) entry->server_idx = 0; entry->tmr = 1; entry->retries = 0; - +#if ESP_DNS + while((entry->server_idx < DNS_MAX_SERVERS) && ip_addr_isany_val(dns_servers[entry->server_idx])) { + entry->server_idx++; + } +#endif /* send DNS packet for this entry */ err = dns_send(i); if (err != ERR_OK) { @@ -1070,6 +1087,12 @@ dns_check_entry(u8_t i) case DNS_STATE_ASKING: if (--entry->tmr == 0) { if (++entry->retries == DNS_MAX_RETRIES) { +#if ESP_DNS + /* skip DNS servers with zero address */ + while ((entry->server_idx + 1 < DNS_MAX_SERVERS) && ip_addr_isany_val(dns_servers[entry->server_idx + 1])) { + entry->server_idx++; + } +#endif if (dns_backupserver_available(entry) #if LWIP_DNS_SUPPORT_MDNS_QUERIES && !entry->is_mdns @@ -1529,6 +1552,19 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun return dns_gethostbyname_addrtype(hostname, addr, found, callback_arg, LWIP_DNS_ADDRTYPE_DEFAULT); } +#if ESP_DNS +static bool dns_server_is_set (void) +{ + int i = 0; + for (i = 0;i < DNS_MAX_SERVERS; i++) { + if (!ip_addr_isany_val(dns_servers[i])) { + return true; + } + } + return false; +} +#endif + /** * @ingroup dns * Like dns_gethostbyname, but returned address type can be controlled: @@ -1618,7 +1654,11 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call #endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ { /* prevent calling found callback if no server is set, return error instead */ +#if ESP_DNS + if (dns_server_is_set() == false) { +#else if (ip_addr_isany_val(dns_servers[0])) { +#endif return ERR_VAL; } } diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c index 7a38502b..de399516 100644 --- a/src/core/ipv4/dhcp.c +++ b/src/core/ipv4/dhcp.c @@ -712,6 +712,11 @@ dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in) /* DNS servers */ for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) { ip_addr_t dns_addr; +#if ESP_DNS + if (n == DNS_FALLBACK_SERVER_INDEX) { + continue; + } +#endif ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); dns_setserver(n, &dns_addr); } diff --git a/src/include/lwip/dns.h b/src/include/lwip/dns.h index 09134154..db52fedd 100644 --- a/src/include/lwip/dns.h +++ b/src/include/lwip/dns.h @@ -111,7 +111,9 @@ err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg, u8_t dns_addrtype); - +#if ESP_DNS +void dns_clear_servers(bool keep_fallback); +#endif #if DNS_LOCAL_HOSTLIST size_t dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg); diff --git a/test/unit/lwipopts.h b/test/unit/lwipopts.h index 05b320c9..4af0bd1a 100644 --- a/test/unit/lwipopts.h +++ b/test/unit/lwipopts.h @@ -84,6 +84,7 @@ #define LWIP_MEM_ILLEGAL_FREE(msg) /* to nothing */ #ifdef ESP_LWIP +#define ESP_DNS 1 #define LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS 1 #define LWIP_DHCP_ENABLE_CLIENT_ID 1 #define LWIP_DHCP_ENABLE_MTU_UPDATE 1 @@ -156,6 +157,7 @@ u32_t esp_random(void); #else #define ESP_LWIP 0 +#define ESP_DNS 0 #define ESP_LWIP_IGMP_TIMERS_ONDEMAND 0 #define ESP_LWIP_MLD6_TIMERS_ONDEMAND 0