]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Make the interval of Dynamic Blocks cleaning configurable
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 26 Nov 2020 13:54:48 +0000 (14:54 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 27 Nov 2020 10:00:40 +0000 (11:00 +0100)
pdns/dnsdist-console.cc
pdns/dnsdist-dynblocks.hh
pdns/dnsdist-lua.cc
pdns/dnsdistdist/dnsdist-dynblocks.cc
pdns/dnsdistdist/docs/reference/config.rst

index b1b589d5075abe67de4d68d4bad7ba739c2a1747..52328d9b6a02e81c1bb7ef84dd709f9ea283507f 100644 (file)
@@ -522,6 +522,7 @@ const std::vector<ConsoleKeyword> 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" },
index 8ebe2cfe85b89e9e208d1fce00f66c6efee0538a..eaf85f09e0e74e30d07513cfc5cf312be06e62a7 100644 (file)
@@ -381,6 +381,8 @@ public:
   static std::map<std::string, std::list<std::pair<DNSName, unsigned int>>> getTopSuffixes();
   static void purgeExpired(const struct timespec& now);
 
+  static time_t s_expiredDynBlocksPurgeInterval;
+
 private:
   static void collectMetrics();
   static void generateMetrics();
index a890e35217f26b55cbce02b2eb14f0c78f509782..5d8eae4257d35c0d39b1ee1fa3428caf1099ec9a 100644 (file)
@@ -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<std::string, std::vector<std::pair<int, std::string>>> certFiles, boost::variant<std::string, std::vector<std::pair<int, std::string>>> keyFiles, boost::optional<localbind_t> vars) {
       if (g_configurationDone) {
         g_outputBuffer="addDNSCryptBind cannot be used at runtime!\n";
index a24bd906152089b1ef177c4603bf80cbf42c8e61..95a59145593e150f728e5417f6c1ac1250d57b5a 100644 (file)
@@ -440,6 +440,7 @@ std::list<DynBlockMaintenance::MetricsSnapshot> DynBlockMaintenance::s_metricsDa
 std::map<std::string, std::list<std::pair<Netmask, unsigned int>>> DynBlockMaintenance::s_topNMGsByReason;
 std::map<std::string, std::list<std::pair<DNSName, unsigned int>>> 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<time_t>::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) {
index f27ffbe80ae2cb592329f9b20bc6778c36e049b8..a196f3905f2c631a886ad39e593faf093c214e6d 100644 (file)
@@ -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