From: Otto Moerbeek Date: Mon, 26 Feb 2024 07:55:35 +0000 (+0100) Subject: rec: allocate hit data in policy on demand instead of always X-Git-Tag: auth-5.0.0-alpha0~2^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba8fe6b141341b89b861b3ca09f717ff0aea329a;p=thirdparty%2Fpdns.git rec: allocate hit data in policy on demand instead of always --- diff --git a/pdns/recursordist/filterpo.cc b/pdns/recursordist/filterpo.cc index f73b95d54d..1fbf867376 100644 --- a/pdns/recursordist/filterpo.cc +++ b/pdns/recursordist/filterpo.cc @@ -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_mapsecond; - 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_mapsecond; - 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 ("<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"<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& 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))); } diff --git a/pdns/recursordist/filterpo.hh b/pdns/recursordist/filterpo.hh index 7d20b7a387..f91858ac8e 100644 --- a/pdns/recursordist/filterpo.hh +++ b/pdns/recursordist/filterpo.hh @@ -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(*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(*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> d_custom; std::shared_ptr d_zoneData{nullptr}; - DNSName d_trigger; - string d_hit; + struct HitData + { + DNSName d_trigger; + string d_hit; + }; + std::unique_ptr 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); + } + + [[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& custom) const; }; diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index 0a381b2b89..8062cb9061 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -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("policyTrigger", + [](const DNSFilterEngine::Policy& pol) { + return pol.getTrigger(); + }, + [](DNSFilterEngine::Policy& pol, const DNSName& dnsname) { + pol.setHitData(dnsname, pol.getHit()); + }); + d_lw->registerMember("policyHit", + [](const DNSFilterEngine::Policy& pol) { + return pol.getHit(); + }, + [](DNSFilterEngine::Policy& pol, const std::string& hit) { + pol.setHitData(pol.getTrigger(), hit); + }); d_lw->registerMember("policyCustom", [](const DNSFilterEngine::Policy& pol) -> std::string { std::string result; diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 5071a38787..87135c81e3 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -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()); diff --git a/pdns/recursordist/test-filterpo_cc.cc b/pdns/recursordist/test-filterpo_cc.cc index f91abdf075..2981471f40 100644 --- a/pdns/recursordist/test-filterpo_cc.cc +++ b/pdns/recursordist/test-filterpo_cc.cc @@ -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(), 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(), 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(), 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(), 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(), 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()); } {