]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add testcase for "almost expired".
authorOtto <otto.moerbeek@open-xchange.com>
Fri, 4 Jun 2021 11:27:44 +0000 (13:27 +0200)
committerOtto <otto.moerbeek@open-xchange.com>
Fri, 4 Jun 2021 11:27:44 +0000 (13:27 +0200)
pdns/recursordist/Makefile.am
pdns/recursordist/test-syncres_cc.cc
pdns/recursordist/test-syncres_cc.hh
pdns/recursordist/test-syncres_cc2.cc

index ecdc4632f4d0e0817796357f672030e1a8f69fbf..5061ef079042f8af5896b32b6ba7dedc7640bfaa 100644 (file)
@@ -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 \
index d593d5c62f818b8ac81729e0bd36c8400c971c20..f4a624f100a9a0c35f9bead26540735193ac679c 100644 (file)
@@ -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});
 }
index 73b33d330d0d4078ef804bb3b7cf17967ed3964d..dbd05f7c9863c3a652f3ac7cdfe8a6b001df1b16 100644 (file)
@@ -28,6 +28,7 @@
 #include "syncres.hh"
 #include "test-common.hh"
 #include "validate-recursor.hh"
+#include "taskqueue.hh"
 
 extern GlobalStateHolder<LuaConfigItems> 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<time_t> 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;
index efa71b0848c45995007e6f2a477de4f4752b022f..6c8ef50cff181a4bc62471307ef30c18a8c74b24 100644 (file)
@@ -2,6 +2,7 @@
 #include <boost/test/unit_test.hpp>
 
 #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<ARecordContent>(ret[0])->getCA().toStringWithPort(), ComboAddress("192.0.2.2").toStringWithPort());
 }
 
+BOOST_AUTO_TEST_CASE(test_cache_almost_expired_ttl)
+{
+
+  std::unique_ptr<SyncRes> 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<Netmask>& srcmask, boost::optional<const ResolveContext&> 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<DNSRecord> records;
+  std::vector<shared_ptr<RRSIGRecordContent>> 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<std::shared_ptr<DNSRecord>>(), true, g_rootdnsname, boost::optional<Netmask>());
+
+  /* Same for the NS record */
+  std::vector<DNSRecord> 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<std::shared_ptr<DNSRecord>>(), false, target, boost::optional<Netmask>());
+
+  vector<DNSRecord> 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<ARecordContent>(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<ARecordContent>(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<NSRecordContent>(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()