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
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();
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)
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();
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)
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);
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;
rr.content = toLower(rr.content);
nsset.push_back(DNSRecord(rr));
}
- insertIntoRootNSZones(rr.qname.getLastLabel());
}
// Check reachability of A and AAAA records
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;
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);
}
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());
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)
uint64_t* pleaseGetPacketCacheSize();
void doCarbonDump(void*);
bool primeHints(time_t now = time(nullptr));
-void primeRootNSZones(DNSSECMode, unsigned int depth);
struct WipeCacheResult
{