]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Move handling of backend parameters out of the Lua code
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 24 Dec 2024 11:08:30 +0000 (12:08 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 16 Jan 2025 08:50:22 +0000 (09:50 +0100)
pdns/dnsdistdist/dnsdist-backend.cc
pdns/dnsdistdist/dnsdist-lua.cc
pdns/dnsdistdist/dnsdist.hh

index 0139982c075a3a0035aac43d56f26ceb3b0de9f8..1907f797330f45a7f500003f87e00fedc2b216da 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+
+// for OpenBSD, sys/socket.h needs to come before net/if.h
+#include <sys/socket.h>
+#include <net/if.h>
+
 #include <boost/format.hpp>
 
 #include "config.h"
@@ -916,6 +921,71 @@ void DownstreamState::registerXsk(std::vector<std::shared_ptr<XskSocket>>& xsks)
 }
 #endif /* HAVE_XSK */
 
+bool DownstreamState::parseSourceParameter(const std::string& source, DownstreamState::Config& config)
+{
+  /* handle source in the following forms:
+     - v4 address ("192.0.2.1")
+     - v6 address ("2001:DB8::1")
+     - interface name ("eth0")
+     - v4 address and interface name ("192.0.2.1@eth0")
+     - v6 address and interface name ("2001:DB8::1@eth0")
+  */
+  std::string::size_type pos = source.find('@');
+  if (pos == std::string::npos) {
+    /* no '@', try to parse that as a valid v4/v6 address */
+    try {
+      config.sourceAddr = ComboAddress(source);
+      return true;
+    }
+    catch (...) {
+    }
+  }
+
+  /* try to parse as interface name, or v4/v6@itf */
+  config.sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1);
+  unsigned int itfIdx = if_nametoindex(config.sourceItfName.c_str());
+  if (itfIdx != 0) {
+    if (pos == 0 || pos == std::string::npos) {
+      /* "eth0" or "@eth0" */
+      config.sourceItf = itfIdx;
+    }
+    else {
+      /* "192.0.2.1@eth0" */
+      config.sourceAddr = ComboAddress(source.substr(0, pos));
+      config.sourceItf = itfIdx;
+    }
+#ifdef SO_BINDTODEVICE
+    if (!dnsdist::configuration::isImmutableConfigurationDone()) {
+      /* we need to retain CAP_NET_RAW to be able to set SO_BINDTODEVICE in the health checks */
+      dnsdist::configuration::updateImmutableConfiguration([](dnsdist::configuration::ImmutableConfiguration& currentConfig) {
+        currentConfig.d_capabilitiesToRetain.insert("CAP_NET_RAW");
+      });
+    }
+#endif
+    return true;
+  }
+
+  warnlog("Dismissing source %s because '%s' is not a valid interface name", source, config.sourceItfName);
+  return false;
+}
+
+std::optional<DownstreamState::Availability> DownstreamState::getAvailabilityFromStr(const std::string& mode)
+{
+  if (pdns_iequals(mode, "auto")) {
+    return DownstreamState::Availability::Auto;
+  }
+  if (pdns_iequals(mode, "lazy")) {
+    return DownstreamState::Availability::Lazy;
+  }
+  if (pdns_iequals(mode, "up")) {
+    return DownstreamState::Availability::Up;
+  }
+  if (pdns_iequals(mode, "down")) {
+    return DownstreamState::Availability::Down;
+  }
+  return std::nullopt;
+}
+
 size_t ServerPool::countServers(bool upOnly)
 {
   std::shared_ptr<const ServerPolicy::NumberedServerVector> servers = nullptr;
index d530a9564a0873e7f0012ab2719b2287d2e4bb08..61f19e61935565e62cbca7e3902513a3d908e358 100644 (file)
 #include <fstream>
 #include <cinttypes>
 
-// for OpenBSD, sys/socket.h needs to come before net/if.h
-#include <sys/socket.h>
-#include <net/if.h>
-
 #include <regex>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -328,17 +324,9 @@ static void handleNewServerHealthCheckParameters(boost::optional<newserver_t>& v
 
   if (getOptionalValue<std::string>(vars, "healthCheckMode", valueStr) > 0) {
     const auto& mode = valueStr;
-    if (pdns_iequals(mode, "auto")) {
-      config.availability = DownstreamState::Availability::Auto;
-    }
-    else if (pdns_iequals(mode, "lazy")) {
-      config.availability = DownstreamState::Availability::Lazy;
-    }
-    else if (pdns_iequals(mode, "up")) {
-      config.availability = DownstreamState::Availability::Up;
-    }
-    else if (pdns_iequals(mode, "down")) {
-      config.availability = DownstreamState::Availability::Down;
+    auto availability = DownstreamState::getAvailabilityFromStr(mode);
+    if (availability) {
+      config.availability = *availability;
     }
     else {
       warnlog("Ignoring unknown value '%s' for 'healthCheckMode' on 'newServer'", mode);
@@ -411,52 +399,11 @@ static void handleNewServerHealthCheckParameters(boost::optional<newserver_t>& v
 static void handleNewServerSourceParameter(boost::optional<newserver_t>& vars, DownstreamState::Config& config)
 {
   std::string source;
-  if (getOptionalValue<std::string>(vars, "source", source) > 0) {
-    /* handle source in the following forms:
-       - v4 address ("192.0.2.1")
-       - v6 address ("2001:DB8::1")
-       - interface name ("eth0")
-                              - v4 address and interface name ("192.0.2.1@eth0")
-                              - v6 address and interface name ("2001:DB8::1@eth0")
-    */
-    bool parsed = false;
-    std::string::size_type pos = source.find('@');
-    if (pos == std::string::npos) {
-      /* no '@', try to parse that as a valid v4/v6 address */
-      try {
-        config.sourceAddr = ComboAddress(source);
-        parsed = true;
-      }
-      catch (...) {
-      }
-    }
-
-    if (!parsed) {
-      /* try to parse as interface name, or v4/v6@itf */
-      config.sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1);
-      unsigned int itfIdx = if_nametoindex(config.sourceItfName.c_str());
-      if (itfIdx != 0) {
-        if (pos == 0 || pos == std::string::npos) {
-          /* "eth0" or "@eth0" */
-          config.sourceItf = itfIdx;
-        }
-        else {
-          /* "192.0.2.1@eth0" */
-          config.sourceAddr = ComboAddress(source.substr(0, pos));
-          config.sourceItf = itfIdx;
-        }
-#ifdef SO_BINDTODEVICE
-        /* we need to retain CAP_NET_RAW to be able to set SO_BINDTODEVICE in the health checks */
-        dnsdist::configuration::updateImmutableConfiguration([](dnsdist::configuration::ImmutableConfiguration& currentConfig) {
-          currentConfig.d_capabilitiesToRetain.insert("CAP_NET_RAW");
-        });
-#endif
-      }
-      else {
-        warnlog("Dismissing source %s because '%s' is not a valid interface name", source, config.sourceItfName);
-      }
-    }
+  if (getOptionalValue<std::string>(vars, "source", source) <= 0) {
+    return;
   }
+
+  DownstreamState::parseSourceParameter(source, config);
 }
 
 // NOLINTNEXTLINE(readability-function-cognitive-complexity,readability-function-size): this function declares Lua bindings, even with a good refactoring it will likely blow up the threshold
index d4bd9b9cb7c3a2f6eb43480e9a4047ed878f80df..24e3a3ca9968afd4b7cd12925c271cf5741e532e 100644 (file)
@@ -719,6 +719,9 @@ private:
   bool d_stopped{false};
 
 public:
+  static bool parseSourceParameter(const std::string& source, Config& config);
+  static std::optional<DownstreamState::Availability> getAvailabilityFromStr(const std::string& mode);
+
   void updateStatisticsInfo()
   {
     auto delta = sw.udiffAndSet() / 1000000.0;