Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNS lookup failed, last netif doesn't have a DNS server (IDFGH-6421) #8080

Closed
wowaz opened this issue Dec 14, 2021 · 8 comments
Closed

DNS lookup failed, last netif doesn't have a DNS server (IDFGH-6421) #8080

wowaz opened this issue Dec 14, 2021 · 8 comments
Labels
Awaiting Response awaiting a response from the author Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@wowaz
Copy link

wowaz commented Dec 14, 2021

Environment

  • Development Kit: none
  • Module or chip used: ESP32-PICO-D4
  • IDF version: v4.2.1
  • Build System: idf.py
  • Compiler version: 1.22.0-80-g6c4433a5-5.2.0
  • Operating System: Windows
  • (Windows only) environment type: MSYS2 mingw32
  • Using an IDE?: Yes (vscode)
  • Power Supply: USB

Problem Description

If more than one interface is present it seems the dnslookup uses the newest to resolve the name, even if the interface doesn't have an DNS-Server.

Expected Behavior

Dnslookup tries to resolve the name with every interface until success.

Actual Behavior

Dnslookup seems only trying to resolve the name with the latest interface.

Steps to reproduce

  1. Connect to network with DHCP and DNS via Wifi STA
  2. Init ETH, set static IP, start ETH (in my case using a static IP because of a device to device connection, should also happen with DHCP-Server without an DNS server)
    esp_netif_dhcpc_stop(eth_netif);
    esp_netif_ip_info_t info = {
        .netmask.addr = ESP_IP4TOADDR(255, 255, 255, 0), .ip.addr = ESP_IP4TOADDR(192, 168, 2, 101), .gw.addr = ESP_IP4TOADDR(0, 0, 0, 0)
    };
    esp_netif_set_ip_info(eth_netif, &info);

    eth_glue = esp_eth_new_netif_glue(eth_handle);
    LAN_ERROR_CHECK(esp_netif_attach(eth_netif, eth_glue));
    esp_err_t err = esp_eth_start(eth_handle);
  1. Try to resolve domainname

Debug Logs

E (14.11.2021 10:04:41.213) TRANS_TCP: DNS lookup failed err=202 res=0x0
E (14.11.2021 10:04:41.222) HTTP_CLIENT: Connection failed, sock < 0
@espressif-bot espressif-bot added the Status: Opened Issue is new label Dec 14, 2021
@github-actions github-actions bot changed the title DNS lookup failed, last netif doesn't have a DNS server DNS lookup failed, last netif doesn't have a DNS server (IDFGH-6421) Dec 14, 2021
@david-cermak
Copy link
Collaborator

Hi @wowaz

DNS servers are configured globally in lwip, they don't belong to specific interfaces.

My guess is that the DNS server set by the DHCP client on WiFi station would not work on the ethernet subnet.
Can you please check all DNS servers configured in lwip after the step 2)

    esp_netif_dns_info_t gdns1, gdns2, gdns3;
    ESP_ERROR_CHECK(esp_netif_get_dns_info(eth_netif, ESP_NETIF_DNS_MAIN, &gdns1));
    ESP_ERROR_CHECK(esp_netif_get_dns_info(eth_netif, ESP_NETIF_DNS_BACKUP, &gdns2));
    ESP_ERROR_CHECK(esp_netif_get_dns_info(eth_netif, ESP_NETIF_DNS_FALLBACK, &gdns3));

    ESP_LOGI(TAG, "DNS servers : " IPSTR " , " IPSTR " , " IPSTR,
      IP2STR(&gdns1.ip.u_addr.ip4),
      IP2STR(&gdns2.ip.u_addr.ip4),
      IP2STR(&gdns3.ip.u_addr.ip4));

@wowaz
Copy link
Author

wowaz commented Dec 15, 2021

Before eth init:

// esp_netif_get_dns_info(    STA_netif     , ...);
I (15.11.2021 10:08:53.069) NetworkHandler: DNS servers: 10.10.1.105 , 10.10.1.42 , 0.0.0.0

After eth init:

// esp_netif_get_dns_info(    STA_netif     , ...);
I (15.11.2021 10:08:59.380) NetworkHandler: DNS servers: 0.0.0.0 , 0.0.0.0 , 0.0.0.0

// esp_netif_get_dns_info(    ETH_netif     , ...);
I (15.11.2021 10:08:60.121) NetworkHandler: DNS servers: 0.0.0.0 , 0.0.0.0 , 0.0.0.0

ESP-NETIF as abstraction-layer could store the DNS information for each interface, go through all interfaces in the route_prio order and change the DNS server before trying to resolve the name.
Even if other TCP/IP stacks with interface bound DNS are supported by ESP-NETIF in the future, they would all behave the same way with the above suggested behavior.

@david-cermak
Copy link
Collaborator

@wowaz You're right, the DNS info is cleared in ESP-NETIF for interfaces with configured DHCP client, which is true for the predefined ethernet netif.

#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
dns_clear_servers(true);
#endif

Could you please try to disable the DHCP_CLIENT flag in the netif config?

     // Create new default instance of esp-netif for Ethernet
-    esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
+    esp_netif_inherent_config_t custom_eth_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
+    custom_eth_config.flags &= ~ESP_NETIF_DHCP_CLIENT;
+    esp_netif_config_t cfg =     {
+        .base = &custom_eth_config,
+        .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
+    };
     esp_netif_t *eth_netif = esp_netif_new(&cfg);

@wowaz
Copy link
Author

wowaz commented Dec 16, 2021

@david-cermak well this could help with the example above, but not if both, wifi sta and eth, are DHPC clients.
Most likely both DHCPs would server a DNS server which could resolve external names, but local resolving would only work with the last connected interface.

@david-cermak
Copy link
Collaborator

@wowaz As mentioned in the first post, DNS servers are set globally in LWIP and IDF relies on this functionality, so this is currently a limitation we have to cope with.

If you have any specific use-case, please describe it here, so we can discuss it and come up with a proposal, solution or a workaround as we did for the STA + ETH scenario.

If you're looking for a general solution, could you please close this issue and subscribe here #6270 ?

@wowaz
Copy link
Author

wowaz commented Dec 17, 2021

@david-cermak Sorry, don't get me wrong, i appreciate your help. The Issue you posted is really interesting.

My use-case is pretty complex. The Ethernet and Wifi interface can switch between DHCP Client and static IP.
If both are assigned via DHCP, both local networks should be resolvable.
In some usescases it's possible, that both networks don't provide WAN.
In that case the third player comes into play, a LTE PPP interface which would resolve the external names.

The simplest option probably would be listening on all IP_EVENT_*_GOT_IP events, manually store the DNS info and write a custom getaddrinfo which switches between the stored DNS entries.

The best option for me is probably trying to implement the patch described in the other issue. But instead only using the default netif, i'll going through all available. This way no other changes in the whole project are necessary. Let's see how many obstacles i'll have to face to. 😄

@david-cermak
Copy link
Collaborator

@wowaz Any update on this issue? Have you succeeded in any of the proposed options? I'm sorry, there's no update from our side, as you can see in the referenced issue.

@espressif-bot espressif-bot added the Awaiting Response awaiting a response from the author label Apr 6, 2022
@Alvin1Zhang
Copy link
Collaborator

Thanks for reporting, will close due to short of feedback, feel free to reopen with more updates. Thanks.

@espressif-bot espressif-bot added Resolution: Done Issue is done internally Status: Done Issue is done internally and removed Status: Opened Issue is new labels Jun 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Response awaiting a response from the author Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

4 participants