From: Remi Gacogne Date: Thu, 10 Jul 2025 10:05:02 +0000 (+0200) Subject: dnsdist: Handle named rcodes in the dynamic block YAML configuration X-Git-Tag: rec-5.4.0-alpha0~36^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f84cc5ad3e19c73cc45b393d0934d9c4579bde10;p=thirdparty%2Fpdns.git dnsdist: Handle named rcodes in the dynamic block YAML configuration Signed-off-by: Remi Gacogne --- diff --git a/pdns/dns.cc b/pdns/dns.cc index 12f97eaee9..d78027d80e 100644 --- a/pdns/dns.cc +++ b/pdns/dns.cc @@ -85,6 +85,18 @@ std::string RCode::to_short_s(uint8_t rcode) { return rcodes_short_s.at(rcode); } +std::optional RCode::from_short(const std::string_view& rcode_string) +{ + uint8_t position = 0; + for (const auto& short_rcode : rcodes_short_s) { + if (short_rcode == rcode_string) { + return position; + } + ++position; + } + return std::nullopt; +} + std::string ERCode::to_s(uint16_t rcode) { if (rcode >= RCode::rcodes_s.size()) { return std::string("Err#")+std::to_string(rcode); diff --git a/pdns/dns.hh b/pdns/dns.hh index b12559dfcb..76fa8e1858 100644 --- a/pdns/dns.hh +++ b/pdns/dns.hh @@ -23,6 +23,8 @@ #include "qtype.hh" #include "dnsname.hh" #include +#include +#include #include #undef BADSIG // signal.h SIG_ERR @@ -35,6 +37,7 @@ public: enum rcodes_ : uint8_t { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10}; static std::string to_s(uint8_t rcode); static std::string to_short_s(uint8_t rcode); + static std::optional from_short(const std::string_view& rcode_string); const static std::array rcodes_s; }; diff --git a/pdns/dnsdistdist/dnsdist-configuration-yaml.cc b/pdns/dnsdistdist/dnsdist-configuration-yaml.cc index 5c9b59ad91..8efc581c64 100644 --- a/pdns/dnsdistdist/dnsdist-configuration-yaml.cc +++ b/pdns/dnsdistdist/dnsdist-configuration-yaml.cc @@ -132,6 +132,17 @@ static bool getOptionalLuaFunction(T& destination, const ::rust::string& functio return true; } +static uint8_t strToRCode(const std::string& context, const std::string& parameterName, const ::rust::String& rcode_rust_string) +{ + auto rcode_str = std::string(rcode_rust_string); + boost::to_lower(rcode_str); + auto rcode = RCode::from_short(rcode_str); + if (!rcode) { + return checkedConversionFromStr(context, parameterName, rcode_rust_string); + } + return *rcode; +} + static std::optional loadContentFromConfigurationFile(const std::string& fileName) { /* no check on the file size, don't do this with just any file! */ @@ -618,7 +629,7 @@ static void loadDynamicBlockConfiguration(const dnsdist::rust::settings::Dynamic ruleParams.d_tagSettings->d_name = std::string(rule.tag_name); ruleParams.d_tagSettings->d_value = std::string(rule.tag_value); } - dbrgObj->setRCodeRate(checkedConversionFromStr("dynamic-rules.rules.rcode_rate", "rcode", rule.rcode), std::move(ruleParams)); + dbrgObj->setRCodeRate(strToRCode("dynamic-rules.rules.rcode_rate", "rcode", rule.rcode), std::move(ruleParams)); } else if (rule.rule_type == "rcode-ratio") { DynBlockRulesGroup::DynBlockRatioRule ruleParams(std::string(rule.comment), rule.action_duration, rule.ratio, rule.warning_ratio, rule.seconds, rule.action.empty() ? DNSAction::Action::None : DNSAction::typeFromString(std::string(rule.action)), rule.minimum_number_of_responses); @@ -627,7 +638,7 @@ static void loadDynamicBlockConfiguration(const dnsdist::rust::settings::Dynamic ruleParams.d_tagSettings->d_name = std::string(rule.tag_name); ruleParams.d_tagSettings->d_value = std::string(rule.tag_value); } - dbrgObj->setRCodeRatio(checkedConversionFromStr("dynamic-rules.rules.rcode_ratio", "rcode", rule.rcode), std::move(ruleParams)); + dbrgObj->setRCodeRatio(strToRCode("dynamic-rules.rules.rcode_ratio", "rcode", rule.rcode), std::move(ruleParams)); } else if (rule.rule_type == "qtype-rate") { DynBlockRulesGroup::DynBlockRule ruleParams(std::string(rule.comment), rule.action_duration, rule.rate, rule.warning_rate, rule.seconds, rule.action.empty() ? DNSAction::Action::None : DNSAction::typeFromString(std::string(rule.action))); diff --git a/regression-tests.dnsdist/test_DynBlocksServFail.py b/regression-tests.dnsdist/test_DynBlocksServFail.py index ec3bb830e4..777fe0b22f 100644 --- a/regression-tests.dnsdist/test_DynBlocksServFail.py +++ b/regression-tests.dnsdist/test_DynBlocksServFail.py @@ -134,7 +134,7 @@ dynamic_rules: action_duration: %d comment: "Exceeded query rate" action: "Drop" - rcode: "2" + rcode: "servfail" backends: - address: "127.0.0.1:%d"