From 272e9a0034e8c5ea29d1ab7d24630424f178e926 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 7 Jun 2019 16:50:40 +0200 Subject: [PATCH] rec: Optimize for large number of filtering policies, empty sections --- pdns/filterpo.cc | 137 ++++++++++++++++++++++++++++++++++++++++------- pdns/filterpo.hh | 35 ++++++++++-- 2 files changed, 149 insertions(+), 23 deletions(-) diff --git a/pdns/filterpo.cc b/pdns/filterpo.cc index c3585ce03..bfca7b4d8 100644 --- a/pdns/filterpo.cc +++ b/pdns/filterpo.cc @@ -36,11 +36,21 @@ bool DNSFilterEngine::Zone::findQNamePolicy(const DNSName& qname, DNSFilterEngin return findNamedPolicy(d_qpolName, qname, pol); } +bool DNSFilterEngine::Zone::findExactQNamePolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const +{ + return findExactNamedPolicy(d_qpolName, qname, pol); +} + bool DNSFilterEngine::Zone::findNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const { return findNamedPolicy(d_propolName, qname, pol); } +bool DNSFilterEngine::Zone::findExactNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const +{ + return findExactNamedPolicy(d_propolName, qname, pol); +} + bool DNSFilterEngine::Zone::findNSIPPolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const { if (const auto fnd = d_propolNSAddr.lookup(addr)) { @@ -68,8 +78,12 @@ bool DNSFilterEngine::Zone::findClientPolicy(const ComboAddress& addr, DNSFilter return false; } -bool DNSFilterEngine::Zone::findNamedPolicy(const std::unordered_map& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol) const +bool DNSFilterEngine::Zone::findNamedPolicy(const std::unordered_map& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol) { + if (polmap.empty()) { + return false; + } + /* for www.powerdns.com, we need to check: www.powerdns.com. *.powerdns.com. @@ -96,21 +110,70 @@ bool DNSFilterEngine::Zone::findNamedPolicy(const std::unordered_map& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol) +{ + if (polmap.empty()) { + return false; + } + + const auto& it = polmap.find(qname); + if (it != polmap.end()) { + pol = it->second; + return true; + } + + return false; +} + DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies) const { - // cout<<"Got question for nameserver name "< zoneEnabled(d_zones.size()); + size_t count = 0; + bool allEmpty = true; + for (const auto& z : d_zones) { + bool enabled = true; const auto zoneName = z->getName(); - if(zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) { - continue; + if (zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) { + enabled = false; + } + else { + if (z->hasNSPolicies()) { + allEmpty = false; + } + else { + enabled = false; + } } - if(z->findNSPolicy(qname, pol)) { - // cerr<<"Had a hit on the nameserver ("<findNSPolicy(qname, pol)) { + // cerr<<"Had a hit on the nameserver ("<findNSPolicy(g_wildcarddnsname+s, pol)) { + // cerr<<"Had a hit on the nameserver ("<& discardedPolicies) const { // cout<<"Got question for "< zoneEnabled(d_zones.size()); + size_t count = 0; + bool allEmpty = true; + for (const auto& z : d_zones) { + bool enabled = true; const auto zoneName = z->getName(); - if(zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) { - continue; + if (zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) { + enabled = false; + } + else { + if (z->hasQNamePolicies()) { + allEmpty = false; + } + else { + enabled = false; + } } - if(z->findQNamePolicy(qname, pol)) { - // cerr<<"Had a hit on the name of the query"<findExactQNamePolicy(qname, pol)) { + // cerr<<"Had a hit on the name of the query"<findClientPolicy(ca, pol)) { + DNSName s(qname); + while(s.chopOff()){ + count = 0; + for(const auto& z : d_zones) { + if (zoneEnabled[count] && z->findExactQNamePolicy(g_wildcarddnsname+s, pol)) { + // cerr<<"Had a hit on the name of the query"<findClientPolicy(ca, pol)) { // cerr<<"Had a hit on the IP address ("< DNSFilterEngine::Policy::getRecords(const DNSName& qname) return result; } -void DNSFilterEngine::Zone::dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol) const +void DNSFilterEngine::Zone::dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol) { auto records = pol.getRecords(name); for (const auto& dr : records) { @@ -486,7 +585,7 @@ DNSName DNSFilterEngine::Zone::maskToRPZ(const Netmask& nm) } -void DNSFilterEngine::Zone::dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol) const +void DNSFilterEngine::Zone::dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol) { DNSName full = maskToRPZ(nm); full += name; diff --git a/pdns/filterpo.hh b/pdns/filterpo.hh index 3d5aea5d8..7aab1969d 100644 --- a/pdns/filterpo.hh +++ b/pdns/filterpo.hh @@ -152,7 +152,6 @@ public: size_t size() const { return d_qpolAddr.size() + d_postpolAddr.size() + d_propolName.size() + d_propolNSAddr.size() + d_qpolName.size(); - } void dump(FILE * fp) const; @@ -170,16 +169,40 @@ public: bool rmResponseTrigger(const Netmask& nm, const Policy& pol); bool findQNamePolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const; + bool findExactQNamePolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const; bool findNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const; + bool findExactNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const; bool findNSIPPolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const; bool findResponsePolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const; bool findClientPolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const; + bool hasClientPolicies() const + { + return !d_qpolAddr.empty(); + } + bool hasQNamePolicies() const + { + return !d_qpolName.empty(); + } + bool hasNSPolicies() const + { + return !d_propolName.empty(); + } + bool hasNSIPPolicies() const + { + return !d_propolNSAddr.empty(); + } + bool hasResponsePolicies() const + { + return !d_postpolAddr.empty(); + } + private: static DNSName maskToRPZ(const Netmask& nm); - bool findNamedPolicy(const std::unordered_map& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol) const; - void dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol) const; - void dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol) const; + static bool findExactNamedPolicy(const std::unordered_map& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol); + static bool findNamedPolicy(const std::unordered_map& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol); + static void dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol); + static void dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol); std::unordered_map d_qpolName; // QNAME trigger (RPZ) NetmaskTree d_qpolAddr; // Source address @@ -199,6 +222,10 @@ public: z->clear(); } } + void clearZones() + { + d_zones.clear(); + } const std::shared_ptr getZone(size_t zoneIdx) const { std::shared_ptr result{nullptr}; -- 2.40.0