SyncRes::s_ecsipv6limit = 56;
SyncRes::s_ecsipv4cachelimit = 24;
SyncRes::s_ecsipv6cachelimit = 56;
+ SyncRes::s_ecscachelimitttl = 0;
SyncRes::s_rootNXTrust = true;
SyncRes::s_minimumTTL = 0;
SyncRes::s_minimumECSTTL = 0;
BOOST_REQUIRE_EQUAL(cached.size(), 0);
}
+BOOST_AUTO_TEST_CASE(test_ecs_cache_ttllimit_allowed) {
+ std::unique_ptr<SyncRes> sr;
+ initSR(sr);
+
+ primeHints();
+
+ const DNSName target("www.powerdns.com.");
+
+ SyncRes::addEDNSDomain(DNSName("powerdns.com."));
+
+ EDNSSubnetOpts incomingECS;
+ incomingECS.source = Netmask("192.0.2.128/32");
+ sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
+ SyncRes::s_ecscachelimitttl = 30;
+
+ sr->setAsyncCallback([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) {
+
+ BOOST_REQUIRE(srcmask);
+ BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
+
+ setLWResult(res, 0, true, false, true);
+ addRecordToLW(res, target, QType::A, "192.0.2.1");
+
+ return 1;
+ });
+
+ const time_t now = sr->getNow().tv_sec;
+ vector<DNSRecord> ret;
+ int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
+ BOOST_CHECK_EQUAL(res, RCode::NoError);
+ BOOST_CHECK_EQUAL(ret.size(), 1);
+
+ /* 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_EQUAL(cached.size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_ecs_cache_ttllimit_notallowed) {
+ std::unique_ptr<SyncRes> sr;
+ initSR(sr);
+
+ primeHints();
+
+ const DNSName target("www.powerdns.com.");
+
+ SyncRes::addEDNSDomain(DNSName("powerdns.com."));
+
+ EDNSSubnetOpts incomingECS;
+ incomingECS.source = Netmask("192.0.2.128/32");
+ sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
+ SyncRes::s_ecscachelimitttl = 100;
+
+ sr->setAsyncCallback([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) {
+
+ BOOST_REQUIRE(srcmask);
+ BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
+
+ setLWResult(res, 0, true, false, true);
+ addRecordToLW(res, target, QType::A, "192.0.2.1");
+
+ return 1;
+ });
+
+ const time_t now = sr->getNow().tv_sec;
+ vector<DNSRecord> ret;
+ int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
+ BOOST_CHECK_EQUAL(res, RCode::NoError);
+ BOOST_CHECK_EQUAL(ret.size(), 1);
+
+ /* should have NOT been cached because TTL of 60 is too small */
+ 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_EQUAL(cached.size(), 0);
+}
+
+
BOOST_AUTO_TEST_CASE(test_ns_speed) {
std::unique_ptr<SyncRes> sr;
initSR(sr);
SyncRes::SyncRes(const struct timeval& now) : d_authzonequeries(0), d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_unreachables(0),
d_totUsec(0), d_now(now),
d_cacheonly(false), d_doDNSSEC(false), d_doEDNS0(false), d_lm(s_lm)
-
-{
+
+{
}
/** everything begins here - this is the entry point just after receiving a packet */
Another cause of "No answer" may simply be a network condition.
Nonsense answers are a clearer indication this host won't be able to do DNSSEC evah.
- Previous implementations have suffered from turning off DNSSEC questions for an authoritative server based on timeouts.
+ Previous implementations have suffered from turning off DNSSEC questions for an authoritative server based on timeouts.
A clever idea is to only turn off DNSSEC if we know a domain isn't signed anyhow. The problem with that really
- clever idea however is that at this point in PowerDNS, we may simply not know that yet. All the DNSSEC thinking happens
- elsewhere. It may not have happened yet.
+ clever idea however is that at this point in PowerDNS, we may simply not know that yet. All the DNSSEC thinking happens
+ elsewhere. It may not have happened yet.
For now this means we can't be clever, but will turn off DNSSEC if you reply with FormError or gibberish.
*/
the goal is to get as many remotes as possible on the highest level of EDNS support
The levels are:
- 0) UNKNOWN Unknown state
+ 0) UNKNOWN Unknown state
1) EDNS: Honors EDNS0
2) EDNSIGNORANT: Ignores EDNS0, gives replies without EDNS0
3) NOEDNS: Generates FORMERR on EDNS queries
Everybody starts out assumed to be '0'.
If '0', send out EDNS0
- If you FORMERR us, go to '3',
+ If you FORMERR us, go to '3',
If no EDNS in response, go to '2'
If '1', send out EDNS0
If FORMERR, downgrade to 3
If '2', keep on including EDNS0, see what happens
- Same behaviour as 0
+ Same behaviour as 0
If '3', send bare queries
*/
int ret;
for(int tries = 0; tries < 3; ++tries) {
// cerr<<"Remote '"<<ip.toString()<<"' currently in mode "<<mode<<endl;
-
+
if(mode==EDNSStatus::NOEDNS) {
g_stats.noEdnsOutQueries++;
EDNSLevel = 0; // level != mode
mode = EDNSStatus::EDNSOK;
// cerr<<"We find that "<<ip.toString()<<" is EDNS OK!"<<endl;
}
-
+
}
if(oldmode != mode || !ednsstatus->modeSetAt)
ednsstatus->modeSetAt=d_now.tv_sec;
- // cerr<<"Result: ret="<<ret<<", EDNS-level: "<<EDNSLevel<<", haveEDNS: "<<res->d_haveEDNS<<", new mode: "<<mode<<endl;
+ // cerr<<"Result: ret="<<ret<<", EDNS-level: "<<EDNSLevel<<", haveEDNS: "<<res->d_haveEDNS<<", new mode: "<<mode<<endl;
return ret;
}
return ret;
DNSRecord dr;
dr.d_type=QType::RRSIG;
dr.d_name=sqname;
- dr.d_ttl=ttl;
+ dr.d_ttl=ttl;
dr.d_content=signature;
dr.d_place = DNSResourceRecord::ANSWER;
dr.d_class=QClass::IN;
g_log<<Logger::Error<<"Failed to resolve "<<qname.toLogString()<<", got an exception"<<endl;
ret.clear();
}
-
+
return res;
}