From 801812e69aa370d3cd78a8bb073ef28164f63c1d Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Fri, 1 Aug 2014 01:22:05 +0200 Subject: [PATCH] reversed packetcache 'powerdns.com' -> 'moc sndrewop ' --- pdns/packetcache.cc | 74 +++++++++++++-------------------------------- pdns/packetcache.hh | 21 ++----------- 2 files changed, 23 insertions(+), 72 deletions(-) diff --git a/pdns/packetcache.cc b/pdns/packetcache.cc index cd244a58e..7db48e1fa 100644 --- a/pdns/packetcache.cc +++ b/pdns/packetcache.cc @@ -158,7 +158,7 @@ void PacketCache::insert(const string &qname, const QType& qtype, CacheEntryType CacheEntry val; val.created=time(0); val.ttd=val.created+ttl; - val.qname=qname; + val.qname=pcReverse(qname); val.qtype=qtype.getCode(); val.value=value; val.ctype=cet; @@ -198,60 +198,17 @@ int PacketCache::purge(const string &match) WriteLock l(&d_mut); int delcount=0; - /* ok, the suffix delete plan. We want to be able to delete everything that - pertains 'www.powerdns.com' but we also want to be able to delete everything - in the powerdns.com zone, so: 'powerdns.com' and '*.powerdns.com'. - - However, we do NOT want to delete 'usepowerdns.com!, nor 'powerdnsiscool.com' - - So, at first shot, store in reverse label order: - - 'be.someotherdomain' - 'com.powerdns' - 'com.powerdns.images' - 'com.powerdns.www' - 'com.powerdnsiscool' - 'com.usepowerdns.www' - - If we get a request to remove 'everything above powerdns.com', we do a search for 'com.powerdns' which is guaranteed to come first (it is shortest!) - Then we delete everything that is either equal to 'com.powerdns' or begins with 'com.powerdns.' This trailing dot saves us - from deleting 'com.powerdnsiscool'. - - We can stop the process once we reach something that doesn't match. - - Ok - fine so far, except it doesn't work! Let's say there *is* no 'com.powerdns' in cache! - - In that case our request doesn't find anything.. now what. - lower_bound to the rescue! It finds the place where 'com.powerdns' *would* be. - - Ok - next step, can we get away with simply reversing the string? - - 'moc.sndrewop' - 'moc.sndrewop.segami' - 'moc.sndrewop.www' - 'moc.loocsidnsrewop' - 'moc.dnsrewopesu.www' - - Ok - next step, can we get away with only reversing the comparison? - - 'powerdns.com' - 'images.powerdns.com' - ' www.powerdns.com' - 'powerdnsiscool.com' - 'www.userpowerdns.com' - - */ if(ends_with(match, "$")) { - string suffix(match); - suffix.resize(suffix.size()-1); + string prefix(match); + prefix.resize(prefix.size()-1); + + string zone = pcReverse(prefix); - cmap_t::const_iterator iter = d_map.lower_bound(tie(suffix)); + cmap_t::const_iterator iter = d_map.lower_bound(tie(zone)); cmap_t::const_iterator start=iter; - string dotsuffix = "."+suffix; for(; iter != d_map.end(); ++iter) { - if(!pdns_iequals(iter->qname, suffix) && !iends_with(iter->qname, dotsuffix)) { - // cerr<<"Stopping!"<qname.compare(0, zone.size(), zone)) { break; } delcount++; @@ -259,8 +216,10 @@ int PacketCache::purge(const string &match) d_map.erase(start, iter); } else { - delcount=d_map.count(tie(match)); - pair range = d_map.equal_range(tie(match)); + string qname = pcReverse(match); + + delcount=d_map.count(tie(qname)); + pair range = d_map.equal_range(tie(qname)); d_map.erase(range.first, range.second); } *d_statnumentries=d_map.size(); @@ -292,7 +251,8 @@ bool PacketCache::getEntryLocked(const string &qname, const QType& qtype, CacheE { uint16_t qt = qtype.getCode(); //cerr<<"Lookup for maxReplyLen: "<ttd > now); if(ret) { @@ -304,6 +264,14 @@ bool PacketCache::getEntryLocked(const string &qname, const QType& qtype, CacheE return ret; } + +string PacketCache::pcReverse(const string &content) +{ + string tmp = string(content.rbegin(), content.rend()); + return toLower(boost::replace_all_copy(tmp, ".", " "))+" "; +} + + map PacketCache::getCounts() { ReadLock l(&d_mut); diff --git a/pdns/packetcache.hh b/pdns/packetcache.hh index a447a8813..2121b44d5 100644 --- a/pdns/packetcache.hh +++ b/pdns/packetcache.hh @@ -47,24 +47,6 @@ using namespace ::boost::multi_index; first marks and then sweeps, a second lock is present to prevent simultaneous inserts and deletes. */ -struct CIBackwardsStringCompare: public std::binary_function -{ - bool operator()(const string& str_a, const string& str_b) const - { - string::const_reverse_iterator ra, rb; - char a=0, b=0; - for(ra = str_a.rbegin(), rb = str_b.rbegin(); - ra < str_a.rend() && rb < str_b.rend() && (a=dns_tolower(*ra)) == (b=dns_tolower(*rb)); - ra++, rb++); - - if (ra < str_a.rend() && rb==str_b.rend()) { a=*(ra++); b=0; return false; } // we are at the beginning of b -> b smaller - if (rb < str_b.rend() && ra==str_a.rend()) { b=*(rb++); a=0; return true; } // we are at the beginning of a -> a smaller - // if BOTH are at their ends, a and b will be equal, and we should return false, which we will - return a < b; - } -}; - - class PacketCache : public boost::noncopyable { public: @@ -90,6 +72,7 @@ public: private: bool getEntryLocked(const string &content, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1, bool meritsRecursion=false, unsigned int maxReplyLen=512, bool dnssecOk=false, bool hasEDNS=false, unsigned int *age=0); + string pcReverse(const string &content); struct CacheEntry { CacheEntry() { qtype = ctype = 0; zoneID = -1; meritsRecursion=false; dnssecOk=false; hasEDNS=false;} @@ -124,7 +107,7 @@ private: member, member >, - composite_key_compare, std::less, std::less, std::less, + composite_key_compare, std::less, std::less, std::less, std::less, std::less, std::less, std::less > >, sequenced<> -- 2.40.0