]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
(re)load Lua config from either Lua or YAML
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 1 Feb 2024 11:45:34 +0000 (12:45 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 25 Apr 2024 09:31:40 +0000 (11:31 +0200)
16 files changed:
pdns/recursordist/Makefile.am
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-main.hh
pdns/recursordist/rec_channel.hh
pdns/recursordist/rec_channel_rec.cc
pdns/recursordist/rec_control.cc
pdns/recursordist/rpzloader.hh
pdns/recursordist/settings/cxxsettings.hh
pdns/recursordist/settings/cxxsupport.cc
pdns/recursordist/settings/rust/src/bridge.rs
pdns/recursordist/test-settings.cc
regression-tests.recursor-dnssec/test_Carbon.py
regression-tests.recursor-dnssec/test_ECS.py
regression-tests.recursor-dnssec/test_Protobuf.py
regression-tests.recursor-dnssec/test_RPZIncomplete.py
regression-tests.recursor-dnssec/test_RecDnstap.py

index afc41e9a46727ddcedee2d0089afd7b21d1289ed..fbec4c82b1e8755a7403fc16cbdc32b8027009ec 100644 (file)
@@ -516,10 +516,10 @@ rec_control_SOURCES = \
        dnsrecords.cc dnsrecords.hh \
        dnswriter.cc dnswriter.hh \
        filterpo.cc filterpo.hh \
-       lua-base4.cc lua-base4.hh \
        iputils.cc iputils.hh \
        logger.cc \
        logging.cc \
+       lua-base4.cc lua-base4.hh \
        misc.cc \
        nsecrecords.cc \
        qtype.cc \
index 5ff54beb9bf21c6a30019e7d6649f9dc79476e63..bf2255404456960d99414c5bb38d99b8bd161887 100644 (file)
@@ -72,6 +72,7 @@ string g_pidfname;
 RecursorControlChannel g_rcc; // only active in the handler thread
 bool g_regressionTestMode;
 bool g_yamlSettings;
+bool g_luaSettingsInYAML;
 
 #ifdef NOD_ENABLED
 bool g_nodEnabled;
@@ -2081,19 +2082,20 @@ static int serviceMain(Logr::log_t log)
   }
   g_maxCacheEntries = ::arg().asNum("max-cache-entries");
 
-  try {
-    ProxyMapping proxyMapping;
-    LuaConfigItems lci;
-    loadRecursorLuaConfig(::arg()["lua-config-file"], proxyMapping, lci);
-    // Initial proxy mapping
-    g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique<ProxyMapping>(proxyMapping);
-    activateLuaConfig(lci);
-  }
-  catch (PDNSException& e) {
-    SLOG(g_log << Logger::Error << "Cannot load Lua configuration: " << e.reason << endl,
-         log->error(Logr::Error, e.reason, "Cannot load Lua configuration"));
-    return 1;
-  }
+  luaconfig(false);
+  // try {
+  //   ProxyMapping proxyMapping;
+  //   LuaConfigItems lci;
+  //   loadRecursorLuaConfig(::arg()["lua-config-file"], proxyMapping, lci);
+  //   // Initial proxy mapping
+  //   g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique<ProxyMapping>(proxyMapping);
+  //   activateLuaConfig(lci);
+  // }
+  // catch (PDNSException& e) {
+  //   SLOG(g_log << Logger::Error << "Cannot load Lua configuration: " << e.reason << endl,
+  //        log->error(Logr::Error, e.reason, "Cannot load Lua configuration"));
+  //   return 1;
+  // }
 
   parseACLs();
   initPublicSuffixList(::arg()["public-suffix-list-file"]);
@@ -2260,8 +2262,10 @@ static int serviceMain(Logr::log_t log)
     return ret;
   }
 
-  auto lci = g_luaconfs.getCopy();
-  activateLuaConfig(lci);
+  {
+    auto lci = g_luaconfs.getCopy();
+    startLuaConfigDelayedThreads(lci.rpzs, lci.generation);
+  }
 
   RecThreadInfo::makeThreadPipes(log);
 
@@ -2973,6 +2977,8 @@ static pair<int, bool> doConfig(Logr::log_t startupLog, const string& configname
   return {0, false};
 }
 
+LockGuarded<pdns::rust::settings::rec::Recursorsettings> g_yamlStruct;
+
 static void handleRuntimeDefaults(Logr::log_t log)
 {
 #ifdef HAVE_FIBER_SANITIZER
@@ -3138,28 +3144,10 @@ int main(int argc, char** argv)
     ::arg().setSLog(startupLog);
 
     const string yamlconfigname = configname + ".yml";
-    string msg;
     pdns::rust::settings::rec::Recursorsettings settings;
-    // TODO: handle include-dir on command line
-    auto yamlstatus = pdns::settings::rec::readYamlSettings(yamlconfigname, ::arg()["include-dir"], settings, msg, startupLog);
-
-    switch (yamlstatus) {
-    case pdns::settings::rec::YamlSettingsStatus::CannotOpen:
-      SLOG(g_log << Logger::Debug << "No YAML config found for configname '" << yamlconfigname << "': " << msg << endl,
-           startupLog->error(Logr::Debug, msg, "No YAML config found", "configname", Logging::Loggable(yamlconfigname)));
-      break;
-    case pdns::settings::rec::YamlSettingsStatus::PresentButFailed:
-      SLOG(g_log << Logger::Error << "YAML config found for configname '" << yamlconfigname << "' but error ocurred processing it" << endl,
-           startupLog->error(Logr::Error, msg, "YAML config found, but error occurred processsing it", "configname", Logging::Loggable(yamlconfigname)));
+    auto yamlstatus = pdns::settings::rec::tryReadYAML(yamlconfigname, true, g_yamlSettings, g_luaSettingsInYAML, settings, startupLog);
+    if (yamlstatus == pdns::settings::rec::PresentButFailed) {
       return 1;
-      break;
-    case pdns::settings::rec::YamlSettingsStatus::OK:
-      g_yamlSettings = true;
-      SLOG(g_log << Logger::Notice << "YAML config found and processed for configname '" << yamlconfigname << "'" << endl,
-           startupLog->info(Logr::Notice, "YAML config found and processed", "configname", Logging::Loggable(yamlconfigname)));
-      pdns::settings::rec::processAPIDir(arg()["include-dir"], settings, startupLog);
-      pdns::settings::rec::bridgeStructToOldStyleSettings(settings);
-      break;
     }
 
     if (g_yamlSettings) {
@@ -3169,7 +3157,10 @@ int main(int argc, char** argv)
         return ret;
       }
     }
-
+    if (yamlstatus == pdns::settings::rec::YamlSettingsStatus::OK) {
+      auto lock = g_yamlStruct.lock();
+      *lock = settings;
+    }
     if (yamlstatus == pdns::settings::rec::YamlSettingsStatus::CannotOpen) {
       configname += ".conf";
       bool mustExit = false;
@@ -3338,13 +3329,15 @@ struct WipeCacheResult wipeCaches(const DNSName& canon, bool subtree, uint16_t q
   return res;
 }
 
-static void startLuaConfigDelayedThreads(const vector<RPZTrackerParams>& rpzs, uint64_t generation)
+void startLuaConfigDelayedThreads(const vector<RPZTrackerParams>& rpzs, uint64_t generation)
 {
+  cerr << "slcdt: " << rpzs.size() << endl;
   for (const auto& rpzPrimary : rpzs) {
     if (rpzPrimary.primaries.empty()) {
       continue;
     }
     try {
+      cerr << "STARTING" << endl;
       // The get calls all return a value object here. That is essential, since we want copies so that RPZIXFRTracker gets values
       // with the proper lifetime.
       std::thread theThread(RPZIXFRTracker, rpzPrimary, generation);
@@ -3373,7 +3366,7 @@ static void activateRPZFile(const RPZTrackerParams& params, LuaConfigItems& lci,
          log->info(Logr::Info, "Loading RPZ from file"));
     loadRPZFromFile(params.name, zone, params.defpol, params.defpolOverrideLocal, params.maxTTL);
     SLOG(g_log << Logger::Warning << "Done loading RPZ from file '" << params.name << "'" << endl,
-         log->info(Logr::Info,  "Done loading RPZ from file"));
+         log->info(Logr::Info, "Done loading RPZ from file"));
   }
   catch (const std::exception& e) {
     SLOG(g_log << Logger::Error << "Unable to load RPZ zone from '" << params.name << "': " << e.what() << endl,
@@ -3397,19 +3390,19 @@ static void activateRPZPrimary(RPZTrackerParams& params, LuaConfigItems& lci, sh
 
       if (params.soaRecordContent == nullptr) {
         throw PDNSException("The RPZ zone " + params.name + " loaded from the seed file (" + zone->getDomain().toString() + ") has no SOA record");
-        }
-      }
-      catch (const PDNSException& e) {
-        SLOG(g_log << Logger::Warning << "Unable to pre-load RPZ zone " << params.name << " from seed file '" << params.seedFileName << "': " << e.reason << endl,
-             log->error(Logr::Warning, e.reason, "Exception while pre-loading RPZ zone", "exception", Logging::Loggable("PDNSException")));
-        zone->clear();
-      }
-      catch (const std::exception& e) {
-        SLOG(g_log << Logger::Warning << "Unable to pre-load RPZ zone " << params.name << " from seed file '" << params.seedFileName << "': " << e.what() << endl,
-             log->error(Logr::Warning, e.what(), "Exception while pre-loading RPZ zone", "exception", Logging::Loggable("std::exception")));
-        zone->clear();
       }
     }
+    catch (const PDNSException& e) {
+      SLOG(g_log << Logger::Warning << "Unable to pre-load RPZ zone " << params.name << " from seed file '" << params.seedFileName << "': " << e.reason << endl,
+           log->error(Logr::Warning, e.reason, "Exception while pre-loading RPZ zone", "exception", Logging::Loggable("PDNSException")));
+      zone->clear();
+    }
+    catch (const std::exception& e) {
+      SLOG(g_log << Logger::Warning << "Unable to pre-load RPZ zone " << params.name << " from seed file '" << params.seedFileName << "': " << e.what() << endl,
+           log->error(Logr::Warning, e.what(), "Exception while pre-loading RPZ zone", "exception", Logging::Loggable("std::exception")));
+      zone->clear();
+    }
+  }
 }
 
 static void activateRPZs(LuaConfigItems& lci)
@@ -3420,7 +3413,11 @@ static void activateRPZs(LuaConfigItems& lci)
       zone->reserve(params.zoneSizeHint);
     }
     if (!params.tags.empty()) {
-      zone->setTags(params.tags);
+      std::unordered_set<std::string> tags;
+      for (const auto& tag : params.tags) {
+        tags.emplace(tag);
+      }
+      zone->setTags(tags);
     }
     zone->setPolicyOverridesGettag(params.defpolOverrideLocal);
     if (params.extendedErrorCode != std::numeric_limits<uint32_t>::max()) {
@@ -3435,7 +3432,7 @@ static void activateRPZs(LuaConfigItems& lci)
     if (params.primaries.empty()) {
       activateRPZFile(params, lci, zone);
       lci.dfe.addZone(std::move(zone));
-   }
+    }
     else {
       DNSName domain(params.name);
       zone->setDomain(domain);
@@ -3444,7 +3441,6 @@ static void activateRPZs(LuaConfigItems& lci)
       activateRPZPrimary(params, lci, zone, domain);
     }
   }
-  startLuaConfigDelayedThreads(lci.rpzs, lci.generation);
 }
 
 void activateLuaConfig(LuaConfigItems& lci)
@@ -3454,11 +3450,11 @@ void activateLuaConfig(LuaConfigItems& lci)
     updateTrustAnchorsFromFile(lci.trustAnchorFileInfo.fname, lci.dsAnchors, lci.d_slog);
   }
   if (lci.dsAnchors.size() > rootDSs.size()) {
-     warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC, but dnssec is set to 'off'!");
+    warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC, but dnssec is set to 'off'!");
   }
   if (!lci.negAnchors.empty()) {
-     warnIfDNSSECDisabled("Warning: adding Negative Trust Anchor for DNSSEC, but dnssec is set to 'off'!");
+    warnIfDNSSECDisabled("Warning: adding Negative Trust Anchor for DNSSEC, but dnssec is set to 'off'!");
   }
   activateRPZs(lci);
-  g_luaconfs.setState(std::move(lci));
+  g_luaconfs.setState(lci);
 }
index fd51919d412f48e700b4204169b86c006d88cc08..74168567a31b870e19e6c66c88e67d34207f7c76 100644 (file)
@@ -620,6 +620,8 @@ void handleNewTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t&);
 
 void makeUDPServerSockets(deferredAdd_t& deferredAdds, Logr::log_t);
 string doTraceRegex(FDWrapper file, vector<string>::const_iterator begin, vector<string>::const_iterator end);
+extern bool g_luaSettingsInYAML;
+void startLuaConfigDelayedThreads(const vector<RPZTrackerParams>& rpzs, uint64_t generation);
 void activateLuaConfig(LuaConfigItems& lci);
 
 #define LOCAL_NETS "127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10"
index 784539fb2f2a624a34001393b633a8a3ab916a6a..f9977e5892477a238294660a20efb794a2774e5e 100644 (file)
@@ -143,3 +143,4 @@ void doExitGeneric(bool nicely);
 void doExit();
 void doExitNicely();
 RecursorControlChannel::Answer doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
+RecursorControlChannel::Answer luaconfig(bool broadcast);
index fe95ee0558c11c63abaad3f9676912725f9a9615..dd45c5e5f873456c0d55663493aee8aa13b24435 100644 (file)
@@ -2131,27 +2131,82 @@ static RecursorControlChannel::Answer help()
           "wipe-cache-typed type domain0 [domain1] ..  wipe domain data with qtype from cache\n"};
 }
 
+RecursorControlChannel::Answer luaconfig(bool broadcast)
+{
+    ProxyMapping proxyMapping;
+    LuaConfigItems lci;
+    lci.d_slog = g_slog;
+    extern std::unique_ptr<ProxyMapping> g_proxyMapping;
+    if (!g_luaSettingsInYAML) {
+      try {
+        loadRecursorLuaConfig(::arg()["lua-config-file"], proxyMapping, lci);
+        activateLuaConfig(lci);
+        lci = g_luaconfs.getCopy();
+        if (broadcast) {
+          startLuaConfigDelayedThreads(lci.rpzs, lci.generation);
+          broadcastFunction([=] { return pleaseSupplantProxyMapping(proxyMapping); });
+        }
+        else {
+          // Initial proxy mapping
+          g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique<ProxyMapping>(proxyMapping);
+        }
+        SLOG(g_log << Logger::Notice << "Reloaded Lua configuration file '" << ::arg()["lua-config-file"] << "', requested via control channel" << endl,
+             g_slog->withName("config")->info(Logr::Info, "Reloaded"));
+        return {0, "Reloaded Lua configuration file '" + ::arg()["lua-config-file"] + "'\n"};
+      }
+      catch (std::exception& e) {
+        return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.what() + "\n"};
+      }
+      catch (const PDNSException& e) {
+        return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.reason + "\n"};
+      }
+    }
+    try {
+      string configname = ::arg()["config-dir"] + "/recursor";
+      if (!::arg()["config-name"].empty()) {
+        configname = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"];
+      }
+      bool dummy1{};
+      bool dummy2{};
+      pdns::rust::settings::rec::Recursorsettings settings;
+      auto yamlstat = pdns::settings::rec::tryReadYAML(configname + ".yml", false, dummy1, dummy2, settings, g_slog);
+      if (yamlstat != pdns::settings::rec::YamlSettingsStatus::OK) {
+        // HANDLE
+      }
+      auto generation = g_luaconfs.getLocal()->generation;
+      lci.generation = generation + 1;
+      pdns::settings::rec::fromBridgeStructToLuaConfig(settings, lci, proxyMapping);
+      activateLuaConfig(lci);
+      lci = g_luaconfs.getCopy();
+      if (broadcast) {
+        startLuaConfigDelayedThreads(lci.rpzs, lci.generation);
+        broadcastFunction([=] { return pleaseSupplantProxyMapping(proxyMapping); });
+      }
+      else {
+        // Initial proxy mapping
+        g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique<ProxyMapping>(proxyMapping);
+      }
+
+      return {0, "Reloaded dynamic part of YAML configuration\n"};
+    }
+    catch (std::exception& e) {
+      return {1, "Unable to reload dynamic YAML changes: " + std::string(e.what()) + "\n"};
+    }
+    catch (const PDNSException& e) {
+      return {1, "Unable to reload dynamic YAML changes: " + e.reason + "\n"};
+    }
+}
+
 template <typename T>
 static RecursorControlChannel::Answer luaconfig(T begin, T end)
 {
   if (begin != end) {
+    if (g_luaSettingsInYAML) {
+      return {1, "Unable to reload Lua script from '" + ::arg()["lua-config-file"] + " as there is not active Lua configuration\n"};
+    }
     ::arg().set("lua-config-file") = *begin;
   }
-  try {
-    ProxyMapping proxyMapping;
-    LuaConfigItems lci;
-    loadRecursorLuaConfig(::arg()["lua-config-file"], proxyMapping, lci);
-    activateLuaConfig(lci);
-    broadcastFunction([=] { return pleaseSupplantProxyMapping(proxyMapping); });
-    g_log << Logger::Warning << "Reloaded Lua configuration file '" << ::arg()["lua-config-file"] << "', requested via control channel" << endl;
-    return {0, "Reloaded Lua configuration file '" + ::arg()["lua-config-file"] + "'\n"};
-  }
-  catch (std::exception& e) {
-    return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.what() + "\n"};
-  }
-  catch (const PDNSException& e) {
-    return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.reason + "\n"};
-  }
+  return luaconfig(true);
 }
 
 static RecursorControlChannel::Answer reloadACLs()
index 4ad16e440f7a0bade9ccad9d4aea1c48c0a75d4f..0561b5ac145fd8d78b9ad093700719a9116088e0 100644 (file)
@@ -141,7 +141,7 @@ static std::string showLuaYAML(const ::rust::string rfile)
     msg += "\n# End of converted " + file + "\n#\n";
   }
   catch (PDNSException& e) {
-    cerr <<  "Cannot load Lua configuration: " << e.reason << endl;
+    cerr << "Cannot load Lua configuration: " << e.reason << endl;
   }
   return msg;
 }
index 3e94acde492b0522d5436667875922c5abb23299..8b2252f14cce90fe15ad47b5f2c3e0afbbdd81f3 100644 (file)
@@ -46,7 +46,7 @@ struct RPZTrackerParams
   std::string dumpZoneFileName;
   std::string polName;
   size_t zoneSizeHint{0};
-  std::unordered_set<std::string> tags;
+  std::set<std::string> tags;
   uint32_t extendedErrorCode{std::numeric_limits<uint32_t>::max()};
   std::string extendedErrorExtra;
   bool includeSOA{false};
index d327820f5b43575f2591a0259ba496c3f7a404e5..0d65b121de085de2060aac05ff3fab20cdd17b1e 100644 (file)
@@ -54,4 +54,6 @@ void setArgsForZoneRelatedSettings(pdns::rust::settings::rec::Recursorsettings&
 void setArgsForACLRelatedSettings(pdns::rust::settings::rec::Recursorsettings& settings);
 void fromLuaConfigToBridgeStruct(LuaConfigItems& luaConfig, const ProxyMapping& proxyMapping, pdns::rust::settings::rec::Recursorsettings& settings);
 void fromBridgeStructToLuaConfig(const pdns::rust::settings::rec::Recursorsettings& settings, LuaConfigItems& luaConfig, ProxyMapping& proxyMapping);
+bool luaItemSet(const pdns::rust::settings::rec::Recursorsettings& settings);
+YamlSettingsStatus tryReadYAML(const string& yamlconfigname, bool setGlobals, bool& yamlSettings, bool& luaSettingsInYAML, rust::settings::rec::Recursorsettings& settings, Logr::log_t startupLog);
 }
index 8a12eeffd3ab2cd3421fc27dde60436244ed1069..feaeafa5d6e753afd3b3255e13143a76fe2b591e 100644 (file)
@@ -623,7 +623,7 @@ std::string pdns::settings::rec::defaultsToYaml()
     ::rust::String section;
     ::rust::String fieldname;
     ::rust::String type_name;
-    pdns::rust::settings::rec::Value rustvalue{false, 0, 0.0, "", {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}};
+    pdns::rust::settings::rec::Value rustvalue{};
     string name = var;
     string val = arg().getDefault(var);
     if (pdns::settings::rec::oldKVToBridgeStruct(name, val, section, fieldname, type_name, rustvalue)) {
@@ -633,7 +633,8 @@ std::string pdns::settings::rec::defaultsToYaml()
 
   // Should be generated
   auto def = [&](const string& section, const string& name, const string& type) {
-    pdns::rust::settings::rec::Value rustvalue{.vec_trustanchor_val = {}, .vec_negativetrustanchor_val = {}, .string_val = "", .u64_val = 24, .vec_protobufserver_val = {}};
+    pdns::rust::settings::rec::Value rustvalue{};
+    rustvalue.u64_val = 24; // XXX
     map.emplace(std::pair{std::pair{section, name}, pdns::rust::settings::rec::OldStyle{section, name, name, type, rustvalue, false}});
   };
   def("dnssec", "trustanchors", "Vec<TrustAnchor>");
@@ -719,12 +720,14 @@ void fromLuaToRust(const LuaConfigItems& luaConfig, pdns::rust::settings::rec::D
     ::rust::Vec<::rust::String> dsRecords;
     for (const auto& dsRecord : anchors.second) {
       const auto dsString = dsRecord.getZoneRepresentation();
-      if (std::find(rootDSs.begin(), rootDSs.end(), dsString) == rootDSs.end()) {
+      if (anchors.first != g_rootdnsname || std::find(rootDSs.begin(), rootDSs.end(), dsString) == rootDSs.end()) {
         dsRecords.emplace_back(dsRecord.getZoneRepresentation());
       }
     }
-    pdns::rust::settings::rec::TrustAnchor trustAnchor{anchors.first.toString(), dsRecords};
-    dnssec.trustanchors.emplace_back(trustAnchor);
+    if (!dsRecords.empty()) {
+      pdns::rust::settings::rec::TrustAnchor trustAnchor{anchors.first.toString(), dsRecords};
+      dnssec.trustanchors.emplace_back(trustAnchor);
+    }
   }
   for (const auto& anchors : luaConfig.negAnchors) {
     pdns::rust::settings::rec::NegativeTrustAnchor negtrustAnchor{anchors.first.toString(), anchors.second};
@@ -757,7 +760,7 @@ void fromLuaToRust(const FrameStreamExportConfig& fsc, pdns::rust::settings::rec
   }
   dnstap.logQueries = fsc.logQueries;
   dnstap.logResponses = fsc.logQueries;
-  dnstap.bufferHint= fsc.bufferHint;
+  dnstap.bufferHint = fsc.bufferHint;
   dnstap.flushTimeout = fsc.flushTimeout;
   dnstap.inputQueueSize = fsc.inputQueueSize;
   dnstap.outputQueueSize = fsc.outputQueueSize;
@@ -772,7 +775,7 @@ void fromLuaToRust(const FrameStreamExportConfig& fsc, pdns::rust::settings::rec
   }
   dnstap.logNODs = fsc.logNODs;
   dnstap.logUDRs = fsc.logUDRs;
-  dnstap.bufferHint= fsc.bufferHint;
+  dnstap.bufferHint = fsc.bufferHint;
   dnstap.flushTimeout = fsc.flushTimeout;
   dnstap.inputQueueSize = fsc.inputQueueSize;
   dnstap.outputQueueSize = fsc.outputQueueSize;
@@ -789,8 +792,12 @@ void assign(pdns::rust::settings::rec::TSIGTriplet& var, const TSIGTriplet& tsig
 
 void assign(TSIGTriplet& var, const pdns::rust::settings::rec::TSIGTriplet& tsig)
 {
-  var.name = DNSName(std::string(tsig.name));
-  var.algo = DNSName(std::string(tsig.algo));
+  if (!tsig.name.empty()) {
+    var.name = DNSName(std::string(tsig.name));
+  }
+  if (!tsig.algo.empty()) {
+    var.algo = DNSName(std::string(tsig.algo));
+  }
   B64Decode(std::string(tsig.secret), var.secret);
 }
 
@@ -810,23 +817,36 @@ std::string cvt(DNSFilterEngine::PolicyKind kind)
   case DNSFilterEngine::PolicyKind::Custom:
     return "Custom";
   }
+  return "UnknownPolicyKind";
 }
 
 void fromLuaToRust(const vector<RPZTrackerParams>& rpzs, pdns::rust::settings::rec::Recursor& rec)
 {
   for (const auto& rpz : rpzs) {
     pdns::rust::settings::rec::RPZ rustrpz{
+      .name = "",
+      .addresses = {},
+      .defcontent = "",
+      .defpol = "",
       .defpolOverrideLocalData = true,
       .defttl = std::numeric_limits<uint32_t>::max(),
       .extendedErrorCode = std::numeric_limits<uint32_t>::max(),
+      .extendedErrorExtra = "",
       .includeSOA = false,
       .ignoreDuplicates = false,
       .maxTTL = std::numeric_limits<uint32_t>::max(),
+      .policyName = "",
+      .tags = {},
       .overridesGettag = true,
       .zoneSizeHint = 0,
+      .tsig = {},
       .refresh = 0,
       .maxReceivedMBytes = 0,
-      .axfrTimeout = 20};
+      .localAddress = "",
+      .axfrTimeout = 20,
+      .dumpFile = "",
+      .seedFile = "",
+    };
 
     for (const auto& address : rpz.primaries) {
       rustrpz.addresses.emplace_back(address.toStringWithPort());
@@ -873,6 +893,7 @@ string cvt(pdns::ZoneMD::Config cfg)
   case pdns::ZoneMD::Config::Require:
     return "require";
   }
+  return "UnknownZoneMDConfig";
 }
 
 void fromLuaToRust(const map<DNSName, RecZoneToCache::Config>& ztcConfigs, pdns::rust::settings::rec::Recordcache& recordcache)
@@ -916,17 +937,17 @@ std::string cvt(AdditionalMode mode)
   case AdditionalMode::ResolveDeferred:
     return "ResolveDeferred";
   }
+  return "UnknownAdditionalMode";
 }
 
 AdditionalMode cvtAdditional(const std::string& mode)
 {
   static const std::map<std::string, AdditionalMode> map = {
-    { "Ignore", AdditionalMode::Ignore },
-    { "CacheOnly", AdditionalMode::CacheOnly },
-    { "CacheOnlyRequireAuth", AdditionalMode::CacheOnlyRequireAuth },
-    { "ResolveImmediately", AdditionalMode::ResolveImmediately },
-    { "ResolveDeferred", AdditionalMode::ResolveDeferred}
-  };
+    {"Ignore", AdditionalMode::Ignore},
+    {"CacheOnly", AdditionalMode::CacheOnly},
+    {"CacheOnlyRequireAuth", AdditionalMode::CacheOnlyRequireAuth},
+    {"ResolveImmediately", AdditionalMode::ResolveImmediately},
+    {"ResolveDeferred", AdditionalMode::ResolveDeferred}};
   if (auto iter = map.find(mode); iter != map.end()) {
     return iter->second;
   }
@@ -936,9 +957,9 @@ AdditionalMode cvtAdditional(const std::string& mode)
 pdns::ZoneMD::Config cvtZoneMDConfig(const std::string& mode)
 {
   static const std::map<std::string, pdns::ZoneMD::Config> map = {
-    { "ignore", pdns::ZoneMD::Config::Ignore },
-    { "validate", pdns::ZoneMD::Config::Validate },
-    { "require", pdns::ZoneMD::Config::Require },
+    {"ignore", pdns::ZoneMD::Config::Ignore},
+    {"validate", pdns::ZoneMD::Config::Validate},
+    {"require", pdns::ZoneMD::Config::Require},
   };
   if (auto iter = map.find(mode); iter != map.end()) {
     return iter->second;
@@ -1036,13 +1057,14 @@ void pdns::settings::rec::fromLuaConfigToBridgeStruct(LuaConfigItems& luaConfig,
   fromLuaToRust(proxyMapping, settings.incoming);
 }
 
-namespace {
+namespace
+{
 void fromRustToLuaConfig(const pdns::rust::settings::rec::Dnssec& dnssec, LuaConfigItems& luaConfig)
 {
   for (const auto& trustAnchor : dnssec.trustanchors) {
     // Do not inser the default root DS records
     if (trustAnchor.name == ".") {
-      for (const auto &dsRecord : trustAnchor.dsrecords) {
+      for (const autodsRecord : trustAnchor.dsrecords) {
         const std::string dsString = std::string(dsRecord);
         if (std::find(rootDSs.begin(), rootDSs.end(), dsString) == rootDSs.end()) {
           auto dsRecContent = std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(dsString));
@@ -1051,7 +1073,7 @@ void fromRustToLuaConfig(const pdns::rust::settings::rec::Dnssec& dnssec, LuaCon
       }
     }
     else {
-      for (const auto &dsRecord : trustAnchor.dsrecords) {
+      for (const autodsRecord : trustAnchor.dsrecords) {
         auto dsRecContent = std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(std::string(dsRecord)));
         luaConfig.dsAnchors[DNSName(std::string(trustAnchor.name))].emplace(*dsRecContent);
       }
@@ -1119,20 +1141,18 @@ void fromRustToLuaConfig(const pdns::rust::settings::rec::DNSTapNODFrameStreamSe
 DNSFilterEngine::PolicyKind cvtKind(const std::string& kind)
 {
   static const std::map<std::string, DNSFilterEngine::PolicyKind> map = {
-    { "Custom", DNSFilterEngine::PolicyKind::Custom },
-    { "Drop", DNSFilterEngine::PolicyKind::Drop },
-    { "NoAction", DNSFilterEngine::PolicyKind::NoAction },
-    { "NODATA", DNSFilterEngine::PolicyKind::NODATA },
-    { "NXDOMAIN", DNSFilterEngine::PolicyKind::NXDOMAIN },
-    { "Truncate", DNSFilterEngine::PolicyKind::Truncate }
-  };
+    {"Custom", DNSFilterEngine::PolicyKind::Custom},
+    {"Drop", DNSFilterEngine::PolicyKind::Drop},
+    {"NoAction", DNSFilterEngine::PolicyKind::NoAction},
+    {"NODATA", DNSFilterEngine::PolicyKind::NODATA},
+    {"NXDOMAIN", DNSFilterEngine::PolicyKind::NXDOMAIN},
+    {"Truncate", DNSFilterEngine::PolicyKind::Truncate}};
   if (auto iter = map.find(kind); iter != map.end()) {
     return iter->second;
   }
   throw runtime_error("PolicyKind '" + kind + "' unknown");
 }
 
-
 void fromRustToLuaConfig(const rust::Vec<pdns::rust::settings::rec::RPZ>& rpzs, LuaConfigItems& luaConfig)
 {
   for (const auto& rpz : rpzs) {
@@ -1188,14 +1208,14 @@ void fromRustToLuaConfig(const rust::Vec<pdns::rust::settings::rec::RPZ>& rpzs,
   }
 }
 
-  void fromRustToLuaConfig(const rust::Vec<pdns::rust::settings::rec::ZoneToCache>& ztcs, map<DNSName, RecZoneToCache::Config>& lua)
+void fromRustToLuaConfig(const rust::Vec<pdns::rust::settings::rec::ZoneToCache>& ztcs, map<DNSName, RecZoneToCache::Config>& lua)
 {
   for (const auto& ztc : ztcs) {
     DNSName zone = DNSName(std::string(ztc.zone));
     RecZoneToCache::Config lztc;
     for (const auto& source : ztc.sources) {
       lztc.d_sources.emplace_back(std::string(source));
-     }
+    }
     lztc.d_zone = std::string(ztc.zone);
     lztc.d_method = std::string(ztc.method);
     if (!ztc.localAddress.empty()) {
@@ -1280,3 +1300,62 @@ void pdns::settings::rec::fromBridgeStructToLuaConfig(const pdns::rust::settings
   fromRustToLuaConfig(settings.incoming.proxymappings, proxyMapping);
 }
 
+// Return true if an item that's (also) a Lua config ite is set
+bool pdns::settings::rec::luaItemSet(const pdns::rust::settings::rec::Recursorsettings& settings)
+{
+  bool alldefault = true;
+  alldefault = alldefault && settings.dnssec.trustanchors.empty();
+  alldefault = alldefault && settings.dnssec.negative_trustanchors.empty();
+  alldefault = alldefault && settings.dnssec.trustanchorfile.empty();
+  alldefault = alldefault && settings.dnssec.trustanchorfile_interval == 24;
+  alldefault = alldefault && settings.logging.protobuf_mask_v4 == 32;
+  alldefault = alldefault && settings.logging.protobuf_mask_v6 == 128;
+  alldefault = alldefault && settings.logging.protobuf_servers.empty();
+  alldefault = alldefault && settings.logging.outgoing_protobuf_servers.empty();
+  alldefault = alldefault && settings.logging.dnstap_framestream_servers.empty();
+  alldefault = alldefault && settings.logging.dnstap_nod_framestream_servers.empty();
+  alldefault = alldefault && settings.recursor.sortlists.empty();
+  alldefault = alldefault && settings.recursor.rpzs.empty();
+  alldefault = alldefault && settings.recordcache.zonetocaches.empty();
+  alldefault = alldefault && settings.recursor.allowed_additional_qtypes.empty();
+  alldefault = alldefault && settings.incoming.proxymappings.empty();
+  return !alldefault;
+}
+
+pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::tryReadYAML(const string& yamlconfigname, bool setGlobals, bool& yamlSettings, bool& luaSettingsInYAML, rust::settings::rec::Recursorsettings& settings, Logr::log_t startupLog)
+{
+  string msg;
+  // TODO: handle include-dir on command line
+  auto yamlstatus = pdns::settings::rec::readYamlSettings(yamlconfigname, ::arg()["include-dir"], settings, msg, startupLog);
+
+  switch (yamlstatus) {
+  case pdns::settings::rec::YamlSettingsStatus::CannotOpen:
+    SLOG(g_log << Logger::Debug << "No YAML config found for configname '" << yamlconfigname << "': " << msg << endl,
+         startupLog->error(Logr::Debug, msg, "No YAML config found", "configname", Logging::Loggable(yamlconfigname)));
+    break;
+
+  case pdns::settings::rec::YamlSettingsStatus::PresentButFailed:
+    SLOG(g_log << Logger::Error << "YAML config found for configname '" << yamlconfigname << "' but error ocurred processing it" << endl,
+         startupLog->error(Logr::Error, msg, "YAML config found, but error occurred processsing it", "configname", Logging::Loggable(yamlconfigname)));
+    break;
+
+  case pdns::settings::rec::YamlSettingsStatus::OK:
+    yamlSettings = true;
+    SLOG(g_log << Logger::Notice << "YAML config found and processed for configname '" << yamlconfigname << "'" << endl,
+         startupLog->info(Logr::Notice, "YAML config found and processed", "configname", Logging::Loggable(yamlconfigname)));
+    pdns::settings::rec::processAPIDir(arg()["include-dir"], settings, startupLog);
+    luaSettingsInYAML = pdns::settings::rec::luaItemSet(settings);
+    cerr << "XXXX " << luaSettingsInYAML << ' ' << settings.recursor.lua_config_file.empty() << endl;
+    if (luaSettingsInYAML && !settings.recursor.lua_config_file.empty()) {
+      const std::string err = "YAML settings include values originally in Lua but also sets `recursor.lua_config_file`. This is unsupported";
+      SLOG(g_log << Logger::Error << err << endl,
+           startupLog->info(Logr::Error, err, "configname", Logging::Loggable(yamlconfigname)));
+      yamlstatus = pdns::settings::rec::PresentButFailed;
+    }
+    else if (setGlobals) {
+      pdns::settings::rec::bridgeStructToOldStyleSettings(settings);
+    }
+    break;
+  }
+  return yamlstatus;
+}
index dfb5ed6922464892e46d538b8c31d53f2db9c125..fd8d04107ea8f728a82077d1cdac5742f362b2b5 100644 (file)
@@ -323,6 +323,7 @@ impl ProtobufServer {
             seq2.push(serde_yaml::Value::String(entry.to_owned()));
         }
         insertseq(&mut map, "exportTypes", &seq2);
+        insertb(&mut map, "logMappedFrom", self.logMappedFrom);
         serde_yaml::Value::Mapping(map)
     }
 }
index 2470fae8fb7022632cb74446a66a7715213660e6..6fbdde7ec8efaa90a9b70ebe77a80b6b5f5b7e57 100644 (file)
@@ -965,9 +965,9 @@ recordcache:
 
   // Create YAML, given a Lua config
   auto newsettings = pdns::rust::settings::rec::parse_yaml_string("");
-  //GlobalStateHolder<LuaConfigItems> gsluaConfig;
-  //gsluaConfig.setState(luaConfig);
-  //LuaConfigItems local; // = gsluaConfig.getCopy();
+  // GlobalStateHolder<LuaConfigItems> gsluaConfig;
+  // gsluaConfig.setState(luaConfig);
+  // LuaConfigItems local; // = gsluaConfig.getCopy();
   try {
     pdns::settings::rec::fromLuaConfigToBridgeStruct(luaConfig, proxyMapping, newsettings);
   }
@@ -980,8 +980,12 @@ recordcache:
 
   std::ofstream aaa("a");
   std::ofstream bbb("b");
-  aaa << "===" << endl << yaml << endl << "===" << endl;
-  bbb << "===" << endl << newyaml << endl << "===" << endl;
+  aaa << "===" << endl
+      << yaml << endl
+      << "===" << endl;
+  bbb << "===" << endl
+      << newyaml << endl
+      << "===" << endl;
 
   BOOST_CHECK_EQUAL(yaml, std::string(newyaml));
 }
index 83a70d7acfaf0a742066d6febd815d12f620b22e..f9ed9450cd0b99058a66bd45c8c21e29340aa3ca 100644 (file)
@@ -68,10 +68,10 @@ class TestCarbon(RecursorTest):
                 cls._carbonQueue1.put(lines, True, timeout=2.0)
             else:
                 cls._carbonQueue2.put(lines, True, timeout=2.0)
-            if threading.currentThread().name in cls._carbonCounters:
-                cls._carbonCounters[threading.currentThread().name] += 1
+            if threading.current_thread().name in cls._carbonCounters:
+                cls._carbonCounters[threading.current_thread().name] += 1
             else:
-                cls._carbonCounters[threading.currentThread().name] = 1
+                cls._carbonCounters[threading.current_thread().name] = 1
 
             conn.close()
         sock.close()
@@ -79,11 +79,11 @@ class TestCarbon(RecursorTest):
     @classmethod
     def startResponders(cls):
         cls._CarbonResponder1 = threading.Thread(name='Carbon Responder 1', target=cls.CarbonResponder, args=[cls._carbonServer1Port])
-        cls._CarbonResponder1.setDaemon(True)
+        cls._CarbonResponder1.daemon = True
         cls._CarbonResponder1.start()
 
         cls._CarbonResponder2 = threading.Thread(name='Carbon Responder 2', target=cls.CarbonResponder, args=[cls._carbonServer2Port])
-        cls._CarbonResponder2.setDaemon(True)
+        cls._CarbonResponder2.daemon = True
         cls._CarbonResponder2.start()
 
     def testCarbon(self):
index d4e5e9d72b435ad9d85a63808a0b30f9c639bb3c..29a75cf1e24c6a1efba166bc784be7e2458bd161 100644 (file)
@@ -95,7 +95,7 @@ ecs-add-for=0.0.0.0/0
 
         if not reactor.running:
             cls._UDPResponder = threading.Thread(name='UDP Responder', target=reactor.run, args=(False,))
-            cls._UDPResponder.setDaemon(True)
+            cls._UDPResponder.daemon = True
             cls._UDPResponder.start()
 
     @classmethod
index 953a9ce20ead2a57aa4516deb8597f2b72ee935a..4a5007488bb5ef6c5c392bfbae4ca3e0a3ceb8cf 100644 (file)
@@ -52,7 +52,7 @@ def ProtobufListener(queue, port):
             thread = threading.Thread(name='Connection Handler',
                                       target=ProtobufConnectionHandler,
                                       args=[queue, conn])
-            thread.setDaemon(True)
+            thread.daemon = True
             thread.start()
 
         except socket.error as e:
@@ -70,7 +70,7 @@ protobufServersParameters = [ProtobufServerParams(4243), ProtobufServerParams(42
 protobufListeners = []
 for param in protobufServersParameters:
   listener = threading.Thread(name='Protobuf Listener', target=ProtobufListener, args=[param.queue, param.port])
-  listener.setDaemon(True)
+  listener.daemon = True
   listener.start()
   protobufListeners.append(listener)
 
index b5a0e8a9852068f9eb3a915b87381362128c3e33..baeb2db053d0dfd87df54487b36ea21fcd41f076 100644 (file)
@@ -17,7 +17,7 @@ class BadRPZServer(object):
         self._targetSerial = 1
         self._serverPort = port
         listener = threading.Thread(name='RPZ Listener', target=self._listener, args=[])
-        listener.setDaemon(True)
+        listener.daemon = True
         listener.start()
 
     def getCurrentSerial(self):
@@ -117,7 +117,7 @@ class BadRPZServer(object):
                 thread = threading.Thread(name='RPZ Connection Handler',
                                       target=self._connectionHandler,
                                       args=[conn])
-                thread.setDaemon(True)
+                thread.daemon = True
                 thread.start()
 
             except socket.error as e:
index 5856a1bb00cc35d35bc448274c8b0a186a5c2701..b975483d7d76e3367b0783368216d1ef3d45278c 100644 (file)
@@ -214,7 +214,7 @@ class TestRecursorDNSTap(RecursorTest):
             try:
                 (conn, addr) = sock.accept()
                 listener = threading.Thread(name='DNSTap Worker', target=cls.FrameStreamUnixListener, args=[conn, param])
-                listener.setDaemon(True)
+                listener.daemon = True
                 listener.start()
             except socket.error as e:
                 if e.errno != errno.EBADF:
@@ -233,7 +233,7 @@ class TestRecursorDNSTap(RecursorTest):
         cls.startResponders()
 
         listener = threading.Thread(name='DNSTap Listener', target=cls.FrameStreamUnixListenerMain, args=[DNSTapServerParameters])
-        listener.setDaemon(True)
+        listener.daemon = True
         listener.start()
 
         confdir = os.path.join('configs', cls._confdir)