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"));
// 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)
{
}
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();
}
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) {
{
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);
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;
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;
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;
};
}
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
^^^^^^^^^
'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'
},
]
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));