1 #ifndef BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_DYN_LINK
5 #include <boost/test/unit_test.hpp>
7 #include "aggressive_nsec.hh"
9 #include "lua-recursor4.hh"
10 #include "root-dnssec.hh"
11 #include "rec-taskqueue.hh"
12 #include "test-syncres_cc.hh"
13 #include "recpacketcache.hh"
15 GlobalStateHolder
<LuaConfigItems
> g_luaconfs
;
16 GlobalStateHolder
<SuffixMatchNode
> g_xdnssec
;
17 GlobalStateHolder
<SuffixMatchNode
> g_dontThrottleNames
;
18 GlobalStateHolder
<NetmaskGroup
> g_dontThrottleNetmasks
;
19 GlobalStateHolder
<SuffixMatchNode
> g_DoTToAuthNames
;
20 std::unique_ptr
<MemRecursorCache
> g_recCache
;
21 std::unique_ptr
<NegCache
> g_negCache
;
22 bool g_lowercaseOutgoing
= false;
24 pdns::TaskQueue g_test_tasks
;
25 pdns::TaskQueue g_resolve_tasks
;
27 /* Fake some required functions we didn't want the trouble to
31 static ArgvMap theArg
;
39 void BaseLua4::getFeatures(Features
& /* features */)
43 bool RecursorLua4::preoutquery(const ComboAddress
& /* ns */, const ComboAddress
& /* requestor */, const DNSName
& /* query */, const QType
& /* qtype */, bool /* isTcp */, vector
<DNSRecord
>& /* res */, int& /* ret */, RecEventTrace
& /* et */, const struct timeval
& /* tv */) const
48 bool RecursorLua4::policyHitEventFilter(const ComboAddress
& /* remote */, const DNSName
& /* qname */, const QType
& /* qtype */, bool /* tcp */, DNSFilterEngine::Policy
& /* policy */, std::unordered_set
<std::string
>& /* tags */, std::unordered_map
<std::string
, bool>& /* discardedPolicies */) const
53 RecursorLua4::~RecursorLua4()
57 void RecursorLua4::postPrepareContext()
61 void RecursorLua4::postLoad()
65 void RecursorLua4::getFeatures(Features
& /* features */)
69 LWResult::Result
asyncresolve(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 */, const std::shared_ptr
<std::vector
<std::unique_ptr
<RemoteLogger
>>>& /* outgoingLoggers */, const std::shared_ptr
<std::vector
<std::unique_ptr
<FrameStreamLogger
>>>& /* fstrmLoggers */, const std::set
<uint16_t>& /* exportTypes */, LWResult
* /* res */, bool* /* chained */)
71 return LWResult::Result::Timeout
;
74 /* primeHints() is only here for now because it
75 was way too much trouble to link with the real one.
76 We should fix this, empty functions are one thing, but this is
80 #include "root-addresses.hh"
82 bool primeHints(time_t now
)
84 vector
<DNSRecord
> nsset
;
86 g_recCache
= std::make_unique
<MemRecursorCache
>();
88 g_negCache
= std::make_unique
<NegCache
>();
90 DNSRecord arr
, aaaarr
, nsrr
;
91 nsrr
.d_name
= g_rootdnsname
;
92 arr
.d_type
= QType::A
;
93 aaaarr
.d_type
= QType::AAAA
;
94 nsrr
.d_type
= QType::NS
;
95 arr
.d_ttl
= aaaarr
.d_ttl
= nsrr
.d_ttl
= now
+ 3600000;
97 for (char c
= 'a'; c
<= 'm'; ++c
) {
99 strncpy(templ
, "a.root-servers.net.", sizeof(templ
) - 1);
100 templ
[sizeof(templ
) - 1] = '\0';
102 aaaarr
.d_name
= arr
.d_name
= DNSName(templ
);
103 nsrr
.setContent(std::make_shared
<NSRecordContent
>(DNSName(templ
)));
104 arr
.setContent(std::make_shared
<ARecordContent
>(ComboAddress(rootIps4
[c
- 'a'])));
105 vector
<DNSRecord
> aset
;
107 g_recCache
->replace(now
, DNSName(templ
), QType(QType::A
), aset
, vector
<std::shared_ptr
<const RRSIGRecordContent
>>(), vector
<std::shared_ptr
<DNSRecord
>>(), false, g_rootdnsname
);
108 if (!rootIps6
[c
- 'a'].empty()) {
109 aaaarr
.setContent(std::make_shared
<AAAARecordContent
>(ComboAddress(rootIps6
[c
- 'a'])));
111 vector
<DNSRecord
> aaaaset
;
112 aaaaset
.push_back(aaaarr
);
113 g_recCache
->replace(now
, DNSName(templ
), QType(QType::AAAA
), aaaaset
, vector
<std::shared_ptr
<const RRSIGRecordContent
>>(), vector
<std::shared_ptr
<DNSRecord
>>(), false, g_rootdnsname
);
116 nsset
.push_back(nsrr
);
118 g_recCache
->replace(now
, g_rootdnsname
, QType(QType::NS
), nsset
, vector
<std::shared_ptr
<const RRSIGRecordContent
>>(), vector
<std::shared_ptr
<DNSRecord
>>(), false, g_rootdnsname
); // and stuff in the cache
122 LuaConfigItems::LuaConfigItems()
124 for (const auto& dsRecord
: rootDSs
) {
125 auto ds
= std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(dsRecord
));
126 dsAnchors
[g_rootdnsname
].insert(*ds
);
130 /* Some helpers functions */
132 void initSR(bool debug
)
134 g_log
.setName("test");
135 g_log
.disableSyslog(true);
138 g_log
.setLoglevel((Logger::Urgency
)(6)); // info and up
139 g_log
.toConsole(Logger::Info
);
142 g_log
.setLoglevel(Logger::None
);
143 g_log
.toConsole(Logger::Error
);
146 RecursorPacketCache::s_refresh_ttlperc
= 0;
147 MemRecursorCache::s_maxServedStaleExtensions
= 0;
148 NegCache::s_maxServedStaleExtensions
= 0;
149 g_recCache
= std::make_unique
<MemRecursorCache
>();
150 g_negCache
= std::make_unique
<NegCache
>();
152 SyncRes::s_maxqperq
= 50;
153 SyncRes::s_maxnsaddressqperq
= 10;
154 SyncRes::s_maxtotusec
= 1000 * 7000;
155 SyncRes::s_maxdepth
= 40;
156 SyncRes::s_maxnegttl
= 3600;
157 SyncRes::s_maxbogusttl
= 3600;
158 SyncRes::s_maxcachettl
= 86400;
159 SyncRes::s_packetcachettl
= 3600;
160 SyncRes::s_packetcacheservfailttl
= 60;
161 SyncRes::s_serverdownmaxfails
= 64;
162 SyncRes::s_serverdownthrottletime
= 60;
163 SyncRes::s_doIPv4
= true;
164 SyncRes::s_doIPv6
= true;
165 SyncRes::s_ecsipv4limit
= 24;
166 SyncRes::s_ecsipv6limit
= 56;
167 SyncRes::s_ecsipv4cachelimit
= 24;
168 SyncRes::s_ecsipv6cachelimit
= 56;
169 SyncRes::s_ecscachelimitttl
= 0;
170 SyncRes::s_rootNXTrust
= true;
171 SyncRes::s_hardenNXD
= SyncRes::HardenNXD::DNSSEC
;
172 SyncRes::s_minimumTTL
= 0;
173 SyncRes::s_minimumECSTTL
= 0;
174 SyncRes::s_serverID
= "PowerDNS Unit Tests Server ID";
175 SyncRes::clearEDNSLocalSubnets();
176 SyncRes::addEDNSLocalSubnet("0.0.0.0/0");
177 SyncRes::addEDNSLocalSubnet("::/0");
178 SyncRes::clearEDNSRemoteSubnets();
179 SyncRes::clearEDNSDomains();
180 SyncRes::clearDontQuery();
181 SyncRes::setECSScopeZeroAddress(Netmask("127.0.0.1/32"));
182 SyncRes::s_qnameminimization
= false;
183 SyncRes::s_nonresolvingnsmaxfails
= 0;
184 SyncRes::s_nonresolvingnsthrottletime
= 0;
185 SyncRes::s_refresh_ttlperc
= 0;
186 SyncRes::s_save_parent_ns_set
= true;
187 SyncRes::s_maxnsperresolve
= 13;
188 SyncRes::s_locked_ttlperc
= 0;
189 SyncRes::s_minimize_one_label
= 4;
190 SyncRes::s_max_minimize_count
= 10;
192 SyncRes::clearNSSpeeds();
193 BOOST_CHECK_EQUAL(SyncRes::getNSSpeedsSize(), 0U);
194 SyncRes::clearEDNSStatuses();
195 BOOST_CHECK_EQUAL(SyncRes::getEDNSStatusesSize(), 0U);
196 SyncRes::clearThrottle();
197 BOOST_CHECK_EQUAL(SyncRes::getThrottledServersSize(), 0U);
198 SyncRes::clearFailedServers();
199 BOOST_CHECK_EQUAL(SyncRes::getFailedServersSize(), 0U);
200 SyncRes::clearNonResolvingNS();
201 BOOST_CHECK_EQUAL(SyncRes::getNonResolvingNSSize(), 0U);
202 SyncRes::clearSaveParentsNSSets();
203 BOOST_CHECK_EQUAL(SyncRes::getSaveParentsNSSetsSize(), 0U);
205 SyncRes::clearECSStats();
207 auto luaconfsCopy
= g_luaconfs
.getCopy();
208 luaconfsCopy
.dfe
.clear();
209 luaconfsCopy
.dsAnchors
.clear();
210 for (const auto& dsRecord
: rootDSs
) {
211 auto ds
= std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(dsRecord
));
212 luaconfsCopy
.dsAnchors
[g_rootdnsname
].insert(*ds
);
214 luaconfsCopy
.negAnchors
.clear();
215 g_luaconfs
.setState(luaconfsCopy
);
217 g_dnssecmode
= DNSSECMode::Off
;
218 g_maxNSEC3Iterations
= 2500;
220 g_aggressiveNSECCache
.reset();
221 AggressiveNSECCache::s_maxNSEC3CommonPrefix
= AggressiveNSECCache::s_default_maxNSEC3CommonPrefix
;
225 ::arg().set("version-string", "string reported on version.pdns or version.bind") = "PowerDNS Unit Tests";
226 ::arg().set("rng") = "auto";
227 ::arg().set("entropy-source") = "/dev/urandom";
228 ::arg().set("hint-file") = "";
231 void initSR(std::unique_ptr
<SyncRes
>& sr
, bool dnssec
, bool debug
, time_t fakeNow
)
235 now
.tv_sec
= fakeNow
;
239 Utility::gettimeofday(&now
, 0);
244 sr
= std::make_unique
<SyncRes
>(now
);
245 sr
->setDoEDNS0(true);
247 sr
->setDoDNSSEC(dnssec
);
250 sr
->setLogMode(debug
== false ? SyncRes::LogNone
: SyncRes::Log
);
252 SyncRes::setDomainMap(std::make_shared
<SyncRes::domainmap_t
>());
256 void setDNSSECValidation(std::unique_ptr
<SyncRes
>& sr
, const DNSSECMode
& mode
)
258 sr
->setDNSSECValidationRequested(true);
262 void setLWResult(LWResult
* res
, int rcode
, bool aa
, bool tc
, bool edns
, bool validpacket
)
264 res
->d_rcode
= rcode
;
267 res
->d_haveEDNS
= edns
;
268 res
->d_validpacket
= validpacket
;
271 void addRecordToLW(LWResult
* res
, const DNSName
& name
, uint16_t type
, const std::string
& content
, DNSResourceRecord::Place place
, uint32_t ttl
)
273 addRecordToList(res
->d_records
, name
, type
, content
, place
, ttl
);
276 void addRecordToLW(LWResult
* res
, const std::string
& name
, uint16_t type
, const std::string
& content
, DNSResourceRecord::Place place
, uint32_t ttl
)
278 addRecordToLW(res
, DNSName(name
), type
, content
, place
, ttl
);
281 bool isRootServer(const ComboAddress
& ip
)
284 for (size_t idx
= 0; idx
< rootIps4
.size(); idx
++) {
285 if (ip
.toString() == rootIps4
[idx
]) {
291 for (size_t idx
= 0; idx
< rootIps6
.size(); idx
++) {
292 if (ip
.toString() == rootIps6
[idx
]) {
301 void computeRRSIG(const DNSSECPrivateKey
& dpk
, const DNSName
& signer
, const DNSName
& signQName
, uint16_t signQType
, uint32_t signTTL
, uint32_t sigValidity
, RRSIGRecordContent
& rrc
, const sortedRecords_t
& toSign
, boost::optional
<uint8_t> algo
, boost::optional
<uint32_t> inception
, boost::optional
<time_t> now
)
306 DNSKEYRecordContent drc
= dpk
.getDNSKEY();
307 const auto& rc
= dpk
.getKey();
309 rrc
.d_type
= signQType
;
310 rrc
.d_labels
= signQName
.countLabels() - (signQName
.isWildcard() ? 1 : 0);
311 rrc
.d_originalttl
= signTTL
;
312 rrc
.d_siginception
= inception
? *inception
: (*now
- 10);
313 rrc
.d_sigexpire
= *now
+ sigValidity
;
314 rrc
.d_signer
= signer
;
315 rrc
.d_tag
= drc
.getTag();
316 rrc
.d_algorithm
= algo
? *algo
: drc
.d_algorithm
;
318 std::string msg
= getMessageForRRSET(signQName
, rrc
, toSign
);
320 rrc
.d_signature
= rc
->sign(msg
);
323 typedef std::unordered_map
<DNSName
, std::pair
<DNSSECPrivateKey
, DSRecordContent
>> testkeysset_t
;
325 bool addRRSIG(const testkeysset_t
& keys
, std::vector
<DNSRecord
>& records
, const DNSName
& signer
, uint32_t sigValidity
, bool broken
, boost::optional
<uint8_t> algo
, boost::optional
<DNSName
> wildcard
, boost::optional
<time_t> now
)
327 if (records
.empty()) {
331 const auto it
= keys
.find(signer
);
332 if (it
== keys
.cend()) {
333 throw std::runtime_error("No DNSKEY found for " + signer
.toLogString() + ", unable to compute the requested RRSIG");
336 size_t recordsCount
= records
.size();
337 const DNSName
& name
= records
[recordsCount
- 1].d_name
;
338 const uint16_t type
= records
[recordsCount
- 1].d_type
;
340 sortedRecords_t recordcontents
;
341 for (const auto& record
: records
) {
342 if (record
.d_name
== name
&& record
.d_type
== type
) {
343 recordcontents
.insert(record
.getContent());
347 RRSIGRecordContent rrc
;
348 computeRRSIG(it
->second
.first
, signer
, wildcard
? *wildcard
: records
[recordsCount
- 1].d_name
, records
[recordsCount
- 1].d_type
, records
[recordsCount
- 1].d_ttl
, sigValidity
, rrc
, recordcontents
, algo
, boost::none
, now
);
350 rrc
.d_signature
[0] ^= 42;
354 rec
.d_type
= QType::RRSIG
;
355 rec
.d_place
= records
[recordsCount
- 1].d_place
;
356 rec
.d_name
= records
[recordsCount
- 1].d_name
;
357 rec
.d_ttl
= records
[recordsCount
- 1].d_ttl
;
359 rec
.setContent(std::make_shared
<RRSIGRecordContent
>(rrc
));
360 records
.push_back(rec
);
365 void addDNSKEY(const testkeysset_t
& keys
, const DNSName
& signer
, uint32_t ttl
, std::vector
<DNSRecord
>& records
)
367 const auto it
= keys
.find(signer
);
368 if (it
== keys
.cend()) {
369 throw std::runtime_error("No DNSKEY found for " + signer
.toLogString());
373 rec
.d_place
= DNSResourceRecord::ANSWER
;
375 rec
.d_type
= QType::DNSKEY
;
378 rec
.setContent(std::make_shared
<DNSKEYRecordContent
>(it
->second
.first
.getDNSKEY()));
379 records
.push_back(rec
);
382 bool addDS(const DNSName
& domain
, uint32_t ttl
, std::vector
<DNSRecord
>& records
, const testkeysset_t
& keys
, DNSResourceRecord::Place place
)
384 const auto it
= keys
.find(domain
);
385 if (it
== keys
.cend()) {
391 rec
.d_type
= QType::DS
;
394 rec
.setContent(std::make_shared
<DSRecordContent
>(it
->second
.second
));
396 records
.push_back(rec
);
400 void addNSECRecordToLW(const DNSName
& domain
, const DNSName
& next
, const std::set
<uint16_t>& types
, uint32_t ttl
, std::vector
<DNSRecord
>& records
)
402 NSECRecordContent nrc
;
404 for (const auto& type
: types
) {
411 rec
.d_type
= QType::NSEC
;
412 rec
.setContent(std::make_shared
<NSECRecordContent
>(std::move(nrc
)));
413 rec
.d_place
= DNSResourceRecord::AUTHORITY
;
415 records
.push_back(rec
);
418 void addNSEC3RecordToLW(const DNSName
& hashedName
, const std::string
& hashedNext
, const std::string
& salt
, unsigned int iterations
, const std::set
<uint16_t>& types
, uint32_t ttl
, std::vector
<DNSRecord
>& records
, bool optOut
)
420 NSEC3RecordContent nrc
;
422 nrc
.d_flags
= optOut
? 1 : 0;
423 nrc
.d_iterations
= iterations
;
425 nrc
.d_nexthash
= hashedNext
;
426 for (const auto& type
: types
) {
431 rec
.d_name
= hashedName
;
433 rec
.d_type
= QType::NSEC3
;
434 rec
.setContent(std::make_shared
<NSEC3RecordContent
>(std::move(nrc
)));
435 rec
.d_place
= DNSResourceRecord::AUTHORITY
;
437 records
.push_back(rec
);
440 void addNSEC3UnhashedRecordToLW(const DNSName
& domain
, const DNSName
& zone
, const std::string
& next
, const std::set
<uint16_t>& types
, uint32_t ttl
, std::vector
<DNSRecord
>& records
, unsigned int iterations
, bool optOut
)
442 static const std::string salt
= "deadbeef";
443 std::string hashed
= hashQNameWithSalt(salt
, iterations
, domain
);
445 addNSEC3RecordToLW(DNSName(toBase32Hex(hashed
)) + zone
, next
, salt
, iterations
, types
, ttl
, records
, optOut
);
448 /* Proves a NODATA (name exists, type does not) but the next owner name is right behind, so it should not prove anything else unless we are very unlucky */
449 void addNSEC3NoDataNarrowRecordToLW(const DNSName
& domain
, const DNSName
& zone
, const std::set
<uint16_t>& types
, uint32_t ttl
, std::vector
<DNSRecord
>& records
, unsigned int iterations
, bool optOut
)
451 static const std::string salt
= "deadbeef";
452 std::string hashed
= hashQNameWithSalt(salt
, iterations
, domain
);
453 std::string
hashedNext(hashed
);
454 incrementHash(hashedNext
);
456 addNSEC3RecordToLW(DNSName(toBase32Hex(hashed
)) + zone
, hashedNext
, salt
, iterations
, types
, ttl
, records
, optOut
);
459 void addNSEC3NarrowRecordToLW(const DNSName
& domain
, const DNSName
& zone
, const std::set
<uint16_t>& types
, uint32_t ttl
, std::vector
<DNSRecord
>& records
, unsigned int iterations
, bool optOut
)
461 static const std::string salt
= "deadbeef";
462 std::string hashed
= hashQNameWithSalt(salt
, iterations
, domain
);
463 std::string
hashedNext(hashed
);
464 incrementHash(hashedNext
);
465 decrementHash(hashed
);
467 addNSEC3RecordToLW(DNSName(toBase32Hex(hashed
)) + zone
, hashedNext
, salt
, iterations
, types
, ttl
, records
, optOut
);
470 void generateKeyMaterial(const DNSName
& name
, unsigned int algo
, uint8_t digest
, testkeysset_t
& keys
)
472 auto dcke
= std::shared_ptr
<DNSCryptoKeyEngine
>(DNSCryptoKeyEngine::make(algo
));
473 dcke
->create((algo
<= 10) ? 2048 : dcke
->getBits());
474 DNSSECPrivateKey dpk
;
475 dpk
.setKey(dcke
, 256);
476 DSRecordContent ds
= makeDSFromDNSKey(name
, dpk
.getDNSKEY(), digest
);
477 keys
[name
] = std::pair
<DNSSECPrivateKey
, DSRecordContent
>(dpk
, ds
);
480 void generateKeyMaterial(const DNSName
& name
, unsigned int algo
, uint8_t digest
, testkeysset_t
& keys
, map
<DNSName
, dsmap_t
>& dsAnchors
)
482 generateKeyMaterial(name
, algo
, digest
, keys
);
483 dsAnchors
[name
].insert(keys
[name
].second
);
486 LWResult::Result
genericDSAndDNSKEYHandler(LWResult
* res
, const DNSName
& domain
, DNSName auth
, int type
, const testkeysset_t
& keys
, bool proveCut
, boost::optional
<time_t> now
, bool nsec3
, bool optOut
)
488 if (type
== QType::DS
) {
491 setLWResult(res
, 0, true, false, true);
493 if (addDS(domain
, 300, res
->d_records
, keys
, DNSResourceRecord::ANSWER
)) {
494 addRRSIG(keys
, res
->d_records
, auth
, 300, false, boost::none
, boost::none
, now
);
497 addRecordToLW(res
, auth
, QType::SOA
, "foo. bar. 2017032800 1800 900 604800 86400", DNSResourceRecord::AUTHORITY
, 86400);
499 /* if the auth zone is signed, we need to provide a secure denial */
500 const auto it
= keys
.find(auth
);
501 if (it
!= keys
.cend()) {
503 addRRSIG(keys
, res
->d_records
, auth
, 300, false, boost::none
, boost::none
, now
);
504 /* add a NSEC denying the DS */
505 std::set
<uint16_t> types
= {QType::RRSIG
};
507 types
.insert(QType::NS
);
511 addNSECRecordToLW(domain
, DNSName("+") + domain
, types
, 600, res
->d_records
);
514 DNSName
next(DNSName("z") + domain
);
515 next
.makeUsRelative(auth
);
516 addNSEC3UnhashedRecordToLW(domain
, auth
, next
.toString(), types
, 600, res
->d_records
, 10, optOut
);
519 addRRSIG(keys
, res
->d_records
, auth
, 300, false, boost::none
, boost::none
, now
);
523 return LWResult::Result::Success
;
526 if (type
== QType::DNSKEY
) {
527 setLWResult(res
, 0, true, false, true);
528 addDNSKEY(keys
, domain
, 300, res
->d_records
);
529 addRRSIG(keys
, res
->d_records
, domain
, 300, false, boost::none
, boost::none
, now
);
530 return LWResult::Result::Success
;
533 return LWResult::Result::Timeout
;
536 LWResult::Result
basicRecordsForQnameMinimization(LWResult
* res
, const DNSName
& domain
, int type
)
538 if (domain
== DNSName(".") && type
== QType::A
) {
539 setLWResult(res
, 0, true);
540 addRecordToLW(res
, DNSName("."), QType::SOA
, "a.root-servers.net. nstld.verisign-grs.com. 2019042400 1800 900 604800 86400", DNSResourceRecord::AUTHORITY
);
541 return LWResult::Result::Success
;
543 if (domain
== DNSName("com") && type
== QType::A
) {
544 setLWResult(res
, 0, true);
545 addRecordToLW(res
, DNSName("com"), QType::NS
, "ns1.com", DNSResourceRecord::AUTHORITY
);
546 addRecordToLW(res
, DNSName("ns1.com"), QType::A
, "1.2.3.4", DNSResourceRecord::ADDITIONAL
);
547 return LWResult::Result::Success
;
549 if (domain
== DNSName("ns1.com") && type
== QType::A
) {
550 setLWResult(res
, 0, true);
551 addRecordToLW(res
, DNSName("ns1.com"), QType::A
, "1.2.3.4");
552 return LWResult::Result::Success
;
554 if (domain
== DNSName("powerdns.com") && type
== QType::A
) {
555 setLWResult(res
, 0, true);
556 addRecordToLW(res
, domain
, QType::NS
, "ns1.powerdns.com", DNSResourceRecord::AUTHORITY
);
557 addRecordToLW(res
, DNSName("ns1.powerdns.com"), QType::A
, "4.5.6.7", DNSResourceRecord::ADDITIONAL
);
558 return LWResult::Result::Success
;
560 if (domain
== DNSName("powerdns.com") && type
== QType::NS
) {
561 setLWResult(res
, 0, true);
562 addRecordToLW(res
, domain
, QType::NS
, "ns1.powerdns.com");
563 addRecordToLW(res
, DNSName("ns1.powerdns.com"), QType::A
, "4.5.6.7", DNSResourceRecord::ADDITIONAL
);
564 return LWResult::Result::Success
;
566 return LWResult::Result::Timeout
;