]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Purge views more thoroughly. 15609/head
authorMiod Vallat <miod.vallat@powerdns.com>
Wed, 11 Jun 2025 05:27:05 +0000 (07:27 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Wed, 11 Jun 2025 06:02:15 +0000 (08:02 +0200)
pdns/auth-packetcache.cc
pdns/auth-packetcache.hh
pdns/test-packetcache_cc.cc
pdns/ws-auth.cc

index 2be70171685ddebdc6852bf6dd416b974d2816aa..262454ace55b6750e6ce831ed9fafb5c87988b17 100644 (file)
@@ -73,7 +73,7 @@ void AuthPacketCache::MapCombo::reserve(size_t numberOfEntries)
 
 bool AuthPacketCache::get(DNSPacket& pkt, DNSPacket& cached, const std::string& view)
 {
-  if(!d_ttl) {
+  if (d_ttl == 0) {
     return false;
   }
 
@@ -131,7 +131,7 @@ bool AuthPacketCache::entryMatches(cmap_t::index<HashTag>::type::iterator& iter,
 
 void AuthPacketCache::insert(DNSPacket& query, DNSPacket& response, unsigned int maxTTL, const std::string& view)
 {
-  if(!d_ttl) {
+  if (d_ttl == 0) {
     return;
   }
 
@@ -231,7 +231,7 @@ bool AuthPacketCache::getEntryLocked(const cmap_t& map, const std::string& query
 /* clears the entire cache. */
 uint64_t AuthPacketCache::purge()
 {
-  if(!d_ttl) {
+  if (d_ttl == 0) {
     return 0;
   }
 
@@ -265,23 +265,6 @@ uint64_t AuthPacketCache::purgeExact(const DNSName& qname)
   return delcount;
 }
 
-uint64_t AuthPacketCache::purgeExact(const std::string& view, const DNSName& qname)
-{
-  uint64_t delcount = 0;
-
-  {
-    auto cache = d_cache.write_lock();
-    if (auto iter = cache->find(view); iter != cache->end()) {
-      auto& mc = getMap(iter->second, qname); // NOLINT(readability-identifier-length)
-      delcount += purgeExactLockedCollection<NameTag>(mc, qname);
-    }
-  }
-
-  *d_statnumentries -= delcount;
-
-  return delcount;
-}
-
 uint64_t AuthPacketCache::purgeView(const std::string& view)
 {
   uint64_t delcount = 0;
@@ -303,7 +286,7 @@ uint64_t AuthPacketCache::purgeView(const std::string& view)
 /* purges entries from the packetcache. If match ends on a $, it is treated as a suffix */
 uint64_t AuthPacketCache::purge(const string &match)
 {
-  if(!d_ttl) {
+  if (d_ttl == 0) {
     return 0;
   }
 
@@ -326,6 +309,34 @@ uint64_t AuthPacketCache::purge(const string &match)
   return delcount;
 }
 
+uint64_t AuthPacketCache::purge(const std::string& view, const std::string& match)
+{
+  if (d_ttl == 0) {
+    return 0;
+  }
+
+  uint64_t delcount = 0;
+
+  {
+    auto cache = d_cache.write_lock();
+    if (auto iter = cache->find(view); iter != cache->end()) {
+      if (boost::ends_with(match, "$")) {
+        auto *map = iter->second.get();
+        delcount += purgeLockedCollectionsVector<NameTag>(*map, match);
+      }
+      else {
+        DNSName qname(match);
+        auto& mc = getMap(iter->second, qname); // NOLINT(readability-identifier-length)
+        delcount += purgeExactLockedCollection<NameTag>(mc, qname);
+      }
+    }
+  }
+
+  *d_statnumentries -= delcount;
+
+  return delcount;
+}
+
 void AuthPacketCache::cleanup()
 {
   uint64_t totErased = 0;
index b10a6b210e05af89c98073a47262d7662fcc9a10..27c343f633a05421cfa993a8f3b457f0664679fd 100644 (file)
@@ -64,8 +64,8 @@ public:
   void cleanup(); //!< force the cache to preen itself from expired packets
   uint64_t purge();
   uint64_t purge(const std::string& match); // could be $ terminated. Is not a dnsname!
+  uint64_t purge(const std::string& view, const std::string& match); // same as above, but in the given view
   uint64_t purgeExact(const DNSName& qname); // no wildcard matching here
-  uint64_t purgeExact(const std::string& view, const DNSName& qname); // same as above, but in the given view
   uint64_t purgeView(const std::string& view);
 
   uint64_t size() const { return *d_statnumentries; };
index 037860130bbadc6c21cf5c879fccde6764360967..7ccd190166038e4ad0172cacc30577d98a39ec48 100644 (file)
@@ -678,7 +678,9 @@ BOOST_AUTO_TEST_CASE(test_AuthViews)
   BOOST_CHECK_EQUAL(queryPacketCache2(PC, ZC, ComboAddress("192.0.2.1"), qname, innerMask, view2, "2.2.2.2"), true);
 
   // Purge view2
-  BOOST_CHECK_EQUAL(PC.purgeExact(view2, qname), 1);
+  std::string purgeName = qname.toString();
+  purgeName.append("$");
+  BOOST_CHECK_EQUAL(PC.purge(view2, purgeName), 1);
   BOOST_CHECK_EQUAL(PC.size(), 1);
 
   // Check that requesting from view2 causes a cache miss
@@ -688,7 +690,9 @@ BOOST_AUTO_TEST_CASE(test_AuthViews)
   BOOST_CHECK_EQUAL(queryPacketCache2(PC, ZC, ComboAddress("192.0.2.128"), qname, outerMask, view1, "1.1.1.1"), true);
 
   // Purge view1
-  BOOST_CHECK_EQUAL(PC.purgeExact(view1, qname), 1);
+  purgeName = qname.toString();
+  purgeName.append("$");
+  BOOST_CHECK_EQUAL(PC.purge(view1, purgeName), 1);
   BOOST_CHECK_EQUAL(PC.size(), 0);
 
   // Check that requesting from view1 causes a cache miss
index f583122e83a1c5acef4786f1088a18a47289fc8c..fbbc34dcf72c29000d16564c58b9619f9e399271 100644 (file)
@@ -2721,7 +2721,10 @@ static void apiServerViewsPOST(HttpRequest* req, HttpResponse* resp)
   }
   // Purge packet cache for that zone
   if (PC.enabled()) {
-    (void)PC.purgeExact(view, zonename.operator const DNSName&());
+    // Note that this relies upon ZoneName::toString NOT emitting the variant name.
+    std::string purgename = zonename.toString();
+    purgename.append("$");
+    (void)PC.purge(view, purgename);
   }
 
   resp->body = "";
@@ -2748,7 +2751,10 @@ static void apiServerViewsDELETE(HttpRequest* req, HttpResponse* resp)
       (void)PC.purgeView(view);
     }
     else {
-      (void)PC.purgeExact(view, zoneData.zoneName.operator const DNSName&());
+      // Note that this relies upon ZoneName::toString NOT emitting the variant name.
+      std::string purgename = zoneData.zoneName.toString();
+      purgename.append("$");
+      (void)PC.purge(view, purgename);
     }
   }