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),
#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};
bool d_randomizeIDsToBackend{false};
};
+/* this part of the configuration can be updated at runtime via
+ a RCU-like mechanism */
struct RuntimeConfiguration
{
NetmaskGroup d_proxyProtocolACL;
#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>
FDWrapper d_fileDesc;
};
-void setConsoleMaximumConcurrentConnections(size_t max)
-{
- s_connManager.setMaxConcurrentConnections(max);
-}
-
static void feedConfigDelta(const std::string& line)
{
if (line.empty()) {
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;
}
}
}
+}
#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"},
#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
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++;
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.
#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 {
}
// 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
errlog("Control thread died: %s", e.what());
}
}
-
-void clearConsoleHistory()
-{
-#ifdef HAVE_LIBEDIT
- clear_history();
-#endif /* HAVE_LIBEDIT */
- s_confDelta.lock()->clear();
}
#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
{
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();
}
{"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
{
ComboAddress local(str, 5199);
if (client || configCheck) {
- g_serverControl = local;
+ dnsdist::configuration::updateImmutableConfiguration([&local](dnsdist::configuration::Configuration& config) {
+ config.d_consoleServerAddress = local;
+ });
return;
}
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) {
}
});
- luaCtx.writeFunction("setConsoleMaximumConcurrentConnections", [](uint64_t max) {
- setLuaSideEffect();
- setConsoleMaximumConcurrentConnections(max);
- });
-
luaCtx.writeFunction("clearQueryCounters", []() {
unsigned int size{0};
{
});
luaCtx.writeFunction("clearConsoleHistory", []() {
- clearConsoleHistory();
+ dnsdist::console::clearHistory();
});
luaCtx.writeFunction("testCrypto", [](boost::optional<string> optTestMsg) {
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";
}
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)},
#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>
}
RecursiveLockGuarded<LuaContext> g_lua{LuaContext()};
-ComboAddress g_serverControl{"127.0.0.1:5199"};
static void spoofResponseFromString(DNSQuestion& dnsQuestion, const string& spoofContent, bool raw)
{
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);
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
}
else {
healththread.detach();
- doConsole();
+ dnsdist::console::doConsole();
}
#ifdef COVERAGE
cleanupLuaObjects();
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;