]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
For zones having many NS records, we are not interested in all so take a sample. 11936/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 6 Sep 2022 07:50:52 +0000 (09:50 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 12 Sep 2022 07:49:58 +0000 (09:49 +0200)
(cherry picked from commit a49b0b40a0c1c1af9531b99e9266a8c2aa89cd68)

pdns/recursordist/docs/settings.rst
pdns/recursordist/rec-main.cc
pdns/syncres.cc
pdns/syncres.hh

index 015924200ac76163161c8f386e87f456b7986f52..d2ccfb479436be4e235a50d5ea73b5c1db0869e9 100644 (file)
@@ -1220,6 +1220,19 @@ it by the number of NS records found above the
 `max-ns-address-qperq`_ value. The limit wil not be reduced to a
 number lower than 5.
 
+.. _setting-max-ns-per-resolve:
+
+``max-ns-per-resolve``
+----------------------
+.. versionadded:: 4.8.0
+
+-  Integer
+-  Default: 13
+
+The maximum number of NS records that will be considered to select a nameserver to contact to resolve a name.
+If a zone has more than `max-ns-per-resolve`_ NS records, a random sample of this size will be used.
+If `max-ns-per-resolve`_ is zero, no limit applies.
+
 .. _setting-max-negative-ttl:
 
 ``max-negative-ttl``
index 6203a4c0ea6e68eec8d3dde81f468b6ccb742021..e107a4aba738650ca32d5478adec7ea5a5e2b0fe 100644 (file)
@@ -1316,6 +1316,7 @@ static int serviceMain(int argc, char* argv[])
   SyncRes::s_nonresolvingnsthrottletime = ::arg().asNum("non-resolving-ns-throttle-time");
   SyncRes::s_serverID = ::arg()["server-id"];
   SyncRes::s_maxqperq = ::arg().asNum("max-qperq");
+  SyncRes::s_maxnsperresolve = ::arg().asNum("max-ns-per-resolve");
   SyncRes::s_maxnsaddressqperq = ::arg().asNum("max-ns-address-qperq");
   SyncRes::s_maxtotusec = 1000 * ::arg().asNum("max-total-msec");
   SyncRes::s_maxdepth = ::arg().asNum("max-recursion-depth");
@@ -2437,6 +2438,7 @@ int main(int argc, char** argv)
     ::arg().set("edns-outgoing-bufsize", "Outgoing EDNS buffer size") = "1232";
     ::arg().set("minimum-ttl-override", "The minimum TTL") = "1";
     ::arg().set("max-qperq", "Maximum outgoing queries per query") = "60";
+    ::arg().set("max-ns-per-resolve", "Maximum number of NS records to consider to resolve a name, 0 is no limit") = "13";
     ::arg().set("max-ns-address-qperq", "Maximum outgoing NS address queries per query") = "10";
     ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited") = "7000";
     ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited") = "40";
index 58516eb290af4b8b09c962565dead60a5d5ed501..83403054dd4a61d653fbd205994d7d94a8786090 100644 (file)
@@ -332,6 +332,7 @@ unsigned int SyncRes::s_maxnegttl;
 unsigned int SyncRes::s_maxbogusttl;
 unsigned int SyncRes::s_maxcachettl;
 unsigned int SyncRes::s_maxqperq;
+unsigned int SyncRes::s_maxnsperresolve;
 unsigned int SyncRes::s_maxnsaddressqperq;
 unsigned int SyncRes::s_maxtotusec;
 unsigned int SyncRes::s_maxdepth;
@@ -1984,6 +1985,12 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType qtype, vector
     *flawedNSSet = false;
 
     if(g_recCache->get(d_now.tv_sec, subdomain, QType::NS, false, &ns, d_cacheRemote, false, d_routingTag) > 0) {
+      if (s_maxnsperresolve > 0 && ns.size() > s_maxnsperresolve) {
+        vector<DNSRecord> selected;
+        selected.reserve(s_maxnsperresolve);
+        std::sample(ns.cbegin(), ns.cend(), std::back_inserter(selected), s_maxnsperresolve, pdns::dns_random_engine());
+        ns = selected;
+      }
       bestns.reserve(ns.size());
 
       for(auto k=ns.cbegin();k!=ns.cend(); ++k) {
index 61204c3bd392501f0d068527e28f7b730475095b..af3c01b544534392562ba4a9b498bac543a2bce2 100644 (file)
@@ -568,6 +568,7 @@ public:
   static unsigned int s_minimumTTL;
   static unsigned int s_minimumECSTTL;
   static unsigned int s_maxqperq;
+  static unsigned int s_maxnsperresolve;
   static unsigned int s_maxnsaddressqperq;
   static unsigned int s_maxtotusec;
   static unsigned int s_maxdepth;