Skip to content

Commit

Permalink
dnsdist: Move Rings to the new configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
rgacogne committed Jul 5, 2024
1 parent 3d82e6b commit 8477f0b
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 114 deletions.
1 change: 0 additions & 1 deletion pdns/dnsdistdist/dnsdist-carbon.hh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public:

static Endpoint newEndpoint(const std::string& address, std::string ourName, uint64_t interval, const std::string& namespace_name, const std::string& instance_name);
static void run(const std::vector<Endpoint>& endpoints);
static void addEndpointAtRuntime(const Endpoint& endpoint);
};

}
Expand Down
8 changes: 8 additions & 0 deletions pdns/dnsdistdist/dnsdist-configuration.hh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <optional>
#include <string>

#include "config.h"
#include "credentials.hh"
#include "dnsdist-carbon.hh"
#include "dnsdist-query-count.hh"
Expand Down Expand Up @@ -182,13 +183,18 @@ struct Configuration
uint64_t d_maxTCPClientThreads{0};
size_t d_maxTCPConnectionsPerClient{0};
size_t d_udpVectorSize{1};
size_t d_ringsCapacity{10000};
size_t d_ringsNumberOfShards{10};
size_t d_ringsNbLockTries{5};
uint32_t d_socketUDPSendBuffer{0};
uint32_t d_socketUDPRecvBuffer{0};
uint32_t d_hashPerturbation{0};
uint16_t d_maxUDPOutstanding{std::numeric_limits<uint16_t>::max()};
uint8_t d_udpTimeout{2};
bool d_randomizeUDPSocketsToBackend{false};
bool d_randomizeIDsToBackend{false};
bool d_ringsRecordQueries{true};
bool d_ringsRecordResponses{true};
};

/* this part of the configuration can be updated at runtime via
Expand All @@ -197,7 +203,9 @@ struct RuntimeConfiguration
{
rules::RuleChains d_ruleChains;
servers_t d_backends;
#ifndef DISABLE_CARBON
std::vector<dnsdist::Carbon::Endpoint> d_carbonEndpoints;
#endif /* DISABLE_CARBON */
std::map<std::string, std::shared_ptr<ServerPool>> d_pools;
std::shared_ptr<const CredentialsHolder> d_webPassword;
std::shared_ptr<const CredentialsHolder> d_webAPIKey;
Expand Down
2 changes: 1 addition & 1 deletion pdns/dnsdistdist/dnsdist-dynblocks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#include "dnsdist-metrics.hh"
#include "sholder.hh"

#ifndef DISABLE_DYNBLOCKS
static GlobalStateHolder<ClientAddressDynamicRules> s_dynblockNMG;
static GlobalStateHolder<SuffixDynamicRules> s_dynblockSMT;

#ifndef DISABLE_DYNBLOCKS
void DynBlockRulesGroup::apply(const timespec& now)
{
counts_t counts;
Expand Down
91 changes: 48 additions & 43 deletions pdns/dnsdistdist/dnsdist-lua.cc
Original file line number Diff line number Diff line change
Expand Up @@ -860,27 +860,29 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
const std::function<void(dnsdist::configuration::Configuration& config, uint64_t value)> mutator;
const size_t maximumValue{std::numeric_limits<uint64_t>::max()};
};
static const std::vector<UnsignedIntegerImmutableConfigurationItems> unsignedIntegerImmutableConfigItems{
static const std::vector<UnsignedIntegerImmutableConfigurationItems> unsignedIntegerImmutableConfigItems
{
{"setMaxTCPQueuedConnections", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_maxTCPQueuedConnections = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setMaxTCPClientThreads", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_maxTCPClientThreads = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setMaxTCPConnectionsPerClient", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_maxTCPConnectionsPerClient = newValue; }, std::numeric_limits<uint64_t>::max()},
{"setTCPInternalPipeBufferSize", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_tcpInternalPipeBufferSize = newValue; }, std::numeric_limits<uint64_t>::max()},
{"setMaxCachedTCPConnectionsPerDownstream", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingTCPMaxIdlePerBackend = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setTCPDownstreamCleanupInterval", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingTCPCleanupInterval = newValue; }, std::numeric_limits<uint32_t>::max()},
{"setTCPDownstreamMaxIdleTime", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingTCPMaxIdleTime = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setMaxTCPClientThreads", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_maxTCPClientThreads = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setMaxTCPConnectionsPerClient", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_maxTCPConnectionsPerClient = newValue; }, std::numeric_limits<uint64_t>::max()},
{"setTCPInternalPipeBufferSize", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_tcpInternalPipeBufferSize = newValue; }, std::numeric_limits<uint64_t>::max()},
{"setMaxCachedTCPConnectionsPerDownstream", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingTCPMaxIdlePerBackend = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setTCPDownstreamCleanupInterval", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingTCPCleanupInterval = newValue; }, std::numeric_limits<uint32_t>::max()},
{"setTCPDownstreamMaxIdleTime", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingTCPMaxIdleTime = newValue; }, std::numeric_limits<uint16_t>::max()},
#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
{"setOutgoingDoHWorkerThreads", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHWorkers = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setMaxIdleDoHConnectionsPerDownstream", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHMaxIdlePerBackend = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setDoHDownstreamCleanupInterval", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHCleanupInterval = newValue; }, std::numeric_limits<uint32_t>::max()},
{"setDoHDownstreamMaxIdleTime", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHMaxIdleTime = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setOutgoingDoHWorkerThreads", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHWorkers = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setMaxIdleDoHConnectionsPerDownstream", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHMaxIdlePerBackend = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setDoHDownstreamCleanupInterval", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHCleanupInterval = newValue; }, std::numeric_limits<uint32_t>::max()},
{"setDoHDownstreamMaxIdleTime", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_outgoingDoHMaxIdleTime = newValue; }, std::numeric_limits<uint16_t>::max()},
#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
{"setMaxUDPOutstanding", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_maxUDPOutstanding = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setWHashedPertubation", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_hashPerturbation = newValue; }, std::numeric_limits<uint32_t>::max()},
{"setMaxUDPOutstanding", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_maxUDPOutstanding = newValue; }, std::numeric_limits<uint16_t>::max()},
{"setWHashedPertubation", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_hashPerturbation = newValue; }, std::numeric_limits<uint32_t>::max()},
#ifndef DISABLE_RECVMMSG
{"setUDPMultipleMessagesVectorSize", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_udpVectorSize = newValue; }, std::numeric_limits<uint32_t>::max()},
{"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()},
{"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()},
{"setRingBuffersLockRetries", [](dnsdist::configuration::Configuration& config, uint64_t newValue) { config.d_ringsNbLockTries = newValue; }, std::numeric_limits<uint64_t>::max()},
};

struct DoubleImmutableConfigurationItems
Expand Down Expand Up @@ -2139,39 +2141,45 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
});

luaCtx.writeFunction("setRingBuffersSize", [client](uint64_t capacity, boost::optional<uint64_t> numberOfShards) {
setLuaSideEffect();
if (!checkConfigurationTime("setRingBuffersSize")) {
if (client) {
return;
}
if (!client) {
g_rings.setCapacity(capacity, numberOfShards ? *numberOfShards : 10);
setLuaSideEffect();
try {
dnsdist::configuration::updateImmutableConfiguration([capacity, numberOfShards](dnsdist::configuration::Configuration& config) {
config.d_ringsCapacity = capacity;
if (numberOfShards) {
config.d_ringsNumberOfShards = *numberOfShards;
}
});
}
else {
g_rings.setCapacity(0, 1);
catch (const std::exception& exp) {
g_outputBuffer = "setRingBuffersSize cannot be used at runtime!\n";
errlog("setRingBuffersSize cannot be used at runtime!");
}
});

luaCtx.writeFunction("setRingBuffersLockRetries", [](uint64_t retries) {
setLuaSideEffect();
g_rings.setNumberOfLockRetries(retries);
});

luaCtx.writeFunction("setRingBuffersOptions", [](const LuaAssociativeTable<boost::variant<bool, uint64_t>>& options) {
setLuaSideEffect();
if (!checkConfigurationTime("setRingBuffersOptions")) {
luaCtx.writeFunction("setRingBuffersOptions", [client](const LuaAssociativeTable<boost::variant<bool, uint64_t>>& options) {
if (client) {
return;
}
if (options.count("lockRetries") > 0) {
auto retries = boost::get<uint64_t>(options.at("lockRetries"));
g_rings.setNumberOfLockRetries(retries);
}
if (options.count("recordQueries") > 0) {
auto record = boost::get<bool>(options.at("recordQueries"));
g_rings.setRecordQueries(record);
setLuaSideEffect();
try {
dnsdist::configuration::updateImmutableConfiguration([&options](dnsdist::configuration::Configuration& config) {
if (options.count("lockRetries") > 0) {
config.d_ringsNbLockTries = boost::get<uint64_t>(options.at("lockRetries"));
}
if (options.count("recordQueries") > 0) {
config.d_ringsRecordQueries = boost::get<bool>(options.at("recordQueries"));
}
if (options.count("recordResponses") > 0) {
config.d_ringsRecordResponses = boost::get<bool>(options.at("recordResponses"));
}
});
}
if (options.count("recordResponses") > 0) {
auto record = boost::get<bool>(options.at("recordResponses"));
g_rings.setRecordResponses(record);
catch (const std::exception& exp) {
g_outputBuffer = "setRingBuffersOption cannot be used at runtime!\n";
errlog("setRingBuffersOption cannot be used at runtime!");
}
});

Expand Down Expand Up @@ -2289,9 +2297,6 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
#endif /* DISABLE_POLICIES_BINDINGS */

luaCtx.writeFunction("setProxyProtocolACL", [](LuaTypeOrArrayOf<std::string> inp) {
if (!checkConfigurationTime("setProxyProtocolACL")) {
return;
}
setLuaSideEffect();
NetmaskGroup nmg;
if (auto* str = boost::get<string>(&inp)) {
Expand Down
2 changes: 2 additions & 0 deletions pdns/dnsdistdist/dnsdist-metrics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ Stats::Stats() :
{"cpu-user-msec", getCPUTimeUser},
{"fd-usage", getOpenFileDescriptors},
{"dyn-blocked", &dynBlocked},
#ifndef DISABLE_DYNBLOCKS
{"dyn-block-nmg-size", [](const std::string&) { return dnsdist::DynamicBlocks::getClientAddressDynamicRules().size(); }},
#endif /* DISABLE_DYNBLOCKS */
{"security-status", &securityStatus},
{"doh-query-pipe-full", &dohQueryPipeFull},
{"doh-response-pipe-full", &dohResponsePipeFull},
Expand Down
36 changes: 6 additions & 30 deletions pdns/dnsdistdist/dnsdist-rings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,17 @@

#include "dnsdist-rings.hh"

void Rings::setCapacity(size_t newCapacity, size_t numberOfShards)
{
if (d_initialized) {
throw std::runtime_error("Rings::setCapacity() should not be called once the rings have been initialized");
}
d_capacity = newCapacity;
d_numberOfShards = numberOfShards;
}

void Rings::init()
void Rings::init(size_t capacity, size_t numberOfShards, size_t nbLockRetries, bool recordQueries, bool recordResponses)
{
if (d_initialized.exchange(true)) {
throw std::runtime_error("Rings::init() should only be called once");
}

d_capacity = capacity;
d_numberOfShards = numberOfShards;
d_nbLockTries = nbLockRetries;
d_recordQueries = recordQueries;
d_recordResponses = recordResponses;
if (d_numberOfShards <= 1) {
d_nbLockTries = 0;
}
Expand All @@ -61,26 +57,6 @@ void Rings::init()
d_nbResponseEntries = 0;
}

void Rings::setNumberOfLockRetries(size_t retries)
{
if (d_numberOfShards <= 1) {
d_nbLockTries = 0;
}
else {
d_nbLockTries = retries;
}
}

void Rings::setRecordQueries(bool record)
{
d_recordQueries = record;
}

void Rings::setRecordResponses(bool record)
{
d_recordResponses = record;
}

size_t Rings::numDistinctRequestors()
{
std::set<ComboAddress, ComboAddress::addressOnlyLessThan> requestors;
Expand Down
44 changes: 17 additions & 27 deletions pdns/dnsdistdist/dnsdist-rings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,11 @@ struct Rings
LockGuarded<boost::circular_buffer<Response>> respRing;
};

Rings(size_t capacity = 10000, size_t numberOfShards = 10, size_t nbLockTries = 5, bool keepLockingStats = false) :
d_blockingQueryInserts(0), d_blockingResponseInserts(0), d_deferredQueryInserts(0), d_deferredResponseInserts(0), d_nbQueryEntries(0), d_nbResponseEntries(0), d_currentShardId(0), d_capacity(capacity), d_numberOfShards(numberOfShards), d_nbLockTries(nbLockTries), d_keepLockingStats(keepLockingStats)
{
}

std::unordered_map<int, vector<boost::variant<string, double>>> getTopBandwidth(unsigned int numentries);
size_t numDistinctRequestors();
/* this function should not be called after init() has been called */
void setCapacity(size_t newCapacity, size_t numberOfShards);

/* This function should only be called at configuration time before any query or response has been inserted */
void init();

void setNumberOfLockRetries(size_t retries);
void setRecordQueries(bool);
void setRecordResponses(bool);
void init(size_t capacity, size_t numberOfShards, size_t nbLockRetries = 5, bool recordQueries = true, bool recordResponses = true);

size_t getNumberOfShards() const
{
Expand Down Expand Up @@ -125,13 +114,13 @@ struct Rings
#endif
return;
}
if (d_keepLockingStats) {
if (s_keepLockingStats) {
++d_deferredQueryInserts;
}
}

/* out of luck, let's just wait */
if (d_keepLockingStats) {
if (s_keepLockingStats) {
++d_blockingResponseInserts;
}
auto& shard = getOneShard();
Expand All @@ -152,13 +141,13 @@ struct Rings
insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend, protocol);
return;
}
if (d_keepLockingStats) {
if (s_keepLockingStats) {
++d_deferredResponseInserts;
}
}

/* out of luck, let's just wait */
if (d_keepLockingStats) {
if (s_keepLockingStats) {
++d_blockingResponseInserts;
}
auto& shard = getOneShard();
Expand Down Expand Up @@ -204,10 +193,10 @@ struct Rings
}

std::vector<std::unique_ptr<Shard>> d_shards;
pdns::stat_t d_blockingQueryInserts;
pdns::stat_t d_blockingResponseInserts;
pdns::stat_t d_deferredQueryInserts;
pdns::stat_t d_deferredResponseInserts;
pdns::stat_t d_blockingQueryInserts{0};
pdns::stat_t d_blockingResponseInserts{0};
pdns::stat_t d_deferredQueryInserts{0};
pdns::stat_t d_deferredResponseInserts{0};

private:
size_t getShardId()
Expand Down Expand Up @@ -248,15 +237,16 @@ private:
ring.push_back({requestor, backend, name, when, dh, usec, size, qtype, protocol});
}

std::atomic<size_t> d_nbQueryEntries;
std::atomic<size_t> d_nbResponseEntries;
std::atomic<size_t> d_currentShardId;
static constexpr bool s_keepLockingStats{false};

std::atomic<size_t> d_nbQueryEntries{0};
std::atomic<size_t> d_nbResponseEntries{0};
std::atomic<size_t> d_currentShardId{0};
std::atomic<bool> d_initialized{false};

size_t d_capacity;
size_t d_numberOfShards;
size_t d_nbLockTries = 5;
bool d_keepLockingStats{false};
size_t d_capacity{10000};
size_t d_numberOfShards{10};
size_t d_nbLockTries{5};
bool d_recordQueries{true};
bool d_recordResponses{true};
};
Expand Down
1 change: 1 addition & 0 deletions pdns/dnsdistdist/dnsdist-web.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "credentials.hh"
#include "dnsdist-prometheus.hh"
#include "sstuff.hh"

namespace dnsdist::webserver
{
Expand Down
12 changes: 10 additions & 2 deletions pdns/dnsdistdist/dnsdist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2793,7 +2793,7 @@ static void cleanupLuaObjects()
config.d_pools.clear();
config.d_backends.clear();
});
clearWebHandlers();
dnsdist::webserver::clearWebHandlers();
dnsdist::lua::hooks::clearMaintenanceHooks();
}
#endif /* defined(COVERAGE) || (defined(__SANITIZE_ADDRESS__) && defined(HAVE_LEAK_SANITIZER_INTERFACE)) */
Expand Down Expand Up @@ -2824,6 +2824,11 @@ static void sigTermHandler([[maybe_unused]] int sig)
if (dnsdist::g_asyncHolder) {
dnsdist::g_asyncHolder->stop();
}

for (auto& backend : dnsdist::configuration::getCurrentRuntimeConfiguration().d_backends) {
backend->stop();
}

{
auto lock = g_lua.lock();
cleanupLuaObjects();
Expand Down Expand Up @@ -3413,7 +3418,10 @@ int main(int argc, char** argv)
#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}

g_rings.init();
{
const auto& config = dnsdist::configuration::getImmutableConfiguration();
g_rings.init(config.d_ringsCapacity, config.d_ringsNumberOfShards, config.d_ringsNbLockTries, config.d_ringsRecordQueries, config.d_ringsRecordResponses);
}

for (auto& frontend : g_frontends) {
setUpLocalBind(frontend);
Expand Down
2 changes: 1 addition & 1 deletion pdns/dnsdistdist/test-dnsdist-lua-ffi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ BOOST_AUTO_TEST_CASE(test_RingBuffers)
gettime(&now);

g_rings.reset();
g_rings.init();
g_rings.init(10000, 10);
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), 0U);

g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
Expand Down
Loading

0 comments on commit 8477f0b

Please sign in to comment.