uint16_t g_outgoingEDNSBufsize;
bool g_logRPZChanges{false};
+// Used in the Syncres to not throttle certain servers
+GlobalStateHolder<SuffixMatchNode> g_dontThrottleNames;
+GlobalStateHolder<NetmaskGroup> 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:
g_statisticsInterval = ::arg().asNum("statistics-interval");
+ {
+ SuffixMatchNode dontThrottleNames;
+ vector<string> 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
::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";
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``
RecursorStats g_stats;
GlobalStateHolder<LuaConfigItems> g_luaconfs;
+GlobalStateHolder<SuffixMatchNode> g_dontThrottleNames;
+GlobalStateHolder<NetmaskGroup> g_dontThrottleNetmasks;
thread_local std::unique_ptr<MemRecursorCache> t_RC{nullptr};
unsigned int g_numThreads = 1;
bool g_lowercaseOutgoing = false;
LOG(prefix<<qname<<": error resolving from "<<remoteIP.toString()<< (doTCP ? " over TCP" : "") <<", possible error: "<<strerror(errno)<< endl);
}
- if(resolveret != -2 && !chained) { // don't account for resource limits, they are our own fault
+ auto dontThrottleNames = g_dontThrottleNames.getLocal();
+ auto dontThrottleNetmasks = g_dontThrottleNetmasks.getLocal();
+
+ if(resolveret != -2 && !chained && !(dontThrottleNames->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
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);
}
}
#include "ednssubnet.hh"
#include "filterpo.hh"
#include "negcache.hh"
+#include "sholder.hh"
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <boost/uuid/uuid.hpp>
#endif
+extern GlobalStateHolder<SuffixMatchNode> g_dontThrottleNames;
+extern GlobalStateHolder<NetmaskGroup> g_dontThrottleNetmasks;
+
class RecursorLua4;
typedef map<