]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: replace data in the aggressive cache if it becomes available
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 8 Aug 2023 10:15:00 +0000 (12:15 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 21 Aug 2023 11:45:00 +0000 (13:45 +0200)
Currently, new data does not get recorded into the aggressive cache
if there's an existing entry that matches. Together with the fact
that in some cases pruning can be unfair (it scans the zones
always in the same order and stops clearing when it has reached the
goal) and/or not very active (when the recursor is lighlty loaded)
this has the consequence that old expired records can remain in
the cache that prevent new data to be recorded and used.

(cherry picked from commit 93b25e9613f252bc1798975dc1f7a475400f2996)

pdns/recursordist/aggressive_nsec.cc
pdns/recursordist/test-aggressive_nsec_cc.cc

index 96c1c20359f31203404686391e532bdadbd64982..e17bf2dd3aada7a9f0b0515dfa22c874344b556a 100644 (file)
@@ -344,16 +344,22 @@ void AggressiveNSECCache::insertNSEC(const DNSName& zone, const DNSName& owner,
     /* the TTL is already a TTD by now */
     if (!nsec3 && isWildcardExpanded(owner.countLabels(), *signatures.at(0))) {
       DNSName realOwner = getNSECOwnerName(owner, signatures);
-      auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, std::move(realOwner), std::move(next), record.d_ttl});
+      auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, realOwner, next, record.d_ttl});
       if (pair.second) {
         ++d_entriesCount;
       }
+      else {
+        zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, realOwner, next, record.d_ttl});
+      }
     }
     else {
-      auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, owner, std::move(next), record.d_ttl});
+      auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, owner, next, record.d_ttl});
       if (pair.second) {
         ++d_entriesCount;
       }
+      else {
+        zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, owner, next, record.d_ttl});
+      }
     }
   }
 }
index f5424e608a76db4df2b159c2c583dbfe611b5ba3..1596ba3332122bf3314a3ea5bd47cdd17531aa4a 100644 (file)
@@ -1234,6 +1234,36 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump)
     BOOST_CHECK_EQUAL(line, str);
   }
 
+  expected.clear();
+  expected.push_back("; Zone powerdns.com.\n");
+  expected.push_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n");
+  expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");
+  expected.push_back("z.powerdns.com. 30 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n");
+  expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");
+  expected.push_back("; Zone powerdns.org.\n");
+  expected.push_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n");
+  expected.push_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");
+
+  rec.d_name = DNSName("z.powerdns.com");
+  rec.d_type = QType::NSEC;
+  rec.d_ttl = now.tv_sec + 30;
+  rec.setContent(getRecordContent(QType::NSEC, "zz.powerdns.com. AAAA RRSIG NSEC"));
+  rrsig = std::make_shared<RRSIGRecordContent>("NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data");
+  cache->insertNSEC(DNSName("powerdns.com"), rec.d_name, rec, {rrsig}, false);
+
+  fp = std::unique_ptr<FILE, int (*)(FILE*)>(tmpfile(), fclose);
+  BOOST_CHECK_EQUAL(cache->dumpToFile(fp, now), 3U);
+
+  rewind(fp.get());
+
+  for (auto str : expected) {
+    read = getline(&line, &len, fp.get());
+    if (read == -1) {
+      BOOST_FAIL("Unable to read a line from the temp file");
+    }
+    BOOST_CHECK_EQUAL(line, str);
+  }
+
   /* getline() allocates a buffer when called with a nullptr,
      then reallocates it when needed, but we need to free the
      last allocation if any. */