From: Remi Gacogne Date: Thu, 26 Nov 2020 13:54:48 +0000 (+0100) Subject: dnsdist: Make the interval of Dynamic Blocks cleaning configurable X-Git-Tag: rec-4.5.0-alpha1~92^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b03d051c0224ce37afbbe4a9215a5f31c33476f6;p=thirdparty%2Fpdns.git dnsdist: Make the interval of Dynamic Blocks cleaning configurable --- diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index b1b589d507..52328d9b6a 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -522,6 +522,7 @@ const std::vector g_consoleKeywords{ { "setConsoleOutputMaxMsgSize", true, "messageSize", "set console message maximum size in bytes, default is 10 MB" }, { "setDefaultBPFFilter", true, "filter", "When used at configuration time, the corresponding BPFFilter will be attached to every bind" }, { "setDynBlocksAction", true, "action", "set which action is performed when a query is blocked. Only DNSAction.Drop (the default) and DNSAction.Refused are supported" }, + { "setDynBlocksPurgeInterval", true, "sec", "set how often the expired dynamic block entries should be removed" }, { "SetECSAction", true, "v4[, v6]", "Set the ECS prefix and prefix length sent to backends to an arbitrary value" }, { "setECSOverride", true, "bool", "whether to override an existing EDNS Client Subnet value in the query" }, { "setECSSourcePrefixV4", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv4 queries" }, diff --git a/pdns/dnsdist-dynblocks.hh b/pdns/dnsdist-dynblocks.hh index 8ebe2cfe85..eaf85f09e0 100644 --- a/pdns/dnsdist-dynblocks.hh +++ b/pdns/dnsdist-dynblocks.hh @@ -381,6 +381,8 @@ public: static std::map>> getTopSuffixes(); static void purgeExpired(const struct timespec& now); + static time_t s_expiredDynBlocksPurgeInterval; + private: static void collectMetrics(); static void generateMetrics(); diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index a890e35217..5d8eae4257 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -33,6 +33,7 @@ #include "dnsdist.hh" #include "dnsdist-console.hh" +#include "dnsdist-dynblocks.hh" #include "dnsdist-ecs.hh" #include "dnsdist-healthchecks.hh" #include "dnsdist-lua.hh" @@ -1254,6 +1255,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } }); + luaCtx.writeFunction("setDynBlocksPurgeInterval", [](unsigned int interval) { + DynBlockMaintenance::s_expiredDynBlocksPurgeInterval = interval; + }); + luaCtx.writeFunction("addDNSCryptBind", [](const std::string& addr, const std::string& providerName, boost::variant>> certFiles, boost::variant>> keyFiles, boost::optional vars) { if (g_configurationDone) { g_outputBuffer="addDNSCryptBind cannot be used at runtime!\n"; diff --git a/pdns/dnsdistdist/dnsdist-dynblocks.cc b/pdns/dnsdistdist/dnsdist-dynblocks.cc index a24bd90615..95a5914559 100644 --- a/pdns/dnsdistdist/dnsdist-dynblocks.cc +++ b/pdns/dnsdistdist/dnsdist-dynblocks.cc @@ -440,6 +440,7 @@ std::list DynBlockMaintenance::s_metricsDa std::map>> DynBlockMaintenance::s_topNMGsByReason; std::map>> DynBlockMaintenance::s_topSMTsByReason; size_t DynBlockMaintenance::s_topN{20}; +time_t DynBlockMaintenance::s_expiredDynBlocksPurgeInterval{300}; void DynBlockMaintenance::collectMetrics() { @@ -596,17 +597,19 @@ void DynBlockMaintenance::run() 2/ generate metrics that can be used in the API and prometheus endpoints */ - static const time_t expiredPurgeInterval = 300; static const time_t metricsCollectionInterval = 10; static const time_t metricsGenerationInterval = 60; time_t now = time(nullptr); - time_t nextExpiredPurge = now + expiredPurgeInterval; + time_t nextExpiredPurge = now + s_expiredDynBlocksPurgeInterval; time_t nextMetricsCollect = now + metricsCollectionInterval; time_t nextMetricsGeneration = now + metricsGenerationInterval; while (true) { - time_t sleepDelay = (nextExpiredPurge - now); + time_t sleepDelay = std::numeric_limits::max(); + if (s_expiredDynBlocksPurgeInterval > 0) { + sleepDelay = std::min(sleepDelay, (nextExpiredPurge - now)); + } sleepDelay = std::min(sleepDelay, (nextMetricsCollect - now)); sleepDelay = std::min(sleepDelay, (nextMetricsGeneration - now)); @@ -631,13 +634,13 @@ void DynBlockMaintenance::run() nextMetricsGeneration = now + metricsGenerationInterval; } - if (now >= nextExpiredPurge) { + if (s_expiredDynBlocksPurgeInterval > 0 && now >= nextExpiredPurge) { struct timespec tspec; gettime(&tspec); purgeExpired(tspec); now = time(nullptr); - nextExpiredPurge = now + expiredPurgeInterval; + nextExpiredPurge = now + s_expiredDynBlocksPurgeInterval; } } catch (const std::exception& e) { diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index f27ffbe80a..a196f3905f 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1158,6 +1158,17 @@ Dynamic Blocks Set which action is performed when a query is blocked. Only DNSAction.Drop (the default), DNSAction.NoOp, DNSAction.NXDomain, DNSAction.Refused, DNSAction.Truncate and DNSAction.NoRecurse are supported. +.. function:: setDynBlocksPurgeInterval(sec) + + .. versionadded:: 1.6.0 + + Set at which interval, in seconds, the expired dynamic blocks entries will be effectively removed from the tree. Entries are not applied anymore as + soon as they expire, but they remain in the tree for a while for performance reasons. Removing them makes the addition of new entries faster and + frees up the memory they use. + Setting this value to 0 disable the purging mechanism, so entries will remain in the tree. + + :param int sec: The interval between two runs of the cleaning algorithm, in seconds. Default is 300 (5 minutes), 0 means disabled. + .. _exceedfuncs: Getting addresses that exceeded parameters