]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Fix serve-stale logic in negcache by following the record cache case more closely
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 1 Mar 2023 08:28:20 +0000 (09:28 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 1 Mar 2023 08:28:20 +0000 (09:28 +0100)
pdns/recursordist/negcache.cc
pdns/recursordist/negcache.hh

index 50b01abe95af8e148680ff26c2eaace89387b80e..0923b7de5a092bb732a7413e740c4c53408423cc 100644 (file)
@@ -119,27 +119,31 @@ bool NegCache::get(const DNSName& qname, QType qtype, const struct timeval& now,
 
   const auto& idx = content->d_map.get<NegCacheEntry>();
   auto range = idx.equal_range(qname);
-  auto ni = range.first;
 
-  while (ni != range.second) {
+  for (auto ni = range.first; ni != range.second; ++ni) {
     // We have an entry
     if ((!typeMustMatch && ni->d_qtype == QType::ENT) || ni->d_qtype == qtype) {
       // We match the QType or the whole name is denied
       auto firstIndexIterator = content->d_map.project<CompositeKey>(ni);
 
-      if (!refresh && (serveStale || ni->d_servedStale > 0) && ni->d_ttd <= now.tv_sec && ni->d_servedStale < s_maxServedStaleExtensions) {
+      // this checks ttd, but also takes into account serve-stale
+      if (!ni->isEntryUsable(now.tv_sec, serveStale)) {
+        // Outdated
+        moveCacheItemToFront<SequenceTag>(content->d_map, firstIndexIterator);
+        continue;
+      }
+      // If we are serving this record stale (or *should*) and the ttd has passed increase ttd to
+      // the future and remember that we did. Also push a refresh task.
+      if ((serveStale || ni->d_servedStale > 0) && ni->d_ttd <= now.tv_sec && ni->d_servedStale < s_maxServedStaleExtensions) {
         updateStaleEntry(now.tv_sec, firstIndexIterator, qtype);
       }
-      if (now.tv_sec < ni->d_ttd && !(refresh && ni->d_servedStale > 0)) {
+      if (now.tv_sec < ni->d_ttd) {
         // Not expired
         ne = *ni;
         moveCacheItemToBack<SequenceTag>(content->d_map, firstIndexIterator);
-        return true;
+        return !refresh; // when refreshing, we consider everything outdated
       }
-      // expired
-      moveCacheItemToFront<SequenceTag>(content->d_map, firstIndexIterator);
     }
-    ++ni;
   }
   return false;
 }
index 2e989aadef30c33d32067987d1946d9aecfbef06..0d42afee1099384033f3ceb60fc67e70f8f0f129 100644 (file)
@@ -84,6 +84,12 @@ public:
         return d_ttd < now;
       }
     };
+
+    bool isEntryUsable(time_t now, bool serveStale) const
+    {
+      // When serving stale, we consider expired records
+      return d_ttd > now || serveStale || d_servedStale != 0;
+    }
   };
 
   void add(const NegCacheEntry& ne);