diff --git a/examples/esp_netif/multiple_netifs/README.md b/examples/esp_netif/multiple_netifs/README.md index 09ba1a1b9e..e0506d6315 100644 --- a/examples/esp_netif/multiple_netifs/README.md +++ b/examples/esp_netif/multiple_netifs/README.md @@ -19,6 +19,14 @@ This example demonstrates working with multiple different interfaces with differ * It tries to reconfigure DNS server if host name resolution fails * It tries to manually change the default interface if connection fails +### Handling DNS server across interfaces + +This example also demonstrates how DNS servers could be handled on network interface level, as lwIP used global DNS server information. + +All network interfaces store their DNS info upon acquiring an IP in the internal structure (in the application code) and the DNS servers are restored if host name resolution fails. + +This functionality is handled in IDF (supported from v5.3) automatically if `CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF` is enabled, the DNS server info keeps updating per network interface in IDF layers. This examples uses the IDF functionality if `CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF=1`. + ### Hardware Required To run this example, it's recommended that you have an official ESP32 Ethernet development board - [ESP32-Ethernet-Kit](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/get-started-ethernet-kit.html). diff --git a/examples/esp_netif/multiple_netifs/main/Kconfig.projbuild b/examples/esp_netif/multiple_netifs/main/Kconfig.projbuild index c038535a69..3929fa20ea 100644 --- a/examples/esp_netif/multiple_netifs/main/Kconfig.projbuild +++ b/examples/esp_netif/multiple_netifs/main/Kconfig.projbuild @@ -54,4 +54,14 @@ menu "Example Configuration" bool "Using simple UART-PPP driver" endchoice + config EXAMPLE_DEMONSTRATE_DNS_CLEAR_CACHE + bool "Run DNS clear cache" + default n + help + This example will cleanup the DNS cache + every iteration of the demo network operation. + This forces the TCP/IP stack to always resolve DNS names, + thus exercising potentially invalid DNS configuration. + Set this to "y" for testing, but keep as "n" for production. + endmenu diff --git a/examples/esp_netif/multiple_netifs/main/ethernet_connect.c b/examples/esp_netif/multiple_netifs/main/ethernet_connect.c index 53ec398f56..dc2537e08b 100644 --- a/examples/esp_netif/multiple_netifs/main/ethernet_connect.c +++ b/examples/esp_netif/multiple_netifs/main/ethernet_connect.c @@ -95,7 +95,7 @@ static void eth_destroy(iface_info_t *info) free(eth_info); } -iface_info_t *eth_init(int prio) +iface_info_t *example_eth_init(int prio) { struct eth_info_t *eth_info = malloc(sizeof(struct eth_info_t)); assert(eth_info); @@ -124,7 +124,7 @@ iface_info_t *eth_init(int prio) eth_info->parent.netif = esp_netif_new(&cfg); eth_info->glue = esp_eth_new_netif_glue(eth_info->eth_handle); // Attach Ethernet driver to TCP/IP stack - ESP_ERROR_CHECK(esp_netif_attach(eth_info->parent.netif, eth_info->glue )); + ESP_ERROR_CHECK(esp_netif_attach(eth_info->parent.netif, eth_info->glue)); // Register user defined event handers ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_info)); diff --git a/examples/esp_netif/multiple_netifs/main/multi_netif_main.c b/examples/esp_netif/multiple_netifs/main/multi_netif_main.c index 26f8dab443..415e9707c6 100644 --- a/examples/esp_netif/multiple_netifs/main/multi_netif_main.c +++ b/examples/esp_netif/multiple_netifs/main/multi_netif_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -23,9 +23,9 @@ #include "nvs_flash.h" #include "iface_info.h" -iface_info_t *eth_init(int prio); -iface_info_t *wifi_init(int prio); -iface_info_t *ppp_init(int prio); +iface_info_t *example_eth_init(int prio); +iface_info_t *example_wifi_init(int prio); +iface_info_t *example_ppp_init(int prio); esp_err_t check_connectivity(const char *host); #define HOST "www.espressif.com" @@ -69,14 +69,18 @@ void app_main(void) // all interfaces iface_info_t *ifaces[] = { - eth_init(ETH_PRIO), - wifi_init(WIFI_PRIO), - ppp_init(PPP_PRIO), + example_eth_init(ETH_PRIO), + example_wifi_init(WIFI_PRIO), + example_ppp_init(PPP_PRIO), }; size_t num_of_ifaces = sizeof(ifaces) / sizeof(ifaces[0]); while (true) { +#ifdef CONFIG_EXAMPLE_DEMONSTRATE_DNS_CLEAR_CACHE + // For demonstration purposes we clear DNS table every iteration to exercise + // a condition of DNS servers being misconfigured dns_clear_cache(); +#endif vTaskDelay(pdMS_TO_TICKS(2000)); ssize_t i = get_default(ifaces, num_of_ifaces); if (i == -1) { // default netif is NULL, probably all interfaces are down -> retry @@ -91,7 +95,9 @@ void app_main(void) continue; } if (connect_status == ESP_ERR_NOT_FOUND) { +#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF // set the default DNS info to global DNS server list + // manually if DNS_PER_DEFAULT_NETIF if OFF or not-supported for (int j = 0; j < 2; ++j) { esp_netif_dns_info_t dns_info; esp_netif_get_dns_info(ifaces[i]->netif, j, &dns_info); @@ -102,6 +108,12 @@ void app_main(void) ESP_LOGI(TAG, "Reconfigured DNS%i=" IPSTR, j, IP2STR(&ifaces[i]->dns[j].ip.u_addr.ip4)); } } +#else + // simulate that the (default) netif is brought UP + // this is only needed, since we explicitly clear DNS servers every iteration using dns_clear_cache() + // (for demonstration purpose only, won't be needed in your project, unless you delete DNS info for some reasons) + esp_netif_action_connected(ifaces[i]->netif, NULL, 0, NULL); +#endif } if (connect_status == ESP_FAIL) { ESP_LOGE(TAG, "No connection via the default netif!"); diff --git a/examples/esp_netif/multiple_netifs/main/ppp_connect.c b/examples/esp_netif/multiple_netifs/main/ppp_connect.c index b1f2dcf05d..d7740510ad 100644 --- a/examples/esp_netif/multiple_netifs/main/ppp_connect.c +++ b/examples/esp_netif/multiple_netifs/main/ppp_connect.c @@ -85,7 +85,7 @@ static void ppp_destroy(iface_info_t *info) free(info); } -iface_info_t *init_ppp(int prio) +iface_info_t *example_ppp_init(int prio) { struct ppp_info_t *ppp_info = calloc(1, sizeof(struct ppp_info_t)); assert(ppp_info); diff --git a/examples/esp_netif/multiple_netifs/main/wifi_connect.c b/examples/esp_netif/multiple_netifs/main/wifi_connect.c index 523c773568..5723051301 100644 --- a/examples/esp_netif/multiple_netifs/main/wifi_connect.c +++ b/examples/esp_netif/multiple_netifs/main/wifi_connect.c @@ -75,7 +75,7 @@ static void wifi_destroy(iface_info_t *info) free(info); } -iface_info_t *wifi_init(int prio) +iface_info_t *example_wifi_init(int prio) { struct iface_info_t *wifi_info = malloc(sizeof(iface_info_t)); assert(wifi_info); @@ -100,9 +100,9 @@ iface_info_t *wifi_init(int prio) .password = CONFIG_ESP_WIFI_PASSWORD, }, }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); - ESP_ERROR_CHECK(esp_wifi_start() ); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi_init_sta finished."); diff --git a/examples/esp_netif/multiple_netifs/sdkconfig.defaults b/examples/esp_netif/multiple_netifs/sdkconfig.defaults index 3c08a9a30d..84966ec347 100644 --- a/examples/esp_netif/multiple_netifs/sdkconfig.defaults +++ b/examples/esp_netif/multiple_netifs/sdkconfig.defaults @@ -1,2 +1,5 @@ +# You can use CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF +# to perform DNS server updates automatically in esp_netif layers +# instead of manually as it is demonstrated in this example CONFIG_LWIP_PPP_SUPPORT=y CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y