]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
reported by Andreas Jakum & investigated by Stefan Schmidt - make sure we don't hamme...
authorBert Hubert <bert.hubert@netherlabs.nl>
Sun, 5 Oct 2008 09:49:53 +0000 (09:49 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sun, 5 Oct 2008 09:49:53 +0000 (09:49 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1265 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/recursor_cache.cc
pdns/recursor_cache.hh
pdns/syncres.cc

index b49effa72e8efdc43c6f6d220bcd324be93f9655..0c92f127cf5b2157f72e9cd88b05927a58cfdef7 100644 (file)
@@ -233,7 +233,7 @@ int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<
       }
 
     //    cerr<<"time left : "<<ttd - now<<", "<< (res ? res->size() : 0) <<"\n";
-    return (unsigned int)ttd-now;
+    return (int)ttd-now;
   }
   return -1;
 }
@@ -362,6 +362,34 @@ int MemRecursorCache::doWipeCache(const string& name, uint16_t qtype)
   return count;
 }
 
+bool MemRecursorCache::doAgeCache(time_t now, const string& name, uint16_t qtype, int32_t newTTL)
+{
+  cache_t::iterator iter = d_cache.find(tie(name, qtype));
+  if(iter == d_cache.end()) 
+    return false;
+
+  int32_t ttl = iter->getTTD() - now;
+  if(ttl < 0) 
+    return false;  // would be dead anyhow
+
+  if(ttl > newTTL) {
+    d_cachecachevalid=false;
+
+    ttl = newTTL;
+    uint32_t newTTD = now + ttl;
+    
+    CacheEntry ce = *iter;
+    for(vector<StoredRecord>::iterator j = ce.d_records.begin() ; j != ce.d_records.end(); ++j)  {
+      j->d_ttd = newTTD;
+    }
+    
+    d_cache.replace(iter, ce);
+    return true;
+  }
+  return false;
+}
+
+
 void MemRecursorCache::doDumpAndClose(int fd)
 {
   FILE* fp=fdopen(fd, "w");
index d5b1f5385f141230d15580f2bb3bd439b487fd31..f78daf2882110fe8cc46a095adaa79de34c8ece9 100644 (file)
@@ -39,6 +39,7 @@ public:
   void doSlash(int perc);
   void doDumpAndClose(int fd);
   int doWipeCache(const string& name, uint16_t qtype=0xffff);
+  bool doAgeCache(time_t now, const string& name, uint16_t qtype, int32_t newTTL);
   uint64_t cacheHits, cacheMisses;
   bool d_followRFC2181;
 
index 1527c410609ee4a115d5c9a25d4c274143d646c7..3195a31c3793626561de87d3d0497cf6578817ea 100644 (file)
@@ -607,9 +607,9 @@ int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth,
       if(tns==rnameservers.end()) {
        LOG<<prefix<<qname<<": Failed to resolve via any of the "<<(unsigned int)rnameservers.size()<<" offered NS at level '"<<auth<<"'"<<endl;
        if(auth!="." && flawedNSSet) {
-         g_stats.nsSetInvalidations++;
-         LOG<<prefix<<qname<<": Invalidating nameservers for level '"<<auth<<"', next query might succeed"<<endl;
-         RC.doWipeCache(auth, QType::NS);
+         LOG<<prefix<<qname<<": Ageing nameservers for level '"<<auth<<"', next query might succeed"<<endl;
+         if(RC.doAgeCache(d_now.tv_sec, auth, QType::NS, 10))
+           g_stats.nsSetInvalidations++;
        }
        return -1;
       }