1 #define BOOST_TEST_DYN_LINK
2 #include <boost/test/unit_test.hpp>
4 #include "test-syncres_cc.hh"
6 BOOST_AUTO_TEST_SUITE(syncres_cc3
)
8 BOOST_AUTO_TEST_CASE(test_cache_auth
)
10 std::unique_ptr
<SyncRes
> sr
;
15 /* the auth server is sending the same answer in answer and additional,
16 check that we only return one result, and we only cache one too. */
17 const DNSName
target("cache-auth.powerdns.com.");
19 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
) {
20 setLWResult(res
, 0, true, false, true);
21 addRecordToLW(res
, domain
, QType::A
, "192.0.2.2", DNSResourceRecord::ANSWER
, 10);
22 addRecordToLW(res
, domain
, QType::A
, "192.0.2.2", DNSResourceRecord::ADDITIONAL
, 10);
27 const time_t now
= sr
->getNow().tv_sec
;
29 vector
<DNSRecord
> ret
;
30 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
31 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
32 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
33 BOOST_REQUIRE_EQUAL(QType(ret
.at(0).d_type
).getName(), QType(QType::A
).getName());
34 BOOST_CHECK_EQUAL(getRR
<ARecordContent
>(ret
.at(0))->getCA().toString(), ComboAddress("192.0.2.2").toString());
36 /* check that we correctly cached only the answer entry, not the additional one */
37 const ComboAddress who
;
38 vector
<DNSRecord
> cached
;
39 BOOST_REQUIRE_GT(s_RC
->get(now
, target
, QType(QType::A
), true, &cached
, who
), 0);
40 BOOST_REQUIRE_EQUAL(cached
.size(), 1U);
41 BOOST_REQUIRE_EQUAL(QType(cached
.at(0).d_type
).getName(), QType(QType::A
).getName());
42 BOOST_CHECK_EQUAL(getRR
<ARecordContent
>(cached
.at(0))->getCA().toString(), ComboAddress("192.0.2.2").toString());
45 BOOST_AUTO_TEST_CASE(test_delegation_only
)
47 std::unique_ptr
<SyncRes
> sr
;
52 /* Thanks, Verisign */
53 SyncRes::addDelegationOnly(DNSName("com."));
54 SyncRes::addDelegationOnly(DNSName("net."));
56 const DNSName
target("nx-powerdns.com.");
58 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
) {
59 if (isRootServer(ip
)) {
60 setLWResult(res
, 0, false, false, true);
61 addRecordToLW(res
, "com.", QType::NS
, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY
, 172800);
62 addRecordToLW(res
, "a.gtld-servers.net.", QType::A
, "192.0.2.1", DNSResourceRecord::ADDITIONAL
, 3600);
65 else if (ip
== ComboAddress("192.0.2.1:53")) {
67 setLWResult(res
, 0, true, false, true);
68 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
75 vector
<DNSRecord
> ret
;
76 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
77 BOOST_CHECK_EQUAL(res
, RCode::NXDomain
);
78 BOOST_CHECK_EQUAL(ret
.size(), 0U);
81 BOOST_AUTO_TEST_CASE(test_unauth_any
)
83 std::unique_ptr
<SyncRes
> sr
;
88 const DNSName
target("powerdns.com.");
90 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
) {
91 if (isRootServer(ip
)) {
92 setLWResult(res
, 0, false, false, true);
93 addRecordToLW(res
, "com.", QType::NS
, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY
, 172800);
94 addRecordToLW(res
, "a.gtld-servers.net.", QType::A
, "192.0.2.1", DNSResourceRecord::ADDITIONAL
, 3600);
97 else if (ip
== ComboAddress("192.0.2.1:53")) {
99 setLWResult(res
, 0, false, false, true);
100 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
107 vector
<DNSRecord
> ret
;
108 int res
= sr
->beginResolve(target
, QType(QType::ANY
), QClass::IN
, ret
);
109 BOOST_CHECK_EQUAL(res
, RCode::ServFail
);
110 BOOST_CHECK_EQUAL(ret
.size(), 0U);
113 static void test_no_data_f(bool qmin
)
115 std::unique_ptr
<SyncRes
> sr
;
118 sr
->setQNameMinimization();
122 const DNSName
target("powerdns.com.");
124 sr
->setAsyncCallback(
125 [target
](const ComboAddress
& ip
, const DNSName
& domain
, int type
, bool doTCP
, bool sendRDQuery
, int EDNS0Level
,
126 struct timeval
* now
, boost::optional
<Netmask
>& srcmask
, boost::optional
<const ResolveContext
&> context
,
127 LWResult
* res
, bool* chained
) {
128 setLWResult(res
, 0, true, false, true);
132 vector
<DNSRecord
> ret
;
133 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
134 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
135 BOOST_CHECK_EQUAL(ret
.size(), 0U);
138 BOOST_AUTO_TEST_CASE(test_no_data
)
140 test_no_data_f(false);
143 BOOST_AUTO_TEST_CASE(test_no_data_qmin
)
145 test_no_data_f(true);
148 BOOST_AUTO_TEST_CASE(test_skip_opt_any
)
150 std::unique_ptr
<SyncRes
> sr
;
155 const DNSName
target("powerdns.com.");
157 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
) {
158 setLWResult(res
, 0, true, false, true);
159 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
160 addRecordToLW(res
, domain
, QType::ANY
, "0 0");
161 addRecordToLW(res
, domain
, QType::OPT
, "");
165 vector
<DNSRecord
> ret
;
166 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
167 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
168 BOOST_CHECK_EQUAL(ret
.size(), 1U);
171 BOOST_AUTO_TEST_CASE(test_nodata_nsec_nodnssec
)
173 std::unique_ptr
<SyncRes
> sr
;
178 const DNSName
target("powerdns.com.");
180 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
) {
181 setLWResult(res
, 0, true, false, true);
182 addRecordToLW(res
, domain
, QType::SOA
, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY
, 3600);
183 /* the NSEC and RRSIG contents are complete garbage, please ignore them */
184 addRecordToLW(res
, domain
, QType::NSEC
, "deadbeef", DNSResourceRecord::AUTHORITY
);
185 addRecordToLW(res
, domain
, QType::RRSIG
, "NSEC 5 2 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
186 addRecordToLW(res
, domain
, QType::RRSIG
, "SOA 5 3 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
190 vector
<DNSRecord
> ret
;
191 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
192 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
193 BOOST_CHECK_EQUAL(ret
.size(), 1U);
196 BOOST_AUTO_TEST_CASE(test_nodata_nsec_dnssec
)
198 std::unique_ptr
<SyncRes
> sr
;
203 const DNSName
target("powerdns.com.");
205 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
) {
206 setLWResult(res
, 0, true, false, true);
207 addRecordToLW(res
, domain
, QType::SOA
, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY
, 3600);
208 /* the NSEC and RRSIG contents are complete garbage, please ignore them */
209 addRecordToLW(res
, domain
, QType::NSEC
, "deadbeef", DNSResourceRecord::AUTHORITY
);
210 addRecordToLW(res
, domain
, QType::RRSIG
, "NSEC 5 2 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
211 addRecordToLW(res
, domain
, QType::RRSIG
, "SOA 5 3 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
215 vector
<DNSRecord
> ret
;
216 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
217 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
218 BOOST_CHECK_EQUAL(ret
.size(), 4U);
221 BOOST_AUTO_TEST_CASE(test_nx_nsec_nodnssec
)
223 std::unique_ptr
<SyncRes
> sr
;
228 const DNSName
target("powerdns.com.");
230 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
) {
231 setLWResult(res
, RCode::NXDomain
, true, false, true);
232 addRecordToLW(res
, domain
, QType::SOA
, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY
, 3600);
233 /* the NSEC and RRSIG contents are complete garbage, please ignore them */
234 addRecordToLW(res
, domain
, QType::NSEC
, "deadbeef", DNSResourceRecord::AUTHORITY
);
235 addRecordToLW(res
, domain
, QType::RRSIG
, "NSEC 5 2 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
236 addRecordToLW(res
, domain
, QType::RRSIG
, "SOA 5 3 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
240 vector
<DNSRecord
> ret
;
241 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
242 BOOST_CHECK_EQUAL(res
, RCode::NXDomain
);
243 BOOST_CHECK_EQUAL(ret
.size(), 1U);
246 BOOST_AUTO_TEST_CASE(test_nx_nsec_dnssec
)
248 std::unique_ptr
<SyncRes
> sr
;
253 const DNSName
target("powerdns.com.");
255 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
) {
256 setLWResult(res
, RCode::NXDomain
, true, false, true);
257 addRecordToLW(res
, domain
, QType::SOA
, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY
, 3600);
258 /* the NSEC and RRSIG contents are complete garbage, please ignore them */
259 addRecordToLW(res
, domain
, QType::NSEC
, "deadbeef", DNSResourceRecord::AUTHORITY
);
260 addRecordToLW(res
, domain
, QType::RRSIG
, "NSEC 5 2 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
261 addRecordToLW(res
, domain
, QType::RRSIG
, "SOA 5 3 600 2100010100000000 2100010100000000 24567 dummy data", DNSResourceRecord::AUTHORITY
);
265 vector
<DNSRecord
> ret
;
266 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
267 BOOST_CHECK_EQUAL(res
, RCode::NXDomain
);
268 BOOST_CHECK_EQUAL(ret
.size(), 4U);
271 BOOST_AUTO_TEST_CASE(test_qclass_none
)
273 std::unique_ptr
<SyncRes
> sr
;
278 /* apart from special names and QClass::ANY, anything else than QClass::IN should be rejected right away */
279 size_t queriesCount
= 0;
281 sr
->setAsyncCallback([&queriesCount
](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
) {
286 const DNSName
target("powerdns.com.");
287 vector
<DNSRecord
> ret
;
288 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::NONE
, ret
);
289 BOOST_CHECK_EQUAL(res
, -1);
290 BOOST_CHECK_EQUAL(ret
.size(), 0U);
291 BOOST_CHECK_EQUAL(queriesCount
, 0U);
294 BOOST_AUTO_TEST_CASE(test_answer_no_aa
)
296 std::unique_ptr
<SyncRes
> sr
;
301 const DNSName
target("powerdns.com.");
303 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
) {
304 setLWResult(res
, 0, false, false, true);
305 addRecordToLW(res
, domain
, QType::A
, "192.0.2.1");
309 const time_t now
= sr
->getNow().tv_sec
;
311 vector
<DNSRecord
> ret
;
312 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
313 BOOST_CHECK_EQUAL(res
, RCode::ServFail
);
314 BOOST_CHECK_EQUAL(ret
.size(), 0U);
316 /* check that the record in the answer section has not been cached */
317 const ComboAddress who
;
318 vector
<DNSRecord
> cached
;
319 vector
<std::shared_ptr
<RRSIGRecordContent
>> signatures
;
320 BOOST_REQUIRE_EQUAL(s_RC
->get(now
, target
, QType(QType::A
), false, &cached
, who
, &signatures
), -1);
323 BOOST_AUTO_TEST_CASE(test_special_types
)
325 std::unique_ptr
<SyncRes
> sr
;
330 /* {A,I}XFR, RRSIG and NSEC3 should be rejected right away */
331 size_t queriesCount
= 0;
333 sr
->setAsyncCallback([&queriesCount
](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
) {
334 cerr
<< "asyncresolve called to ask " << ip
.toStringWithPort() << " about " << domain
.toString() << " / " << QType(type
).getName() << " over " << (doTCP
? "TCP" : "UDP") << " (rd: " << sendRDQuery
<< ", EDNS0 level: " << EDNS0Level
<< ")" << endl
;
339 const DNSName
target("powerdns.com.");
340 vector
<DNSRecord
> ret
;
341 int res
= sr
->beginResolve(target
, QType(QType::AXFR
), QClass::IN
, ret
);
342 BOOST_CHECK_EQUAL(res
, -1);
343 BOOST_CHECK_EQUAL(ret
.size(), 0U);
344 BOOST_CHECK_EQUAL(queriesCount
, 0U);
346 res
= sr
->beginResolve(target
, QType(QType::IXFR
), QClass::IN
, ret
);
347 BOOST_CHECK_EQUAL(res
, -1);
348 BOOST_CHECK_EQUAL(ret
.size(), 0U);
349 BOOST_CHECK_EQUAL(queriesCount
, 0U);
351 res
= sr
->beginResolve(target
, QType(QType::RRSIG
), QClass::IN
, ret
);
352 BOOST_CHECK_EQUAL(res
, -1);
353 BOOST_CHECK_EQUAL(ret
.size(), 0U);
354 BOOST_CHECK_EQUAL(queriesCount
, 0U);
356 res
= sr
->beginResolve(target
, QType(QType::NSEC3
), QClass::IN
, ret
);
357 BOOST_CHECK_EQUAL(res
, -1);
358 BOOST_CHECK_EQUAL(ret
.size(), 0U);
359 BOOST_CHECK_EQUAL(queriesCount
, 0U);
362 BOOST_AUTO_TEST_CASE(test_special_names
)
364 std::unique_ptr
<SyncRes
> sr
;
369 /* special names should be handled internally */
371 size_t queriesCount
= 0;
373 sr
->setAsyncCallback([&queriesCount
](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
) {
378 vector
<DNSRecord
> ret
;
379 int res
= sr
->beginResolve(DNSName("1.0.0.127.in-addr.arpa."), QType(QType::PTR
), QClass::IN
, ret
);
380 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
381 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
382 BOOST_CHECK(ret
[0].d_type
== QType::PTR
);
383 BOOST_CHECK_EQUAL(queriesCount
, 0U);
386 res
= sr
->beginResolve(DNSName("1.0.0.127.in-addr.arpa."), QType(QType::ANY
), QClass::IN
, ret
);
387 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
388 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
389 BOOST_CHECK(ret
[0].d_type
== QType::PTR
);
390 BOOST_CHECK_EQUAL(queriesCount
, 0U);
393 res
= sr
->beginResolve(DNSName("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa."), QType(QType::PTR
), QClass::IN
, ret
);
394 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
395 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
396 BOOST_CHECK(ret
[0].d_type
== QType::PTR
);
397 BOOST_CHECK_EQUAL(queriesCount
, 0U);
400 res
= sr
->beginResolve(DNSName("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa."), QType(QType::ANY
), QClass::IN
, ret
);
401 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
402 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
403 BOOST_CHECK(ret
[0].d_type
== QType::PTR
);
404 BOOST_CHECK_EQUAL(queriesCount
, 0U);
407 res
= sr
->beginResolve(DNSName("localhost."), QType(QType::A
), QClass::IN
, ret
);
408 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
409 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
410 BOOST_CHECK(ret
[0].d_type
== QType::A
);
411 BOOST_CHECK_EQUAL(getRR
<ARecordContent
>(ret
[0])->getCA().toString(), "127.0.0.1");
412 BOOST_CHECK_EQUAL(queriesCount
, 0U);
415 res
= sr
->beginResolve(DNSName("localhost."), QType(QType::AAAA
), QClass::IN
, ret
);
416 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
417 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
418 BOOST_CHECK(ret
[0].d_type
== QType::AAAA
);
419 BOOST_CHECK_EQUAL(getRR
<AAAARecordContent
>(ret
[0])->getCA().toString(), "::1");
420 BOOST_CHECK_EQUAL(queriesCount
, 0U);
423 res
= sr
->beginResolve(DNSName("localhost."), QType(QType::ANY
), QClass::IN
, ret
);
424 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
425 BOOST_REQUIRE_EQUAL(ret
.size(), 2U);
426 for (const auto& rec
: ret
) {
427 BOOST_REQUIRE((rec
.d_type
== QType::A
) || rec
.d_type
== QType::AAAA
);
428 if (rec
.d_type
== QType::A
) {
429 BOOST_CHECK_EQUAL(getRR
<ARecordContent
>(rec
)->getCA().toString(), "127.0.0.1");
432 BOOST_CHECK_EQUAL(getRR
<AAAARecordContent
>(rec
)->getCA().toString(), "::1");
435 BOOST_CHECK_EQUAL(queriesCount
, 0U);
438 res
= sr
->beginResolve(DNSName("version.bind."), QType(QType::TXT
), QClass::CHAOS
, ret
);
439 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
440 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
441 BOOST_CHECK(ret
[0].d_type
== QType::TXT
);
442 BOOST_CHECK_EQUAL(getRR
<TXTRecordContent
>(ret
[0])->d_text
, "\"PowerDNS Unit Tests\"");
443 BOOST_CHECK_EQUAL(queriesCount
, 0U);
446 res
= sr
->beginResolve(DNSName("version.bind."), QType(QType::ANY
), QClass::CHAOS
, ret
);
447 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
448 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
449 BOOST_CHECK(ret
[0].d_type
== QType::TXT
);
450 BOOST_CHECK_EQUAL(getRR
<TXTRecordContent
>(ret
[0])->d_text
, "\"PowerDNS Unit Tests\"");
451 BOOST_CHECK_EQUAL(queriesCount
, 0U);
454 res
= sr
->beginResolve(DNSName("version.pdns."), QType(QType::TXT
), QClass::CHAOS
, ret
);
455 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
456 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
457 BOOST_CHECK(ret
[0].d_type
== QType::TXT
);
458 BOOST_CHECK_EQUAL(getRR
<TXTRecordContent
>(ret
[0])->d_text
, "\"PowerDNS Unit Tests\"");
459 BOOST_CHECK_EQUAL(queriesCount
, 0U);
462 res
= sr
->beginResolve(DNSName("version.pdns."), QType(QType::ANY
), QClass::CHAOS
, ret
);
463 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
464 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
465 BOOST_CHECK(ret
[0].d_type
== QType::TXT
);
466 BOOST_CHECK_EQUAL(getRR
<TXTRecordContent
>(ret
[0])->d_text
, "\"PowerDNS Unit Tests\"");
467 BOOST_CHECK_EQUAL(queriesCount
, 0U);
470 res
= sr
->beginResolve(DNSName("id.server."), QType(QType::TXT
), QClass::CHAOS
, ret
);
471 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
472 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
473 BOOST_CHECK(ret
[0].d_type
== QType::TXT
);
474 BOOST_CHECK_EQUAL(getRR
<TXTRecordContent
>(ret
[0])->d_text
, "\"PowerDNS Unit Tests Server ID\"");
475 BOOST_CHECK_EQUAL(queriesCount
, 0U);
478 res
= sr
->beginResolve(DNSName("id.server."), QType(QType::ANY
), QClass::CHAOS
, ret
);
479 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
480 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
481 BOOST_CHECK(ret
[0].d_type
== QType::TXT
);
482 BOOST_CHECK_EQUAL(getRR
<TXTRecordContent
>(ret
[0])->d_text
, "\"PowerDNS Unit Tests Server ID\"");
483 BOOST_CHECK_EQUAL(queriesCount
, 0U);
486 BOOST_AUTO_TEST_CASE(test_nameserver_ipv4_rpz
)
488 std::unique_ptr
<SyncRes
> sr
;
493 const DNSName
target("rpz.powerdns.com.");
494 const ComboAddress
ns("192.0.2.1:53");
496 sr
->setAsyncCallback([target
, ns
](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
) {
497 if (isRootServer(ip
)) {
498 setLWResult(res
, false, true, false, true);
499 addRecordToLW(res
, "com.", QType::NS
, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY
, 172800);
500 addRecordToLW(res
, "a.gtld-servers.net.", QType::A
, ns
.toString(), DNSResourceRecord::ADDITIONAL
, 3600);
505 setLWResult(res
, 0, true, false, true);
506 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
513 DNSFilterEngine::Policy pol
;
514 pol
.d_kind
= DNSFilterEngine::PolicyKind::Drop
;
515 std::shared_ptr
<DNSFilterEngine::Zone
> zone
= std::make_shared
<DNSFilterEngine::Zone
>();
516 zone
->setName("Unit test policy 0");
517 zone
->addNSIPTrigger(Netmask(ns
, 32), std::move(pol
));
518 auto luaconfsCopy
= g_luaconfs
.getCopy();
519 luaconfsCopy
.dfe
.clearZones();
520 luaconfsCopy
.dfe
.addZone(zone
);
521 g_luaconfs
.setState(luaconfsCopy
);
523 vector
<DNSRecord
> ret
;
524 BOOST_CHECK_THROW(sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
), PolicyHitException
);
527 BOOST_AUTO_TEST_CASE(test_nameserver_ipv6_rpz
)
529 std::unique_ptr
<SyncRes
> sr
;
534 const DNSName
target("rpz.powerdns.com.");
535 const ComboAddress
ns("[2001:DB8::42]:53");
537 sr
->setAsyncCallback([target
, ns
](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
) {
538 if (isRootServer(ip
)) {
539 setLWResult(res
, 0, false, false, true);
540 addRecordToLW(res
, "com.", QType::NS
, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY
, 172800);
541 addRecordToLW(res
, "a.gtld-servers.net.", QType::AAAA
, ns
.toString(), DNSResourceRecord::ADDITIONAL
, 3600);
546 setLWResult(res
, 0, true, false, true);
547 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
554 DNSFilterEngine::Policy pol
;
555 pol
.d_kind
= DNSFilterEngine::PolicyKind::Drop
;
556 std::shared_ptr
<DNSFilterEngine::Zone
> zone
= std::make_shared
<DNSFilterEngine::Zone
>();
557 zone
->setName("Unit test policy 0");
558 zone
->addNSIPTrigger(Netmask(ns
, 128), std::move(pol
));
559 auto luaconfsCopy
= g_luaconfs
.getCopy();
560 luaconfsCopy
.dfe
.clearZones();
561 luaconfsCopy
.dfe
.addZone(zone
);
562 g_luaconfs
.setState(luaconfsCopy
);
564 vector
<DNSRecord
> ret
;
565 BOOST_CHECK_THROW(sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
), PolicyHitException
);
568 BOOST_AUTO_TEST_CASE(test_nameserver_name_rpz
)
570 std::unique_ptr
<SyncRes
> sr
;
575 const DNSName
target("rpz.powerdns.com.");
576 const ComboAddress
ns("192.0.2.1:53");
577 const DNSName
nsName("ns1.powerdns.com.");
579 sr
->setAsyncCallback([target
, ns
, nsName
](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
) {
580 if (isRootServer(ip
)) {
581 setLWResult(res
, 0, false, false, true);
582 addRecordToLW(res
, domain
, QType::NS
, nsName
.toString(), DNSResourceRecord::AUTHORITY
, 172800);
583 addRecordToLW(res
, nsName
, QType::A
, ns
.toString(), DNSResourceRecord::ADDITIONAL
, 3600);
588 setLWResult(res
, 0, true, false, true);
589 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
596 DNSFilterEngine::Policy pol
;
597 pol
.d_kind
= DNSFilterEngine::PolicyKind::Drop
;
598 std::shared_ptr
<DNSFilterEngine::Zone
> zone
= std::make_shared
<DNSFilterEngine::Zone
>();
599 zone
->setName("Unit test policy 0");
600 zone
->addNSTrigger(nsName
, std::move(pol
));
601 auto luaconfsCopy
= g_luaconfs
.getCopy();
602 luaconfsCopy
.dfe
.clearZones();
603 luaconfsCopy
.dfe
.addZone(zone
);
604 g_luaconfs
.setState(luaconfsCopy
);
606 vector
<DNSRecord
> ret
;
607 BOOST_CHECK_THROW(sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
), PolicyHitException
);
610 BOOST_AUTO_TEST_CASE(test_nameserver_name_rpz_disabled
)
612 std::unique_ptr
<SyncRes
> sr
;
617 const DNSName
target("rpz.powerdns.com.");
618 const ComboAddress
ns("192.0.2.1:53");
619 const DNSName
nsName("ns1.powerdns.com.");
621 sr
->setAsyncCallback([target
, ns
, nsName
](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
) {
622 if (isRootServer(ip
)) {
623 setLWResult(res
, 0, false, false, true);
624 addRecordToLW(res
, domain
, QType::NS
, nsName
.toString(), DNSResourceRecord::AUTHORITY
, 172800);
625 addRecordToLW(res
, nsName
, QType::A
, ns
.toString(), DNSResourceRecord::ADDITIONAL
, 3600);
630 setLWResult(res
, 0, true, false, true);
631 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
638 DNSFilterEngine::Policy pol
;
639 pol
.d_kind
= DNSFilterEngine::PolicyKind::Drop
;
640 std::shared_ptr
<DNSFilterEngine::Zone
> zone
= std::make_shared
<DNSFilterEngine::Zone
>();
641 zone
->setName("Unit test policy 0");
642 zone
->addNSIPTrigger(Netmask(ns
, 128), DNSFilterEngine::Policy(pol
));
643 zone
->addNSTrigger(nsName
, std::move(pol
));
644 auto luaconfsCopy
= g_luaconfs
.getCopy();
645 luaconfsCopy
.dfe
.clearZones();
646 luaconfsCopy
.dfe
.addZone(zone
);
647 g_luaconfs
.setState(luaconfsCopy
);
649 /* RPZ is disabled for this query, we should not be blocked */
650 sr
->setWantsRPZ(false);
652 vector
<DNSRecord
> ret
;
653 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
654 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
655 BOOST_CHECK_EQUAL(ret
.size(), 1U);
658 BOOST_AUTO_TEST_CASE(test_forward_zone_nord
)
660 std::unique_ptr
<SyncRes
> sr
;
665 const DNSName
target("powerdns.com.");
666 const ComboAddress
ns("192.0.2.1:53");
667 const ComboAddress
forwardedNS("192.0.2.42:53");
669 SyncRes::AuthDomain ad
;
670 ad
.d_rdForward
= false;
671 ad
.d_servers
.push_back(forwardedNS
);
672 (*SyncRes::t_sstorage
.domainmap
)[target
] = ad
;
674 sr
->setAsyncCallback([forwardedNS
](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
) {
675 if (ip
== forwardedNS
) {
676 BOOST_CHECK_EQUAL(sendRDQuery
, false);
678 setLWResult(res
, 0, true, false, true);
679 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
686 /* simulate a no-RD query */
689 vector
<DNSRecord
> ret
;
690 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
691 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
692 BOOST_CHECK_EQUAL(ret
.size(), 1U);
695 BOOST_AUTO_TEST_CASE(test_forward_zone_rd
)
697 std::unique_ptr
<SyncRes
> sr
;
702 const DNSName
target("powerdns.com.");
703 const ComboAddress
ns("192.0.2.1:53");
704 const ComboAddress
forwardedNS("192.0.2.42:53");
706 size_t queriesCount
= 0;
707 SyncRes::AuthDomain ad
;
708 ad
.d_rdForward
= true;
709 ad
.d_servers
.push_back(forwardedNS
);
710 (*SyncRes::t_sstorage
.domainmap
)[target
] = ad
;
712 sr
->setAsyncCallback([forwardedNS
, &queriesCount
](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
) {
715 if (ip
== forwardedNS
) {
716 BOOST_CHECK_EQUAL(sendRDQuery
, true);
718 /* set AA=0, we are a recursor */
719 setLWResult(res
, 0, false, false, true);
720 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
727 vector
<DNSRecord
> ret
;
728 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
729 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
730 BOOST_CHECK_EQUAL(ret
.size(), 1U);
731 BOOST_CHECK_EQUAL(queriesCount
, 1U);
733 /* now make sure we can resolve from the cache (see #6340
734 where the entries were added to the cache but not retrieved,
735 because the recursor doesn't set the AA bit and we require
736 it. We fixed it by not requiring the AA bit for forward-recurse
739 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
740 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
741 BOOST_CHECK_EQUAL(ret
.size(), 1U);
742 BOOST_CHECK_EQUAL(queriesCount
, 1U);
745 BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_nord
)
747 std::unique_ptr
<SyncRes
> sr
;
752 const DNSName
target("powerdns.com.");
753 const ComboAddress
ns("192.0.2.1:53");
754 const ComboAddress
forwardedNS("192.0.2.42:53");
756 SyncRes::AuthDomain ad
;
757 ad
.d_rdForward
= true;
758 ad
.d_servers
.push_back(forwardedNS
);
759 (*SyncRes::t_sstorage
.domainmap
)[target
] = ad
;
761 sr
->setAsyncCallback([forwardedNS
](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
) {
762 if (ip
== forwardedNS
) {
763 BOOST_CHECK_EQUAL(sendRDQuery
, false);
765 setLWResult(res
, 0, true, false, true);
766 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
773 /* simulate a no-RD query */
776 vector
<DNSRecord
> ret
;
777 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
778 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
779 BOOST_CHECK_EQUAL(ret
.size(), 1U);
782 BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd
)
784 std::unique_ptr
<SyncRes
> sr
;
789 const DNSName
target("powerdns.com.");
790 const ComboAddress
ns("192.0.2.1:53");
791 const ComboAddress
forwardedNS("192.0.2.42:53");
793 SyncRes::AuthDomain ad
;
794 ad
.d_rdForward
= true;
795 ad
.d_servers
.push_back(forwardedNS
);
796 (*SyncRes::t_sstorage
.domainmap
)[target
] = ad
;
798 sr
->setAsyncCallback([forwardedNS
](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
) {
799 if (ip
== forwardedNS
) {
800 BOOST_CHECK_EQUAL(sendRDQuery
, true);
802 setLWResult(res
, 0, true, false, true);
803 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
810 vector
<DNSRecord
> ret
;
811 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
812 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
813 BOOST_CHECK_EQUAL(ret
.size(), 1U);
816 BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd_dnssec
)
818 std::unique_ptr
<SyncRes
> sr
;
821 setDNSSECValidation(sr
, DNSSECMode::ValidateAll
);
825 const DNSName
target("test.");
827 const DNSName
cnameTarget("cname.");
830 auto luaconfsCopy
= g_luaconfs
.getCopy();
831 luaconfsCopy
.dsAnchors
.clear();
832 generateKeyMaterial(g_rootdnsname
, DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
, luaconfsCopy
.dsAnchors
);
833 generateKeyMaterial(target
, DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
);
834 g_luaconfs
.setState(luaconfsCopy
);
836 const ComboAddress
forwardedNS("192.0.2.42:53");
837 size_t queriesCount
= 0;
839 SyncRes::AuthDomain ad
;
840 ad
.d_rdForward
= true;
841 ad
.d_servers
.push_back(forwardedNS
);
842 (*SyncRes::t_sstorage
.domainmap
)[g_rootdnsname
] = ad
;
844 sr
->setAsyncCallback([target
, cnameTarget
, keys
, forwardedNS
, &queriesCount
](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
) {
847 BOOST_CHECK_EQUAL(sendRDQuery
, true);
849 if (ip
!= forwardedNS
) {
853 if (type
== QType::DS
|| type
== QType::DNSKEY
) {
854 return genericDSAndDNSKEYHandler(res
, domain
, DNSName("."), type
, keys
);
857 if (domain
== target
&& type
== QType::A
) {
859 setLWResult(res
, 0, false, false, true);
860 addRecordToLW(res
, target
, QType::CNAME
, cnameTarget
.toString());
861 addRRSIG(keys
, res
->d_records
, domain
, 300);
862 addRecordToLW(res
, cnameTarget
, QType::A
, "192.0.2.1");
869 vector
<DNSRecord
> ret
;
870 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
871 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
872 BOOST_CHECK_EQUAL(sr
->getValidationState(), Insecure
);
873 BOOST_REQUIRE_EQUAL(ret
.size(), 3U);
874 BOOST_CHECK_EQUAL(queriesCount
, 5U);
876 /* again, to test the cache */
878 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
879 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
880 BOOST_CHECK_EQUAL(sr
->getValidationState(), Insecure
);
881 BOOST_REQUIRE_EQUAL(ret
.size(), 3U);
882 BOOST_CHECK_EQUAL(queriesCount
, 5U);
885 BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd_dnssec_bogus
)
887 std::unique_ptr
<SyncRes
> sr
;
890 setDNSSECValidation(sr
, DNSSECMode::ValidateAll
);
894 const DNSName
target("test.");
896 const DNSName
cnameTarget("cname.");
899 auto luaconfsCopy
= g_luaconfs
.getCopy();
900 luaconfsCopy
.dsAnchors
.clear();
901 generateKeyMaterial(g_rootdnsname
, DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
, luaconfsCopy
.dsAnchors
);
902 generateKeyMaterial(target
, DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
);
903 generateKeyMaterial(cnameTarget
, DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
);
904 g_luaconfs
.setState(luaconfsCopy
);
906 const ComboAddress
forwardedNS("192.0.2.42:53");
907 size_t queriesCount
= 0;
909 SyncRes::AuthDomain ad
;
910 ad
.d_rdForward
= true;
911 ad
.d_servers
.push_back(forwardedNS
);
912 (*SyncRes::t_sstorage
.domainmap
)[g_rootdnsname
] = ad
;
914 sr
->setAsyncCallback([target
, cnameTarget
, keys
, forwardedNS
, &queriesCount
](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
) {
917 BOOST_CHECK_EQUAL(sendRDQuery
, true);
919 if (ip
!= forwardedNS
) {
923 if (type
== QType::DS
|| type
== QType::DNSKEY
) {
924 return genericDSAndDNSKEYHandler(res
, domain
, DNSName("."), type
, keys
);
927 if (domain
== target
&& type
== QType::A
) {
929 setLWResult(res
, 0, false, false, true);
930 addRecordToLW(res
, target
, QType::CNAME
, cnameTarget
.toString());
931 addRRSIG(keys
, res
->d_records
, domain
, 300);
932 addRecordToLW(res
, cnameTarget
, QType::A
, "192.0.2.1");
933 /* no RRSIG in a signed zone, Bogus ! */
940 vector
<DNSRecord
> ret
;
941 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
942 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
943 BOOST_CHECK_EQUAL(sr
->getValidationState(), Bogus
);
944 BOOST_REQUIRE_EQUAL(ret
.size(), 3U);
945 BOOST_CHECK_EQUAL(queriesCount
, 5U);
947 /* again, to test the cache */
949 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
950 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
951 BOOST_CHECK_EQUAL(sr
->getValidationState(), Bogus
);
952 BOOST_REQUIRE_EQUAL(ret
.size(), 3U);
953 BOOST_CHECK_EQUAL(queriesCount
, 5U);
956 BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd_dnssec_nodata_bogus
)
958 std::unique_ptr
<SyncRes
> sr
;
961 setDNSSECValidation(sr
, DNSSECMode::ValidateAll
);
964 const DNSName
target("powerdns.com.");
967 auto luaconfsCopy
= g_luaconfs
.getCopy();
968 luaconfsCopy
.dsAnchors
.clear();
969 generateKeyMaterial(DNSName("."), DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
, luaconfsCopy
.dsAnchors
);
970 generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
, luaconfsCopy
.dsAnchors
);
971 generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256
, DNSSECKeeper::DIGEST_SHA256
, keys
);
972 g_luaconfs
.setState(luaconfsCopy
);
974 const ComboAddress
forwardedNS("192.0.2.42:53");
975 SyncRes::AuthDomain ad
;
976 ad
.d_rdForward
= true;
977 ad
.d_servers
.push_back(forwardedNS
);
978 (*SyncRes::t_sstorage
.domainmap
)[g_rootdnsname
] = ad
;
980 size_t queriesCount
= 0;
982 sr
->setAsyncCallback([target
, forwardedNS
, &queriesCount
, keys
](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
) {
985 BOOST_CHECK_EQUAL(sendRDQuery
, true);
987 if (ip
!= forwardedNS
) {
991 if (type
== QType::DS
|| type
== QType::DNSKEY
) {
992 return genericDSAndDNSKEYHandler(res
, domain
, domain
, type
, keys
);
996 setLWResult(res
, 0, false, false, true);
1003 vector
<DNSRecord
> ret
;
1004 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1005 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
1006 BOOST_CHECK_EQUAL(sr
->getValidationState(), Bogus
);
1007 BOOST_REQUIRE_EQUAL(ret
.size(), 0U);
1008 /* com|NS, powerdns.com|NS, powerdns.com|A */
1009 BOOST_CHECK_EQUAL(queriesCount
, 3U);
1011 /* again, to test the cache */
1013 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1014 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
1015 BOOST_CHECK_EQUAL(sr
->getValidationState(), Bogus
);
1016 BOOST_REQUIRE_EQUAL(ret
.size(), 0U);
1017 /* we don't store empty results */
1018 BOOST_CHECK_EQUAL(queriesCount
, 4U);
1021 BOOST_AUTO_TEST_CASE(test_auth_zone_oob
)
1023 std::unique_ptr
<SyncRes
> sr
;
1028 size_t queriesCount
= 0;
1029 const DNSName
target("test.xx.");
1030 const ComboAddress
targetAddr("127.0.0.1");
1031 const DNSName
authZone("test.xx");
1033 SyncRes::AuthDomain ad
;
1036 dr
.d_place
= DNSResourceRecord::ANSWER
;
1038 dr
.d_type
= QType::A
;
1040 dr
.d_content
= std::make_shared
<ARecordContent
>(targetAddr
);
1041 ad
.d_records
.insert(dr
);
1043 (*SyncRes::t_sstorage
.domainmap
)[authZone
] = ad
;
1045 sr
->setAsyncCallback([&queriesCount
](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
) {
1050 vector
<DNSRecord
> ret
;
1051 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1052 BOOST_CHECK_EQUAL(res
, 0);
1053 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
1054 BOOST_CHECK(ret
[0].d_type
== QType::A
);
1055 BOOST_CHECK_EQUAL(queriesCount
, 0U);
1056 BOOST_CHECK(sr
->wasOutOfBand());
1057 BOOST_CHECK_EQUAL(sr
->getValidationState(), Indeterminate
);
1059 /* a second time, to check that the OOB flag is set when the query cache is used */
1061 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1062 BOOST_CHECK_EQUAL(res
, 0);
1063 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
1064 BOOST_CHECK(ret
[0].d_type
== QType::A
);
1065 BOOST_CHECK_EQUAL(queriesCount
, 0U);
1066 BOOST_CHECK(sr
->wasOutOfBand());
1067 BOOST_CHECK_EQUAL(sr
->getValidationState(), Indeterminate
);
1069 /* a third time, to check that the validation is disabled when the OOB flag is set */
1071 sr
->setDNSSECValidationRequested(true);
1072 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1073 BOOST_CHECK_EQUAL(res
, 0);
1074 BOOST_REQUIRE_EQUAL(ret
.size(), 1U);
1075 BOOST_CHECK(ret
[0].d_type
== QType::A
);
1076 BOOST_CHECK_EQUAL(queriesCount
, 0U);
1077 BOOST_CHECK(sr
->wasOutOfBand());
1078 BOOST_CHECK_EQUAL(sr
->getValidationState(), Indeterminate
);
1081 BOOST_AUTO_TEST_CASE(test_auth_zone_oob_cname
)
1083 std::unique_ptr
<SyncRes
> sr
;
1088 size_t queriesCount
= 0;
1089 const DNSName
target("cname.test.xx.");
1090 const DNSName
targetCname("cname-target.test.xx.");
1091 const ComboAddress
targetCnameAddr("127.0.0.1");
1092 const DNSName
authZone("test.xx");
1094 SyncRes::AuthDomain ad
;
1097 dr
.d_place
= DNSResourceRecord::ANSWER
;
1099 dr
.d_type
= QType::CNAME
;
1101 dr
.d_content
= std::make_shared
<CNAMERecordContent
>(targetCname
);
1102 ad
.d_records
.insert(dr
);
1104 dr
.d_place
= DNSResourceRecord::ANSWER
;
1105 dr
.d_name
= targetCname
;
1106 dr
.d_type
= QType::A
;
1108 dr
.d_content
= std::make_shared
<ARecordContent
>(targetCnameAddr
);
1109 ad
.d_records
.insert(dr
);
1111 (*SyncRes::t_sstorage
.domainmap
)[authZone
] = ad
;
1113 sr
->setAsyncCallback([&queriesCount
](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
) {
1118 vector
<DNSRecord
> ret
;
1119 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1120 BOOST_CHECK_EQUAL(res
, 0);
1121 BOOST_REQUIRE_EQUAL(ret
.size(), 2U);
1122 BOOST_CHECK(ret
[0].d_type
== QType::CNAME
);
1123 BOOST_CHECK(ret
[1].d_type
== QType::A
);
1124 BOOST_CHECK_EQUAL(queriesCount
, 0U);
1125 BOOST_CHECK(sr
->wasOutOfBand());
1126 BOOST_CHECK_EQUAL(sr
->getValidationState(), Indeterminate
);
1128 /* a second time, to check that the OOB flag is set when the query cache is used */
1130 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1131 BOOST_CHECK_EQUAL(res
, 0);
1132 BOOST_REQUIRE_EQUAL(ret
.size(), 2U);
1133 BOOST_CHECK(ret
[0].d_type
== QType::CNAME
);
1134 BOOST_CHECK(ret
[1].d_type
== QType::A
);
1135 BOOST_CHECK_EQUAL(queriesCount
, 0U);
1136 BOOST_CHECK(sr
->wasOutOfBand());
1137 BOOST_CHECK_EQUAL(sr
->getValidationState(), Indeterminate
);
1139 /* a third time, to check that the validation is disabled when the OOB flag is set */
1141 sr
->setDNSSECValidationRequested(true);
1142 res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1143 BOOST_CHECK_EQUAL(res
, 0);
1144 BOOST_REQUIRE_EQUAL(ret
.size(), 2U);
1145 BOOST_CHECK(ret
[0].d_type
== QType::CNAME
);
1146 BOOST_CHECK(ret
[1].d_type
== QType::A
);
1147 BOOST_CHECK_EQUAL(queriesCount
, 0U);
1148 BOOST_CHECK(sr
->wasOutOfBand());
1149 BOOST_CHECK_EQUAL(sr
->getValidationState(), Indeterminate
);
1152 BOOST_AUTO_TEST_CASE(test_auth_zone
)
1154 std::unique_ptr
<SyncRes
> sr
;
1159 size_t queriesCount
= 0;
1160 const DNSName
target("powerdns.com.");
1161 const ComboAddress
addr("192.0.2.5");
1163 SyncRes::AuthDomain ad
;
1166 dr
.d_place
= DNSResourceRecord::ANSWER
;
1168 dr
.d_type
= QType::SOA
;
1170 dr
.d_content
= std::make_shared
<SOARecordContent
>("pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600");
1171 ad
.d_records
.insert(dr
);
1173 dr
.d_place
= DNSResourceRecord::ANSWER
;
1175 dr
.d_type
= QType::A
;
1177 dr
.d_content
= std::make_shared
<ARecordContent
>(addr
);
1178 ad
.d_records
.insert(dr
);
1180 auto map
= std::make_shared
<SyncRes::domainmap_t
>();
1181 (*map
)[target
] = ad
;
1182 SyncRes::setDomainMap(map
);
1184 sr
->setAsyncCallback([&queriesCount
](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
) {
1186 setLWResult(res
, 0, true, false, true);
1187 addRecordToLW(res
, domain
, QType::A
, "192.0.2.42");
1191 vector
<DNSRecord
> ret
;
1192 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1193 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
1194 BOOST_CHECK_EQUAL(ret
.size(), 1U);
1195 BOOST_CHECK(ret
[0].d_type
== QType::A
);
1196 BOOST_CHECK_EQUAL(getRR
<ARecordContent
>(ret
[0])->getCA().toString(), addr
.toString());
1197 BOOST_CHECK_EQUAL(queriesCount
, 0U);
1200 BOOST_AUTO_TEST_CASE(test_auth_zone_cname_lead_to_oob
)
1202 std::unique_ptr
<SyncRes
> sr
;
1207 size_t queriesCount
= 0;
1208 const DNSName
target("powerdns.com.");
1209 const DNSName
authZone("internal.powerdns.com.");
1210 const ComboAddress
addr("192.0.2.5");
1212 SyncRes::AuthDomain ad
;
1213 ad
.d_name
= authZone
;
1215 dr
.d_place
= DNSResourceRecord::ANSWER
;
1216 dr
.d_name
= authZone
;
1217 dr
.d_type
= QType::SOA
;
1219 dr
.d_content
= std::make_shared
<SOARecordContent
>("pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600");
1220 ad
.d_records
.insert(dr
);
1222 dr
.d_place
= DNSResourceRecord::ANSWER
;
1223 dr
.d_name
= authZone
;
1224 dr
.d_type
= QType::A
;
1226 dr
.d_content
= std::make_shared
<ARecordContent
>(addr
);
1227 ad
.d_records
.insert(dr
);
1229 auto map
= std::make_shared
<SyncRes::domainmap_t
>();
1230 (*map
)[authZone
] = ad
;
1231 SyncRes::setDomainMap(map
);
1233 sr
->setAsyncCallback([&queriesCount
, target
, authZone
](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
) {
1236 if (domain
== target
) {
1237 setLWResult(res
, 0, true, false, true);
1238 addRecordToLW(res
, target
, QType::CNAME
, authZone
.toString(), DNSResourceRecord::ANSWER
, 3600);
1245 vector
<DNSRecord
> ret
;
1246 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1247 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
1248 BOOST_CHECK_EQUAL(ret
.size(), 2U);
1249 BOOST_CHECK(ret
[0].d_type
== QType::CNAME
);
1250 BOOST_CHECK_EQUAL(getRR
<CNAMERecordContent
>(ret
[0])->getTarget().toString(), authZone
.toString());
1251 BOOST_CHECK(ret
[1].d_type
== QType::A
);
1252 BOOST_CHECK_EQUAL(getRR
<ARecordContent
>(ret
[1])->getCA().toString(), addr
.toString());
1253 BOOST_CHECK_EQUAL(queriesCount
, 1U);
1256 BOOST_AUTO_TEST_CASE(test_auth_zone_oob_lead_to_outgoing_queryb
)
1258 std::unique_ptr
<SyncRes
> sr
;
1263 size_t queriesCount
= 0;
1264 const DNSName
target("powerdns.com.");
1265 const DNSName
externalCNAME("www.open-xchange.com.");
1266 const ComboAddress
addr("192.0.2.5");
1268 SyncRes::AuthDomain ad
;
1271 dr
.d_place
= DNSResourceRecord::ANSWER
;
1273 dr
.d_type
= QType::SOA
;
1275 dr
.d_content
= std::make_shared
<SOARecordContent
>("pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600");
1276 ad
.d_records
.insert(dr
);
1278 dr
.d_place
= DNSResourceRecord::ANSWER
;
1280 dr
.d_type
= QType::CNAME
;
1282 dr
.d_content
= std::make_shared
<CNAMERecordContent
>(externalCNAME
);
1283 ad
.d_records
.insert(dr
);
1285 auto map
= std::make_shared
<SyncRes::domainmap_t
>();
1286 (*map
)[target
] = ad
;
1287 SyncRes::setDomainMap(map
);
1289 sr
->setAsyncCallback([&queriesCount
, externalCNAME
, addr
](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
) {
1292 if (domain
== externalCNAME
) {
1293 setLWResult(res
, 0, true, false, true);
1294 addRecordToLW(res
, externalCNAME
, QType::A
, addr
.toString(), DNSResourceRecord::ANSWER
, 3600);
1301 vector
<DNSRecord
> ret
;
1302 int res
= sr
->beginResolve(target
, QType(QType::A
), QClass::IN
, ret
);
1303 BOOST_CHECK_EQUAL(res
, RCode::NoError
);
1304 BOOST_CHECK_EQUAL(ret
.size(), 2U);
1305 BOOST_CHECK(ret
[0].d_type
== QType::CNAME
);
1306 BOOST_CHECK_EQUAL(getRR
<CNAMERecordContent
>(ret
[0])->getTarget().toString(), externalCNAME
.toString());
1307 BOOST_CHECK(ret
[1].d_type
== QType::A
);
1308 BOOST_CHECK_EQUAL(getRR
<ARecordContent
>(ret
[1])->getCA().toString(), addr
.toString());
1309 BOOST_CHECK_EQUAL(queriesCount
, 1U);
1312 BOOST_AUTO_TEST_SUITE_END()