]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Continue evaluation of RPZ rules after passthru, taking
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 12 Feb 2020 14:35:12 +0000 (15:35 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 14 Feb 2020 12:39:15 +0000 (13:39 +0100)
into account RPZ priorities.

pdns/filterpo.cc
pdns/filterpo.hh
pdns/pdns_recursor.cc
pdns/recursordist/test-filterpo_cc.cc
pdns/syncres.cc

index a5e4705e17e2590c070be727284c2aaacbb72ad0..df195e4d482377a19e48337a7a5ef26264a67ad9 100644 (file)
@@ -115,13 +115,16 @@ bool DNSFilterEngine::Zone::findExactNamedPolicy(const std::unordered_map<DNSNam
   return false;
 }
 
-DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies) const
+DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies, Priority currentPriority) const
 {
   // cout<<"Got question for nameserver name "<<qname<<endl;
   std::vector<bool> zoneEnabled(d_zones.size());
   size_t count = 0;
   bool allEmpty = true;
   for (const auto& z : d_zones) {
+    if (z->getPriority() > currentPriority) {
+      break;
+    }
     bool enabled = true;
     const auto zoneName = z->getName();
     if (zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
@@ -155,11 +158,13 @@ DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qnam
 
   count = 0;
   for(const auto& z : d_zones) {
+    if (z->getPriority() > currentPriority) {
+      break;
+    }
     if (!zoneEnabled[count]) {
       ++count;
       continue;
     }
-
     if (z->findExactNSPolicy(qname, pol)) {
       // cerr<<"Had a hit on the nameserver ("<<qname<<") used to process the query"<<endl;
       return pol;
@@ -177,11 +182,14 @@ DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qnam
   return pol;
 }
 
-DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const ComboAddress& address, const std::unordered_map<std::string,bool>& discardedPolicies) const
+DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const ComboAddress& address, const std::unordered_map<std::string,bool>& discardedPolicies, Priority currentPriority) const
 {
   Policy pol;
   //  cout<<"Got question for nameserver IP "<<address.toString()<<endl;
   for(const auto& z : d_zones) {
+    if (z->getPriority() > currentPriority) {
+      break;
+    }
     const auto zoneName = z->getName();
     if(zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
       continue;
@@ -195,13 +203,16 @@ DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const ComboAddress&
   return pol;
 }
 
-DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, const ComboAddress& ca, const std::unordered_map<std::string,bool>& discardedPolicies) const
+DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, const ComboAddress& ca, const std::unordered_map<std::string,bool>& discardedPolicies, Priority currentPriority) const
 {
   // cout<<"Got question for "<<qname<<" from "<<ca.toString()<<endl;
   std::vector<bool> zoneEnabled(d_zones.size());
   size_t count = 0;
   bool allEmpty = true;
   for (const auto& z : d_zones) {
+    if (z->getPriority() > currentPriority) {
+      break;
+    }
     bool enabled = true;
     const auto zoneName = z->getName();
     if (zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
@@ -235,11 +246,13 @@ DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, co
 
   count = 0;
   for (const auto& z : d_zones) {
+    if (z->getPriority() > currentPriority) {
+      break;
+    }
     if (!zoneEnabled[count]) {
       ++count;
       continue;
     }
-
     if (z->findExactQNamePolicy(qname, pol)) {
       // cerr<<"Had a hit on the name of the query"<<endl;
       return pol;
@@ -263,7 +276,7 @@ DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, co
   return pol;
 }
 
-DNSFilterEngine::Policy DNSFilterEngine::getPostPolicy(const vector<DNSRecord>& records, const std::unordered_map<std::string,bool>& discardedPolicies) const
+DNSFilterEngine::Policy DNSFilterEngine::getPostPolicy(const vector<DNSRecord>& records, const std::unordered_map<std::string,bool>& discardedPolicies, Priority currentPriority) const
 {
   Policy pol;
   ComboAddress ca;
@@ -284,6 +297,9 @@ DNSFilterEngine::Policy DNSFilterEngine::getPostPolicy(const vector<DNSRecord>&
       continue;
 
     for (const auto& z : d_zones) {
+      if (z->getPriority() > currentPriority) {
+        break;
+      }
       const auto zoneName = z->getName();
       if (zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
         continue;
index fd2a3da267bd2ddcd63bedf1a36d9dd01c01d9c1..a75f291611a1a7086a60e1d3c4939025862f71dc 100644 (file)
@@ -26,6 +26,7 @@
 #include "dnsparser.hh"
 #include <map>
 #include <unordered_map>
+#include <limits>
 
 /* This class implements a filtering policy that is able to fully implement RPZ, but is not bound to it.
    In other words, it is generic enough to support RPZ, but could get its data from other places.
 class DNSFilterEngine
 {
 public:
-  enum class PolicyKind { NoAction, Drop, NXDOMAIN, NODATA, Truncate, Custom};
-  enum class PolicyType { None, QName, ClientIP, ResponseIP, NSDName, NSIP };
-
+  enum class PolicyKind : uint8_t { NoAction, Drop, NXDOMAIN, NODATA, Truncate, Custom};
+  enum class PolicyType : uint8_t { None, QName, ClientIP, ResponseIP, NSDName, NSIP };
+  typedef uint16_t Priority;
+  static const Priority maximumPriority = std::numeric_limits<Priority>::max();
+  
   static std::string getKindToString(PolicyKind kind);
   static std::string getTypeToString(PolicyType type);
 
   struct Policy
   {
-    Policy(): d_name(nullptr), d_kind(PolicyKind::NoAction), d_type(PolicyType::None), d_ttl(0)
+    Policy(): d_name(nullptr), d_ttl(0), d_priority(maximumPriority), d_kind(PolicyKind::NoAction), d_type(PolicyType::None)
     {
     }
 
-    Policy(PolicyKind kind, PolicyType type, int32_t ttl=0, std::shared_ptr<std::string> name=nullptr, const std::vector<std::shared_ptr<DNSRecordContent>>& custom={}): d_custom(custom), d_name(name), d_kind(kind), d_type(type), d_ttl(ttl)
+    Policy(PolicyKind kind, PolicyType type, int32_t ttl=0, std::shared_ptr<std::string> name=nullptr, const std::vector<std::shared_ptr<DNSRecordContent>>& custom={}): d_custom(custom), d_name(name), d_ttl(ttl), d_priority(maximumPriority), d_kind(kind), d_type(type)
     {
     }
 
@@ -90,14 +93,15 @@ public:
 
     std::vector<std::shared_ptr<DNSRecordContent>> d_custom;
     std::shared_ptr<std::string> d_name; // the name of the policy
-    PolicyKind d_kind;
-    PolicyType d_type;
     /* Yup, we are currently using the same TTL for every record for a given name */
     int32_t d_ttl;
+    Priority d_priority;
+    PolicyKind d_kind;
+    PolicyType d_type;
 
   private:
     DNSRecord getRecordFromCustom(const DNSName& qname, const std::shared_ptr<DNSRecordContent>& custom) const;
-};
+  };
 
   class Zone {
   public:
@@ -194,7 +198,12 @@ public:
     {
       return !d_postpolAddr.empty();
     }
-
+    Priority getPriority() const {
+      return d_priority;
+    }
+    void setPriority(Priority p) {
+      d_priority = p;
+    }
   private:
     static DNSName maskToRPZ(const Netmask& nm);
     static bool findExactNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol);
@@ -211,6 +220,7 @@ public:
     std::shared_ptr<std::string> d_name;
     uint32_t d_serial{0};
     uint32_t d_refresh{0};
+    Priority d_priority;
   };
 
   DNSFilterEngine();
@@ -244,6 +254,7 @@ public:
   }
   size_t addZone(std::shared_ptr<Zone> newZone)
   {
+    newZone->setPriority(d_zones.size());
     d_zones.push_back(newZone);
     return (d_zones.size() - 1);
   }
@@ -251,14 +262,15 @@ public:
   {
     if (newZone) {
       assureZones(zoneIdx);
+      newZone->setPriority(zoneIdx);
       d_zones[zoneIdx] = newZone;
     }
   }
 
-  Policy getQueryPolicy(const DNSName& qname, const ComboAddress& nm, const std::unordered_map<std::string,bool>& discardedPolicies) const;
-  Policy getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies) const;
-  Policy getProcessingPolicy(const ComboAddress& address, const std::unordered_map<std::string,bool>& discardedPolicies) const;
-  Policy getPostPolicy(const vector<DNSRecord>& records, const std::unordered_map<std::string,bool>& discardedPolicies) const;
+  Policy getQueryPolicy(const DNSName& qname, const ComboAddress& nm, const std::unordered_map<std::string,bool>& discardedPolicies, Priority Priority) const;
+  Policy getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies, Priority currentPriority) const;
+  Policy getProcessingPolicy(const ComboAddress& address, const std::unordered_map<std::string,bool>& discardedPolicies, Priority currentPriority) const;
+  Policy getPostPolicy(const vector<DNSRecord>& records, const std::unordered_map<std::string,bool>& discardedPolicies, Priority currentPriority) const;
 
   size_t size() const {
     return d_zones.size();
index ebfb3440a55872e28618b31e40ea3ab430e05ab9..001d6f2ada42137e0786866f8d546a7936048ab4 100644 (file)
@@ -1326,8 +1326,8 @@ static void startDoResolve(void *p)
     }
 
     // Check if the query has a policy attached to it
-    if (wantsRPZ && appliedPolicy.d_type == DNSFilterEngine::PolicyType::None) {
-      appliedPolicy = luaconfsLocal->dfe.getQueryPolicy(dc->d_mdp.d_qname, dc->d_source, sr.d_discardedPolicies);
+    if (wantsRPZ && (appliedPolicy.d_type == DNSFilterEngine::PolicyType::None || appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction)) {
+      appliedPolicy = luaconfsLocal->dfe.getQueryPolicy(dc->d_mdp.d_qname, dc->d_source, sr.d_discardedPolicies, appliedPolicy.d_priority);
     }
 
     // if there is a RecursorLua active, and it 'took' the query in preResolve, we don't launch beginResolve
@@ -1428,8 +1428,8 @@ static void startDoResolve(void *p)
         }
       }
 
-      if (wantsRPZ && appliedPolicy.d_type == DNSFilterEngine::PolicyType::None) {
-        appliedPolicy = luaconfsLocal->dfe.getPostPolicy(ret, sr.d_discardedPolicies);
+      if (wantsRPZ && (appliedPolicy.d_type == DNSFilterEngine::PolicyType::None || appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction)) {
+        appliedPolicy = luaconfsLocal->dfe.getPostPolicy(ret, sr.d_discardedPolicies, appliedPolicy.d_priority);
       }
 
       if(t_pdl) {
index a583aa68e49a3d4befac4ab850277ddf9f348f60..8ff22e0d8aaf1256f8c900887f9dc0582be0c094 100644 (file)
@@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
 
   {
     /* blocked NS name */
-    auto matchingPolicy = dfe.getProcessingPolicy(nsName, std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getProcessingPolicy(nsName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSDName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
 
@@ -71,19 +71,19 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     BOOST_CHECK(zonePolicy == matchingPolicy);
 
     /* but a subdomain should not be blocked (not a wildcard, and this is not suffix domain matching */
-    matchingPolicy = dfe.getProcessingPolicy(DNSName("sub") + nsName, std::unordered_map<std::string, bool>());
+    matchingPolicy = dfe.getProcessingPolicy(DNSName("sub") + nsName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
     BOOST_CHECK(zone->findExactNSPolicy(DNSName("sub") + nsName, zonePolicy) == false);
   }
 
   {
     /* blocked NS name via wildcard */
-    const auto matchingPolicy = dfe.getProcessingPolicy(DNSName("sub.sub.wildcard.wolf."), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getProcessingPolicy(DNSName("sub.sub.wildcard.wolf."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSDName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
 
     /* looking for wildcard.wolf. should not match *.wildcard-blocked. */
-    const auto notMatchingPolicy = dfe.getProcessingPolicy(DNSName("wildcard.wolf."), std::unordered_map<std::string, bool>());
+    const auto notMatchingPolicy = dfe.getProcessingPolicy(DNSName("wildcard.wolf."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(notMatchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
 
     /* a direct lookup would not match */
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
 
   {
     /* allowed NS name */
-    const auto matchingPolicy = dfe.getProcessingPolicy(DNSName("ns.bad.rabbit."), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getProcessingPolicy(DNSName("ns.bad.rabbit."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findExactNSPolicy(DNSName("ns.bad.rabbit."), zonePolicy) == false);
@@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
 
   {
     /* blocked NS IP */
-    const auto matchingPolicy = dfe.getProcessingPolicy(nsIP, std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getProcessingPolicy(nsIP, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSIP);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
     DNSFilterEngine::Policy zonePolicy;
@@ -114,7 +114,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
 
   {
     /* allowed NS IP */
-    const auto matchingPolicy = dfe.getProcessingPolicy(ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getProcessingPolicy(ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findNSIPPolicy(ComboAddress("192.0.2.142"), zonePolicy) == false);
@@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
 
   {
     /* blocked qname */
-    auto matchingPolicy = dfe.getQueryPolicy(blockedName, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getQueryPolicy(blockedName, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
     DNSFilterEngine::Policy zonePolicy;
@@ -130,19 +130,19 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     BOOST_CHECK(zonePolicy == matchingPolicy);
 
     /* but a subdomain should not be blocked (not a wildcard, and this is not suffix domain matching */
-    matchingPolicy = dfe.getQueryPolicy(DNSName("sub") + blockedName, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    matchingPolicy = dfe.getQueryPolicy(DNSName("sub") + blockedName, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
     BOOST_CHECK(zone->findExactQNamePolicy(DNSName("sub") + blockedName, zonePolicy) == false);
   }
 
   {
     /* blocked NS name via wildcard */
-    const auto matchingPolicy = dfe.getQueryPolicy(DNSName("sub.sub.wildcard-blocked."), ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(DNSName("sub.sub.wildcard-blocked."), ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
 
     /* looking for wildcard-blocked. should not match *.wildcard-blocked. */
-    const auto notMatchingPolicy = dfe.getQueryPolicy(DNSName("wildcard-blocked."), ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto notMatchingPolicy = dfe.getQueryPolicy(DNSName("wildcard-blocked."), ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(notMatchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
 
     /* a direct lookup would not match */
@@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
 
   {
     /* blocked client IP */
-    const auto matchingPolicy = dfe.getQueryPolicy(DNSName("totally.legit."), clientIP, std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(DNSName("totally.legit."), clientIP, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
     DNSFilterEngine::Policy zonePolicy;
@@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
 
   {
     /* not blocked */
-    const auto matchingPolicy = dfe.getQueryPolicy(DNSName("totally.legit."), ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(DNSName("totally.legit."), ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findClientPolicy(ComboAddress("192.0.2.142"), zonePolicy) == false);
@@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     DNSRecord dr;
     dr.d_type = QType::A;
     dr.d_content = DNSRecordContent::mastermake(QType::A, QClass::IN, responseIP.toString());
-    const auto matchingPolicy = dfe.getPostPolicy({dr}, std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getPostPolicy({dr}, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ResponseIP);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
     DNSFilterEngine::Policy zonePolicy;
@@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     DNSRecord dr;
     dr.d_type = QType::A;
     dr.d_content = DNSRecordContent::mastermake(QType::A, QClass::IN, "192.0.2.142");
-    const auto matchingPolicy = dfe.getPostPolicy({dr}, std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getPostPolicy({dr}, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findResponsePolicy(ComboAddress("192.0.2.142"), zonePolicy) == false);
@@ -246,14 +246,14 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_wildcard_with_enc)
 
   {
     const DNSName tstName("bcbsks.com.102.112.2o7.net.");
-    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction);
   }
 
   {
     const DNSName tstName("2o7.net.");
-    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
   }
@@ -263,28 +263,28 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_wildcard_with_enc)
 
   {
     const DNSName tstName("112.2o7.net.");
-    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_WARN_MESSAGE(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None, m);
     BOOST_WARN_MESSAGE(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction, m);
   }
 
   {
     const DNSName tstName("102.112.2o7.net.");
-    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_WARN_MESSAGE(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None, m);
     BOOST_WARN_MESSAGE(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction, m);
   }
 
   {
     const DNSName tstName("com.112.2o7.net.");
-    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_WARN_MESSAGE(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None, m);
     BOOST_WARN_MESSAGE(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction, m);
   }
 
   {
     const DNSName tstName("wcmatch.2o7.net.");
-    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>());
+    auto matchingPolicy = dfe.getQueryPolicy(tstName, address, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
   }
@@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_local_data)
 
   {
     /* exact type does not exist, but we have a CNAME */
-    const auto matchingPolicy = dfe.getQueryPolicy(bad1, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(bad1, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom);
     auto records = matchingPolicy.getCustomRecords(bad1, QType::A);
@@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_local_data)
 
   {
     /* exact type exists */
-    const auto matchingPolicy = dfe.getQueryPolicy(bad2, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(bad2, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom);
 
@@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_local_data)
 
   {
     /* exact type exists */
-    const auto matchingPolicy = dfe.getQueryPolicy(bad2, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(bad2, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom);
 
@@ -441,7 +441,7 @@ BOOST_AUTO_TEST_CASE(test_multiple_filter_policies)
 
   {
     /* zone 1 should match first */
-    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom);
     auto records = matchingPolicy.getCustomRecords(bad, QType::A);
@@ -456,7 +456,7 @@ BOOST_AUTO_TEST_CASE(test_multiple_filter_policies)
 
   {
     /* zone 2 has an exact match for badUnderWildcard, but the wildcard from the first zone should match first */
-    const auto matchingPolicy = dfe.getQueryPolicy(badUnderWildcard, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>());
+    const auto matchingPolicy = dfe.getQueryPolicy(badUnderWildcard, ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom);
     auto records = matchingPolicy.getCustomRecords(badUnderWildcard, QType::A);
@@ -471,7 +471,7 @@ BOOST_AUTO_TEST_CASE(test_multiple_filter_policies)
 
   {
     /* zone 1 should still match if zone 2 has been disabled */
-    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), {{*(zone2->getName()), true}});
+    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), {{*(zone2->getName()), true}}, DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom);
     auto records = matchingPolicy.getCustomRecords(bad, QType::A);
@@ -486,7 +486,7 @@ BOOST_AUTO_TEST_CASE(test_multiple_filter_policies)
 
   {
     /* if zone 1 is disabled, zone 2 should match */
-    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), {{*(zone1->getName()), true}});
+    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), {{*(zone1->getName()), true}}, DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom);
     auto records = matchingPolicy.getCustomRecords(bad, QType::A);
@@ -501,7 +501,7 @@ BOOST_AUTO_TEST_CASE(test_multiple_filter_policies)
 
   {
     /* if both zones are disabled, we should not match */
-    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), {{*(zone1->getName()), true}, {*(zone2->getName()), true}});
+    const auto matchingPolicy = dfe.getQueryPolicy(bad, ComboAddress("192.0.2.142"), {{*(zone1->getName()), true}, {*(zone2->getName()), true}}, DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None);
   }
 }
index 291fa394be4d5a91c59b10bf4b0bfad067d76e86..9c62b55485d856d9bfe3de55bd937750ad265c21 100644 (file)
@@ -1804,9 +1804,9 @@ bool SyncRes::nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& n
      the only way we can get back here is that it was a 'pass-thru' (NoAction) meaning that we should not
      process any further RPZ rules.
   */
-  if (d_wantsRPZ && d_appliedPolicy.d_type == DNSFilterEngine::PolicyType::None) {
+  if (d_wantsRPZ && (d_appliedPolicy.d_type == DNSFilterEngine::PolicyType::None || d_appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction)) {
     for (auto const &ns : nameservers) {
-      d_appliedPolicy = dfe.getProcessingPolicy(ns.first, d_discardedPolicies);
+      d_appliedPolicy = dfe.getProcessingPolicy(ns.first, d_discardedPolicies, d_appliedPolicy.d_priority);
       if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { // client query needs an RPZ response
         LOG(", however nameserver "<<ns.first<<" was blocked by RPZ policy '"<<(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")<<"'"<<endl);
         return true;
@@ -1814,7 +1814,7 @@ bool SyncRes::nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& n
 
       // Traverse all IP addresses for this NS to see if they have an RPN NSIP policy
       for (auto const &address : ns.second.first) {
-        d_appliedPolicy = dfe.getProcessingPolicy(address, d_discardedPolicies);
+        d_appliedPolicy = dfe.getProcessingPolicy(address, d_discardedPolicies, d_appliedPolicy.d_priority);
         if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { // client query needs an RPZ response
           LOG(", however nameserver "<<ns.first<<" IP address "<<address.toString()<<" was blocked by RPZ policy '"<<(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")<<"'"<<endl);
           return true;
@@ -1833,8 +1833,8 @@ bool SyncRes::nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAd
      the only way we can get back here is that it was a 'pass-thru' (NoAction) meaning that we should not
      process any further RPZ rules.
   */
-  if (d_wantsRPZ && d_appliedPolicy.d_type == DNSFilterEngine::PolicyType::None) {
-    d_appliedPolicy = dfe.getProcessingPolicy(remoteIP, d_discardedPolicies);
+  if (d_wantsRPZ && (d_appliedPolicy.d_type == DNSFilterEngine::PolicyType::None || d_appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction)) {
+    d_appliedPolicy = dfe.getProcessingPolicy(remoteIP, d_discardedPolicies, d_appliedPolicy.d_priority);
     if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) {
       LOG(" (blocked by RPZ policy '"+(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")+"')");
       return true;
@@ -3405,8 +3405,8 @@ bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qn
 
     nameservers.clear();
     for (auto const &nameserver : nsset) {
-      if (d_wantsRPZ && d_appliedPolicy.d_type == DNSFilterEngine::PolicyType::None) {
-        d_appliedPolicy = dfe.getProcessingPolicy(nameserver, d_discardedPolicies);
+      if (d_wantsRPZ && (d_appliedPolicy.d_type == DNSFilterEngine::PolicyType::None || d_appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction)) {
+        d_appliedPolicy = dfe.getProcessingPolicy(nameserver, d_discardedPolicies, d_appliedPolicy.d_priority);
         if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { // client query needs an RPZ response
           LOG("however "<<nameserver<<" was blocked by RPZ policy '"<<(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")<<"'"<<endl);
           throw PolicyHitException();