]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Handle named rcodes in the dynamic block YAML configuration
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 10 Jul 2025 10:05:02 +0000 (12:05 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 10 Jul 2025 13:34:57 +0000 (15:34 +0200)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dns.cc
pdns/dns.hh
pdns/dnsdistdist/dnsdist-configuration-yaml.cc
regression-tests.dnsdist/test_DynBlocksServFail.py

index 12f97eaee9e4ea567433815f47db1a144c98f1aa..d78027d80e2bed64228a139385fc7a2e27484e6f 100644 (file)
@@ -85,6 +85,18 @@ std::string RCode::to_short_s(uint8_t rcode) {
   return rcodes_short_s.at(rcode);
 }
 
+std::optional<uint8_t> 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);
index b12559dfcbfd74d6126388190d79b5bd38385201..76fa8e185898bc9a82e4ed1ca82b563c8a104267 100644 (file)
@@ -23,6 +23,8 @@
 #include "qtype.hh"
 #include "dnsname.hh"
 #include <ctime>
+#include <optional>
+#include <string_view>
 #include <sys/types.h>
 
 #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<uint8_t> from_short(const std::string_view& rcode_string);
   const static std::array<std::string, 24> rcodes_s;
 };
 
index 5c9b59ad9178f805ca4a87876e6d5ab11929246c..8efc581c64ca5b4730f4feca5b50372745174c78 100644 (file)
@@ -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<uint8_t>(context, parameterName, rcode_rust_string);
+  }
+  return *rcode;
+}
+
 static std::optional<std::string> 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<int>("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<int>("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)));
index ec3bb830e412f4172daa04c268b79861d2ee4358..777fe0b22f91a9268f4eee2a6d3a429b694c9fea 100644 (file)
@@ -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"