]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add/fix cache cleaning options
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 29 Feb 2016 14:32:35 +0000 (15:32 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 29 Feb 2016 14:36:38 +0000 (15:36 +0100)
The function to remove expired entries was broken, and we were
missing a way to nuke a lot of valid entries at once.
We can now:
- remove entries by qname and qtype
- remove n expired entries
- remove n entries

Fix #3468.

pdns/README-dnsdist.md
pdns/dnsdist-cache.cc
pdns/dnsdist-cache.hh
pdns/dnsdist-lua2.cc
pdns/dnsdist.cc
pdns/test-dnsdistpacketcache_cc.cc

index ce81d3b653712b16bbb18dc8f2541bc18de941bb..a054eda07623849df3a7b9dbafcf9463f8347f73 100644 (file)
@@ -1032,11 +1032,12 @@ instantiate a server with additional parameters
     * `getCache()`: return the current packet cache, if any
     * `setCache(PacketCache)`: set the cache for this pool
  * PacketCache related:
-    * `expungeByName(DNSName)`: remove entries matching the supplied DNSName from the cache
+    * `expunge(n)`: remove entries from the cache, leaving at most `n` entries
+    * `expungeByName(DNSName [, qtype=ANY])`: remove entries matching the supplied DNSName and type from the cache
     * `isFull()`: return true if the cache has reached the maximum number of entries
     * `newPacketCache(maxEntries, maxTTL=86400, minTTL=60)`: return a new PacketCache
     * `printStats()`: print the cache stats (hits, misses, deferred lookups and deferred inserts)
-    * `purge()`: remove entries from the cache until it the number of entries is lower than the maximum, starting with expired ones.
+    * `purgeExpired(n)`: remove expired entries from the cache until there is at most `n` entries remaining in the cache
     * `toString()`: return the number of entries in the Packet Cache, and the maximum number of entries
  * Advanced functions for writing your own policies and hooks
     * ComboAddress related:
index 29a1c587e58506d166a6f140ed91d858b4755fa4..f14114e9b0e8c57484c10332ed72546411258090 100644 (file)
@@ -144,12 +144,16 @@ bool DNSDistPacketCache::get(const unsigned char* query, uint16_t queryLen, cons
   return true;
 }
 
-void DNSDistPacketCache::purge(size_t upTo)
+/* Remove expired entries, until the cache has at most
+   upTo entries in it.
+*/
+void DNSDistPacketCache::purgeExpired(size_t upTo)
 {
   time_t now = time(NULL);
   WriteLock w(&d_lock);
-  if (upTo <= d_map.size())
+  if (upTo >= d_map.size()) {
     return;
+  }
 
   size_t toRemove = d_map.size() - upTo;
   for(auto it = d_map.begin(); toRemove > 0 && it != d_map.end(); ) {
@@ -164,7 +168,24 @@ void DNSDistPacketCache::purge(size_t upTo)
   }
 }
 
-void DNSDistPacketCache::expunge(const DNSName& name, uint16_t qtype)
+/* Remove all entries, keeping only upTo
+   entries in the cache */
+void DNSDistPacketCache::expunge(size_t upTo)
+{
+  WriteLock w(&d_lock);
+
+  if (upTo >= d_map.size()) {
+    return;
+  }
+
+  size_t toRemove = d_map.size() - upTo;
+  auto beginIt = d_map.begin();
+  auto endIt = beginIt;
+  std::advance(endIt, toRemove);
+  d_map.erase(beginIt, endIt);
+}
+
+void DNSDistPacketCache::expungeByName(const DNSName& name, uint16_t qtype)
 {
   WriteLock w(&d_lock);
 
index 76b1ad2f3266b8821c34f9368c3220fc6cfb4e76..5c9f2d653daf43456e657cdb300741529f3ff8c2 100644 (file)
@@ -12,8 +12,9 @@ public:
 
   void insert(uint32_t key, const DNSName& qname, uint16_t qtype, uint16_t qclass, const char* response, uint16_t responseLen, bool tcp);
   bool get(const unsigned char* query, uint16_t queryLen, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t consumed, uint16_t queryId, char* response, uint16_t* responseLen, bool tcp, uint32_t* keyOut, bool skipAging=false);
-  void purge(size_t upTo=0);
-  void expunge(const DNSName& name, uint16_t qtype=QType::ANY);
+  void purgeExpired(size_t upTo=0);
+  void expunge(size_t upTo=0);
+  void expungeByName(const DNSName& name, uint16_t qtype=QType::ANY);
   bool isFull();
   string toString();
   uint64_t getSize() const { return d_map.size(); };
index 2f766a3fcece0fb82b11ddd67c0a8e19fc748921..07f7e56b5f81412773866b61433709db207156ce 100644 (file)
@@ -536,9 +536,10 @@ void moreLua(bool client)
       });
     g_lua.registerFunction("toString", &DNSDistPacketCache::toString);
     g_lua.registerFunction("isFull", &DNSDistPacketCache::isFull);
-    g_lua.registerFunction("purge", &DNSDistPacketCache::purge);
+    g_lua.registerFunction("purgeExpired", &DNSDistPacketCache::purgeExpired);
+    g_lua.registerFunction("expunge", &DNSDistPacketCache::expunge);
     g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)(const DNSName& dname, boost::optional<uint16_t> qtype)>("expungeByName", [](std::shared_ptr<DNSDistPacketCache> cache, const DNSName& dname, boost::optional<uint16_t> qtype) {
-        cache->expunge(dname, qtype ? *qtype : QType::ANY);
+        cache->expungeByName(dname, qtype ? *qtype : QType::ANY);
       });
     g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)()>("printStats", [](const std::shared_ptr<DNSDistPacketCache> cache) {
         g_outputBuffer="Hits: " + std::to_string(cache->getHits()) + "\n";
index ae636aa6900cae1cf8811c0ad65c633496c396c0..805768918cb8d1e006c327e24d4026fe38969551 100644 (file)
@@ -1035,7 +1035,7 @@ void* maintThread()
           packetCache = entry.second->packetCache;
         }
         if (packetCache) {
-          packetCache->purge();
+          packetCache->purgeExpired();
         }
       }
       counter = 0;
index f1d1085fc6ed3c5ffd47a9a1a339f456256b986a..fbf0cf4cb78c8b51a77e2a4ed79694413ecae651 100644 (file)
@@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) {
       uint32_t key = 0;
       bool found = PC.get((const unsigned char*) query.data(), query.size(), a, QType::A, QClass::IN, a.wirelength(), 0, responseBuf, &responseBufSize, false, &key);
       if (found == true) {
-        PC.expunge(a);
+        PC.expungeByName(a);
         deleted++;
       }
     }