]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Get DS records with QM switched on.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 7 Nov 2022 08:03:51 +0000 (09:03 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 16 Nov 2022 09:40:45 +0000 (10:40 +0100)
This avoid a.root-servers.net going Bogus, which can happen
if the .net NS are not cached and we miss the cut.

Fixes #12160 and avoids the need to prime the .net NS records explicitly.

(cherry picked from commit e2307ada1210fee6198e54db2dc91dac8fa68070)

pdns/recursordist/rec-main.cc
pdns/recursordist/test-syncres_cc7.cc
pdns/reczones.cc
pdns/syncres.cc
pdns/syncres.hh

index f22d84e72415690e86e15ebaa75cc310b3954747..415b7c83386a4067e385046856fce8c189823d45 100644 (file)
@@ -2229,30 +2229,6 @@ static void houseKeeping(void*)
         if (res == 0) {
           // Success, go back to the defaut period
           rootUpdateTask.setPeriod(std::max(SyncRes::s_maxcachettl * 8 / 10, minRootRefreshInterval));
-          const string msg = "Exception while priming the root NS zones";
-          try {
-            primeRootNSZones(g_dnssecmode, 0);
-          }
-          catch (const std::exception& e) {
-            SLOG(g_log << Logger::Error << "Exception while priming the root NS zones: " << e.what() << endl,
-                 log->error(Logr::Error, e.what(), msg, "exception", Logging::Loggable("std::exception")));
-          }
-          catch (const PDNSException& e) {
-            SLOG(g_log << Logger::Error << "Exception while priming the root NS zones: " << e.reason << endl,
-                 log->error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("PDNSException")));
-          }
-          catch (const ImmediateServFailException& e) {
-            SLOG(g_log << Logger::Error << "Exception while priming the root NS zones: " << e.reason << endl,
-                 log->error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("ImmediateServFailException")));
-          }
-          catch (const PolicyHitException& e) {
-            SLOG(g_log << Logger::Error << "Policy hit while priming the root NS zones" << endl,
-                 log->info(Logr::Error, msg, "exception", Logging::Loggable("PolicyHitException")));
-          }
-          catch (...) {
-            SLOG(g_log << Logger::Error << "Exception while priming the root NS zones" << endl,
-                 log->info(Logr::Error, "Exception while priming the root NS zones"));
-          }
         }
         else {
           // On failure, go to the middle of the remaining period (initially 80% / 8 = 10%) and shorten the interval on each
index 7d4484175ff5631628e58eb96c8ad02957473712..0aa1accd66aef9f9e18b93830dc849966b5b4411 100644 (file)
@@ -1407,8 +1407,8 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nodata)
   BOOST_CHECK_EQUAL(res, RCode::NoError);
   BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
   BOOST_REQUIRE_EQUAL(ret.size(), 0U);
-  /* com|NS, powerdns.com|NS, powerdns.com|A */
-  BOOST_CHECK_EQUAL(queriesCount, 3U);
+  /* com|NS, powerdns.com|DS, com|DNSKEY, powerdns.com|A */
+  BOOST_CHECK_EQUAL(queriesCount, 4U);
 
   /* again, to test the cache */
   ret.clear();
@@ -1417,7 +1417,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nodata)
   BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
   BOOST_REQUIRE_EQUAL(ret.size(), 0U);
   /* we don't store empty results */
-  BOOST_CHECK_EQUAL(queriesCount, 4U);
+  BOOST_CHECK_EQUAL(queriesCount, 5U);
 }
 
 BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nxdomain)
@@ -1460,8 +1460,9 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nxdomain)
   BOOST_CHECK_EQUAL(res, RCode::NXDomain);
   BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
   BOOST_REQUIRE_EQUAL(ret.size(), 0U);
-  /* com|NS, powerdns.com|NS, powerdns.com|A */
-  BOOST_CHECK_EQUAL(queriesCount, 3U);
+
+  /* com|A, powerdns.com|DS, com|DNSKEY, powerdns.com|A */
+  BOOST_CHECK_EQUAL(queriesCount, 4U);
 
   /* again, to test the cache */
   ret.clear();
@@ -1470,7 +1471,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nxdomain)
   BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
   BOOST_REQUIRE_EQUAL(ret.size(), 0U);
   /* we don't store empty results */
-  BOOST_CHECK_EQUAL(queriesCount, 4U);
+  BOOST_CHECK_EQUAL(queriesCount, 5U);
 }
 
 BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cut_with_cname_at_apex)
index f833946fab343274199990502cda6da1ec1126ae..6777ee174382f381f04eef6f2307d5d1ebe89fee 100644 (file)
 extern int g_argc;
 extern char** g_argv;
 
-static thread_local set<DNSName> t_rootNSZones;
-
-static void insertIntoRootNSZones(const DNSName& name)
-{
-  // do not insert dot, wiping dot's NS records from the cache in primeRootNSZones()
-  // will cause infinite recursion
-  if (!name.isRoot()) {
-    t_rootNSZones.insert(name);
-  }
-}
-
 bool primeHints(time_t ignored)
 {
   // prime root cache
   const vState validationState = vState::Insecure;
   const ComboAddress from("255.255.255.255");
   vector<DNSRecord> nsset;
-  t_rootNSZones.clear();
 
   time_t now = time(nullptr);
 
@@ -78,7 +66,6 @@ bool primeHints(time_t ignored)
       templ[sizeof(templ) - 1] = '\0';
       *templ = c;
       aaaarr.d_name = arr.d_name = DNSName(templ);
-      insertIntoRootNSZones(arr.d_name.getLastLabel());
       nsrr.d_content = std::make_shared<NSRecordContent>(DNSName(templ));
       arr.d_content = std::make_shared<ARecordContent>(ComboAddress(rootIps4[c - 'a']));
       vector<DNSRecord> aset;
@@ -134,7 +121,6 @@ bool primeHints(time_t ignored)
         rr.content = toLower(rr.content);
         nsset.push_back(DNSRecord(rr));
       }
-      insertIntoRootNSZones(rr.qname.getLastLabel());
     }
 
     // Check reachability of A and AAAA records
@@ -173,32 +159,6 @@ bool primeHints(time_t ignored)
   return true;
 }
 
-// Do not only put the root hints into the cache, but also make sure
-// the NS records of the top level domains of the names of the root
-// servers are in the cache. We need these to correctly determine the
-// security status of that specific domain (normally
-// root-servers.net). This is caused by the accident that the root
-// servers are authoritative for root-servers.net, and some
-// implementations reply not with a delegation on a root-servers.net
-// DS query, but with a NODATA response (the domain is unsigned).
-void primeRootNSZones(DNSSECMode mode, unsigned int depth)
-{
-  struct timeval now;
-  gettimeofday(&now, 0);
-  SyncRes sr(now);
-
-  sr.setDoDNSSEC(mode != DNSSECMode::Off);
-  sr.setDNSSECValidationRequested(mode != DNSSECMode::Off && mode != DNSSECMode::ProcessNoValidate);
-  // beginResolve() can yield to another mthread that could trigger t_rootNSZones updates,
-  // so make a local copy
-  set<DNSName> copy(t_rootNSZones);
-  for (const auto& qname : copy) {
-    g_recCache->doWipeCache(qname, false, QType::NS);
-    vector<DNSRecord> ret;
-    sr.beginResolve(qname, QType(QType::NS), QClass::IN, ret, depth + 1);
-  }
-}
-
 static void convertServersForAD(const std::string& zone, const std::string& input, SyncRes::AuthDomain& ad, const char* sepa, Logr::log_t log, bool verbose = true)
 {
   vector<string> servers;
index 443b94fd63e9d0056dc602ab8fe918cb55af6a19..4784929c3513533dfc09028ab5d53800568888de 100644 (file)
@@ -2311,7 +2311,6 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType qtype, vector
       LOG(prefix<<qname<<": reprimed the root"<<endl);
       /* let's prevent an infinite loop */
       if (!d_updatingRootNS) {
-        primeRootNSZones(g_dnssecmode, depth);
         auto log = g_slog->withName("housekeeping");
         getRootNS(d_now, d_asyncResolve, depth, log);
       }
@@ -3598,8 +3597,10 @@ vState SyncRes::getDSRecords(const DNSName& zone, dsmap_t& ds, bool taOnly, unsi
 
   vState state = vState::Indeterminate;
   const bool oldCacheOnly = setCacheOnly(false);
+  const bool oldQM = setQNameMinimization(true);
   int rcode = doResolve(zone, QType::DS, dsrecords, depth + 1, beenthere, state);
   setCacheOnly(oldCacheOnly);
+  setQNameMinimization(oldQM);
 
   if (rcode == RCode::ServFail) {
     throw ImmediateServFailException("Server Failure while retrieving DS records for " + zone.toLogString());
index b919b4e18927c3d7a38acf0ceb6b55129404d11c..dbd59d6fb3f4155decd015b9d77b4b00a62a6500 100644 (file)
@@ -321,9 +321,11 @@ public:
     return old;
   }
 
-  void setQNameMinimization(bool state=true)
+  bool setQNameMinimization(bool state = true)
   {
-    d_qNameMinimization=state;
+    auto old = d_qNameMinimization;
+    d_qNameMinimization = state;
+    return old;
   }
 
   void setDoEDNS0(bool state=true)
@@ -922,7 +924,6 @@ uint64_t* pleaseGetPacketCacheHits();
 uint64_t* pleaseGetPacketCacheSize();
 void doCarbonDump(void*);
 bool primeHints(time_t now = time(nullptr));
-void primeRootNSZones(DNSSECMode, unsigned int depth);
 
 struct WipeCacheResult
 {