Clear DNS lookup table

MaazSk
Posts: 6
Joined: Mon Dec 02, 2019 5:37 am

Clear DNS lookup table

Postby MaazSk » Tue Dec 28, 2021 5:49 am

Hello everyone,

I was trying DNS resolver to IP address and was successful in implementing it. But the problem I am facing is when there is No, internet at that time also I am getting the IP of the DNS and I am unable to clear it.

Is there any method from which I can clear the cache of the esp32 or I can clear the place where the data is been stored.

My code is as follows.

Code: Select all

while (1)
    {
        printf("Get IP for URL: %s\n", szURL);
        dns_gethostbyname(szURL, &ip_Addr, dns_found_cb, NULL);
        while (!bDNSFound)
            ;
        if (bDNSFound == true)
        {
            printf("DNS found: %i.%i.%i.%i\n",
                   ip4_addr1(&ip_Addr.u_addr.ip4),
                   ip4_addr2(&ip_Addr.u_addr.ip4),
                   ip4_addr3(&ip_Addr.u_addr.ip4),
                   ip4_addr4(&ip_Addr.u_addr.ip4));
            // bDNSFound = 0;
            int ret = 0;
            ret = dns_local_removehost("google.com", &ip_Addr);
            printf("return value is: %d\r\n", ret);
        }
}

Code: Select all

void dns_found_cb(const char *name, const ip_addr_t *ipaddr, void *callback_arg)
{
    if (ipaddr != NULL)
    {
        ip_Addr = *ipaddr;
        bDNSFound = true;
    }
}

ShuMan
Posts: 1
Joined: Thu Apr 14, 2022 11:45 am

Re: Clear DNS lookup table

Postby ShuMan » Thu Apr 14, 2022 11:51 am

Hi MaazSk,

Were you able to solve this issue?

I tried freeaddrinfo() but that did not work as mentioned below:
davdav wrote:
Tue Apr 23, 2019 3:55 pm
Me too I used DNS resolver as a mean to understand if external connection is available or not.
Do not forget to "free" the DNS result or you will have leak memory issue..

Thanks.

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

Re: Clear DNS lookup table

Postby NotMyRealName » Wed Jun 05, 2024 10:03 pm

This is an old thread and I haven't properly tested this, but if someone else comes across this you can try:

Code: Select all

#include "lwip/dns.h"
Which includes this function:

Code: Select all

dns_clear_cache(void);
NOTE: there is only one DNS client shared between all interfaces (at least on IDF4.4). If you have WiFi/Cell/Eth running simultaneously it gets ugly fast. There are calls for each interface but they all map to the same set of DNS settings.

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

Re: Clear DNS lookup table

Postby NotMyRealName » Fri Jun 14, 2024 12:02 am

A word of CAUTION!

Since posting, I've spent a good part of the last week trying to track down a bug. I'm pretty sure its come from me including dns_clear_cache()! :(

If I call dns_clear_cache() from another thread while my MQTT (over tls) connection is busy connecting it causes the MQTT thread to lockup.

Still tracking this through fully to find the root cause, but I'm pretty sure this is it!

Linetkux Wang
Posts: 9
Joined: Sun Jun 16, 2024 2:25 pm

Re: Clear DNS lookup table

Postby Linetkux Wang » Sun Jun 16, 2024 2:44 pm

You need to call dns cache clear within LWIP task context.
  1. #include "lwip/tcpip.h"
  2. #include "lwip/dns.h"
  3. #include "stdio.h"
  4.  
  5. // Data structure for passing to tcpip_api_call
  6. struct dns_clear_cache_call_data {
  7.     // No parameters needed
  8. };
  9.  
  10. // Function to clear DNS cache
  11. void dns_clear_cache(void) {
  12.     extern struct dns_table_entry dns_table[DNS_TABLE_SIZE];
  13.     for (int i = 0; i < DNS_TABLE_SIZE; i++) {
  14.         memset(&dns_table[i], 0, sizeof(struct dns_table_entry));
  15.     }
  16. }
  17.  
  18. // Function to be called by tcpip_api_call
  19. static err_t dns_clear_cache_call_fn(struct tcpip_api_call_data *arg) {
  20.     LWIP_UNUSED_ARG(arg);
  21.     dns_clear_cache();
  22.     return ERR_OK;
  23. }
  24.  
  25. // Function to clear DNS cache
  26. void clear_dns_cache_now() {
  27.     struct dns_clear_cache_call_data data;
  28.  
  29.     // Call tcpip_api_call to clear DNS cache
  30.     err_t result = tcpip_api_call(dns_clear_cache_call_fn, (struct tcpip_api_call_data *)&data);
  31.  
  32.     if (result == ERR_OK) {
  33.         printf("DNS cache cleared successfully.\n");
  34.     } else {
  35.         printf("Failed to clear DNS cache. Error code: %d\n", result);
  36.     }
  37. }
  38.  
  39. // Example function to trigger DNS cache clearing
  40. void some_function() {
  41.     clear_dns_cache_now();
  42. }

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

Re: Clear DNS lookup table

Postby NotMyRealName » Tue Jun 18, 2024 2:05 am

Thanks for the suggestion. :)

"tcpip_api_call( )" is a private function and not accessible from outside of the lwip code as far as I can tell. I tried to copy the design pattern used by the other dns functions that use an IPC call to do essentially the same thing I think?

Here is what I added to esp_netif_lwip.c

Code: Select all

static esp_err_t esp_netif_dns_clear_cache_api(esp_netif_api_msg_t *msg)
{
    esp_netif_t *esp_netif = msg->esp_netif;
    ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
    dns_clear_cache();
    return ESP_OK;
}

esp_err_t esp_netif_dns_clear_cache(esp_netif_t *esp_netif)
{
    return esp_netif_lwip_ipc_call(esp_netif_dns_clear_cache_api, esp_netif, NULL);
}
Unfortunately I still get lockups using my test code. (I.e. call this in a loop on a different thread while MQTT is connecting).

I've solved it for now by using locks around calls that could call DNS but its pretty manual and would be easy to break if I forget to lock around one section.

Linetkux Wang
Posts: 9
Joined: Sun Jun 16, 2024 2:25 pm

Re: Clear DNS lookup table

Postby Linetkux Wang » Tue Jun 18, 2024 1:37 pm

I think memset break the status of the dns table entry. Maybe we should borrow the internal-built mechanism, such as TTL. We may set the TTL of each entry to a small value such as 5, so the tmr of DNS can invaid it in advance.
Realted code:
1187 case DNS_STATE_DONE:
1188 /* if the time to live is nul */
1189 initial_ipaddr_cnt = entry->ipaddr_cnt;
1190 for (i=0; i<initial_ipaddr_cnt; i++) {
1191 if ((entry->ttl == 0) || (--entry->ttl == 0)) {
1192 ip_addr_set_zero(&entry->ipaddr);
1193 entry->ipaddr_cnt--;
1194 }
1195 }

Who is online

Users browsing this forum: Majestic-12 [Bot] and 227 guests