From: Kees Monshouwer Date: Fri, 18 Sep 2015 08:12:15 +0000 (+0200) Subject: improve negative caching for SOA lookups X-Git-Tag: dnsdist-1.0.0-alpha1~24^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f70be3c3bda72455da6875ce568d67ef93914ff5;p=pdns improve negative caching for SOA lookups --- diff --git a/pdns/dnsbackend.cc b/pdns/dnsbackend.cc index 3e96807a0..d4e78d168 100644 --- a/pdns/dnsbackend.cc +++ b/pdns/dnsbackend.cc @@ -33,7 +33,7 @@ #include "dnspacket.hh" #include "dns.hh" -bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target, const int best_match_len) +bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target, const int best_match_len, map& negCacheMap) { bool found=false; DNSName subdomain(target); @@ -41,11 +41,15 @@ bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target, const if( best_match_len >= (int)subdomain.toString().length() ) break; - if( this->getSOA( subdomain, *sd, p ) ) { + map::iterator it = negCacheMap.find(subdomain); + bool negCached = ( it != negCacheMap.end() && it->second == 1 ); + + if(! negCached && this->getSOA( subdomain, *sd, p ) ) { sd->qname = subdomain; if(p->qtype.getCode() == QType::DS && subdomain==target) { // Found authoritative zone but look for parent zone with 'DS' record. + negCacheMap[subdomain]=2; found=true; } else return true; diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index f940661fd..1e1ff5cc3 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -168,7 +168,7 @@ public: virtual void getAllDomains(vector *domains, bool include_disabled=false) { } /** Determines if we are authoritative for a zone, and at what level */ - virtual bool getAuth(DNSPacket *p, SOAData *sd, const DNSName &target, const int best_match_len); + virtual bool getAuth(DNSPacket *p, SOAData *sd, const DNSName &target, const int best_match_len, map& negCacheMap); struct KeyData { std::string content; diff --git a/pdns/ueberbackend.cc b/pdns/ueberbackend.cc index b665184a6..1d10c4565 100644 --- a/pdns/ueberbackend.cc +++ b/pdns/ueberbackend.cc @@ -251,6 +251,7 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target) { int best_match_len = -1; bool from_cache = false; // Was this result fetched from the cache? + map negCacheMap; // 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 @@ -281,14 +282,17 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target) best_match_len = sd->qname.countLabels(); break; - } + } else if (cstat==0) { + negCacheMap[subdomain]=1; + } else + negCacheMap[subdomain]=0; loops++; } while( subdomain.chopOff() ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> '' } - for(vector::const_iterator i=backends.begin(); i!=backends.end();++i) - if((*i)->getAuth(p, sd, target, best_match_len)) { + for(vector::const_iterator i=backends.begin(); i!=backends.end();++i) { + if((*i)->getAuth(p, sd, target, best_match_len, negCacheMap)) { best_match_len = sd->qname.countLabels(); // FIXME400 from_cache = false; @@ -297,6 +301,23 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target) if( best_match_len == (int)target.countLabels() ) goto auth_found; } + } + + if( sd->db != (DNSBackend *)-1 && d_negcache_ttl) { + DNSName shorter(target); + + d_question.qtype=QType::SOA; + d_question.zoneId=-1; + while((int)shorter.countLabels() > best_match_len ) { + map::iterator it = negCacheMap.find(shorter); + if (it == negCacheMap.end() || it->second == 0) { + d_question.qname=shorter; + addNegCache(d_question); + } + if (!shorter.chopOff()) + break; + } + } if( best_match_len == -1 ) return false;