From: Ensar Sarajčić Date: Mon, 29 Dec 2025 10:45:36 +0000 (+0100) Subject: dnsdist: store clear flag in EDNS EDE X-Git-Tag: rec-5.4.0-beta1~68^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4d29280d1a6b239a0ed831b3dba13bd6a245fc1;p=thirdparty%2Fpdns.git dnsdist: store clear flag in EDNS EDE This allows more control over which ENDS EDE entries will be kept (e.g. clear on first one, to delete existing data and then add additional codes on top of that). Signed-off-by: Ensar Sarajčić --- diff --git a/pdns/dnsdistdist/dnsdist-actions-factory.cc b/pdns/dnsdistdist/dnsdist-actions-factory.cc index 47f5d1729f..4a7b02f99f 100644 --- a/pdns/dnsdistdist/dnsdist-actions-factory.cc +++ b/pdns/dnsdistdist/dnsdist-actions-factory.cc @@ -2393,17 +2393,17 @@ class SetExtendedDNSErrorAction : public DNSAction { public: // this action does not stop the processing - SetExtendedDNSErrorAction(uint16_t infoCode, const std::string& extraText, bool clearExistingEntries) : - d_clearExistingEntries(clearExistingEntries) + SetExtendedDNSErrorAction(uint16_t infoCode, const std::string& extraText, bool clearExistingEntries) { d_ede.infoCode = infoCode; d_ede.extraText = extraText; + d_ede.clearExisting = clearExistingEntries; } DNSAction::Action operator()(DNSQuestion* dnsQuestion, std::string* ruleresult) const override { (void)ruleresult; - if (d_clearExistingEntries) { + if (d_ede.clearExisting) { dnsQuestion->ids.d_extendedErrors = std::make_unique>(std::initializer_list({d_ede})); } else { @@ -2425,24 +2425,23 @@ public: private: EDNSExtendedError d_ede; - bool d_clearExistingEntries; }; class SetExtendedDNSErrorResponseAction : public DNSResponseAction { public: // this action does not stop the processing - SetExtendedDNSErrorResponseAction(uint16_t infoCode, const std::string& extraText, bool clearExistingEntries) : - d_clearExistingEntries(clearExistingEntries) + SetExtendedDNSErrorResponseAction(uint16_t infoCode, const std::string& extraText, bool clearExistingEntries) { d_ede.infoCode = infoCode; d_ede.extraText = extraText; + d_ede.clearExisting = clearExistingEntries; } DNSResponseAction::Action operator()(DNSResponse* dnsResponse, std::string* ruleresult) const override { (void)ruleresult; - if (d_clearExistingEntries) { + if (d_ede.clearExisting) { dnsResponse->ids.d_extendedErrors = std::make_unique>(std::initializer_list({d_ede})); } else { @@ -2464,7 +2463,6 @@ public: private: EDNSExtendedError d_ede; - bool d_clearExistingEntries; }; class LimitTTLResponseAction : public DNSResponseAction, public boost::noncopyable diff --git a/pdns/dnsdistdist/dnsdist-edns.cc b/pdns/dnsdistdist/dnsdist-edns.cc index 953b934857..807c08468b 100644 --- a/pdns/dnsdistdist/dnsdist-edns.cc +++ b/pdns/dnsdistdist/dnsdist-edns.cc @@ -57,7 +57,7 @@ std::pair, std::optional> getExtendedDNSErr return {infoCode, std::move(extraText)}; } -bool addExtendedDNSError(PacketBuffer& packet, size_t maximumPacketSize, uint16_t code, const std::string& extraStatus) +bool addExtendedDNSError(PacketBuffer& packet, size_t maximumPacketSize, uint16_t code, const std::string& extraStatus, bool clearExisting) { uint16_t optStart = 0; size_t optLen = 0; @@ -80,7 +80,7 @@ bool addExtendedDNSError(PacketBuffer& packet, size_t maximumPacketSize, uint16_ PacketBuffer newContent; bool ednsAdded = false; bool edeAdded = false; - if (!slowRewriteEDNSOptionInQueryWithRecords(packet, newContent, ednsAdded, EDNSOptionCode::EXTENDEDERROR, edeAdded, false, true, edeOption)) { + if (!slowRewriteEDNSOptionInQueryWithRecords(packet, newContent, ednsAdded, EDNSOptionCode::EXTENDEDERROR, edeAdded, clearExisting, !clearExisting, edeOption)) { return false; } diff --git a/pdns/dnsdistdist/dnsdist-edns.hh b/pdns/dnsdistdist/dnsdist-edns.hh index 8e60e5b049..1fdb9b5adc 100644 --- a/pdns/dnsdistdist/dnsdist-edns.hh +++ b/pdns/dnsdistdist/dnsdist-edns.hh @@ -30,5 +30,5 @@ namespace dnsdist::edns { std::pair, std::optional> getExtendedDNSError(const PacketBuffer& packet); -bool addExtendedDNSError(PacketBuffer& packet, size_t maximumPacketSize, uint16_t code, const std::string& extraStatus); +bool addExtendedDNSError(PacketBuffer& packet, size_t maximumPacketSize, uint16_t code, const std::string& extraStatus, bool clearExisting); } diff --git a/pdns/dnsdistdist/dnsdist-tcp.cc b/pdns/dnsdistdist/dnsdist-tcp.cc index 383f5570fb..b65fe109ab 100644 --- a/pdns/dnsdistdist/dnsdist-tcp.cc +++ b/pdns/dnsdistdist/dnsdist-tcp.cc @@ -1396,7 +1396,7 @@ static bool processXFRResponse(DNSResponse& dnsResponse) if (dnsResponse.ids.d_extendedErrors) { for (auto ede : *dnsResponse.ids.d_extendedErrors) { - dnsdist::edns::addExtendedDNSError(dnsResponse.getMutableData(), dnsResponse.getMaximumSize(), ede.infoCode, ede.extraText); + dnsdist::edns::addExtendedDNSError(dnsResponse.getMutableData(), dnsResponse.getMaximumSize(), ede.infoCode, ede.extraText, ede.clearExisting); } } diff --git a/pdns/dnsdistdist/dnsdist.cc b/pdns/dnsdistdist/dnsdist.cc index e04cf69ad5..602bcaf4ce 100644 --- a/pdns/dnsdistdist/dnsdist.cc +++ b/pdns/dnsdistdist/dnsdist.cc @@ -567,7 +567,7 @@ bool processResponseAfterRules(PacketBuffer& response, DNSResponse& dnsResponse, if (dnsResponse.ids.d_extendedErrors) { for (auto ede : *dnsResponse.ids.d_extendedErrors) { - dnsdist::edns::addExtendedDNSError(dnsResponse.getMutableData(), dnsResponse.getMaximumSize(), ede.infoCode, ede.extraText); + dnsdist::edns::addExtendedDNSError(dnsResponse.getMutableData(), dnsResponse.getMaximumSize(), ede.infoCode, ede.extraText, ede.clearExisting); } } @@ -1407,7 +1407,7 @@ static bool prepareOutgoingResponse([[maybe_unused]] const ClientState& clientSt if (dnsResponse.ids.d_extendedErrors) { for (auto ede : *dnsResponse.ids.d_extendedErrors) { - dnsdist::edns::addExtendedDNSError(dnsResponse.getMutableData(), dnsResponse.getMaximumSize(), ede.infoCode, ede.extraText); + dnsdist::edns::addExtendedDNSError(dnsResponse.getMutableData(), dnsResponse.getMaximumSize(), ede.infoCode, ede.extraText, ede.clearExisting); } } diff --git a/pdns/ednsextendederror.hh b/pdns/ednsextendederror.hh index 7c067a0f52..216c9733e7 100644 --- a/pdns/ednsextendederror.hh +++ b/pdns/ednsextendederror.hh @@ -61,6 +61,7 @@ struct EDNSExtendedError }; uint16_t infoCode; std::string extraText; + bool clearExisting = true; }; bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee);