From: Otto Moerbeek Date: Mon, 7 Nov 2022 08:03:51 +0000 (+0100) Subject: Get DS records with QM switched on. X-Git-Tag: dnsdist-1.8.0-rc1~240^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2307ada1210fee6198e54db2dc91dac8fa68070;p=thirdparty%2Fpdns.git Get DS records with QM switched on. 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. --- diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index f22d84e724..415b7c8338 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -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 diff --git a/pdns/recursordist/test-syncres_cc7.cc b/pdns/recursordist/test-syncres_cc7.cc index 7d4484175f..0aa1accd66 100644 --- a/pdns/recursordist/test-syncres_cc7.cc +++ b/pdns/recursordist/test-syncres_cc7.cc @@ -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) diff --git a/pdns/reczones.cc b/pdns/reczones.cc index f833946fab..6777ee1743 100644 --- a/pdns/reczones.cc +++ b/pdns/reczones.cc @@ -35,24 +35,12 @@ extern int g_argc; extern char** g_argv; -static thread_local set 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 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(DNSName(templ)); arr.d_content = std::make_shared(ComboAddress(rootIps4[c - 'a'])); vector 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 copy(t_rootNSZones); - for (const auto& qname : copy) { - g_recCache->doWipeCache(qname, false, QType::NS); - vector 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 servers; diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 45d33de668..7dd8648c5f 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -2324,7 +2324,6 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType qtype, vector LOG(prefix<withName("housekeeping"); getRootNS(d_now, d_asyncResolve, depth, log); } @@ -3611,8 +3610,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()); diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 8ccb469c5d..e2b42fa3f8 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -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 {