]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Allow runtime setting of TLS config tables by using rec_control reload-yaml
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 6 Oct 2025 11:11:31 +0000 (13:11 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 9 Oct 2025 13:43:50 +0000 (15:43 +0200)
Signed-off-by: Otto Moerbeek <otto.moerbeek@open-xchange.com>
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-rust-lib/cxxsupport.cc
pdns/recursordist/rec-rust-lib/table.py
pdns/recursordist/rec-tcp.cc
pdns/recursordist/rec-tcpout.cc
pdns/recursordist/rec-tcpout.hh
pdns/recursordist/rec_channel_rec.cc

index bdef68605b2d14a73bcce7ba574c959733eda5a4..f272dff790fd715a86f1fb5329dd2cf404b6edb1 100644 (file)
@@ -2124,6 +2124,7 @@ static int serviceMain(Logr::log_t log)
   }
   g_maxCacheEntries = ::arg().asNum("max-cache-entries");
 
+  cerr << "CALL LUACONFIG" << endl;
   auto luaResult = luaconfig(false);
   if (luaResult.d_ret != 0) {
     log->error(Logr::Error, luaResult.d_str, "Cannot load Lua or equivalent YAML configuration");
@@ -2240,7 +2241,6 @@ static int serviceMain(Logr::log_t log)
   TCPOutConnectionManager::s_maxIdlePerAuth = ::arg().asNum("tcp-out-max-idle-per-auth");
   TCPOutConnectionManager::s_maxQueries = ::arg().asNum("tcp-out-max-queries");
   TCPOutConnectionManager::s_maxIdlePerThread = ::arg().asNum("tcp-out-max-idle-per-thread");
-  TCPOutConnectionManager::setupOutgoingTLSTables();
 
   g_gettagNeedsEDNSOptions = ::arg().mustDo("gettag-needs-edns-options");
 
index b6bde5d6524c1a55ae46c501c72e1c685ef9e7cd..cfe7a7dfafc1d1c95454f7bd201020cda2789efb 100644 (file)
@@ -1396,6 +1396,7 @@ bool pdns::settings::rec::luaItemSet(const pdns::rust::settings::rec::Recursorse
   alldefault = alldefault && settings.recordcache.zonetocaches.empty();
   alldefault = alldefault && settings.recursor.allowed_additional_qtypes.empty();
   alldefault = alldefault && settings.incoming.proxymappings.empty();
+  alldefault = alldefault && settings.outgoing.tls_configurations.empty(); // actually not a Lua item, but very much alike
   return !alldefault;
 }
 
index d28db2e752bbe33c5c51d38569fb3c7d718b3eb4..fda1dc3be0a4e50993a37aba32b8665f736b7a68 100644 (file)
@@ -3653,6 +3653,6 @@ Sequence of OutgoingTLSConfiguration.`
         ''',
         'skip-old' : 'No equivalent old style setting',
         'versionadded': '5.4.0',
-        'runtime': ['reload-lua-config', 'reload-yaml'], # XXX
+        'runtime': ['reload-lua-config', 'reload-yaml'],
     },
 ]
index 775d30db8f2be1c6ffdbda786284707263ce35fa..26072b654d407d7014bfd18440fa541212c2b4f7 100644 (file)
@@ -73,7 +73,7 @@ static thread_local std::unique_ptr<tcpClientCounts_t> t_tcpClientCounts = std::
 
 static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var);
 
-#if 1
+#if 0
 #define TCPLOG(tcpsock, x)                                 \
   do {                                                     \
     cerr << []() { timeval t; gettimeofday(&t, nullptr); return t.tv_sec % 10  + t.tv_usec/1000000.0; }() << " FD " << (tcpsock) << ' ' << x; \
index 5fb4076195ab622d18f908ac03e3af0fb83705cc..c090e1fab691c6939efb3dd0d4ca05dc95502032 100644 (file)
@@ -86,52 +86,60 @@ TCPOutConnectionManager::Connection TCPOutConnectionManager::get(const endpoints
   return Connection{};
 }
 
-static SuffixMatchTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> s_suffixToConfig;
-static NetmaskTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> s_netmaskToConfig;
+struct OutgoingTLSConfigTable {
+  SuffixMatchTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> d_suffixToConfig;
+  NetmaskTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> d_netmaskToConfig;
+};
 
-void TCPOutConnectionManager::setupOutgoingTLSTables()
+static LockGuarded<OutgoingTLSConfigTable> s_outgoingTLSConfigTable;
+
+void TCPOutConnectionManager::setupOutgoingTLSConfigTables(pdns::rust::settings::rec::Recursorsettings& settings)
 {
-  auto settings = g_yamlStruct.lock();
-  auto& vec = settings->outgoing.tls_configurations;
+  auto& vec = settings.outgoing.tls_configurations;
+  auto table = s_outgoingTLSConfigTable.lock();
+  table->d_suffixToConfig = SuffixMatchTree<pdns::rust::settings::rec::OutgoingTLSConfiguration>(); // no clear?
+  table->d_netmaskToConfig.clear();
   for (const auto& entry : vec) {
     for (const auto& element : entry.suffixes) {
       DNSName name = DNSName(std::string(element));
       auto copy = entry;
-      s_suffixToConfig.add(name, std::move(copy));
+      table->d_suffixToConfig.add(name, std::move(copy));
     }
     for (const auto& element : entry.subnets) {
-      s_netmaskToConfig.insert(std::string(element)).second = entry;
+      table->d_netmaskToConfig.insert(std::string(element)).second = entry;
     }
   }
 }
 
 std::shared_ptr<TLSCtx> TCPOutConnectionManager::getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string &subjectAddress)
 {
-  pdns::rust::settings::rec::OutgoingTLSConfiguration* config{nullptr};
-
-  if (auto* node = s_netmaskToConfig.lookup(address); node != nullptr) {
-    config = &node->second;
-  }
-  else if (auto* found = s_suffixToConfig.lookup(DNSName(name)); found != nullptr) {
-    config = found;
-  }
-
   TLSContextParameters tlsParams;
   tlsParams.d_provider = "openssl";
   tlsParams.d_validateCertificates = false;
-  if (config != nullptr) {
-    tlsParams.d_provider = std::string(config->provider);
-    tlsParams.d_validateCertificates = config->validate_certificate;
-    tlsParams.d_caStore = std::string(config->ca_store);
-    if (!config->subject_name.empty()) {
-      subjectName = std::string(config->subject_name);
-    };
-    if (!config->subject_address.empty()) {
-      subjectAddress = std::string(config->subject_address);
-    };
-    verboseLogging = config->verbose_logging = true;
-    tlsParams.d_ciphers = std::string(config->ciphers);
-    tlsParams.d_ciphers13 = std::string(config->ciphers_tls_13);
+  const pdns::rust::settings::rec::OutgoingTLSConfiguration* config{nullptr};
+
+  {
+    auto table = s_outgoingTLSConfigTable.lock();
+    if (auto* node = table->d_netmaskToConfig.lookup(address); node != nullptr) {
+      config = &node->second;
+    }
+    else if (const auto* found = table->d_suffixToConfig.lookup(DNSName(name)); found != nullptr) {
+      config = found;
+    }
+    if (config != nullptr) {
+      tlsParams.d_provider = std::string(config->provider);
+      tlsParams.d_validateCertificates = config->validate_certificate;
+      tlsParams.d_caStore = std::string(config->ca_store);
+      if (!config->subject_name.empty()) {
+        subjectName = std::string(config->subject_name);
+      };
+      if (!config->subject_address.empty()) {
+        subjectAddress = std::string(config->subject_address);
+      };
+      verboseLogging = config->verbose_logging;
+      tlsParams.d_ciphers = std::string(config->ciphers);
+      tlsParams.d_ciphers13 = std::string(config->ciphers_tls_13);
+    }
   }
   return ::getTLSContext(tlsParams);
 }
index 4a954b2c77fdca4eab428fbfb58c6b28093cdf23..23fc5723f3ecb1e6134dc015a6fe177a6adf7a32 100644 (file)
 #include "iputils.hh"
 #include "tcpiohandler.hh"
 
+namespace pdns::rust::settings::rec
+{
+struct Recursorsettings;
+}
+
 class TCPOutConnectionManager
 {
 public:
@@ -69,7 +74,7 @@ public:
     return new uint64_t(size()); // NOLINT(cppcoreguidelines-owning-memory): it's the API
   }
 
-  static void setupOutgoingTLSTables();
+  static void setupOutgoingTLSConfigTables(pdns::rust::settings::rec::Recursorsettings& settings);
   static std::shared_ptr<TLSCtx> getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string& subjectAddress);
 
 private:
index b28f5d36d1f915f06e3d25285a0bf73ad2920745..d87f0ba327955fb3ee9caeb3026e5c9f56fff0de 100644 (file)
@@ -2020,6 +2020,7 @@ RecursorControlChannel::Answer luaconfig(bool broadcast)
       // Initial proxy mapping
       g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique<ProxyMapping>(proxyMapping);
     }
+    TCPOutConnectionManager::setupOutgoingTLSConfigTables(settings);
 
     return {0, "Reloaded dynamic part of YAML configuration\n"};
   }