From: Otto Date: Fri, 19 Mar 2021 15:33:06 +0000 (+0100) Subject: Add a unit test and also make the test priming correspond to the new real priming. X-Git-Tag: rec-4.5.0-beta1~5^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f0a21dda052db57b7298e3987ba294a48b512e8;p=thirdparty%2Fpdns.git Add a unit test and also make the test priming correspond to the new real priming. --- diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index b77fb1172d..385ea09460 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -102,13 +102,13 @@ bool primeHints(time_t now) arr.d_content = std::make_shared(ComboAddress(rootIps4[c - 'a'])); vector aset; aset.push_back(arr); - g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector>(), vector>(), true, g_rootdnsname); // auth, nuke it all + g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector>(), vector>(), false, g_rootdnsname); if (rootIps6[c - 'a'] != NULL) { aaaarr.d_content = std::make_shared(ComboAddress(rootIps6[c - 'a'])); vector aaaaset; aaaaset.push_back(aaaarr); - g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector>(), vector>(), true, g_rootdnsname); + g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector>(), vector>(), false, g_rootdnsname); } nsset.push_back(nsrr); diff --git a/pdns/recursordist/test-syncres_cc1.cc b/pdns/recursordist/test-syncres_cc1.cc index 4db3890032..0becb781ec 100644 --- a/pdns/recursordist/test-syncres_cc1.cc +++ b/pdns/recursordist/test-syncres_cc1.cc @@ -13,22 +13,23 @@ BOOST_AUTO_TEST_CASE(test_root_primed) primeHints(); const DNSName target("a.root-servers.net."); - - /* we are primed, we should be able to resolve A a.root-servers.net. without any query */ + try { + /* we are primed, but only with non-auth data so we cannot resolve A a.root-servers.net. without any query */ vector ret; int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); - BOOST_CHECK_EQUAL(res, RCode::NoError); - BOOST_REQUIRE_EQUAL(ret.size(), 1U); - BOOST_CHECK(ret[0].d_type == QType::A); - BOOST_CHECK_EQUAL(ret[0].d_name, target); + BOOST_CHECK_EQUAL(res, RCode::ServFail); + BOOST_REQUIRE_EQUAL(ret.size(), 0U); ret.clear(); res = sr->beginResolve(target, QType(QType::AAAA), QClass::IN, ret); - BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_CHECK_EQUAL(res, RCode::ServFail); BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Indeterminate); - BOOST_REQUIRE_EQUAL(ret.size(), 1U); - BOOST_CHECK(ret[0].d_type == QType::AAAA); - BOOST_CHECK_EQUAL(ret[0].d_name, target); + BOOST_REQUIRE_EQUAL(ret.size(), 0U); + BOOST_CHECK(false); + } + catch (const ImmediateServFailException) { + // Expected + } } BOOST_AUTO_TEST_CASE(test_root_primed_ns) @@ -188,6 +189,66 @@ BOOST_AUTO_TEST_CASE(test_root_ns_poison_resistance) BOOST_REQUIRE_EQUAL(ret.size(), 13U); } +BOOST_AUTO_TEST_CASE(test_root_primed_ns_update) +{ + std::unique_ptr sr; + initSR(sr); + + primeHints(); + const DNSName target("."); + const DNSName aroot("a.root-servers.net."); + const string newA = "1.2.3.4"; + const string newAAAA = "1::2"; + + /* we are primed, but we should not be able to NS . without any query + because the . NS entry is not stored as authoritative */ + + size_t queriesCount = 0; + + auto asynccb = [target, &queriesCount, aroot, newA, newAAAA](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + queriesCount++; + + if (domain == target && type == QType::NS) { + + setLWResult(res, 0, true, false, true); + char addr[] = "a.root-servers.net."; + for (char idx = 'a'; idx <= 'm'; idx++) { + addr[0] = idx; + addRecordToLW(res, g_rootdnsname, QType::NS, std::string(addr), DNSResourceRecord::ANSWER, 3600); + } + + addRecordToLW(res, aroot.toString(), QType::A, newA, DNSResourceRecord::ADDITIONAL, 3600); + addRecordToLW(res, aroot.toString(), QType::AAAA, newAAAA, DNSResourceRecord::ADDITIONAL, 3600); + + return LWResult::Result::Success; + } + return LWResult::Result::Timeout; + }; + + sr->setAsyncCallback(asynccb); + + struct timeval now; + Utility::gettimeofday(&now, nullptr); + + vector ret; + int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_REQUIRE_EQUAL(ret.size(), 13U); + BOOST_CHECK_EQUAL(queriesCount, 1U); + + ret.clear(); + time_t cached = g_recCache->get(now.tv_sec, aroot, QType::A, false, &ret, ComboAddress()); + BOOST_CHECK(cached > 0); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK(getRR(ret[0])->getCA() == ComboAddress(newA)); + + ret.clear(); + cached = g_recCache->get(now.tv_sec, aroot, QType::AAAA, false, &ret, ComboAddress()); + BOOST_CHECK(cached > 0); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK(getRR(ret[0])->getCA() == ComboAddress(newAAAA)); +} + static void test_edns_formerr_fallback_f(bool sample) { std::unique_ptr sr;