From: Pieter Lexis Date: Tue, 12 Feb 2019 14:44:44 +0000 (+0100) Subject: rec: Implement options to not throttle servers X-Git-Tag: rec-4.2.0-beta1~7^2~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=559b6c9331eac5bd419eb31db41e3063c25e0254;p=thirdparty%2Fpdns.git rec: Implement options to not throttle servers --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index f4842e9e7c..749c6750a4 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -237,6 +237,10 @@ unsigned int g_numThreads; uint16_t g_outgoingEDNSBufsize; bool g_logRPZChanges{false}; +// Used in the Syncres to not throttle certain servers +GlobalStateHolder g_dontThrottleNames; +GlobalStateHolder g_dontThrottleNetmasks; + #define LOCAL_NETS "127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10" #define LOCAL_NETS_INVERSE "!127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10" // Bad Nets taken from both: @@ -3715,6 +3719,23 @@ static int serviceMain(int argc, char*argv[]) g_statisticsInterval = ::arg().asNum("statistics-interval"); + { + SuffixMatchNode dontThrottleNames; + vector parts; + stringtok(parts, ::arg()["dont-throttle-names"]); + for (const auto &p : parts) { + dontThrottleNames.add(DNSName(p)); + } + g_dontThrottleNames.setState(dontThrottleNames); + + NetmaskGroup dontThrottleNetmasks; + stringtok(parts, ::arg()["dont-throttle-netmasks"]); + for (const auto &p : parts) { + dontThrottleNetmasks.addMask(Netmask(p)); + } + g_dontThrottleNetmasks.setState(dontThrottleNetmasks); + } + #ifdef SO_REUSEPORT g_reusePort = ::arg().mustDo("reuseport"); #endif @@ -4219,6 +4240,8 @@ int main(int argc, char **argv) ::arg().set("max-tcp-clients","Maximum number of simultaneous TCP clients")="128"; ::arg().set("server-down-max-fails","Maximum number of consecutive timeouts (and unreachables) to mark a server as down ( 0 => disabled )")="64"; ::arg().set("server-down-throttle-time","Number of seconds to throttle all queries to a server after being marked as down")="60"; + ::arg().set("dont-throttle-names", "Do not throttle nameservers with this name or suffix")=""; + ::arg().set("dont-throttle-netmasks", "Do not throttle nameservers with this IP netmask")=""; ::arg().set("hint-file", "If set, load root hints from this file")=""; ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache")="1000000"; ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory")="3600"; diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 5d44334fdb..6e225f36fc 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -268,6 +268,40 @@ Operate in the background. Which domains we only accept delegations from (a Verisign special). +.. _setting-dont-throttle-names: + +``dont-throttle-names`` +---------------------------- +.. versionadded:: 4.2.0 + +- Comma separated list of domain-names +- Default: (empty) + +When an authotitative server does not answer a query or sends a reply the recursor does lot like, it is throttled. +Any servers' name suffix-matching the supplied names will never be throttled. + +.. warning:: + Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-names`` could make this load on the upstream server even higher, resulting in further service degredation. + +.. _setting-dont-throttle-netmasks: + +``dont-throttle-netmasks`` +---------------------------- +.. versionadded:: 4.2.0 + +- Comma separated list of netmasks +- Default: (empty) + +When an authotitative server does not answer a query or sends a reply the recursor does lot like, it is throttled. +Any servers matching the supplied netmasks will never be throttled. + +This can come in handy on lossy networks when forwarding, where the same server is configured multiple times (e.g. with ``forward-zones-recurse=example.com=192.0.2.1;192.0.2.1``). +By default, the PowerDNS Recursor would throttle the "first" server on a timeout and hence not retry the "second" one. +In this case, ``dont-throttle-netmasks`` could be set to ``192.0.2.1``. + +.. warning:: + Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-netmasks`` could make this load on the upstream server even higher, resulting in further service degredation. + .. _setting-disable-packetcache: ``disable-packetcache`` diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index eb38f362c5..bcec3a4f18 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -17,6 +17,8 @@ RecursorStats g_stats; GlobalStateHolder g_luaconfs; +GlobalStateHolder g_dontThrottleNames; +GlobalStateHolder g_dontThrottleNetmasks; thread_local std::unique_ptr t_RC{nullptr}; unsigned int g_numThreads = 1; bool g_lowercaseOutgoing = false; diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 52d3e1b659..2bc62e4b7b 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -2693,7 +2693,12 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, LOG(prefix<check(nsName) || dontThrottleNetmasks->match(remoteIP))) { + // don't account for resource limits, they are our own fault + // And don't throttle when the IP address is on the dontThrottleNetmasks list or the name is part of dontThrottleNames t_sstorage.nsSpeeds[nsName.empty()? DNSName(remoteIP.toStringWithPort()) : nsName].submit(remoteIP, 1000000, &d_now); // 1 sec // code below makes sure we don't filter COM or the root @@ -2707,7 +2712,7 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()), 60, 100); } else { - // timeout + // timeout, 10 seconds or 5 queries t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()), 10, 5); } } diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 53825ac81e..ce44ba24b1 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -49,6 +49,7 @@ #include "ednssubnet.hh" #include "filterpo.hh" #include "negcache.hh" +#include "sholder.hh" #ifdef HAVE_CONFIG_H #include "config.h" @@ -58,6 +59,9 @@ #include #endif +extern GlobalStateHolder g_dontThrottleNames; +extern GlobalStateHolder g_dontThrottleNetmasks; + class RecursorLua4; typedef map<