From 11871d6cf87fa72bfecdeae2772824392a9cde25 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 21 Jan 2022 11:11:15 +0100 Subject: [PATCH] Proper ZTC state maintainance on Lua config change --- pdns/recursordist/rec-main.cc | 11 ++++++++--- pdns/recursordist/rec-zonetocache.cc | 26 ++++++++++++++++++++++++++ pdns/recursordist/rec-zonetocache.hh | 2 ++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 65ea478fb3..c9505adb64 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -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 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 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) { diff --git a/pdns/recursordist/rec-zonetocache.cc b/pdns/recursordist/rec-zonetocache.cc index 67b1fa58f5..6f44b77af7 100644 --- a/pdns/recursordist/rec-zonetocache.cc +++ b/pdns/recursordist/rec-zonetocache.cc @@ -374,6 +374,31 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config) } } +void RecZoneToCache::maintainStates(const map& configs, map& 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; } diff --git a/pdns/recursordist/rec-zonetocache.hh b/pdns/recursordist/rec-zonetocache.hh index e1162bf4d9..2b37f4ba88 100644 --- a/pdns/recursordist/rec-zonetocache.hh +++ b/pdns/recursordist/rec-zonetocache.hh @@ -49,7 +49,9 @@ public: { time_t d_lastrun{0}; time_t d_waittime{0}; + uint64_t d_generation; }; + static void maintainStates(const map&, map&, uint64_t mygeneration); static void ZoneToCache(const Config& config, State& state); }; -- 2.47.2