]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Clean up console configuration
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 30 May 2024 14:13:41 +0000 (16:13 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 15 Jul 2024 09:39:35 +0000 (11:39 +0200)
pdns/dnsdistdist/dnsdist-configuration.hh
pdns/dnsdistdist/dnsdist-console.cc
pdns/dnsdistdist/dnsdist-console.hh
pdns/dnsdistdist/dnsdist-lua.cc
pdns/dnsdistdist/dnsdist-web.cc
pdns/dnsdistdist/dnsdist.cc
pdns/dnsdistdist/dnsdist.hh

index ed1e570bc6875972996e2634da0d80724c2e9864..f33b7ea7e0a1b89b5650a90eaaf23e048ab86475 100644 (file)
@@ -143,9 +143,12 @@ static constexpr uint16_t s_defaultPayloadSizeSelfGenAnswers = 1232;
 static constexpr uint16_t s_udpIncomingBufferSize{1500}; // don't accept UDP queries larger than this value
 static_assert(s_defaultPayloadSizeSelfGenAnswers < s_udpIncomingBufferSize, "The UDP responder's payload size should be smaller or equal to our incoming buffer size");
 
+/* this part of the configuration can only be updated at configuration
+   time, and is immutable once the configuration phase is over */
 struct Configuration
 {
   std::set<std::string> d_capabilitiesToRetain;
+  ComboAddress d_consoleServerAddress{"127.0.0.1:5199"};
   std::string d_consoleKey;
 #ifdef __linux__
   // On Linux this gives us 128k pending queries (default is 8192 queries),
@@ -158,6 +161,7 @@ struct Configuration
 #endif
   double d_weightedBalancingFactor{0};
   double d_consistentHashBalancingFactor{0};
+  uint64_t d_consoleMaxConcurrentConnections{0};
   uint64_t d_maxTCPClientThreads{0};
   size_t d_maxTCPConnectionsPerClient{0};
   size_t d_udpVectorSize{1};
@@ -170,6 +174,8 @@ struct Configuration
   bool d_randomizeIDsToBackend{false};
 };
 
+/* this part of the configuration can be updated at runtime via
+   a RCU-like mechanism */
 struct RuntimeConfiguration
 {
   NetmaskGroup d_proxyProtocolACL;
index 77dee4e812b4206a55f796a32f661303b47f8b57..d4b1b7b552ec88b0755b78f80a4e303ea31a2928 100644 (file)
@@ -28,7 +28,7 @@
 
 #ifdef HAVE_LIBEDIT
 #if defined(__OpenBSD__) || defined(__NetBSD__)
-// If this is not undeffed, __attribute__ wil be redefined by /usr/include/readline/rlstdc.h
+// If this is not undeffed, __attribute__ will be redefined by /usr/include/readline/rlstdc.h
 #undef __STRICT_ANSI__
 #include <readline/readline.h>
 #include <readline/history.h>
@@ -91,11 +91,6 @@ private:
   FDWrapper d_fileDesc;
 };
 
-void setConsoleMaximumConcurrentConnections(size_t max)
-{
-  s_connManager.setMaxConcurrentConnections(max);
-}
-
 static void feedConfigDelta(const std::string& line)
 {
   if (line.empty()) {
@@ -226,9 +221,12 @@ static ConsoleCommandResult sendMessageToServer(int fileDesc, const std::string&
   return ConsoleCommandResult::Valid;
 }
 
-void doClient(ComboAddress server, const std::string& command)
+namespace dnsdist::console
 {
-  const auto& consoleKey = dnsdist::configuration::getImmutableConfiguration().d_consoleKey;
+void doClient(const std::string& command)
+{
+  const auto consoleKey = dnsdist::configuration::getImmutableConfiguration().d_consoleKey;
+  const auto server = dnsdist::configuration::getImmutableConfiguration().d_consoleServerAddress;
   if (!dnsdist::crypto::authenticated::isValidKey(consoleKey)) {
     cerr << "The currently configured console key is not valid, please configure a valid key using the setKey() directive" << endl;
     return;
@@ -475,10 +473,11 @@ void doConsole()
     }
   }
 }
+}
 
 #ifndef DISABLE_COMPLETION
 /**** CARGO CULT CODE AHEAD ****/
-const std::vector<ConsoleKeyword> g_consoleKeywords
+static const std::vector<dnsdist::console::ConsoleKeyword> s_consoleKeywords
 {
   /* keyword, function, parameters, description */
   {"addACL", true, "netmask", "add to the ACL set who can use this server"},
@@ -855,7 +854,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords
 #if defined(HAVE_LIBEDIT)
 extern "C"
 {
-  static char* my_generator(const char* text, int state)
+  static char* dnsdist_completion_generator(const char* text, int state)
   {
     string textStr(text);
     /* to keep it readable, we try to keep only 4 keywords per line
@@ -866,7 +865,7 @@ extern "C"
       s_counter = 0;
     }
 
-    for (const auto& keyword : g_consoleKeywords) {
+    for (const auto& keyword : s_consoleKeywords) {
       if (boost::starts_with(keyword.name, textStr) && counter++ == s_counter) {
         std::string value(keyword.name);
         s_counter++;
@@ -882,12 +881,12 @@ extern "C"
     return nullptr;
   }
 
-  char** my_completion(const char* text, int start, int end)
+  static char** dnsdist_completion_callback(const char* text, int start, int end)
   {
     char** matches = nullptr;
     if (start == 0) {
       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast): readline
-      matches = rl_completion_matches(const_cast<char*>(text), &my_generator);
+      matches = rl_completion_matches(const_cast<char*>(text), &dnsdist_completion_generator);
     }
 
     // skip default filename completion.
@@ -899,6 +898,33 @@ extern "C"
 #endif /* HAVE_LIBEDIT */
 #endif /* DISABLE_COMPLETION */
 
+namespace dnsdist::console
+{
+#ifndef DISABLE_COMPLETION
+const std::vector<ConsoleKeyword>& getConsoleKeywords()
+{
+  return s_consoleKeywords;
+}
+#endif /* DISABLE_COMPLETION */
+
+void setupCompletion()
+{
+#ifndef DISABLE_COMPLETION
+#ifdef HAVE_LIBEDIT
+  rl_attempted_completion_function = dnsdist_completion_callback;
+  rl_completion_append_character = 0;
+#endif /* DISABLE_COMPLETION */
+#endif /* HAVE_LIBEDIT */
+}
+
+void clearHistory()
+{
+#ifdef HAVE_LIBEDIT
+  clear_history();
+#endif /* HAVE_LIBEDIT */
+  s_confDelta.lock()->clear();
+}
+
 static void controlClientThread(ConsoleConnection&& conn)
 {
   try {
@@ -1040,10 +1066,12 @@ static void controlClientThread(ConsoleConnection&& conn)
 }
 
 // NOLINTNEXTLINE(performance-unnecessary-value-param): this is thread
-void controlThread(std::shared_ptr<Socket> acceptFD, ComboAddress local)
+void controlThread(std::shared_ptr<Socket>&& acceptFD, ComboAddress local)
 {
   try {
     setThreadName("dnsdist/control");
+    s_connManager.setMaxConcurrentConnections(dnsdist::configuration::getImmutableConfiguration().d_consoleMaxConcurrentConnections);
+
     ComboAddress client;
     // make sure that the family matches the one from the listening IP,
     // so that getSocklen() returns the correct size later, otherwise
@@ -1085,11 +1113,4 @@ void controlThread(std::shared_ptr<Socket> acceptFD, ComboAddress local)
     errlog("Control thread died: %s", e.what());
   }
 }
-
-void clearConsoleHistory()
-{
-#ifdef HAVE_LIBEDIT
-  clear_history();
-#endif /* HAVE_LIBEDIT */
-  s_confDelta.lock()->clear();
 }
index 077fc2609ce6762d687ec4501ed1a4dd08c0ec98..e59e58b99d74d0702285ed4b8a811466180807ce 100644 (file)
 #include "config.h"
 #include "sstuff.hh"
 
+namespace dnsdist::console
+{
+const std::vector<std::pair<timeval, std::string>>& getConfigurationDelta();
+void doClient(const std::string& command);
+void doConsole();
+void controlThread(std::shared_ptr<Socket>&& acceptFD, ComboAddress local);
+void clearHistory();
+
 #ifndef DISABLE_COMPLETION
 struct ConsoleKeyword
 {
@@ -45,22 +53,8 @@ struct ConsoleKeyword
     return res;
   }
 };
-extern const std::vector<ConsoleKeyword> g_consoleKeywords;
-extern "C"
-{
-  char** my_completion(const char* text, int start, int end);
-}
 
+const std::vector<ConsoleKeyword>& getConsoleKeywords();
 #endif /* DISABLE_COMPLETION */
-
-void doClient(ComboAddress server, const std::string& command);
-void doConsole();
-void controlThread(std::shared_ptr<Socket> acceptFD, ComboAddress local);
-void clearConsoleHistory();
-
-void setConsoleMaximumConcurrentConnections(size_t max);
-
-namespace dnsdist::console
-{
-const std::vector<std::pair<timeval, std::string>>& getConfigurationDelta();
+void setupCompletion();
 }
index dc33e0c7d99af9f76e82e20762a23ac37646e4c5..8e55dea4ba44d5d4e9cab327faae205074755209 100644 (file)
@@ -881,6 +881,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     {"setUDPMultipleMessagesVectorSize", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_udpVectorSize = newValue; }, std::numeric_limits<uint32_t>::max()},
 #endif /* DISABLE_RECVMMSG */
     {"setUDPTimeout", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_udpTimeout = newValue; }, std::numeric_limits<uint8_t>::max()},
+    {"setConsoleMaximumConcurrentConnections", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_consoleMaxConcurrentConnections = newValue; }, std::numeric_limits<uint32_t>::max()},
   };
   struct DoubleImmutableConfigurationItems
   {
@@ -1380,7 +1381,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     ComboAddress local(str, 5199);
 
     if (client || configCheck) {
-      g_serverControl = local;
+      dnsdist::configuration::updateImmutableConfiguration([&local](dnsdist::configuration::Configuration& config) {
+        config.d_consoleServerAddress = local;
+      });
       return;
     }
 
@@ -1398,7 +1401,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       sock->bind(local, true);
       sock->listen(5);
       auto launch = [sock = std::move(sock), local]() {
-        std::thread consoleControlThread(controlThread, sock, local);
+        std::thread consoleControlThread(dnsdist::console::controlThread, std::move(sock), local);
         consoleControlThread.detach();
       };
       if (g_launchWork) {
@@ -1460,11 +1463,6 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     }
   });
 
-  luaCtx.writeFunction("setConsoleMaximumConcurrentConnections", [](uint64_t max) {
-    setLuaSideEffect();
-    setConsoleMaximumConcurrentConnections(max);
-  });
-
   luaCtx.writeFunction("clearQueryCounters", []() {
     unsigned int size{0};
     {
@@ -1525,7 +1523,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
   });
 
   luaCtx.writeFunction("clearConsoleHistory", []() {
-    clearConsoleHistory();
+    dnsdist::console::clearHistory();
   });
 
   luaCtx.writeFunction("testCrypto", [](boost::optional<string> optTestMsg) {
@@ -1988,7 +1986,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     setLuaNoSideEffect();
     g_outputBuffer = "";
 #ifndef DISABLE_COMPLETION
-    for (const auto& keyword : g_consoleKeywords) {
+    for (const auto& keyword : dnsdist::console::getConsoleKeywords()) {
       if (!command) {
         g_outputBuffer += keyword.toString() + "\n";
       }
index 24395fdb0a03095f28fe08c7c6ffc0cdcad7b7ac..fe019e2e2a0ea9ba62dfd3bebc34cd1d1c03d3ef 100644 (file)
@@ -1452,7 +1452,7 @@ static void handleConfigDump(const YaHTTP::Request& req, YaHTTP::Response& resp)
   std::vector<std::pair<std::string, configentry_t>> configEntries{
     {"acl", g_ACL.getLocal()->toString()},
     {"allow-empty-response", runtimeConfiguration.d_allowEmptyResponse},
-    {"control-socket", g_serverControl.toStringWithPort()},
+    {"control-socket", immutableConfig.d_consoleServerAddress.toStringWithPort()},
     {"ecs-override", runtimeConfiguration.d_ecsOverride},
     {"ecs-source-prefix-v4", static_cast<double>(runtimeConfiguration.d_ECSSourcePrefixV4)},
     {"ecs-source-prefix-v6", static_cast<double>(runtimeConfiguration.d_ECSSourcePrefixV6)},
index 44c2f9de2f0ff23551de6637fab08c369e13bc1e..ea1b715248e23866e12740d4d94c58f845b13380 100644 (file)
 #include <sys/resource.h>
 #include <unistd.h>
 
-#ifdef HAVE_LIBEDIT
-#if defined(__OpenBSD__) || defined(__NetBSD__)
-// If this is not undeffed, __attribute__ wil be redefined by /usr/include/readline/rlstdc.h
-#undef __STRICT_ANSI__
-#include <readline/readline.h>
-#else
-#include <editline/readline.h>
-#endif
-#endif /* HAVE_LIBEDIT */
-
 #include "dnsdist-systemd.hh"
 #ifdef HAVE_SYSTEMD
 #include <systemd/sd-daemon.h>
@@ -877,7 +867,6 @@ void responderThread(std::shared_ptr<DownstreamState> dss)
 }
 
 RecursiveLockGuarded<LuaContext> g_lua{LuaContext()};
-ComboAddress g_serverControl{"127.0.0.1:5199"};
 
 static void spoofResponseFromString(DNSQuestion& dnsQuestion, const string& spoofContent, bool raw)
 {
@@ -3267,12 +3256,8 @@ int main(int argc, char** argv)
   try {
     size_t udpBindsCount = 0;
     size_t tcpBindsCount = 0;
-#ifdef HAVE_LIBEDIT
-#ifndef DISABLE_COMPLETION
-    rl_attempted_completion_function = my_completion;
-    rl_completion_append_character = 0;
-#endif /* DISABLE_COMPLETION */
-#endif /* HAVE_LIBEDIT */
+
+    dnsdist::console::setupCompletion();
 
     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast): SIG_IGN macro
     signal(SIGPIPE, SIG_IGN);
@@ -3315,9 +3300,11 @@ int main(int argc, char** argv)
     if (g_cmdLine.beClient || !g_cmdLine.command.empty()) {
       setupLua(*(g_lua.lock()), true, false, g_cmdLine.config);
       if (clientAddress != ComboAddress()) {
-        g_serverControl = clientAddress;
+        dnsdist::configuration::updateImmutableConfiguration([&clientAddress](dnsdist::configuration::Configuration& config) {
+          config.d_consoleServerAddress = clientAddress;
+        });
       }
-      doClient(g_serverControl, g_cmdLine.command);
+      dnsdist::console::doClient(g_cmdLine.command);
 #ifdef COVERAGE
       exit(EXIT_SUCCESS);
 #else
@@ -3516,7 +3503,7 @@ int main(int argc, char** argv)
     }
     else {
       healththread.detach();
-      doConsole();
+      dnsdist::console::doConsole();
     }
 #ifdef COVERAGE
     cleanupLuaObjects();
index 6fdd47394e09b1d5fec94b125cad799e179c6e19..9b5fdabf72a1a27df3bacd8b3a36971d4d9564ba 100644 (file)
@@ -1031,8 +1031,6 @@ extern GlobalStateHolder<servers_t> g_dstates;
 extern GlobalStateHolder<pools_t> g_pools;
 extern GlobalStateHolder<NetmaskGroup> g_ACL;
 
-extern ComboAddress g_serverControl; // not changed during runtime
-
 extern std::vector<shared_ptr<TLSFrontend>> g_tlslocals;
 extern std::vector<shared_ptr<DOHFrontend>> g_dohlocals;
 extern std::vector<shared_ptr<DOQFrontend>> g_doqlocals;