From: Robin Geuze Date: Fri, 17 Mar 2017 11:58:46 +0000 (+0100) Subject: Add suffixmatch option to expungeByName X-Git-Tag: rec-4.1.0-alpha1~206^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=490dc586f61c53c8270cc60735d344165b426492;p=pdns Add suffixmatch option to expungeByName --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index c3d045074..b3acec5df 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -920,11 +920,11 @@ entries remain in the cache. For example, to remove all expired entries: getPool("poolname"):getCache():purgeExpired(0) ``` -Specific entries can also be removed using the `expungeByName(DNSName [, qtype=ANY])` -method. +Specific entries can also be removed using the `expungeByName(DNSName [, qtype=ANY, suffixMatch=false])` +method. If suffixMatch is set to true it will remove any entries below DNSName. ``` -getPool("poolname"):getCache():expungeByName(newDNSName("powerdns.com"), dnsdist.A) +getPool("poolname"):getCache():expungeByName(newDNSName("powerdns.com"), dnsdist.A, true) ``` Finally, the `expunge(n)` method will remove all entries until at most `n` @@ -1535,7 +1535,7 @@ instantiate a server with additional parameters * `unsetCache()`: remove the packet cache from this pool * PacketCache related: * `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 + * `expungeByName(DNSName [, qtype=ANY, suffixMatch=false])`: remove entries matching the supplied DNSName and type from the cache. If suffixMatch is specified also removes names below DNSName * `isFull()`: return true if the cache has reached the maximum number of entries * `newPacketCache(maxEntries[, maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60])`: return a new PacketCache * `printStats()`: print the cache stats (hits, misses, deferred lookups and deferred inserts) diff --git a/pdns/dnsdist-cache.cc b/pdns/dnsdist-cache.cc index 9b5b48ce2..7b41b63d4 100644 --- a/pdns/dnsdist-cache.cc +++ b/pdns/dnsdist-cache.cc @@ -258,18 +258,15 @@ void DNSDistPacketCache::expunge(size_t upTo) d_map.erase(beginIt, endIt); } -void DNSDistPacketCache::expungeByName(const DNSName& name, uint16_t qtype) +void DNSDistPacketCache::expungeByName(const DNSName& name, uint16_t qtype, bool suffixMatch) { WriteLock w(&d_lock); for(auto it = d_map.begin(); it != d_map.end(); ) { const CacheValue& value = it->second; - uint16_t cqtype = 0; - uint16_t cqclass = 0; - DNSName cqname(value.value.c_str(), value.len, sizeof(dnsheader), false, &cqtype, &cqclass, nullptr); - if (cqname == name && (qtype == QType::ANY || qtype == cqtype)) { - it = d_map.erase(it); + if ((value.qname == name || (suffixMatch && value.qname.isPartOf(name))) && (qtype == QType::ANY || qtype == value.qtype)) { + it = d_map.erase(it); } else { ++it; } diff --git a/pdns/dnsdist-cache.hh b/pdns/dnsdist-cache.hh index 10164c7c6..b4c180c78 100644 --- a/pdns/dnsdist-cache.hh +++ b/pdns/dnsdist-cache.hh @@ -37,7 +37,7 @@ public: bool get(const DNSQuestion& dq, uint16_t consumed, uint16_t queryId, char* response, uint16_t* responseLen, uint32_t* keyOut, uint32_t allowExpired=0, bool skipAging=false); void purgeExpired(size_t upTo=0); void expunge(size_t upTo=0); - void expungeByName(const DNSName& name, uint16_t qtype=QType::ANY); + void expungeByName(const DNSName& name, uint16_t qtype=QType::ANY, bool suffixMatch=false); 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 0c3ebc919..e7016f05b 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -694,9 +694,13 @@ void moreLua(bool client) g_lua.registerFunction("isFull", &DNSDistPacketCache::isFull); 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) { + g_lua.registerFunction::*)(const DNSName& dname, boost::optional qtype, boost::optional suffixMatch)>("expungeByName", []( + std::shared_ptr cache, + const DNSName& dname, + boost::optional qtype, + boost::optional suffixMatch) { if (cache) { - cache->expungeByName(dname, qtype ? *qtype : QType::ANY); + cache->expungeByName(dname, qtype ? *qtype : QType::ANY, suffixMatch ? *suffixMatch : false); } }); g_lua.registerFunction::*)()>("printStats", [](const std::shared_ptr cache) { diff --git a/pdns/test-dnsdistpacketcache_cc.cc b/pdns/test-dnsdistpacketcache_cc.cc index 4a944536e..a8b022361 100644 --- a/pdns/test-dnsdistpacketcache_cc.cc +++ b/pdns/test-dnsdistpacketcache_cc.cc @@ -20,7 +20,7 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { ComboAddress remote; try { for(counter = 0; counter < 100000; ++counter) { - DNSName a=DNSName("hello ")+DNSName(std::to_string(counter)); + DNSName a=DNSName(std::to_string(counter))+DNSName(" hello"); BOOST_CHECK_EQUAL(DNSName(a.toString()), a); vector query; @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { size_t deleted=0; size_t delcounter=0; for(delcounter=0; delcounter < counter/1000; ++delcounter) { - DNSName a=DNSName("hello ")+DNSName(std::to_string(delcounter)); + DNSName a=DNSName(std::to_string(delcounter))+DNSName(" hello"); vector query; DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; @@ -80,11 +80,12 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { } BOOST_CHECK_EQUAL(PC.getSize(), counter - skipped - deleted); + size_t matches=0; vector entry; size_t expected=counter-skipped-deleted; for(; delcounter < counter; ++delcounter) { - DNSName a(DNSName("hello ")+DNSName(std::to_string(delcounter))); + DNSName a(DNSName(std::to_string(delcounter))+DNSName(" hello")); vector query; DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; @@ -94,10 +95,13 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { uint16_t responseSize = sizeof(response); DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), len, query.size(), false); if(PC.get(dq, a.wirelength(), pwQ.getHeader()->id, response, &responseSize, &key)) { - matches++; + matches++; } } BOOST_CHECK_EQUAL(matches, expected); + + PC.expungeByName(DNSName(" hello"), QType::ANY, true); + BOOST_CHECK_EQUAL(PC.getSize(), 0); } catch(PDNSException& e) { cerr<<"Had error: "<