From: Otto Date: Fri, 4 Jun 2021 11:27:44 +0000 (+0200) Subject: Add testcase for "almost expired". X-Git-Tag: auth-4.5.0-beta1~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dda768026029ecb1d43d03ccf804fe091b599e8;p=thirdparty%2Fpdns.git Add testcase for "almost expired". --- diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index ecdc4632f4..5061ef0790 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -280,6 +280,7 @@ testrunner_SOURCES = \ stable-bloom.hh \ svc-records.cc svc-records.hh \ syncres.cc syncres.hh \ + taskqueue.cc taskqueue.hh \ test-aggressive_nsec_cc.cc \ test-arguments_cc.cc \ test-base32_cc.cc \ diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index d593d5c62f..f4a624f100 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -177,6 +177,7 @@ void initSR(bool debug) SyncRes::s_qnameminimization = false; SyncRes::s_nonresolvingnsmaxfails = 0; SyncRes::s_nonresolvingnsthrottletime = 0; + SyncRes::s_refresh_ttlperc = 0; SyncRes::clearNSSpeeds(); BOOST_CHECK_EQUAL(SyncRes::getNSSpeedsSize(), 0U); @@ -538,6 +539,9 @@ LWResult::Result basicRecordsForQnameMinimization(LWResult* res, const DNSName& return LWResult::Result::Timeout; } +pdns::TaskQueue g_test_tasks; + void pushTask(const DNSName& qname, uint16_t qtype, time_t deadline) { + g_test_tasks.push({qname, qtype, deadline, true}); } diff --git a/pdns/recursordist/test-syncres_cc.hh b/pdns/recursordist/test-syncres_cc.hh index 73b33d330d..dbd05f7c98 100644 --- a/pdns/recursordist/test-syncres_cc.hh +++ b/pdns/recursordist/test-syncres_cc.hh @@ -28,6 +28,7 @@ #include "syncres.hh" #include "test-common.hh" #include "validate-recursor.hh" +#include "taskqueue.hh" extern GlobalStateHolder g_luaconfs; @@ -69,3 +70,5 @@ void generateKeyMaterial(const DNSName& name, unsigned int algo, uint8_t digest, LWResult::Result genericDSAndDNSKEYHandler(LWResult* res, const DNSName& domain, DNSName auth, int type, const testkeysset_t& keys, bool proveCut = true, boost::optional now = boost::none, bool nsec3 = false, bool optOut = false); LWResult::Result basicRecordsForQnameMinimization(LWResult* res, const DNSName& domain, int type); + +extern pdns::TaskQueue g_test_tasks; diff --git a/pdns/recursordist/test-syncres_cc2.cc b/pdns/recursordist/test-syncres_cc2.cc index efa71b0848..6c8ef50cff 100644 --- a/pdns/recursordist/test-syncres_cc2.cc +++ b/pdns/recursordist/test-syncres_cc2.cc @@ -2,6 +2,7 @@ #include #include "test-syncres_cc.hh" +#include "rec-taskqueue.hh" BOOST_AUTO_TEST_SUITE(syncres_cc2) @@ -1769,4 +1770,84 @@ BOOST_AUTO_TEST_CASE(test_cache_expired_ttl) BOOST_CHECK_EQUAL(getRR(ret[0])->getCA().toStringWithPort(), ComboAddress("192.0.2.2").toStringWithPort()); } +BOOST_AUTO_TEST_CASE(test_cache_almost_expired_ttl) +{ + + std::unique_ptr sr; + initSR(sr); + SyncRes::s_refresh_ttlperc = 50; + primeHints(); + + const DNSName target("powerdns.com."); + + auto cb = [target](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) { + if (isRootServer(ip)) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800); + + addRecordToLW(res, "pdns-public-ns1.powerdns.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); + + return LWResult::Result::Success; + } + else if (ip == ComboAddress("192.0.2.1:53")) { + setLWResult(res, 0, true, false, true); + addRecordToLW(res, domain, QType::A, "192.0.2.2"); + return LWResult::Result::Success; + } + + return LWResult::Result::Timeout; + }; + sr->setAsyncCallback(cb); + + /* we populate the cache with an 60s TTL entry that is 31s old*/ + const time_t now = sr->getNow().tv_sec; + + std::vector records; + std::vector> sigs; + addRecordToList(records, target, QType::A, "192.0.2.2", DNSResourceRecord::ANSWER, now + 29); + + g_recCache->replace(now - 30, target, QType(QType::A), records, sigs, vector>(), true, g_rootdnsname, boost::optional()); + + /* Same for the NS record */ + std::vector ns; + addRecordToList(ns, target, QType::NS, "pdns-public-ns1.powerdns.com", DNSResourceRecord::ANSWER, now + 29); + g_recCache->replace(now - 30, target, QType::NS, ns, sigs, vector>(), false, target, boost::optional()); + + 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_REQUIRE(ret[0].d_type == QType::A); + BOOST_CHECK_EQUAL(getRR(ret[0])->getCA().toStringWithPort(), ComboAddress("192.0.2.2").toStringWithPort()); + auto ttl = ret[0].d_ttl; + BOOST_CHECK_EQUAL(ttl, 29U); + + // One task should be submitted + BOOST_CHECK_EQUAL(g_test_tasks.size(), 1U); + + auto task = g_test_tasks.pop(); + + // Refresh the almost expired record, its NS records also gets updated + sr->setRefreshAlmostExpired(task.d_refreshMode); + ret.clear(); + res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_REQUIRE(ret[0].d_type == QType::A); + BOOST_CHECK_EQUAL(getRR(ret[0])->getCA().toStringWithPort(), ComboAddress("192.0.2.2").toStringWithPort()); + ttl = ret[0].d_ttl; + BOOST_CHECK_EQUAL(ttl, 60U); + + // Also check if NS record was updated + ret.clear(); + BOOST_REQUIRE_GT(g_recCache->get(now, target, QType(QType::NS), false, &ret, ComboAddress()), 0); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_REQUIRE(ret[0].d_type == QType::NS); + BOOST_CHECK_EQUAL(getRR(ret[0])->getNS(), DNSName("pdns-public-ns1.powerdns.com.")); + ttl = ret[0].d_ttl - now; + BOOST_CHECK_EQUAL(ttl, 86400U); + + // ATM we are not testing the almost expiry of root infra records, it would require quite some cache massage... +} + BOOST_AUTO_TEST_SUITE_END()