]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: limit the number of async tasks pushed to resolve NS names 14501/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 17 Jul 2024 08:46:58 +0000 (10:46 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 18 Jul 2024 11:09:48 +0000 (13:09 +0200)
Plus: as we only use a limited set of NS names for resolving,
processing all additional records does not help.

(cherry picked from commit cd2de2ee7ad55f295a00dfce5488ee3863d974d6)

pdns/recursordist/syncres.cc

index 3a19b0bfcd4dd01f713bd40c7a852a604cdbd5c5..20d10395ea4f7c1ed03acaf0a3c1849bd5ce9206 100644 (file)
@@ -2312,13 +2312,22 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector
         g_recCache->doWipeCache(subdomain, false, QType::NS);
       }
       if (!missing.empty() && missing.size() < nsVector.size()) {
-        // We miss glue, but we have a chance to resolve it, since we do have address(es) for at least one NS
+        // We miss glue, but we have a chance to resolve it
+        // Pick a few and push async tasks to resolve them
+        const unsigned int max = 2;
+        unsigned int counter = 0;
+        shuffle(missing.begin(), missing.end(), pdns::dns_random_engine());
         for (const auto& name : missing) {
           if (s_doIPv4 && pushResolveIfNotInNegCache(name, QType::A, d_now)) {
             LOG(prefix << qname << ": A glue for " << subdomain << " NS " << name << " missing, pushed task to resolve" << endl);
+            counter++;
           }
           if (s_doIPv6 && pushResolveIfNotInNegCache(name, QType::AAAA, d_now)) {
             LOG(prefix << qname << ": AAAA glue for " << subdomain << " NS " << name << " missing, pushed task to resolve" << endl);
+            counter++;
+          }
+          if (counter >= max) {
+            break;
           }
         }
       }
@@ -4128,6 +4137,12 @@ void SyncRes::fixupAnswer(const std::string& prefix, LWResult& lwr, const DNSNam
 
 static void allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec)
 {
+  // As we only use a limited amount of NS names for resolving, limit number of additional names as
+  // well.  s_maxnsperresolve is a proper limit for the NS case and is also reasonable for other
+  // qtypes.  Allow one extra for qname itself, which is always in allowedAdditionals.
+  if (SyncRes::s_maxnsperresolve > 0 && allowedAdditionals.size() > SyncRes::s_maxnsperresolve + 1) {
+    return;
+  }
   switch (rec.d_type) {
   case QType::MX:
     if (auto mxContent = getRR<MXRecordContent>(rec)) {