forked from espressif/esp-protocols
fix(examples): Make multi-netif example working with DNS_PER_DEFAULT_NETIF feature
This commit is contained in:
@ -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 reconfigure DNS server if host name resolution fails
|
||||||
* It tries to manually change the default interface if connection 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
|
### 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).
|
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).
|
||||||
|
@ -54,4 +54,14 @@ menu "Example Configuration"
|
|||||||
bool "Using simple UART-PPP driver"
|
bool "Using simple UART-PPP driver"
|
||||||
endchoice
|
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
|
endmenu
|
||||||
|
@ -95,7 +95,7 @@ static void eth_destroy(iface_info_t *info)
|
|||||||
free(eth_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));
|
struct eth_info_t *eth_info = malloc(sizeof(struct eth_info_t));
|
||||||
assert(eth_info);
|
assert(eth_info);
|
||||||
@ -124,7 +124,7 @@ iface_info_t *eth_init(int prio)
|
|||||||
eth_info->parent.netif = esp_netif_new(&cfg);
|
eth_info->parent.netif = esp_netif_new(&cfg);
|
||||||
eth_info->glue = esp_eth_new_netif_glue(eth_info->eth_handle);
|
eth_info->glue = esp_eth_new_netif_glue(eth_info->eth_handle);
|
||||||
// Attach Ethernet driver to TCP/IP stack
|
// 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
|
// Register user defined event handers
|
||||||
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_info));
|
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_info));
|
||||||
|
@ -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
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
@ -23,9 +23,9 @@
|
|||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
#include "iface_info.h"
|
#include "iface_info.h"
|
||||||
|
|
||||||
iface_info_t *eth_init(int prio);
|
iface_info_t *example_eth_init(int prio);
|
||||||
iface_info_t *wifi_init(int prio);
|
iface_info_t *example_wifi_init(int prio);
|
||||||
iface_info_t *ppp_init(int prio);
|
iface_info_t *example_ppp_init(int prio);
|
||||||
esp_err_t check_connectivity(const char *host);
|
esp_err_t check_connectivity(const char *host);
|
||||||
|
|
||||||
#define HOST "www.espressif.com"
|
#define HOST "www.espressif.com"
|
||||||
@ -69,14 +69,18 @@ void app_main(void)
|
|||||||
|
|
||||||
// all interfaces
|
// all interfaces
|
||||||
iface_info_t *ifaces[] = {
|
iface_info_t *ifaces[] = {
|
||||||
eth_init(ETH_PRIO),
|
example_eth_init(ETH_PRIO),
|
||||||
wifi_init(WIFI_PRIO),
|
example_wifi_init(WIFI_PRIO),
|
||||||
ppp_init(PPP_PRIO),
|
example_ppp_init(PPP_PRIO),
|
||||||
};
|
};
|
||||||
size_t num_of_ifaces = sizeof(ifaces) / sizeof(ifaces[0]);
|
size_t num_of_ifaces = sizeof(ifaces) / sizeof(ifaces[0]);
|
||||||
|
|
||||||
while (true) {
|
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();
|
dns_clear_cache();
|
||||||
|
#endif
|
||||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
ssize_t i = get_default(ifaces, num_of_ifaces);
|
ssize_t i = get_default(ifaces, num_of_ifaces);
|
||||||
if (i == -1) { // default netif is NULL, probably all interfaces are down -> retry
|
if (i == -1) { // default netif is NULL, probably all interfaces are down -> retry
|
||||||
@ -91,7 +95,9 @@ void app_main(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (connect_status == ESP_ERR_NOT_FOUND) {
|
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
|
// 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) {
|
for (int j = 0; j < 2; ++j) {
|
||||||
esp_netif_dns_info_t dns_info;
|
esp_netif_dns_info_t dns_info;
|
||||||
esp_netif_get_dns_info(ifaces[i]->netif, j, &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));
|
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) {
|
if (connect_status == ESP_FAIL) {
|
||||||
ESP_LOGE(TAG, "No connection via the default netif!");
|
ESP_LOGE(TAG, "No connection via the default netif!");
|
||||||
|
@ -85,7 +85,7 @@ static void ppp_destroy(iface_info_t *info)
|
|||||||
free(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));
|
struct ppp_info_t *ppp_info = calloc(1, sizeof(struct ppp_info_t));
|
||||||
assert(ppp_info);
|
assert(ppp_info);
|
||||||
|
@ -75,7 +75,7 @@ static void wifi_destroy(iface_info_t *info)
|
|||||||
free(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));
|
struct iface_info_t *wifi_info = malloc(sizeof(iface_info_t));
|
||||||
assert(wifi_info);
|
assert(wifi_info);
|
||||||
@ -100,9 +100,9 @@ iface_info_t *wifi_init(int prio)
|
|||||||
.password = CONFIG_ESP_WIFI_PASSWORD,
|
.password = CONFIG_ESP_WIFI_PASSWORD,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
|
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_set_config(WIFI_IF_STA, &wifi_config));
|
||||||
ESP_ERROR_CHECK(esp_wifi_start() );
|
ESP_ERROR_CHECK(esp_wifi_start());
|
||||||
|
|
||||||
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
||||||
|
|
||||||
|
@ -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_SUPPORT=y
|
||||||
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y
|
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y
|
||||||
|
Reference in New Issue
Block a user