]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Read the base Lua definitions into the Lua context for reading the Lua config.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 14 Feb 2022 09:22:05 +0000 (10:22 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 14 Feb 2022 09:25:55 +0000 (10:25 +0100)
This allows symbolic names for e.g. QTypes. Use that in protobufServer() and
outgoingProtobufServer(). Will also be used for the upcoming additional records code.

pdns/rec-lua-conf.cc
pdns/recursordist/docs/lua-config/protobuf.rst

index 92840a5d580f48ae1868cc7f843bab62d6af4589..7ebf707c5467fc22a9bdbfc0fced9e415bb9173a 100644 (file)
@@ -5,6 +5,7 @@
 #include <thread>
 #include "namespaces.hh"
 #include "logger.hh"
+#include "lua-base4.hh"
 #include "rec-lua-conf.hh"
 #include "sortlist.hh"
 #include "filterpo.hh"
@@ -150,20 +151,19 @@ static void parseProtobufOptions(boost::optional<protobufOptions_t> vars, Protob
 
     auto types = boost::get<std::vector<std::pair<int, std::string>>>((*vars)["exportTypes"]);
     for (const auto& pair : types) {
-      const auto type = pair.second;
-      bool found = false;
-
-      for (const auto& entry : QType::names) {
-        if (entry.first == type) {
-          found = true;
-          config.exportTypes.insert(entry.second);
-          break;
-        }
-      }
+      const auto& type = pair.second;
 
-      if (!found) {
-        throw std::runtime_error("Unknown QType '" + type + "' in protobuf's export types");
+      QType qtype;
+      try {
+        qtype = std::stoul(type);
       }
+      catch (const std::exception& ex) {
+        qtype = QType::chartocode(type.c_str());
+        if (qtype == 0) {
+          throw std::runtime_error("Unknown QType '" + type + "' in protobuf's export types");
+        }
+      }
+      config.exportTypes.insert(qtype);
     }
   }
 }
@@ -322,11 +322,33 @@ static void rpzPrimary(LuaConfigItems& lci, luaConfigDelayedThreads& delayedThre
   delayedThreads.rpzPrimaryThreads.push_back(std::make_tuple(primaries, defpol, defpolOverrideLocal, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes, localAddress, axfrTimeout, refresh, sr, dumpFile));
 }
 
+// A wrapper clas that load the snadrad Lua defintions into the conext, so that we can use things
+// like pdns.A
+class RecLuaConfigContext : public BaseLua4
+{
+public:
+  RecLuaConfigContext()
+  {
+    prepareContext();
+  }
+  virtual void postPrepareContext() override
+  {
+  }
+  void postLoad() override
+  {
+  }
+  std::unique_ptr<LuaContext>& operator()()
+  {
+    return d_lw;
+  }
+};
+
 void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& delayedThreads)
 {
   LuaConfigItems lci;
 
-  LuaContext Lua;
+  RecLuaConfigContext Lua;
+
   if (fname.empty())
     return;
   ifstream ifs(fname);
@@ -336,21 +358,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
   auto luaconfsLocal = g_luaconfs.getLocal();
   lci.generation = luaconfsLocal->generation + 1;
 
-  // pdnslog here is compatible with pdnslog in lua-base4.cc.
-  Lua.writeFunction("pdnslog", [](const std::string& msg, boost::optional<int> loglevel) { g_log << (Logger::Urgency)loglevel.get_value_or(Logger::Warning) << msg << endl; });
-  std::unordered_map<string, std::unordered_map<string, int>> pdns_table;
-  pdns_table["loglevels"] = std::unordered_map<string, int>{
-    {"Alert", LOG_ALERT},
-    {"Critical", LOG_CRIT},
-    {"Debug", LOG_DEBUG},
-    {"Emergency", LOG_EMERG},
-    {"Info", LOG_INFO},
-    {"Notice", LOG_NOTICE},
-    {"Warning", LOG_WARNING},
-    {"Error", LOG_ERR}};
-  Lua.writeVariable("pdns", pdns_table);
-
-  Lua.writeFunction("clearSortlist", [&lci]() { lci.sortlist.clear(); });
+  Lua()->writeFunction("clearSortlist", [&lci]() { lci.sortlist.clear(); });
 
   /* we can get: "1.2.3.4"
                  {"1.2.3.4", "4.5.6.7"}
@@ -364,9 +372,9 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
     {"NODATA", DNSFilterEngine::PolicyKind::NODATA},
     {"Truncate", DNSFilterEngine::PolicyKind::Truncate},
     {"Custom", DNSFilterEngine::PolicyKind::Custom}};
-  Lua.writeVariable("Policy", pmap);
+  Lua()->writeVariable("Policy", pmap);
 
-  Lua.writeFunction("rpzFile", [&lci](const string& filename, boost::optional<rpzOptions_t> options) {
+  Lua()->writeFunction("rpzFile", [&lci](const string& filename, boost::optional<rpzOptions_t> options) {
     try {
       boost::optional<DNSFilterEngine::Policy> defpol;
       bool defpolOverrideLocal = true;
@@ -388,17 +396,17 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
     }
   });
 
-  Lua.writeFunction("rpzMaster", [&lci, &delayedThreads](const boost::variant<string, std::vector<std::pair<int, string>>>& primaries_, const string& zoneName, boost::optional<rpzOptions_t> options) {
+  Lua()->writeFunction("rpzMaster", [&lci, &delayedThreads](const boost::variant<string, std::vector<std::pair<int, string>>>& primaries_, const string& zoneName, boost::optional<rpzOptions_t> options) {
     g_log << Logger::Warning << "'rpzMaster' is deprecated and will be removed in a future release, use 'rpzPrimary' instead" << endl;
     rpzPrimary(lci, delayedThreads, primaries_, zoneName, options);
   });
-  Lua.writeFunction("rpzPrimary", [&lci, &delayedThreads](const boost::variant<string, std::vector<std::pair<int, string>>>& primaries_, const string& zoneName, boost::optional<rpzOptions_t> options) {
+  Lua()->writeFunction("rpzPrimary", [&lci, &delayedThreads](const boost::variant<string, std::vector<std::pair<int, string>>>& primaries_, const string& zoneName, boost::optional<rpzOptions_t> options) {
     rpzPrimary(lci, delayedThreads, primaries_, zoneName, options);
   });
 
   typedef std::unordered_map<std::string, boost::variant<uint32_t, std::string>> zoneToCacheOptions_t;
 
-  Lua.writeFunction("zoneToCache", [&lci](const string& zoneName, const string& method, const boost::variant<string, std::vector<std::pair<int, string>>>& srcs, boost::optional<zoneToCacheOptions_t> options) {
+  Lua()->writeFunction("zoneToCache", [&lci](const string& zoneName, const string& method, const boost::variant<string, std::vector<std::pair<int, string>>>& srcs, boost::optional<zoneToCacheOptions_t> options) {
     try {
       RecZoneToCache::Config conf;
       DNSName validZoneName(zoneName);
@@ -479,7 +487,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
   });
 
   typedef vector<pair<int, boost::variant<string, vector<pair<int, string>>>>> argvec_t;
-  Lua.writeFunction("addSortList",
+  Lua()->writeFunction("addSortList",
                     [&lci](const std::string& formask_,
                            const boost::variant<string, argvec_t>& masks,
                            boost::optional<int> order_) {
@@ -509,14 +517,14 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
                       }
                     });
 
-  Lua.writeFunction("addTA", [&lci](const std::string& who, const std::string& what) {
+  Lua()->writeFunction("addTA", [&lci](const std::string& who, const std::string& what) {
     warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC (addTA), but dnssec is set to 'off'!");
     DNSName zone(who);
     auto ds = std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(what));
     lci.dsAnchors[zone].insert(*ds);
   });
 
-  Lua.writeFunction("clearTA", [&lci](boost::optional<string> who) {
+  Lua()->writeFunction("clearTA", [&lci](boost::optional<string> who) {
     warnIfDNSSECDisabled("Warning: removing Trust Anchor for DNSSEC (clearTA), but dnssec is set to 'off'!");
     if (who)
       lci.dsAnchors.erase(DNSName(*who));
@@ -525,7 +533,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
   });
 
   /* Remove in 4.3 */
-  Lua.writeFunction("addDS", [&lci](const std::string& who, const std::string& what) {
+  Lua()->writeFunction("addDS", [&lci](const std::string& who, const std::string& what) {
     warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC (addDS), but dnssec is set to 'off'!");
     g_log << Logger::Warning << "addDS is deprecated and will be removed in the future, switch to addTA" << endl;
     DNSName zone(who);
@@ -534,7 +542,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
   });
 
   /* Remove in 4.3 */
-  Lua.writeFunction("clearDS", [&lci](boost::optional<string> who) {
+  Lua()->writeFunction("clearDS", [&lci](boost::optional<string> who) {
     g_log << Logger::Warning << "clearDS is deprecated and will be removed in the future, switch to clearTA" << endl;
     warnIfDNSSECDisabled("Warning: removing Trust Anchor for DNSSEC (clearDS), but dnssec is set to 'off'!");
     if (who)
@@ -543,7 +551,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
       lci.dsAnchors.clear();
   });
 
-  Lua.writeFunction("addNTA", [&lci](const std::string& who, const boost::optional<std::string> why) {
+  Lua()->writeFunction("addNTA", [&lci](const std::string& who, const boost::optional<std::string> why) {
     warnIfDNSSECDisabled("Warning: adding Negative Trust Anchor for DNSSEC (addNTA), but dnssec is set to 'off'!");
     if (why)
       lci.negAnchors[DNSName(who)] = static_cast<string>(*why);
@@ -551,7 +559,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
       lci.negAnchors[DNSName(who)] = "";
   });
 
-  Lua.writeFunction("clearNTA", [&lci](boost::optional<string> who) {
+  Lua()->writeFunction("clearNTA", [&lci](boost::optional<string> who) {
     warnIfDNSSECDisabled("Warning: removing Negative Trust Anchor for DNSSEC (clearNTA), but dnssec is set to 'off'!");
     if (who)
       lci.negAnchors.erase(DNSName(*who));
@@ -559,7 +567,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
       lci.negAnchors.clear();
   });
 
-  Lua.writeFunction("readTrustAnchorsFromFile", [&lci](const std::string& fnamearg, const boost::optional<uint32_t> interval) {
+  Lua()->writeFunction("readTrustAnchorsFromFile", [&lci](const std::string& fnamearg, const boost::optional<uint32_t> interval) {
     uint32_t realInterval = 24;
     if (interval) {
       realInterval = static_cast<uint32_t>(*interval);
@@ -570,12 +578,12 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
     updateTrustAnchorsFromFile(fnamearg, lci.dsAnchors);
   });
 
-  Lua.writeFunction("setProtobufMasks", [&lci](const uint8_t maskV4, uint8_t maskV6) {
+  Lua()->writeFunction("setProtobufMasks", [&lci](const uint8_t maskV4, uint8_t maskV6) {
     lci.protobufMaskV4 = maskV4;
     lci.protobufMaskV6 = maskV6;
   });
 
-  Lua.writeFunction("protobufServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<protobufOptions_t> vars) {
+  Lua()->writeFunction("protobufServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<protobufOptions_t> vars) {
     if (!lci.protobufExportConfig.enabled) {
 
       lci.protobufExportConfig.enabled = true;
@@ -607,7 +615,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
     }
   });
 
-  Lua.writeFunction("outgoingProtobufServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<protobufOptions_t> vars) {
+  Lua()->writeFunction("outgoingProtobufServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<protobufOptions_t> vars) {
     if (!lci.outgoingProtobufExportConfig.enabled) {
 
       lci.outgoingProtobufExportConfig.enabled = true;
@@ -640,7 +648,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
   });
 
 #ifdef HAVE_FSTRM
-  Lua.writeFunction("dnstapFrameStreamServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<frameStreamOptions_t> vars) {
+  Lua()->writeFunction("dnstapFrameStreamServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<frameStreamOptions_t> vars) {
     if (!lci.frameStreamExportConfig.enabled) {
 
       lci.frameStreamExportConfig.enabled = true;
@@ -676,7 +684,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
 #endif /* HAVE_FSTRM */
 
   try {
-    Lua.executeCode(ifs);
+    Lua()->executeCode(ifs);
     g_luaconfs.setState(std::move(lci));
   }
   catch (const LuaContext::ExecutionErrorException& e) {
index c2c44dd7fe9aa864407355d0c49f666767262b36..21a222f89e78e968678c671f1a7514b4379c0322 100644 (file)
@@ -33,6 +33,10 @@ Protobuf export to a server is enabled using the ``protobufServer()`` directive:
   * ``logResponses=true``: bool - Whether to export responses
   * ``exportTypes={'A', 'AAAA', 'CNAME'}``: list of strings - The list of record types found in the answer section to export. Only A, AAAA, CNAME, MX, NS, PTR, SPF, SRV and TXT are currently supported
 
+  .. versionchanged:: 4.7.0
+
+  The values in ``exportTypes`` can be numeric as well as strings. Symbolic names from ``pdns`` can be used, e.g.  ``exportTypes = { pdns.A, pdns.AAAA, pdns.CNAME }``
+
 .. function:: protobufServer(server [[[[[[[, timeout=2], maxQueuedEntries=100], reconnectWaitTime=1], maskV4=32], maskV6=128], asyncConnect=false], taggedOnly=false])
 
   .. deprecated:: 4.2.0
@@ -77,7 +81,11 @@ While :func:`protobufServer` only exports the queries sent to the recursor from
   * ``asyncConnect``: bool - When set to false (default) the first connection to the server during startup will block up to ``timeout`` seconds, otherwise the connection is done in a separate thread, after the first message has been queued
   * ``logQueries=true``: bool - Whether to export queries
   * ``logResponses=true``: bool - Whether to export responses
-  * ``exportTypes={'A', 'AAAA', 'CNAME'}``: list of strings - The list of record types found in the answer section to export. Only A, AAAA, CNAME, MX, NS, PTR, SPF, SRV and TXT are currently supported
+  * ``exportTypes={'A', 'AAAA', 'CNAME'}``: list of strings or qtypes - The list of record types found in the answer section to export. Only A, AAAA, CNAME, MX, NS, PTR, SPF, SRV and TXT are currently supported
+
+  .. versionchanged:: 4.7.0
+
+  The values in ``exportTypes`` can be numeric as well as strings. Symbolic names from ``pdns`` can be used, e.g.  ``exportTypes = { pdns.A, pdns.AAAA, pdns.CNAME }``
 
 .. function:: outgoingProtobufServer(server [[[[, timeout=2], maxQueuedEntries=100], reconnectWaitTime=1], asyncConnect=false])