Permalink
Browse files

reversed packetcache 'powerdns.com' -> 'moc sndrewop '

  • Loading branch information...
1 parent 829d948 commit 801812e69aa370d3cd78a8bb073ef28164f63c1d @mind04 mind04 committed with mind04 Jul 31, 2014
Showing with 23 additions and 72 deletions.
  1. +21 −53 pdns/packetcache.cc
  2. +2 −19 pdns/packetcache.hh
View
@@ -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,69 +198,28 @@ 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!"<<endl;
+ if(!iter->qname.compare(0, zone.size(), zone)) {
break;
}
delcount++;
}
d_map.erase(start, iter);
}
else {
- delcount=d_map.count(tie(match));
- pair<cmap_t::iterator, cmap_t::iterator> range = d_map.equal_range(tie(match));
+ string qname = pcReverse(match);
+
+ delcount=d_map.count(tie(qname));
+ pair<cmap_t::iterator, cmap_t::iterator> 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: "<<maxReplyLen<<endl;
- cmap_t::const_iterator i=d_map.find(tie(qname, qt, cet, zoneID, meritsRecursion, maxReplyLen, dnssecOK, hasEDNS, *age));
+ string pcqname = pcReverse(qname);
+ cmap_t::const_iterator i=d_map.find(tie(pcqname, qt, cet, zoneID, meritsRecursion, maxReplyLen, dnssecOK, hasEDNS, *age));
time_t now=time(0);
bool ret=(i!=d_map.end() && i->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<char,int> PacketCache::getCounts()
{
ReadLock l(&d_mut);
View
@@ -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<string, string, bool>
-{
- 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<CacheEntry,bool, &CacheEntry::dnssecOk>,
member<CacheEntry,bool, &CacheEntry::hasEDNS>
>,
- composite_key_compare<CIBackwardsStringCompare, std::less<uint16_t>, std::less<uint16_t>, std::less<int>, std::less<bool>,
+ composite_key_compare<std::less<string>, std::less<uint16_t>, std::less<uint16_t>, std::less<int>, std::less<bool>,
std::less<unsigned int>, std::less<bool>, std::less<bool> >
>,
sequenced<>

0 comments on commit 801812e

Please sign in to comment.