From: Remi Gacogne Date: Thu, 6 Oct 2016 10:15:32 +0000 (+0200) Subject: Move SuffixMatchTree from dnsdist.hh to dnsname.hh X-Git-Tag: dnsdist-1.1.0-beta2~6^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40ea5b5b55cf7ba63d17e95ff7205deac2a222f9;p=thirdparty%2Fpdns.git Move SuffixMatchTree from dnsdist.hh to dnsname.hh --- diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index e6132997e9..dbbfb3d83a 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -554,100 +554,6 @@ enum ednsHeaderFlags { EDNS_HEADER_FLAG_DO = 32768 }; -/* Quest in life: serve as a rapid block list. If you add a DNSName to a root SuffixMatchNode, - anything part of that domain will return 'true' in check */ -template -struct SuffixMatchTree -{ - SuffixMatchTree(const std::string& name_="", bool endNode_=false) : name(name_), endNode(endNode_) - {} - - SuffixMatchTree(const SuffixMatchTree& rhs) - { - name = rhs.name; - d_human = rhs.d_human; - children = rhs.children; - endNode = rhs.endNode; - d_value = rhs.d_value; - } - std::string name; - std::string d_human; - mutable std::set children; - mutable bool endNode; - mutable T d_value; - bool operator<(const SuffixMatchTree& rhs) const - { - return strcasecmp(name.c_str(), rhs.name.c_str()) < 0; - } - typedef SuffixMatchTree value_type; - - template - void visit(const V& v) const { - for(const auto& c : children) - c.visit(v); - if(endNode) - v(*this); - } - - void add(const DNSName& name, const T& t) - { - add(name.getRawLabels(), t); - } - - void add(std::vector labels, const T& value) const - { - if(labels.empty()) { // this allows insertion of the root - endNode=true; - d_value=value; - } - else if(labels.size()==1) { - SuffixMatchTree newChild(*labels.begin(), true); - newChild.d_value=value; - children.insert(newChild); - } - else { - SuffixMatchTree newnode(*labels.rbegin(), false); - auto res=children.insert(newnode); - if(!res.second) { - children.erase(newnode); - res=children.insert(newnode); - } - labels.pop_back(); - res.first->add(labels, value); - } - } - - T* lookup(const DNSName& name) const - { - if(children.empty()) { // speed up empty set - if(endNode) - return &d_value; - return 0; - } - return lookup(name.getRawLabels()); - } - - T* lookup(std::vector labels) const - { - if(labels.empty()) { // optimization - if(endNode) - return &d_value; - return 0; - } - - SuffixMatchTree smn(*labels.rbegin()); - auto child = children.find(smn); - if(child == children.end()) { - if(endNode) - return &d_value; - return 0; - } - labels.pop_back(); - return child->lookup(labels); - } - -}; - extern GlobalStateHolder> g_dynblockSMT; extern GlobalStateHolder > g_carbon; diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index 7a668068a9..f951dfaf15 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -292,6 +292,98 @@ struct SuffixMatchNode }; +template +struct SuffixMatchTree +{ + SuffixMatchTree(const std::string& name_="", bool endNode_=false) : name(name_), endNode(endNode_) + {} + + SuffixMatchTree(const SuffixMatchTree& rhs) + { + name = rhs.name; + d_human = rhs.d_human; + children = rhs.children; + endNode = rhs.endNode; + d_value = rhs.d_value; + } + std::string name; + std::string d_human; + mutable std::set children; + mutable bool endNode; + mutable T d_value; + bool operator<(const SuffixMatchTree& rhs) const + { + return strcasecmp(name.c_str(), rhs.name.c_str()) < 0; + } + typedef SuffixMatchTree value_type; + + template + void visit(const V& v) const { + for(const auto& c : children) + c.visit(v); + if(endNode) + v(*this); + } + + void add(const DNSName& name, const T& t) + { + add(name.getRawLabels(), t); + } + + void add(std::vector labels, const T& value) const + { + if(labels.empty()) { // this allows insertion of the root + endNode=true; + d_value=value; + } + else if(labels.size()==1) { + SuffixMatchTree newChild(*labels.begin(), true); + newChild.d_value=value; + children.insert(newChild); + } + else { + SuffixMatchTree newnode(*labels.rbegin(), false); + auto res=children.insert(newnode); + if(!res.second) { + children.erase(newnode); + res=children.insert(newnode); + } + labels.pop_back(); + res.first->add(labels, value); + } + } + + T* lookup(const DNSName& name) const + { + if(children.empty()) { // speed up empty set + if(endNode) + return &d_value; + return 0; + } + return lookup(name.getRawLabels()); + } + + T* lookup(std::vector labels) const + { + if(labels.empty()) { // optimization + if(endNode) + return &d_value; + return 0; + } + + SuffixMatchTree smn(*labels.rbegin()); + auto child = children.find(smn); + if(child == children.end()) { + if(endNode) + return &d_value; + return 0; + } + labels.pop_back(); + return child->lookup(labels); + } + +}; + std::ostream & operator<<(std::ostream &os, const DNSName& d); namespace std { template <>