]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: allocate hit data in policy on demand instead of always
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 26 Feb 2024 07:55:35 +0000 (08:55 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 26 Feb 2024 08:09:47 +0000 (09:09 +0100)
pdns/recursordist/filterpo.cc
pdns/recursordist/filterpo.hh
pdns/recursordist/lua-recursor4.cc
pdns/recursordist/pdns_recursor.cc
pdns/recursordist/test-filterpo_cc.cc

index f73b95d54d3437e756d4df439531b99b92bfcb48..1fbf8673761e4326aa78b71b13a994452bc13383 100644 (file)
@@ -50,8 +50,8 @@ bool DNSFilterEngine::Zone::findExactQNamePolicy(const DNSName& qname, DNSFilter
 bool DNSFilterEngine::Zone::findExactNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const
 {
   if (findExactNamedPolicy(d_propolName, qname, pol)) {
-    pol.d_trigger = qname;
-    pol.d_trigger.appendRawLabel(rpzNSDnameName);
+    // hitdata set by findExactNamedPolicy
+    pol.d_hitdata->d_trigger.appendRawLabel(rpzNSDnameName);
     return true;
   }
   return false;
@@ -61,9 +61,8 @@ bool DNSFilterEngine::Zone::findNSIPPolicy(const ComboAddress& addr, DNSFilterEn
 {
   if (const auto* fnd = d_propolNSAddr.lookup(addr)) {
     pol = fnd->second;
-    pol.d_trigger = Zone::maskToRPZ(fnd->first);
-    pol.d_trigger.appendRawLabel(rpzNSIPName);
-    pol.d_hit = addr.toString();
+    pol.setHitData(Zone::maskToRPZ(fnd->first), addr.toString());
+    pol.d_hitdata->d_trigger.appendRawLabel(rpzNSIPName);
     return true;
   }
   return false;
@@ -73,9 +72,8 @@ bool DNSFilterEngine::Zone::findResponsePolicy(const ComboAddress& addr, DNSFilt
 {
   if (const auto* fnd = d_postpolAddr.lookup(addr)) {
     pol = fnd->second;
-    pol.d_trigger = Zone::maskToRPZ(fnd->first);
-    pol.d_trigger.appendRawLabel(rpzIPName);
-    pol.d_hit = addr.toString();
+    pol.setHitData(Zone::maskToRPZ(fnd->first), addr.toString());
+    pol.d_hitdata->d_trigger.appendRawLabel(rpzIPName);
     return true;
   }
   return false;
@@ -85,9 +83,8 @@ bool DNSFilterEngine::Zone::findClientPolicy(const ComboAddress& addr, DNSFilter
 {
   if (const auto* fnd = d_qpolAddr.lookup(addr)) {
     pol = fnd->second;
-    pol.d_trigger = Zone::maskToRPZ(fnd->first);
-    pol.d_trigger.appendRawLabel(rpzClientIPName);
-    pol.d_hit = addr.toString();
+    pol.setHitData(Zone::maskToRPZ(fnd->first), addr.toString());
+    pol.d_hitdata->d_trigger.appendRawLabel(rpzClientIPName);
     return true;
   }
   return false;
@@ -119,8 +116,7 @@ bool DNSFilterEngine::Zone::findNamedPolicy(const std::unordered_map<DNSName, DN
     iter = polmap.find(g_wildcarddnsname + sub);
     if (iter != polmap.end()) {
       pol = iter->second;
-      pol.d_trigger = iter->first;
-      pol.d_hit = qname.toStringNoDot();
+      pol.setHitData(iter->first, qname.toStringNoDot());
       return true;
     }
   }
@@ -136,8 +132,7 @@ bool DNSFilterEngine::Zone::findExactNamedPolicy(const std::unordered_map<DNSNam
   const auto iter = polmap.find(qname);
   if (iter != polmap.end()) {
     pol = iter->second;
-    pol.d_trigger = qname;
-    pol.d_hit = qname.toStringNoDot();
+    pol.setHitData(qname, qname.toStringNoDot());
     return true;
   }
 
@@ -196,7 +191,7 @@ bool DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unord
       if (zone->findExactNSPolicy(wildcard, pol)) {
         // cerr<<"Had a hit on the nameserver ("<<qname<<") used to process the query"<<endl;
         // Hit is not the wildcard passed to findExactQNamePolicy but the actual qname!
-        pol.d_hit = qname.toStringNoDot();
+        pol.d_hitdata->d_hit = qname.toStringNoDot();
         return true;
       }
     }
@@ -304,7 +299,7 @@ bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_
       if (zone->findExactQNamePolicy(wildcard, pol)) {
         // cerr<<"Had a hit on the name of the query"<<endl;
         // Hit is not the wildcard passed to findExactQNamePolicy but the actual qname!
-        pol.d_hit = qname.toStringNoDot();
+        pol.d_hitdata->d_hit = qname.toStringNoDot();
         return true;
       }
     }
@@ -558,13 +553,13 @@ bool DNSFilterEngine::Zone::rmNSIPTrigger(const Netmask& netmask, const Policy&
 
 std::string DNSFilterEngine::Policy::getLogString() const
 {
-  return ": RPZ Hit; PolicyName=" + getName() + "; Trigger=" + d_trigger.toLogString() + "; Hit=" + d_hit + "; Type=" + getTypeToString(d_type) + "; Kind=" + getKindToString(d_kind);
+  return ": RPZ Hit; PolicyName=" + getName() + "; Trigger=" + getTrigger().toLogString() + "; Hit=" + getHit() + "; Type=" + getTypeToString(d_type) + "; Kind=" + getKindToString(d_kind);
 }
 
 void DNSFilterEngine::Policy::info(Logr::Priority prio, const std::shared_ptr<Logr::Logger>& log) const
 {
-  log->info(prio, "RPZ Hit", "policyName", Logging::Loggable(getName()), "trigger", Logging::Loggable(d_trigger),
-            "hit", Logging::Loggable(d_hit), "type", Logging::Loggable(getTypeToString(d_type)),
+  log->info(prio, "RPZ Hit", "policyName", Logging::Loggable(getName()), "trigger", Logging::Loggable(getTrigger()),
+            "hit", Logging::Loggable(getHit()), "type", Logging::Loggable(getTypeToString(d_type)),
             "kind", Logging::Loggable(getKindToString(d_kind)));
 }
 
index 7d20b7a387127d80a9895f96b5f44a4c6df51e0d..f91858ac8ed8d0e634e74cb373ebf6ba4facbb42 100644 (file)
@@ -117,6 +117,39 @@ public:
     {
     }
 
+    ~Policy() = default;
+
+    Policy(const Policy& rhs) :
+      d_custom(rhs.d_custom),
+      d_zoneData(rhs.d_zoneData),
+      d_hitdata(rhs.d_hitdata ? make_unique<HitData>(*rhs.d_hitdata) : nullptr),
+      d_ttl(rhs.d_ttl),
+      d_kind(rhs.d_kind),
+      d_type(rhs.d_type)
+    {
+    }
+
+    Policy& operator=(const Policy& rhs)
+    {
+      if (this != &rhs) {
+        d_custom = rhs.d_custom;
+        d_zoneData = rhs.d_zoneData;
+        if (rhs.d_hitdata) {
+          d_hitdata = make_unique<HitData>(*rhs.d_hitdata);
+        }
+        else {
+          d_hitdata = nullptr;
+        }
+        d_ttl = rhs.d_ttl;
+        d_kind = rhs.d_kind;
+        d_type = rhs.d_type;
+      }
+      return *this;
+    }
+
+    Policy(Policy&&) = default;
+    Policy& operator=(Policy&&) = default;
+
     bool operator==(const Policy& rhs) const
     {
       return d_kind == rhs.d_kind && d_type == rhs.d_type && d_ttl == rhs.d_ttl && d_custom == rhs.d_custom;
@@ -201,8 +234,12 @@ public:
 
     std::vector<std::shared_ptr<const DNSRecordContent>> d_custom;
     std::shared_ptr<PolicyZoneData> d_zoneData{nullptr};
-    DNSName d_trigger;
-    string d_hit;
+    struct HitData
+    {
+      DNSName d_trigger;
+      string d_hit;
+    };
+    std::unique_ptr<HitData> d_hitdata;
     /* Yup, we are currently using the same TTL for every record for a given name */
     int32_t d_ttl;
     PolicyKind d_kind;
@@ -217,6 +254,22 @@ public:
       }
     }
 
+    void setHitData(const DNSName& name, const string& hit)
+    {
+      HitData hitdata{name, hit};
+      d_hitdata = make_unique<HitData>(hitdata);
+    }
+
+    [[nodiscard]] DNSName getTrigger() const
+    {
+      return d_hitdata ? d_hitdata->d_trigger : DNSName();
+    }
+
+    [[nodiscard]] std::string getHit() const
+    {
+      return d_hitdata ? d_hitdata->d_hit : "";
+    }
+
   private:
     [[nodiscard]] DNSRecord getRecordFromCustom(const DNSName& qname, const std::shared_ptr<const DNSRecordContent>& custom) const;
   };
index 0a381b2b890b406168cba35f5ecbe36d3f0f6567..8062cb9061be20ee49f812ceebeb0b59b2d8ad3c 100644 (file)
@@ -218,8 +218,20 @@ void RecursorLua4::postPrepareContext()
   d_lw->registerMember("policyKind", &DNSFilterEngine::Policy::d_kind);
   d_lw->registerMember("policyType", &DNSFilterEngine::Policy::d_type);
   d_lw->registerMember("policyTTL", &DNSFilterEngine::Policy::d_ttl);
-  d_lw->registerMember("policyTrigger", &DNSFilterEngine::Policy::d_trigger);
-  d_lw->registerMember("policyHit", &DNSFilterEngine::Policy::d_hit);
+  d_lw->registerMember<DNSFilterEngine::Policy, DNSName>("policyTrigger",
+    [](const DNSFilterEngine::Policy& pol) {
+      return pol.getTrigger();
+    },
+    [](DNSFilterEngine::Policy& pol, const DNSName& dnsname) {
+      pol.setHitData(dnsname, pol.getHit());
+    });
+  d_lw->registerMember<DNSFilterEngine::Policy, std::string>("policyHit",
+    [](const DNSFilterEngine::Policy& pol) {
+      return pol.getHit();
+    },
+    [](DNSFilterEngine::Policy& pol, const std::string& hit) {
+      pol.setHitData(pol.getTrigger(), hit);
+    });
   d_lw->registerMember<DNSFilterEngine::Policy, std::string>("policyCustom",
     [](const DNSFilterEngine::Policy& pol) -> std::string {
       std::string result;
index 5071a38787c5ee4b1351d2f0430dd2d5354292e2..87135c81e3de9b6e89931b04ade906f5cf8e794f 100644 (file)
@@ -1713,8 +1713,8 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi
       if (!appliedPolicy.getName().empty()) {
         pbMessage.setAppliedPolicy(appliedPolicy.getName());
         pbMessage.setAppliedPolicyType(appliedPolicy.d_type);
-        pbMessage.setAppliedPolicyTrigger(appliedPolicy.d_trigger);
-        pbMessage.setAppliedPolicyHit(appliedPolicy.d_hit);
+        pbMessage.setAppliedPolicyTrigger(appliedPolicy.getTrigger());
+        pbMessage.setAppliedPolicyHit(appliedPolicy.getHit());
         pbMessage.setAppliedPolicyKind(appliedPolicy.d_kind);
       }
       pbMessage.setInBytes(packet.size());
index f91abdf07570c89d73be16d58235540ee3572da6..2981471f4012c25b7f91a22fd0592c559c9eda20 100644 (file)
@@ -84,8 +84,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     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);
-    BOOST_CHECK_EQUAL(matchingPolicy.d_trigger, DNSName("*.wildcard.wolf.rpz-nsdname"));
-    BOOST_CHECK_EQUAL(matchingPolicy.d_hit, "sub.sub.wildcard.wolf");
+    BOOST_CHECK_EQUAL(matchingPolicy.d_hitdata->d_trigger, DNSName("*.wildcard.wolf.rpz-nsdname"));
+    BOOST_CHECK_EQUAL(matchingPolicy.d_hitdata->d_hit, "sub.sub.wildcard.wolf");
 
     /* looking for wildcard.wolf. should not match *.wildcard-blocked. */
     const auto notMatchingPolicy = dfe.getProcessingPolicy(DNSName("wildcard.wolf."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
@@ -97,8 +97,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     /* except if we look exactly for the wildcard */
     BOOST_CHECK(zone->findExactNSPolicy(nsWildcardName, zonePolicy));
     BOOST_CHECK(zonePolicy == matchingPolicy);
-    BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("*.wildcard.wolf.rpz-nsdname"));
-    BOOST_CHECK_EQUAL(zonePolicy.d_hit, nsWildcardName.toStringNoDot());
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_trigger, DNSName("*.wildcard.wolf.rpz-nsdname"));
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_hit, nsWildcardName.toStringNoDot());
   }
 
   {
@@ -117,8 +117,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findNSIPPolicy(nsIP, zonePolicy));
     BOOST_CHECK(zonePolicy == matchingPolicy);
-    BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("31.0.2.0.192.rpz-nsip"));
-    BOOST_CHECK_EQUAL(zonePolicy.d_hit, nsIP.toString());
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_trigger, DNSName("31.0.2.0.192.rpz-nsip"));
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_hit, nsIP.toString());
   }
 
   {
@@ -137,8 +137,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findExactQNamePolicy(blockedName, zonePolicy));
     BOOST_CHECK(zonePolicy == matchingPolicy);
-    BOOST_CHECK_EQUAL(zonePolicy.d_trigger, blockedName);
-    BOOST_CHECK_EQUAL(zonePolicy.d_hit, blockedName.toStringNoDot());
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_trigger, blockedName);
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_hit, blockedName.toStringNoDot());
 
     /* but a subdomain should not be blocked (not a wildcard, and this is not suffix domain matching */
     matchingPolicy = dfe.getQueryPolicy(DNSName("sub") + blockedName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
@@ -151,8 +151,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     const auto matchingPolicy = dfe.getQueryPolicy(DNSName("sub.sub.wildcard-blocked."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
     BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName);
     BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop);
-    BOOST_CHECK_EQUAL(matchingPolicy.d_trigger, blockedWildcardName);
-    BOOST_CHECK_EQUAL(matchingPolicy.d_hit, "sub.sub.wildcard-blocked");
+    BOOST_CHECK_EQUAL(matchingPolicy.d_hitdata->d_trigger, blockedWildcardName);
+    BOOST_CHECK_EQUAL(matchingPolicy.d_hitdata->d_hit, "sub.sub.wildcard-blocked");
 
     /* looking for wildcard-blocked. should not match *.wildcard-blocked. */
     const auto notMatchingPolicy = dfe.getQueryPolicy(DNSName("wildcard-blocked."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority);
@@ -164,8 +164,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     /* except if we look exactly for the wildcard */
     BOOST_CHECK(zone->findExactQNamePolicy(blockedWildcardName, zonePolicy));
     BOOST_CHECK(zonePolicy == matchingPolicy);
-    BOOST_CHECK_EQUAL(zonePolicy.d_trigger, blockedWildcardName);
-    BOOST_CHECK_EQUAL(zonePolicy.d_hit, blockedWildcardName.toStringNoDot());
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_trigger, blockedWildcardName);
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_hit, blockedWildcardName.toStringNoDot());
   }
 
   {
@@ -176,8 +176,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findClientPolicy(clientIP, zonePolicy));
     BOOST_CHECK(zonePolicy == matchingPolicy);
-    BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("31.128.2.0.192.rpz-client-ip"));
-    BOOST_CHECK_EQUAL(zonePolicy.d_hit, clientIP.toString());
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_trigger, DNSName("31.128.2.0.192.rpz-client-ip"));
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_hit, clientIP.toString());
   }
 
   {
@@ -200,8 +200,8 @@ BOOST_AUTO_TEST_CASE(test_filter_policies_basic)
     DNSFilterEngine::Policy zonePolicy;
     BOOST_CHECK(zone->findResponsePolicy(responseIP, zonePolicy));
     BOOST_CHECK(zonePolicy == matchingPolicy);
-    BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("31.254.2.0.192.rpz-ip"));
-    BOOST_CHECK_EQUAL(zonePolicy.d_hit, responseIP.toString());
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_trigger, DNSName("31.254.2.0.192.rpz-ip"));
+    BOOST_CHECK_EQUAL(zonePolicy.d_hitdata->d_hit, responseIP.toString());
   }
 
   {