A caller can stop waiting for a DNS result while the resolver keeps
the request and callback. If another lwIP client continues polling, that
callback can later use state which its owner has already released.

Add dns_cancel() to remove matching callbacks without canceling a
query shared by other callers. Use it when stopping SNTP so a pending
name lookup cannot outlive the client.

Signed-off-by: James Hilliard <[email protected]>
---
 lib/lwip/lwip/src/apps/sntp/sntp.c   |  3 +++
 lib/lwip/lwip/src/core/dns.c         | 26 ++++++++++++++++++++++++++
 lib/lwip/lwip/src/include/lwip/dns.h |  1 +
 3 files changed, 30 insertions(+)

diff --git a/lib/lwip/lwip/src/apps/sntp/sntp.c 
b/lib/lwip/lwip/src/apps/sntp/sntp.c
index 0e7f36520fa..a37699f65b7 100644
--- a/lib/lwip/lwip/src/apps/sntp/sntp.c
+++ b/lib/lwip/lwip/src/apps/sntp/sntp.c
@@ -711,6 +711,9 @@ void
 sntp_stop(void)
 {
   LWIP_ASSERT_CORE_LOCKED();
+#if SNTP_SERVER_DNS
+  dns_cancel(sntp_dns_found, NULL);
+#endif
   if (sntp_pcb != NULL) {
 #if SNTP_MONITOR_SERVER_REACHABILITY
     u8_t i;
diff --git a/lib/lwip/lwip/src/core/dns.c b/lib/lwip/lwip/src/core/dns.c
index 6540f143bac..5762647ee27 100644
--- a/lib/lwip/lwip/src/core/dns.c
+++ b/lib/lwip/lwip/src/core/dns.c
@@ -387,6 +387,32 @@ dns_getserver(u8_t numdns)
   }
 }
 
+/**
+ * @ingroup dns
+ * Cancel pending callbacks registered by dns_gethostbyname().
+ *
+ * DNS queries shared with other callers continue so their result can still be
+ * cached and delivered. Only callbacks matching both arguments are removed.
+ *
+ * @param found callback passed to dns_gethostbyname()
+ * @param callback_arg callback argument passed to dns_gethostbyname()
+ */
+void
+dns_cancel(dns_found_callback found, void *callback_arg)
+{
+  u8_t i;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  for (i = 0; i < DNS_MAX_REQUESTS; i++) {
+    if ((dns_requests[i].found == found) &&
+        (dns_requests[i].arg == callback_arg)) {
+      dns_requests[i].found = NULL;
+      dns_requests[i].arg = NULL;
+    }
+  }
+}
+
 /**
  * The DNS resolver client timer - handle retries and timeouts and should
  * be called every DNS_TMR_INTERVAL milliseconds (every second by default).
diff --git a/lib/lwip/lwip/src/include/lwip/dns.h 
b/lib/lwip/lwip/src/include/lwip/dns.h
index 091341544f3..82579f09f35 100644
--- a/lib/lwip/lwip/src/include/lwip/dns.h
+++ b/lib/lwip/lwip/src/include/lwip/dns.h
@@ -111,6 +111,7 @@ 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);
+void             dns_cancel(dns_found_callback found, void *callback_arg);
 
 
 #if DNS_LOCAL_HOSTLIST

-- 
2.53.0

Reply via email to