]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Resolve NS names without QName Minimization.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 22 Sep 2023 07:55:14 +0000 (09:55 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 22 Sep 2023 12:58:43 +0000 (14:58 +0200)
The assumption being that using Qname Minimization for infra queries does not
enhance privacy, but increases query load.

Also determine max-qperq bound dynamically

pdns/recursordist/rec-main.cc
pdns/recursordist/syncres.cc
pdns/recursordist/test-syncres_cc5.cc

index 09bf5acf8dd5943518bd0b4677c49ad3d40fa705..d46be550149c913f2b801f2a98711b834c146f94 100644 (file)
@@ -1644,6 +1644,7 @@ static int initSyncRes(Logr::log_t log)
   SyncRes::s_nonresolvingnsmaxfails = ::arg().asNum("non-resolving-ns-max-fails");
   SyncRes::s_nonresolvingnsthrottletime = ::arg().asNum("non-resolving-ns-throttle-time");
   SyncRes::s_serverID = ::arg()["server-id"];
+  // This bound is dynamically adjusted in SyncRes, depending on qname minimization being active
   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");
@@ -1686,12 +1687,6 @@ static int initSyncRes(Logr::log_t log)
 
   SyncRes::s_qnameminimization = ::arg().mustDo("qname-minimization");
 
-  if (SyncRes::s_qnameminimization) {
-    // With an empty cache, a rev ipv6 query with dnssec enabled takes
-    // almost 100 queries. Default maxqperq is 60.
-    SyncRes::s_maxqperq = std::max(SyncRes::s_maxqperq, static_cast<unsigned int>(100));
-  }
-
   SyncRes::s_hardenNXD = SyncRes::HardenNXD::DNSSEC;
   string value = ::arg()["nothing-below-nxdomain"];
   if (value == "yes") {
index 2a5b46ae4eb395a13b28b2774a55518936b4ced6..780264ed907149487dfab7d36a9a4c7631451fa6 100644 (file)
@@ -2107,7 +2107,7 @@ vector<ComboAddress> SyncRes::getAddrs(const DNSName& qname, unsigned int depth,
       Context newContext1;
       cset.clear();
       // Go out to get A's
-      if (s_doIPv4 && doResolve(qname, QType::A, cset, depth + 1, beenthere, newContext1) == 0) { // this consults cache, OR goes out
+      if (s_doIPv4 && doResolveNoQNameMinimization(qname, QType::A, cset, depth + 1, beenthere, newContext1) == 0) { // this consults cache, OR goes out
         for (auto const& i : cset) {
           if (i.d_type == QType::A) {
             if (auto rec = getRR<ARecordContent>(i)) {
@@ -2120,7 +2120,7 @@ vector<ComboAddress> SyncRes::getAddrs(const DNSName& qname, unsigned int depth,
         if (ret.empty()) {
           // We only go out immediately to find IPv6 records if we did not find any IPv4 ones.
           Context newContext2;
-          if (doResolve(qname, QType::AAAA, cset, depth + 1, beenthere, newContext2) == 0) { // this consults cache, OR goes out
+          if (doResolveNoQNameMinimization(qname, QType::AAAA, cset, depth + 1, beenthere, newContext2) == 0) { // this consults cache, OR goes out
             for (const auto& i : cset) {
               if (i.d_type == QType::AAAA) {
                 if (auto rec = getRR<AAAARecordContent>(i)) {
@@ -3420,8 +3420,17 @@ vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix,
 
 void SyncRes::checkMaxQperQ(const DNSName& qname) const
 {
-  if (d_outqueries + d_throttledqueries > s_maxqperq) {
-    throw ImmediateServFailException("more than " + std::to_string(s_maxqperq) + " (max-qperq) queries sent or throttled while resolving " + qname.toLogString());
+  auto bound = s_maxqperq;
+  if (d_qNameMinimization) {
+    // With an empty cache, a rev ipv6 query with dnssec enabled takes
+    // almost 100 queries. Default maxqperq is 60
+    // Note: This no longer seems to be true. The examples taken from #8646 take now way less
+    // queries. The main reason seems to be a much better zone cut determination.
+    bound = std::max(100U, bound);
+  }
+
+  if (d_outqueries + d_throttledqueries > bound) {
+    throw ImmediateServFailException("more than " + std::to_string(bound) + " (adjusted max-qperq) queries sent or throttled while resolving " + qname.toLogString());
   }
 }
 
index bb893939f1b6518c889c3edc520c269914e0b570..367a68a6cee1db450b1d9caefda15e84f9d35621 100644 (file)
@@ -1969,8 +1969,11 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm)
     DNSName auth(domain);
     DNSName com("com.");
     DNSName net("net.");
+    DNSName nsone("nsone.net.");
+    DNSName hero("herokuapp.com.");
+    DNSName p03nsone("dns1.p03.nsone.net.");
 
-    //cerr <<  ip.toString() << ": " << domain << '|' << QType(type).getName() << endl;
+    // cerr <<  ip.toString() << ": " << domain << '|' << QType(type).toString() << endl;
     if (type == QType::DS || type == QType::DNSKEY) {
       return genericDSAndDNSKEYHandler(res, domain, auth, type, keys);
     }
@@ -1990,6 +1993,13 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm)
         addRRSIG(keys, res->d_records, g_rootdnsname, 300);
         addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
       }
+      else if (domain == p03nsone && type == QType::A) {
+        setLWResult(res, 0, false, false, true);
+        addRecordToLW(res, nsone, QType::NS, "dns1.p01.nsone.net.", DNSResourceRecord::AUTHORITY, 3600);
+        addNSECRecordToLW(nsone, DNSName("zzz.nsone.net."), {QType::NS, QType::SOA, QType::RRSIG, QType::DNSKEY}, 600, res->d_records);
+        addRRSIG(keys, res->d_records, net, 300);
+        addRecordToLW(res, "dns1.p01.nsone.net", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
+      }
       else {
         BOOST_ASSERT(0);
       }
@@ -1997,8 +2007,6 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm)
     }
 
     else if (ip == ComboAddress("192.0.2.1:53")) {
-      DNSName hero("herokuapp.com.");
-      DNSName nsone("nsone.net.");
       if (domain == hero && type == QType::NS) {
         setLWResult(res, 0, false, false, true);
         addRecordToLW(res, hero, QType::NS, "dns1.p03.nsone.net.", DNSResourceRecord::AUTHORITY, 3600);
@@ -2018,11 +2026,9 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm)
       return LWResult::Result::Success;
     }
     else if (ip == ComboAddress("192.0.2.2:53")) {
-      DNSName hero("herokuapp.com.");
       DNSName p01("p01.nsone.net.");
       DNSName p03("p03.nsone.net.");
       DNSName p01nsone("dns1.p01.nsone.net.");
-      DNSName p03nsone("dns1.p03.nsone.net.");
       if (domain == hero && type == QType::NS) {
         setLWResult(res, 0, true, false, true);
         addRecordToLW(res, hero, QType::NS, "dns1.p03.nsone.net.", DNSResourceRecord::ANSWER, 3600);
@@ -2058,7 +2064,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm)
   BOOST_CHECK_EQUAL(res, RCode::NoError);
   BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
   BOOST_REQUIRE_EQUAL(ret.size(), 2U);
-  BOOST_CHECK_EQUAL(queriesCount, 10U);
+  BOOST_CHECK_EQUAL(queriesCount, 8U);
 
   ret.clear();
   res = sr->beginResolve(DNSName("dns1.p03.nsone.net."), QType(QType::A), QClass::IN, ret);