From: Remi Gacogne Date: Mon, 29 Feb 2016 14:32:35 +0000 (+0100) Subject: dnsdist: Add/fix cache cleaning options X-Git-Tag: rec-4.0.0-alpha2~20^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4275aaba2477de0df6c50690d47644030fd27828;p=thirdparty%2Fpdns.git dnsdist: Add/fix cache cleaning options 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. --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index ce81d3b653..a054eda076 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -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: diff --git a/pdns/dnsdist-cache.cc b/pdns/dnsdist-cache.cc index 29a1c587e5..f14114e9b0 100644 --- a/pdns/dnsdist-cache.cc +++ b/pdns/dnsdist-cache.cc @@ -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); diff --git a/pdns/dnsdist-cache.hh b/pdns/dnsdist-cache.hh index 76b1ad2f32..5c9f2d653d 100644 --- a/pdns/dnsdist-cache.hh +++ b/pdns/dnsdist-cache.hh @@ -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(); }; diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index 2f766a3fce..07f7e56b5f 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -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::*)(const DNSName& dname, boost::optional qtype)>("expungeByName", [](std::shared_ptr cache, const DNSName& dname, boost::optional qtype) { - cache->expunge(dname, qtype ? *qtype : QType::ANY); + cache->expungeByName(dname, qtype ? *qtype : QType::ANY); }); g_lua.registerFunction::*)()>("printStats", [](const std::shared_ptr cache) { g_outputBuffer="Hits: " + std::to_string(cache->getHits()) + "\n"; diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index ae636aa690..805768918c 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1035,7 +1035,7 @@ void* maintThread() packetCache = entry.second->packetCache; } if (packetCache) { - packetCache->purge(); + packetCache->purgeExpired(); } } counter = 0; diff --git a/pdns/test-dnsdistpacketcache_cc.cc b/pdns/test-dnsdistpacketcache_cc.cc index f1d1085fc6..fbf0cf4cb7 100644 --- a/pdns/test-dnsdistpacketcache_cc.cc +++ b/pdns/test-dnsdistpacketcache_cc.cc @@ -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++; } }