You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2017/08/09 16:37:51 UTC

[trafficserver] 02/02: Removing the old record when the DNS lookup failed with NXDOMAIN

This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit b0c492fe4c4f5ab99e05a0a78bb281f16fcfa2e5
Author: Zizhong Zhang <zi...@linkedin.com>
AuthorDate: Mon May 29 22:19:17 2017 -0700

    Removing the old record when the DNS lookup failed with NXDOMAIN
---
 iocore/dns/DNS.cc           | 43 +++++++++++++++++++++++++------------------
 iocore/dns/I_DNSProcessor.h |  3 ++-
 iocore/hostdb/HostDB.cc     | 10 ++++++++--
 3 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/iocore/dns/DNS.cc b/iocore/dns/DNS.cc
index e067682..4afb522 100644
--- a/iocore/dns/DNS.cc
+++ b/iocore/dns/DNS.cc
@@ -111,6 +111,24 @@ ink_get16(const uint8_t *src)
   return dst;
 }
 
+static inline unsigned int
+get_rcode(char *buff)
+{
+  return reinterpret_cast<HEADER *>(buff)->rcode;
+}
+
+static inline unsigned int
+get_rcode(HostEnt *ent)
+{
+  return get_rcode(reinterpret_cast<char *>(ent->buf));
+}
+
+bool
+HostEnt::isNameError()
+{
+  return get_rcode(this) == NXDOMAIN;
+}
+
 void
 HostEnt::free()
 {
@@ -728,18 +746,6 @@ DNSHandler::rr_failure(int ndx)
   }
 }
 
-static inline unsigned int
-get_rcode(char *buff)
-{
-  return reinterpret_cast<HEADER *>(buff)->rcode;
-}
-
-static inline unsigned int
-get_rcode(HostEnt *ent)
-{
-  return get_rcode(reinterpret_cast<char *>(ent));
-}
-
 static bool
 good_rcode(char *buff)
 {
@@ -1157,7 +1163,7 @@ dns_result(DNSHandler *h, DNSEntry *e, HostEnt *ent, bool retry)
   ProxyMutex *mutex = h->mutex.get();
   bool cancelled    = (e->action.cancelled ? true : false);
 
-  if (!ent && !cancelled) {
+  if ((!ent || !ent->good) && !cancelled) {
     // try to retry operation
     if (retry && e->retries) {
       Debug("dns", "doing retry for %s", e->qname);
@@ -1205,7 +1211,7 @@ dns_result(DNSHandler *h, DNSEntry *e, HostEnt *ent, bool retry)
     ent = nullptr;
   }
   if (!cancelled) {
-    if (!ent) {
+    if (!ent || !ent->good) {
       DNS_SUM_DYN_STAT(dns_fail_time_stat, Thread::get_hrtime() - e->submit_time);
     } else {
       DNS_SUM_DYN_STAT(dns_success_time_stat, Thread::get_hrtime() - e->submit_time);
@@ -1218,13 +1224,13 @@ dns_result(DNSHandler *h, DNSEntry *e, HostEnt *ent, bool retry)
       ip_text_buffer buff;
       const char *ptr    = "<none>";
       const char *result = "FAIL";
-      if (ent) {
+      if (ent && ent->good) {
         result = "SUCCESS";
         ptr    = inet_ntop(e->qtype == T_AAAA ? AF_INET6 : AF_INET, ent->ent.h_addr_list[0], buff, sizeof(buff));
       }
       Debug("dns", "%s result for %s = %s retry %d", result, e->qname, ptr, retry);
     } else {
-      if (ent) {
+      if (ent && ent->good) {
         Debug("dns", "SUCCESS result for %s = %s af=%d retry %d", e->qname, ent->ent.h_name, ent->ent.h_addrtype, retry);
       } else {
         Debug("dns", "FAIL result for %s = <not found> retry %d", e->qname, retry);
@@ -1232,7 +1238,7 @@ dns_result(DNSHandler *h, DNSEntry *e, HostEnt *ent, bool retry)
     }
   }
 
-  if (ent) {
+  if (ent || !ent->good) {
     DNS_INCREMENT_DYN_STAT(dns_lookup_success_stat);
   } else {
     DNS_INCREMENT_DYN_STAT(dns_lookup_fail_stat);
@@ -1657,7 +1663,8 @@ dns_process(DNSHandler *handler, HostEnt *buf, int len)
   }
 Lerror:;
   DNS_INCREMENT_DYN_STAT(dns_lookup_fail_stat);
-  dns_result(handler, e, nullptr, retry);
+  buf->good = false;
+  dns_result(handler, e, buf, retry);
   return server_ok;
 }
 
diff --git a/iocore/dns/I_DNSProcessor.h b/iocore/dns/I_DNSProcessor.h
index 0c3d324..18e7ed0 100644
--- a/iocore/dns/I_DNSProcessor.h
+++ b/iocore/dns/I_DNSProcessor.h
@@ -48,7 +48,8 @@ struct HostEnt : RefCountObj {
   u_char *h_addr_ptrs[DNS_MAX_ADDRS + 1] = {nullptr};
   u_char hostbuf[DNS_HOSTBUF_SIZE]       = {0};
   SRVHosts srv_hosts;
-
+  bool good = true;
+  bool isNameError();
   virtual void free();
 };
 
diff --git a/iocore/hostdb/HostDB.cc b/iocore/hostdb/HostDB.cc
index c0afd34..afbc95b 100644
--- a/iocore/hostdb/HostDB.cc
+++ b/iocore/hostdb/HostDB.cc
@@ -1285,7 +1285,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
     timeout = thread->schedule_in(this, HRTIME_SECONDS(hostdb_insert_timeout));
     return EVENT_DONE;
   } else {
-    bool failed = !e;
+    bool failed = !e || !e->good;
 
     bool is_rr     = false;
     pending_action = nullptr;
@@ -1301,6 +1301,12 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
     int ttl_seconds = failed ? 0 : e->ttl; // ebalsa: moving to second accuracy
 
     Ptr<HostDBInfo> old_r = probe(mutex.get(), md5, false);
+    // If the DNS lookup failed with NXDOMAIN, remove the old record
+    if (e && e->isNameError() && old_r) {
+      hostDB.refcountcache->erase(old_r->key);
+      old_r = nullptr;
+      Debug("hostdb", "Removing the old record when the DNS lookup failed with NXDOMAIN");
+    }
     HostDBInfo old_info;
     if (old_r) {
       old_info = *old_r.get();
@@ -1365,7 +1371,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
     ink_strlcpy(r->perm_hostname(), aname, s_size);
     offset += s_size;
 
-    // If the DNS lookup failed (errors such as NXDOMAIN, SERVFAIL, etc.) but we have an old record
+    // If the DNS lookup failed (errors such as SERVFAIL, etc.) but we have an old record
     // which is okay with being served stale-- lets continue to serve the stale record as long as
     // the record is willing to be served.
     if (failed && old_r && old_r->serve_stale_but_revalidate()) {

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.