BOOST_AUTO_TEST_SUITE(syncres_cc2)
-BOOST_AUTO_TEST_CASE(test_referral_depth)
+static void do_test_referral_depth(bool limited)
{
std::unique_ptr<SyncRes> sr;
initSR(sr);
}
else if (domain == DNSName("ns3.powerdns.org.")) {
addRecordToLW(res, domain, QType::NS, "ns4.powerdns.org.", DNSResourceRecord::AUTHORITY, 172800);
- }
- else if (domain == DNSName("ns4.powerdns.org.")) {
- addRecordToLW(res, domain, QType::NS, "ns5.powerdns.org.", DNSResourceRecord::AUTHORITY, 172800);
- addRecordToLW(res, domain, QType::A, "192.0.2.1", DNSResourceRecord::AUTHORITY, 172800);
+ addRecordToLW(res, "ns4.powerdns.org.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
}
return 1;
}
else if (ip == ComboAddress("192.0.2.1:53")) {
-
setLWResult(res, 0, true, false, false);
- addRecordToLW(res, domain, QType::A, "192.0.2.2");
+ if (domain == DNSName("www.powerdns.com.")) {
+ addRecordToLW(res, domain, QType::A, "192.0.2.2");
+ }
+ else {
+ addRecordToLW(res, domain, QType::A, "192.0.2.1");
+ }
return 1;
}
return 0;
});
- /* Set the maximum depth low */
- SyncRes::s_maxdepth = 10;
-
- try {
- vector<DNSRecord> ret;
- sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
- BOOST_CHECK(false);
+ if (limited) {
+ /* Set the maximum depth low */
+ SyncRes::s_maxdepth = 4;
+ try {
+ vector<DNSRecord> ret;
+ sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
+ BOOST_CHECK(false);
+ }
+ catch (const ImmediateServFailException& e) {
+ BOOST_CHECK(e.reason.find("max-recursion-depth") != string::npos);
+ }
}
- catch (const ImmediateServFailException& e) {
+ else {
+ // Check if the setup with high limit is OK.
+ SyncRes::s_maxdepth = 50;
+ try {
+ vector<DNSRecord> ret;
+ int rcode = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
+ BOOST_CHECK_EQUAL(rcode, RCode::NoError);
+ BOOST_REQUIRE_EQUAL(ret.size(), 1U);
+ BOOST_CHECK_EQUAL(ret[0].d_name, target);
+ BOOST_REQUIRE(ret[0].d_type == QType::A);
+ BOOST_CHECK(getRR<ARecordContent>(ret[0])->getCA() == ComboAddress("192.0.2.2"));
+ }
+ catch (const ImmediateServFailException& e) {
+ BOOST_CHECK(false);
+ }
}
}
+BOOST_AUTO_TEST_CASE(test_referral_depth)
+{
+ // Test with limit
+ do_test_referral_depth(true);
+}
+
+BOOST_AUTO_TEST_CASE(test_referral_depth_ok)
+{
+ // Test with default limit
+ do_test_referral_depth(false);
+}
+
BOOST_AUTO_TEST_CASE(test_cname_qperq)
{
std::unique_ptr<SyncRes> sr;
/* should have been cached */
const ComboAddress who("192.0.2.128");
vector<DNSRecord> cached;
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
}
/* should have been cached because /24 is more specific than /16 but TTL limit is nof effective */
const ComboAddress who("192.0.2.128");
vector<DNSRecord> cached;
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
}
/* should have been cached */
const ComboAddress who("192.0.2.128");
vector<DNSRecord> cached;
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
}
/* should have been cached */
const ComboAddress who("192.0.2.128");
vector<DNSRecord> cached;
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
}
/* should have NOT been cached because TTL of 60 is too small and /24 is more specific than /16 */
const ComboAddress who("192.0.2.128");
vector<DNSRecord> cached;
- BOOST_REQUIRE_LT(t_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
+ BOOST_REQUIRE_LT(s_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 0U);
}
std::vector<shared_ptr<RRSIGRecordContent>> sigs;
addRecordToList(records, target, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, now + 3600);
- t_RC->replace(now, target, QType(QType::NS), records, sigs, vector<std::shared_ptr<DNSRecord>>(), true, boost::optional<Netmask>());
+ s_RC->replace(now, target, QType(QType::NS), records, sigs, vector<std::shared_ptr<DNSRecord>>(), true, boost::optional<Netmask>());
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
BOOST_CHECK_EQUAL(queriesCount, 5U);
}
+BOOST_AUTO_TEST_CASE(test_completely_flawed_big_nsset)
+{
+ std::unique_ptr<SyncRes> sr;
+ initSR(sr);
+
+ primeHints();
+
+ const DNSName target("powerdns.com.");
+ size_t queriesCount = 0;
+
+ sr->setAsyncCallback([&queriesCount, 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) {
+ queriesCount++;
+
+ if (isRootServer(ip) && domain == target) {
+ setLWResult(res, 0, false, false, true);
+ // 20 NS records
+ for (int i = 0; i < 20; i++) {
+ string n = string("pdns-public-ns") + std::to_string(i) + string(".powerdns.com.");
+ addRecordToLW(res, domain, QType::NS, n, DNSResourceRecord::AUTHORITY, 172800);
+ }
+ return 1;
+ }
+ else if (domain.toString().length() > 14 && domain.toString().substr(0, 14) == "pdns-public-ns") {
+ setLWResult(res, 0, true, false, true);
+ addRecordToLW(res, ".", QType::SOA, "a.root-servers.net. nstld.verisign-grs.com. 2017032800 1800 900 604800 86400", DNSResourceRecord::AUTHORITY, 86400);
+ return 1;
+ }
+ return 0;
+ });
+
+ vector<DNSRecord> ret;
+ try {
+ sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
+ BOOST_CHECK(0);
+ }
+ catch (const ImmediateServFailException& ex) {
+ BOOST_CHECK_EQUAL(ret.size(), 0U);
+ // one query to get NSs, then A and AAAA for each NS, 5th NS hits the limit
+ // limit is reduced to 5, because zone publishes many (20) NS
+ BOOST_CHECK_EQUAL(queriesCount, 11);
+ }
+}
+
BOOST_AUTO_TEST_CASE(test_cache_hit)
{
std::unique_ptr<SyncRes> sr;
return 0;
});
- /* we populate the cache with eveything we need */
+ /* we populate the cache with everything we need */
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.1", DNSResourceRecord::ANSWER, now + 3600);
- t_RC->replace(now, target, QType(QType::A), records, sigs, vector<std::shared_ptr<DNSRecord>>(), true, boost::optional<Netmask>());
+ s_RC->replace(now, target, QType(QType::A), records, sigs, vector<std::shared_ptr<DNSRecord>>(), true, boost::optional<Netmask>());
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
const ComboAddress who;
vector<DNSRecord> cached;
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
BOOST_REQUIRE_GT(cached[0].d_ttl, now);
BOOST_CHECK_EQUAL((cached[0].d_ttl - now), SyncRes::s_minimumTTL);
cached.clear();
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::NS), false, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::NS), false, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
BOOST_REQUIRE_GT(cached[0].d_ttl, now);
BOOST_CHECK_LE((cached[0].d_ttl - now), SyncRes::s_maxcachettl);
const ComboAddress who("192.0.2.128");
vector<DNSRecord> cached;
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::A), true, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
BOOST_REQUIRE_GT(cached[0].d_ttl, now);
BOOST_CHECK_EQUAL((cached[0].d_ttl - now), SyncRes::s_minimumECSTTL);
cached.clear();
- BOOST_REQUIRE_GT(t_RC->get(now, target, QType(QType::NS), false, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, target, QType(QType::NS), false, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
BOOST_REQUIRE_GT(cached[0].d_ttl, now);
BOOST_CHECK_LE((cached[0].d_ttl - now), SyncRes::s_maxcachettl);
cached.clear();
- BOOST_REQUIRE_GT(t_RC->get(now, DNSName("a.gtld-servers.net."), QType(QType::A), false, &cached, who), 0);
+ BOOST_REQUIRE_GT(s_RC->get(now, DNSName("a.gtld-servers.net."), QType(QType::A), false, &cached, who), 0);
BOOST_REQUIRE_EQUAL(cached.size(), 1U);
BOOST_REQUIRE_GT(cached[0].d_ttl, now);
BOOST_CHECK_LE((cached[0].d_ttl - now), SyncRes::s_minimumTTL);
std::vector<shared_ptr<RRSIGRecordContent>> sigs;
addRecordToList(records, target, QType::A, "192.0.2.42", DNSResourceRecord::ANSWER, now - 60);
- t_RC->replace(now - 3600, target, QType(QType::A), records, sigs, vector<std::shared_ptr<DNSRecord>>(), true, boost::optional<Netmask>());
+ s_RC->replace(now - 3600, target, QType(QType::A), records, sigs, vector<std::shared_ptr<DNSRecord>>(), true, boost::optional<Netmask>());
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);