]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Proper ZTC state maintainance on Lua config change
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 21 Jan 2022 10:11:15 +0000 (11:11 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 21 Jan 2022 11:15:54 +0000 (12:15 +0100)
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-zonetocache.cc
pdns/recursordist/rec-zonetocache.hh

index 65ea478fb37b012e977b48c7b71bed843755cac9..c9505adb6457396c5ebf704d1fb32bfbc6b1dc31 100644 (file)
@@ -1769,6 +1769,7 @@ static void houseKeeping(void*)
   static thread_local int t_cleanCounter = 0;
   static thread_local bool t_running; // houseKeeping can get suspended in secpoll, and be restarted, which makes us do duplicate work
   static time_t s_last_RC_prune = 0;
+  static time_t s_last_ZTC_prune = 0;
   auto luaconfsLocal = g_luaconfs.getLocal();
 
   if (t_last_trustAnchorUpdate == 0 && !luaconfsLocal->trustAnchorFileInfo.fname.empty() && luaconfsLocal->trustAnchorFileInfo.interval != 0) {
@@ -1807,9 +1808,13 @@ static void houseKeeping(void*)
     }
 
     if (isHandlerThread()) {
-      static map<DNSName, RecZoneToCache::State> ztcState;
-      for (auto& ztc : luaconfsLocal->ztcConfigs) {
-        RecZoneToCache::ZoneToCache(ztc.second, ztcState[ztc.first]);
+      if (now.tv_sec - s_last_ZTC_prune > 60) {
+        s_last_ZTC_prune = now.tv_sec;
+        static map<DNSName, RecZoneToCache::State> ztcStates;
+        RecZoneToCache::maintainStates(luaconfsLocal->ztcConfigs, ztcStates, luaconfsLocal->generation);
+        for (auto& ztc : luaconfsLocal->ztcConfigs) {
+          RecZoneToCache::ZoneToCache(ztc.second, ztcStates.at(ztc.first));
+        }
       }
 
       if (now.tv_sec - s_last_RC_prune > 5) {
index 67b1fa58f5541ea22e953529cbea1f61a340cc72..6f44b77af72cd04de112438b1dca6a9f3b9fb12f 100644 (file)
@@ -374,6 +374,31 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config)
   }
 }
 
+void RecZoneToCache::maintainStates(const map<DNSName, Config>& configs, map<DNSName, State>& states, uint64_t mygeneration)
+{
+  // Delete states that have no config
+  for (auto it = states.begin(); it != states.end();) {
+    if (configs.find(it->first) == configs.end()) {
+      it = states.erase(it);
+    }
+    else {
+      it = ++it;
+    }
+  }
+  // Reset states for which the config generation changed and create new states for new configs
+  for (auto config : configs) {
+    auto state = states.find(config.first);
+    if (state != states.end()) {
+      if (state->second.d_generation != mygeneration) {
+        state->second = {0, 0, mygeneration};
+      }
+    }
+    else {
+      states.emplace(std::make_pair(config.first, State{0, 0, mygeneration}));
+    }
+  }
+}
+
 void RecZoneToCache::ZoneToCache(const RecZoneToCache::Config& config, RecZoneToCache::State& state)
 {
   if (state.d_waittime == 0 && state.d_lastrun > 0) {
@@ -402,4 +427,5 @@ void RecZoneToCache::ZoneToCache(const RecZoneToCache::Config& config, RecZoneTo
     log->info("Unable to load zone into cache, will retry", "exception", Logging::Loggable("unknown"), "refresh", Logging::Loggable(state.d_waittime));
   }
   state.d_lastrun = time(nullptr);
+  return;
 }
index e1162bf4d98d0016dab637e9e0b5921beb81210f..2b37f4ba88cf3dc882c376f80a5b76110e35ed1b 100644 (file)
@@ -49,7 +49,9 @@ public:
   {
     time_t d_lastrun{0};
     time_t d_waittime{0};
+    uint64_t d_generation;
   };
 
+  static void maintainStates(const map<DNSName, Config>&, map<DNSName, State>&, uint64_t mygeneration);
   static void ZoneToCache(const Config& config, State& state);
 };