diff --git a/pdns/dnsdistdist/dnsdist-configuration.hh b/pdns/dnsdistdist/dnsdist-configuration.hh index ed1e570bc6875..f33b7ea7e0a1b 100644 --- a/pdns/dnsdistdist/dnsdist-configuration.hh +++ b/pdns/dnsdistdist/dnsdist-configuration.hh @@ -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 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; diff --git a/pdns/dnsdistdist/dnsdist-console.cc b/pdns/dnsdistdist/dnsdist-console.cc index 77dee4e812b42..d4b1b7b552ec8 100644 --- a/pdns/dnsdistdist/dnsdist-console.cc +++ b/pdns/dnsdistdist/dnsdist-console.cc @@ -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 #include @@ -91,11 +91,6 @@ class ConsoleConnection 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 g_consoleKeywords +static const std::vector 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 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(text), &my_generator); + matches = rl_completion_matches(const_cast(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& 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 acceptFD, ComboAddress local) +void controlThread(std::shared_ptr&& 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 acceptFD, ComboAddress local) errlog("Control thread died: %s", e.what()); } } - -void clearConsoleHistory() -{ -#ifdef HAVE_LIBEDIT - clear_history(); -#endif /* HAVE_LIBEDIT */ - s_confDelta.lock()->clear(); } diff --git a/pdns/dnsdistdist/dnsdist-console.hh b/pdns/dnsdistdist/dnsdist-console.hh index 077fc2609ce67..e59e58b99d74d 100644 --- a/pdns/dnsdistdist/dnsdist-console.hh +++ b/pdns/dnsdistdist/dnsdist-console.hh @@ -27,6 +27,14 @@ #include "config.h" #include "sstuff.hh" +namespace dnsdist::console +{ +const std::vector>& getConfigurationDelta(); +void doClient(const std::string& command); +void doConsole(); +void controlThread(std::shared_ptr&& acceptFD, ComboAddress local); +void clearHistory(); + #ifndef DISABLE_COMPLETION struct ConsoleKeyword { @@ -45,22 +53,8 @@ struct ConsoleKeyword return res; } }; -extern const std::vector g_consoleKeywords; -extern "C" -{ - char** my_completion(const char* text, int start, int end); -} +const std::vector& getConsoleKeywords(); #endif /* DISABLE_COMPLETION */ - -void doClient(ComboAddress server, const std::string& command); -void doConsole(); -void controlThread(std::shared_ptr acceptFD, ComboAddress local); -void clearConsoleHistory(); - -void setConsoleMaximumConcurrentConnections(size_t max); - -namespace dnsdist::console -{ -const std::vector>& getConfigurationDelta(); +void setupCompletion(); } diff --git a/pdns/dnsdistdist/dnsdist-lua.cc b/pdns/dnsdistdist/dnsdist-lua.cc index 713e737508ee9..fedc37dd1928a 100644 --- a/pdns/dnsdistdist/dnsdist-lua.cc +++ b/pdns/dnsdistdist/dnsdist-lua.cc @@ -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::max()}, #endif /* DISABLE_RECVMMSG */ {"setUDPTimeout", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_udpTimeout = newValue; }, std::numeric_limits::max()}, + {"setConsoleMaximumConcurrentConnections", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_consoleMaxConcurrentConnections = newValue; }, std::numeric_limits::max()}, }; struct DoubleImmutableConfigurationItems { @@ -1378,7 +1379,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; } @@ -1396,7 +1399,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) { @@ -1458,11 +1461,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}; { @@ -1523,7 +1521,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) }); luaCtx.writeFunction("clearConsoleHistory", []() { - clearConsoleHistory(); + dnsdist::console::clearHistory(); }); luaCtx.writeFunction("testCrypto", [](boost::optional optTestMsg) { @@ -1986,7 +1984,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"; } diff --git a/pdns/dnsdistdist/dnsdist-web.cc b/pdns/dnsdistdist/dnsdist-web.cc index 24395fdb0a030..fe019e2e2a0ea 100644 --- a/pdns/dnsdistdist/dnsdist-web.cc +++ b/pdns/dnsdistdist/dnsdist-web.cc @@ -1452,7 +1452,7 @@ static void handleConfigDump(const YaHTTP::Request& req, YaHTTP::Response& resp) std::vector> 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(runtimeConfiguration.d_ECSSourcePrefixV4)}, {"ecs-source-prefix-v6", static_cast(runtimeConfiguration.d_ECSSourcePrefixV6)}, diff --git a/pdns/dnsdistdist/dnsdist.cc b/pdns/dnsdistdist/dnsdist.cc index 0aeb912274066..d023cb9fcffa6 100644 --- a/pdns/dnsdistdist/dnsdist.cc +++ b/pdns/dnsdistdist/dnsdist.cc @@ -33,16 +33,6 @@ #include #include -#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 -#else -#include -#endif -#endif /* HAVE_LIBEDIT */ - #include "dnsdist-systemd.hh" #ifdef HAVE_SYSTEMD #include @@ -877,7 +867,6 @@ void responderThread(std::shared_ptr dss) } RecursiveLockGuarded 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(); diff --git a/pdns/dnsdistdist/dnsdist.hh b/pdns/dnsdistdist/dnsdist.hh index 4b946fd376717..2ea1812127be9 100644 --- a/pdns/dnsdistdist/dnsdist.hh +++ b/pdns/dnsdistdist/dnsdist.hh @@ -1030,8 +1030,6 @@ extern GlobalStateHolder g_dstates; extern GlobalStateHolder g_pools; extern GlobalStateHolder g_ACL; -extern ComboAddress g_serverControl; // not changed during runtime - extern std::vector> g_tlslocals; extern std::vector> g_dohlocals; extern std::vector> g_doqlocals;