diff --git a/pdns/dnsbackend.cc b/pdns/dnsbackend.cc index 47351ed16996..6a0c3affa301 100644 --- a/pdns/dnsbackend.cc +++ b/pdns/dnsbackend.cc @@ -44,36 +44,9 @@ bool DNSBackend::getRemote(DNSPacket *p, struct sockaddr *sa, Utility::socklen_t return true; } -bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId, const int best_match_len, map& negCacheMap) +bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target) { - bool found=false; - string subdomain(target); - do { - if( best_match_len >= (int)subdomain.length() && p->qtype != QType::DS ) - break; - - 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(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. - 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' -> '' - - return found; + return this->getSOA(target, *sd, p); } void DNSBackend::setArgPrefix(const string &prefix) diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index 4a057be21ce3..a8bc9e0a694b 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -163,7 +163,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 string &target, int *zoneId, const int best_match_len, map& negCacheMap); + virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target); struct KeyData { unsigned int id; diff --git a/pdns/ueberbackend.cc b/pdns/ueberbackend.cc index a2aa6657bc51..df8d5ff3b95f 100644 --- a/pdns/ueberbackend.cc +++ b/pdns/ueberbackend.cc @@ -276,85 +276,73 @@ void UeberBackend::getUpdatedMasters(vector* domains) bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId) { - 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 - // dont bother with caching as it confuses matters. - if( sd->db != (DNSBackend *)-1 && (d_cache_ttl || d_negcache_ttl)) { - string subdomain(target); - int cstat, loops = 0; - do { - d_question.qtype = QType::SOA; - d_question.qname = subdomain; - d_question.zoneId = -1; - - cstat = cacheHas(d_question,d_answers); - - if(cstat==1 && !d_answers.empty() && d_cache_ttl) { - fillSOAData(d_answers[0].content,*sd); - sd->domain_id = d_answers[0].domain_id; - sd->ttl = d_answers[0].ttl; - sd->db = 0; - sd->qname = subdomain; - //L<qname << " itteration " << loops <qtype != QType::DS) - return true; - - from_cache = true; - best_match_len = sd->qname.length(); - - if ( p->qtype != QType::DS || best_match_len < (int)target.length()) - break; - } else if (cstat==0 && d_negcache_ttl) { - negCacheMap[subdomain]=1; - } else - negCacheMap[subdomain]=0; - loops++; + bool found = false; + int cstat; + string shorter(target); + vector > bestmatch (backends.size(), make_pair(target.size()+1, SOAData())); + do { + + // Check cache + if(sd->db != (DNSBackend *)-1 && (d_cache_ttl || d_negcache_ttl)) { + d_question.qtype = QType::SOA; + d_question.qname = shorter; + d_question.zoneId = -1; + + cstat = cacheHas(d_question,d_answers); + + if(cstat == 1 && !d_answers.empty() && d_cache_ttl) { + DLOG(L<domain_id = d_answers[0].domain_id; + sd->ttl = d_answers[0].ttl; + sd->db = 0; + sd->qname = shorter; + goto found; + } else if(cstat == 0 && d_negcache_ttl) { + DLOG(L< 'powerdns.org' -> 'org' -> '' - } - - for(vector::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; } - } - - if( sd->db != (DNSBackend *)-1 && d_negcache_ttl) { - string shorter(target); - d_question.qtype=QType::SOA; - d_question.zoneId=-1; - while((int)shorter.length() > best_match_len ) { - map::iterator it = negCacheMap.find(shorter); - if (it == negCacheMap.end() || it->second == 0) { - d_question.qname=shorter; - addNegCache(d_question); + // Check backends + { + vector::const_iterator i = backends.begin(); + vector >::iterator j = bestmatch.begin(); + for(; i != backends.end() && j != bestmatch.end(); ++i, ++j) { + + L<first < shorter.length()) { + DLOG(L<second.qname<first == shorter.length()) { + DLOG(L<second.qname<second; + break; + } else { + L<getAuth(p, sd, shorter)) { + L<qname<first = sd->qname.length(); + if(sd->qname.length() == shorter.length()) { + break; + } + } else { + L<qtype != QType::DS ) { - //L<qname <qname<qname; d_question.zoneId = -1; @@ -368,9 +356,20 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int vector rrs; rrs.push_back(rr); addCache(d_question, rrs); + } + } + +found: + if(found == (p->qtype == QType::DS)){ + DLOG(L<qname<qname<