Permalink
Browse files

improve negative caching for SOA lookups

  • Loading branch information...
1 parent 665ac8c commit 4549a7200dfc5c80cd3f1a24b0f058d4579b1dab @mind04 mind04 committed with mind04 Sep 18, 2015
Showing with 34 additions and 9 deletions.
  1. +6 −2 pdns/dnsbackend.cc
  2. +1 −1 pdns/dnsbackend.hh
  3. +25 −4 pdns/ueberbackend.cc
  4. +2 −2 pdns/ueberbackend.hh
View
@@ -44,21 +44,25 @@ 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)
+bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId, const int best_match_len, map<string,int>& negCacheMap)
{
bool found=false;
string subdomain(target);
do {
if( best_match_len >= (int)subdomain.length() )
break;
- if( this->getSOA( subdomain, *sd, p ) ) {
+ map<string,int>::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(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;
View
@@ -163,7 +163,7 @@ public:
virtual void getAllDomains(vector<DomainInfo> *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);
+ virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId, const int best_match_len, map<string,int>& negCacheMap);
struct KeyData {
unsigned int id;
View
@@ -278,6 +278,7 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int
{
int best_match_len = -1;
bool from_cache = false; // Was this result fetched from the cache?
+ map<string,int> 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
@@ -308,22 +309,42 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, int
best_match_len = sd->qname.length();
break;
- }
+ } else if (cstat==0) {
+ negCacheMap[subdomain]=1;
+ } else
+ negCacheMap[subdomain]=0;
loops++;
}
while( chopOff( subdomain ) ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
}
- for(vector<DNSBackend *>::const_iterator i=backends.begin(); i!=backends.end();++i)
- if((*i)->getAuth(p, sd, target, zoneId, best_match_len)) {
+ for(vector<DNSBackend *>::const_iterator i=backends.begin(); i!=backends.end();++i) {
+ 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;
+ goto auth_found;
}
+ }
+
+ if( sd->db != (DNSBackend *)-1 && d_cache_ttl) {
+ string shorter(target);
+
+ d_question.qtype=QType::SOA;
+ d_question.zoneId=-1;
+ while((int)shorter.length() > best_match_len ) {
+ map<string,int>::iterator it = negCacheMap.find(shorter);
+ if (it == negCacheMap.end() || it->second == 0) {
+ d_question.qname=shorter;
+ addNegCache(d_question);
+ }
+ if (!chopOff(shorter))
+ break;
+ }
+ }
if( best_match_len == -1 )
return false;
@@ -114,8 +114,8 @@ public:
void lookup(const QType &, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1);
/* 5-arg version is only valid for backends and should never be called directly */
- virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId, const int best_match_len) {
- throw PDNSException("5-arg version of getAuth should not be called in UeberBackend");
+ virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId, const int best_match_len, map<string,int>& negCacheMap) {
+ throw PDNSException("6-arg version of getAuth should not be called in UeberBackend");
}
bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId);

0 comments on commit 4549a72

Please sign in to comment.