]> granicus.if.org Git - pdns/commitdiff
recursor: when replacing an expired entry, move it to the back
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 10 Feb 2016 08:02:17 +0000 (09:02 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 10 Feb 2016 10:47:27 +0000 (11:47 +0100)
If we did a lookup earlier and found the entry to be expired,
we moved it to the front of the expunge queue. If we don't move
it to the back, and the next cache purging operation occurs before
a cache hit using this entry, it's very likely to get expunged.

pdns/recpacketcache.cc
pdns/recursor_cache.cc

index c9e89d12b127a24cc76b081ecdce17aea109100c..76534530ae9b20bf2e034332b4d97dd9722317bf 100644 (file)
@@ -92,6 +92,13 @@ void RecursorPacketCache::insertResponsePacket(const std::string& responsePacket
   packetCache_t::iterator iter = d_packetCache.find(e);
   
   if(iter != d_packetCache.end()) {
+    if (iter->d_ttd <= now) {
+      /* entry had expired, a cache miss might have
+         moved it to the front, and we don't want to
+         get expunged just right now */
+      moveCacheItemToBack(d_packetCache, iter);
+    }
+
     iter->d_packet = responsePacket;
     iter->d_ttd = now + ttl;
     iter->d_creation = now;
index dda3f4266635977e31d5b73ec0d8bab7bdd7ce25..2c9cb2f850e37d86686b0f977ccf0c758ac46caf 100644 (file)
@@ -191,10 +191,23 @@ void MemRecursorCache::replace(time_t now, const string &qname, const QType& qt,
   cache_t::iterator stored=d_cache.find(key);
   uint32_t maxTTD=UINT_MAX;
 
+  bool hadExpired=false;
   bool isNew=false;
   if(stored == d_cache.end()) {
     stored=d_cache.insert(CacheEntry(key,vector<StoredRecord>(), auth)).first;
     isNew=true;
+  } else {
+    vector<StoredRecord>::const_iterator j;
+    bool expired=true;
+    for(j = stored->d_records.begin() ; j != stored->d_records.end(); ++j) {
+      if (now < j->d_ttd) {
+        expired = false;
+        break;
+      }
+    }
+    if (expired) {
+      hadExpired = true;
+    }
   }
   pair<vector<StoredRecord>::iterator, vector<StoredRecord>::iterator> range;
 
@@ -290,6 +303,12 @@ void MemRecursorCache::replace(time_t now, const string &qname, const QType& qt,
   if(ce.d_records.capacity() != ce.d_records.size())
     vector<StoredRecord>(ce.d_records).swap(ce.d_records);
   
+  if (hadExpired) {
+    /* previous entry had expired, a cache miss might have
+       moved it to the front, and we don't want to
+       get expunged just right now */
+    moveCacheItemToBack(d_cache, stored);
+  }
   d_cache.replace(stored, ce);
 }