]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Make resolve check interval and self-resolve check settable
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 25 Mar 2024 12:33:41 +0000 (13:33 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 25 Mar 2024 13:00:45 +0000 (14:00 +0100)
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-system-resolve.cc
pdns/recursordist/rec-system-resolve.hh
pdns/recursordist/settings/docs-new-preamble-in.rst
pdns/recursordist/settings/table.py
pdns/recursordist/test-rec-system-resolve.cc

index 3de3e1eb37d9b968086088bf81529bca0df9f0c5..0da7724e6fae9d857d18044e6891e6e4727c2cd5 100644 (file)
@@ -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<MemRecursorCache>(::arg().asNum("record-cache-shards"));
index 682f6ee2a21d8ec2626d696c2d5df9925f079163..c41a0160af69bb32dac7a6646481cceb90e938fa 100644 (file)
@@ -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<void()> pdns::RecResolve::s_callback;
+bool pdns::RecResolve::s_selfResolveCheck{false};
 
-void pdns::RecResolve::setInstanceParameters(std::string serverID, time_t ttl, const std::function<void()>& callback)
+void pdns::RecResolve::setInstanceParameters(std::string serverID, time_t ttl, time_t interval, bool selfResolveCheck, const std::function<void()>& 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<RecResolve> res = make_unique<pdns::RecResolve>(s_ttl, s_callback);
+  static unique_ptr<RecResolve> res = make_unique<pdns::RecResolve>(s_ttl, s_interval, s_selfResolveCheck, s_callback);
   return *res;
 }
 
-pdns::RecResolve::RecResolve(time_t ttl, const std::function<void()>& callback) :
-  d_ttl(ttl), d_refresher(ttl / 6, callback, *this)
+pdns::RecResolve::RecResolve(time_t ttl, time_t interval, bool selfResolveCheck, const std::function<void()>& 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<void()>& callback, pdns::RecResolve& res) :
-  d_resolver(res), d_callback(callback), d_interval(std::max(static_cast<time_t>(1), interval))
+pdns::RecResolve::Refresher::Refresher(time_t interval, const std::function<void()>& callback, bool selfResolveCheck, pdns::RecResolve& res) :
+  d_resolver(res), d_callback(callback), d_interval(std::max(static_cast<time_t>(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) {
index 2a50ca22e22f2113dc7b89bb95968d63602a4402..b3e199a46b64a7fea7dd361e07f46746cecb383c 100644 (file)
@@ -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<void()>& callback);
+  static void setInstanceParameters(std::string serverID, time_t ttl, time_t interval, bool selfResolveCheck, const std::function<void()>& callback);
   // Get "the" instance of the system resolver.
   static RecResolve& getInstance();
 
-  RecResolve(time_t ttl = 60, const std::function<void()>& callback = nullptr);
+  RecResolve(time_t ttl, time_t interval, bool selfResolveCheck, const std::function<void()>& 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<void()>& callback, pdns::RecResolve& res);
+    Refresher(time_t interval, const std::function<void()>& 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<void()> d_callback;
-    time_t d_interval;
+    const time_t d_interval;
     std::thread d_thread;
     std::mutex mutex;
     std::condition_variable condVar;
     std::atomic<bool> wakeup{false};
     std::atomic<bool> stop{false};
+    const bool d_selfResolveCheck;
   };
 
   Refresher d_refresher;
@@ -141,6 +142,8 @@ private:
   static std::string s_serverID;
   static std::function<void()> s_callback;
   static time_t s_ttl;
+  static time_t s_interval;
+  static bool s_selfResolveCheck;
 };
 
 }
index 03e6d983d26d8f906461d801060cb17732a81bc8..9c2b9b128517f65b4a75a176a06c531f21d84a9c 100644 (file)
@@ -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
 ^^^^^^^^^
index 919e5845dcd6d7f36182859a539619033a598bb0..442520d7df84582e02a60dfc2a68946ed04c5ed5 100644 (file)
@@ -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'
     },
 ]
index 7c559b6706d0696977ff59906e8a83b6b5c41fad..c903c635aba029b664e4d7b1e4b23663e8c2240c 100644 (file)
@@ -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));