]> granicus.if.org Git - pdns/commitdiff
improve SOA caching for DS queries
authorKees Monshouwer <mind04@monshouwer.org>
Fri, 18 Sep 2015 11:52:44 +0000 (13:52 +0200)
committermind04 <mind04@monshouwer.org>
Thu, 1 Oct 2015 14:57:20 +0000 (16:57 +0200)
pdns/dnsbackend.cc
pdns/ueberbackend.cc

index 09e02e47dbba9a2ff565f8703c3a863607bdb200..47351ed169963f4e00c78c030fee5caaa9afdc7e 100644 (file)
@@ -49,7 +49,7 @@ bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int *z
   bool found=false;
   string subdomain(target);
   do {
-    if( best_match_len >= (int)subdomain.length() )
+    if( best_match_len >= (int)subdomain.length() && p->qtype != QType::DS )
       break;
 
     map<string,int>::iterator it = negCacheMap.find(subdomain);
@@ -59,14 +59,17 @@ bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int *z
       sd->qname = subdomain;
       if(zoneId)
         *zoneId = sd->domain_id;
+      if(found) // Second SOA found, we are done
+        return true;
 
       if(p->qtype.getCode() == QType::DS && pdns_iequals(subdomain, target)) {
         // Found authoritative zone but look for parent zone with 'DS' record.
-        negCacheMap[subdomain]=2;
         found=true;
       } else
         return true;
     }
+    if (found)
+      negCacheMap[subdomain]=2; // don't cache SOA's during our quest for a parent zone
   }
   while( chopOff( subdomain ) );   // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
 
index 8ddfa981a5791391b4d5ae78b404134b68a9f407..0a3d4f2ca04b83cdb136b6505c4a44968b055c75 100644 (file)
@@ -283,7 +283,7 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int
   // If not special case of caching explicitly disabled (sd->db = -1), first
   // find the best match from the cache. If DS then we need to find parent so
   // dont bother with caching as it confuses matters.
-  if( sd->db != (DNSBackend *)-1 && d_cache_ttl && p->qtype != QType::DS ) {
+  if( sd->db != (DNSBackend *)-1 && d_cache_ttl ) {
       string subdomain(target);
       int cstat, loops = 0;
       do {
@@ -302,13 +302,14 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int
           //L<<Logger::Error<<"Best cache match: " << sd->qname << " itteration " << loops <<endl;
 
           // Found first time round this must be the best match
-          if( loops == 0 )
+          if( loops == 0  && p->qtype != QType::DS)
             return true;
 
           from_cache = true;
           best_match_len = sd->qname.length();
 
-          break;
+          if ( p->qtype != QType::DS || best_match_len < (int)target.length())
+            break;
         } else if (cstat==0) {
           negCacheMap[subdomain]=1;
         } else
@@ -319,14 +320,15 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int
   }
 
   for(vector<DNSBackend *>::const_iterator i=backends.begin(); i!=backends.end();++i) {
+
+    // Shortcut for the case that we got a direct hit - no need to go
+    // through the other backends then.
+    if( best_match_len == (int)target.length() && p->qtype != QType::DS )
+      goto auth_found;
+
     if((*i)->getAuth(p, sd, target, zoneId, best_match_len, negCacheMap)) {
         best_match_len = sd->qname.length();
         from_cache = false;
-
-        // Shortcut for the case that we got a direct hit - no need to go
-        // through the other backends then.
-        if( best_match_len == (int)target.length() )
-          goto auth_found;
     }
   }