From: Otto Moerbeek Date: Mon, 25 Mar 2024 12:33:41 +0000 (+0100) Subject: Make resolve check interval and self-resolve check settable X-Git-Tag: rec-5.1.0-alpha1~82^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19b6a857a894c7e05068088b851f17709de44622;p=thirdparty%2Fpdns.git Make resolve check interval and self-resolve check settable --- diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 3de3e1eb37..0da7724e6f 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -3202,8 +3202,13 @@ int main(int argc, char** argv) handleRuntimeDefaults(startupLog); if (auto ttl = ::arg().asNum("system-resolver-ttl"); ttl != 0) { + time_t interval = ttl; + if (::arg().asNum("system-resolver-interval") != 0) { + interval = ::arg().asNum("system-resolver-interval"); + } + bool selfResolveCheck = ::arg().mustDo("system-resolver-self-resolve-check"); // Cannot use SyncRes::s_serverID, it is not set yet - pdns::RecResolve::setInstanceParameters(arg()["server-id"], ttl, []() { reloadZoneConfiguration(g_yamlSettings); }); + pdns::RecResolve::setInstanceParameters(arg()["server-id"], ttl, interval, selfResolveCheck, []() { reloadZoneConfiguration(g_yamlSettings); }); } g_recCache = std::make_unique(::arg().asNum("record-cache-shards")); diff --git a/pdns/recursordist/rec-system-resolve.cc b/pdns/recursordist/rec-system-resolve.cc index 682f6ee2a2..c41a0160af 100644 --- a/pdns/recursordist/rec-system-resolve.cc +++ b/pdns/recursordist/rec-system-resolve.cc @@ -109,23 +109,27 @@ std::string serverID() // RecResolve class members. std::string pdns::RecResolve::s_serverID; time_t pdns::RecResolve::s_ttl{0}; +time_t pdns::RecResolve::s_interval{0}; std::function pdns::RecResolve::s_callback; +bool pdns::RecResolve::s_selfResolveCheck{false}; -void pdns::RecResolve::setInstanceParameters(std::string serverID, time_t ttl, const std::function& callback) +void pdns::RecResolve::setInstanceParameters(std::string serverID, time_t ttl, time_t interval, bool selfResolveCheck, const std::function& callback) { pdns::RecResolve::s_serverID = std::move(serverID); pdns::RecResolve::s_ttl = ttl; + pdns::RecResolve::s_interval = interval; + pdns::RecResolve::s_selfResolveCheck = selfResolveCheck; pdns::RecResolve::s_callback = callback; } pdns::RecResolve& pdns::RecResolve::getInstance() { - static unique_ptr res = make_unique(s_ttl, s_callback); + static unique_ptr res = make_unique(s_ttl, s_interval, s_selfResolveCheck, s_callback); return *res; } -pdns::RecResolve::RecResolve(time_t ttl, const std::function& callback) : - d_ttl(ttl), d_refresher(ttl / 6, callback, *this) +pdns::RecResolve::RecResolve(time_t ttl, time_t interval, bool selfResolveCheck, const std::function& callback) : + d_ttl(ttl), d_refresher(interval, callback, selfResolveCheck, *this) { } @@ -229,8 +233,8 @@ bool pdns::RecResolve::refresh(time_t now) return updated; } -pdns::RecResolve::Refresher::Refresher(time_t interval, const std::function& callback, pdns::RecResolve& res) : - d_resolver(res), d_callback(callback), d_interval(std::max(static_cast(1), interval)) +pdns::RecResolve::Refresher::Refresher(time_t interval, const std::function& callback, bool selfResolveCheck, pdns::RecResolve& res) : + d_resolver(res), d_callback(callback), d_interval(std::max(static_cast(1), interval)), d_selfResolveCheck(selfResolveCheck) { start(); } @@ -261,7 +265,7 @@ void pdns::RecResolve::Refresher::refreshLoop() if (stop) { break; } - if (lastSelfCheck < time(nullptr) - 3600) { + if (d_selfResolveCheck && lastSelfCheck < time(nullptr) - 3600) { lastSelfCheck = time(nullptr); auto resolvedServerID = serverID(); if (resolvedServerID == s_serverID) { diff --git a/pdns/recursordist/rec-system-resolve.hh b/pdns/recursordist/rec-system-resolve.hh index 2a50ca22e2..b3e199a46b 100644 --- a/pdns/recursordist/rec-system-resolve.hh +++ b/pdns/recursordist/rec-system-resolve.hh @@ -76,11 +76,11 @@ class RecResolve { public: // Should be called before any getInstance() call is done - static void setInstanceParameters(std::string serverID, time_t ttl, const std::function& callback); + static void setInstanceParameters(std::string serverID, time_t ttl, time_t interval, bool selfResolveCheck, const std::function& callback); // Get "the" instance of the system resolver. static RecResolve& getInstance(); - RecResolve(time_t ttl = 60, const std::function& callback = nullptr); + RecResolve(time_t ttl, time_t interval, bool selfResolveCheck, const std::function& callback = nullptr); ~RecResolve(); // Lookup a name and register it in the names to be checked if not already there ComboAddress lookupAndRegister(const std::string& name, time_t now); @@ -112,7 +112,7 @@ private: class Refresher { public: - Refresher(time_t interval, const std::function& callback, pdns::RecResolve& res); + Refresher(time_t interval, const std::function& callback, bool selfResolveCheck, pdns::RecResolve& res); Refresher(const Refresher&) = delete; Refresher(Refresher&&) = delete; Refresher& operator=(const Refresher&) = delete; @@ -128,12 +128,13 @@ private: pdns::RecResolve& d_resolver; std::function d_callback; - time_t d_interval; + const time_t d_interval; std::thread d_thread; std::mutex mutex; std::condition_variable condVar; std::atomic wakeup{false}; std::atomic stop{false}; + const bool d_selfResolveCheck; }; Refresher d_refresher; @@ -141,6 +142,8 @@ private: static std::string s_serverID; static std::function s_callback; static time_t s_ttl; + static time_t s_interval; + static bool s_selfResolveCheck; }; } diff --git a/pdns/recursordist/settings/docs-new-preamble-in.rst b/pdns/recursordist/settings/docs-new-preamble-in.rst index 03e6d983d2..9c2b9b1285 100644 --- a/pdns/recursordist/settings/docs-new-preamble-in.rst +++ b/pdns/recursordist/settings/docs-new-preamble-in.rst @@ -171,6 +171,8 @@ An example of a ``forward_zones`` entry, which consists of a sequence of forward Starting with version 5.1.0, names can be used if :ref:`setting-yaml-recursor.system_resolver_ttl` is set. The names will be resolved using the system resolver and an automatic refresh of the forwarding zones will happen if a name starts resolving to a new address. +Te refresh is done by performig the equivalent of ``rec_control reload-zones``. + Auth Zone ^^^^^^^^^ diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index 919e5845dc..442520d7df 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -3120,12 +3120,46 @@ This can be used to not count known failing (test) name validations in the ordin 'help' : 'Set TTL of system resolver feature, 0 (default) is disabled', 'doc' : ''' Sets TTL in seconds of the system resolver feature. -This allows names to be used in the config in forwarding targets. -The TTL is used as a check interval to see if the names used in forwarding resolve to a different address than before. -If that happens, the forward configuration is reloaded. +If not equal to zero names can be used for forwarding targets. +The names will be resolved by the system resolver configured in the OS. + +The TTL is used as a time to live to see if the names used in forwarding resolve to a different address than before. +If the TTL is expired, a re-resolve will be done by the next iteration of the check function; +if a change is detected, the recursor performs an equivalent of ``rec_control reload-zones``. + Make sure the recursor itself is not used by the system resolver! Default is 0 (not enabled). A suggested value is 60. - ''', +''', + 'versionadded': '5.1.0' + }, + { + 'name' : 'system_resolver_interval', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Set interval (in seconds) of the re-resolve checks of system resolver subsystem.', + 'doc' : ''' +Sets the check interval (in seconds) of the system resolver feature. +All names known by the system resolver subsystem are periodically checked for changing values. + +If the TTL of a name has expired, it is checked by re-resolving it. +if a change is detected, the recursor performs an equivalent of ``rec_control reload-zones``. + +This settings sets the interval between the checks. +If set to zero (the default), the value :ref:`setting-system-resolver-ttl` is used. +''', + 'versionadded': '5.1.0' + }, + { + 'name' : 'system_resolver_self_resolve_check', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Check for potential self-resolve, default enabled.', + 'doc' : ''' +Warn on potential self-resolve. +If this check draws the wrong conclusion, you can disable it. +''', 'versionadded': '5.1.0' }, ] diff --git a/pdns/recursordist/test-rec-system-resolve.cc b/pdns/recursordist/test-rec-system-resolve.cc index 7c559b6706..c903c635ab 100644 --- a/pdns/recursordist/test-rec-system-resolve.cc +++ b/pdns/recursordist/test-rec-system-resolve.cc @@ -11,7 +11,7 @@ BOOST_AUTO_TEST_SUITE(rec_system_resolve) BOOST_AUTO_TEST_CASE(test_basic_resolve) { - pdns::RecResolve::setInstanceParameters("foo", 60, nullptr); + pdns::RecResolve::setInstanceParameters("foo", 60, 10, false, nullptr); auto& sysResolve = pdns::RecResolve::getInstance(); auto address = sysResolve.lookupAndRegister("localhost", time(nullptr));