]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/recursordist/test-syncres_cc.cc
Merge pull request #8650 from spheron1/master
[thirdparty/pdns.git] / pdns / recursordist / test-syncres_cc.cc
CommitLineData
30ee601a 1#define BOOST_TEST_DYN_LINK
30ee601a
RG
2#include <boost/test/unit_test.hpp>
3
95823c07 4#include "base32.hh"
30ee601a 5#include "lua-recursor4.hh"
30ee601a 6#include "root-dnssec.hh"
86675669 7#include "test-syncres_cc.hh"
30ee601a 8
30ee601a
RG
9RecursorStats g_stats;
10GlobalStateHolder<LuaConfigItems> g_luaconfs;
559b6c93
PL
11GlobalStateHolder<SuffixMatchNode> g_dontThrottleNames;
12GlobalStateHolder<NetmaskGroup> g_dontThrottleNetmasks;
f26bf547 13thread_local std::unique_ptr<MemRecursorCache> t_RC{nullptr};
30ee601a 14unsigned int g_numThreads = 1;
c1c29961 15bool g_lowercaseOutgoing = false;
30ee601a
RG
16
17/* Fake some required functions we didn't want the trouble to
18 link with */
42dcf516 19ArgvMap& arg()
30ee601a
RG
20{
21 static ArgvMap theArg;
22 return theArg;
23}
24
25int getMTaskerTID()
26{
27 return 0;
28}
29
159b1242
OM
30void primeRootNSZones(bool)
31{
32}
33
5899ee54 34bool RecursorLua4::preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret) const
30ee601a
RG
35{
36 return false;
37}
38
42dcf516 39int 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)
30ee601a
RG
40{
41 return 0;
42}
43
44/* primeHints() is only here for now because it
45 was way too much trouble to link with the real one.
46 We should fix this, empty functions are one thing, but this is
47 bad.
48*/
49
50#include "root-addresses.hh"
51
52void primeHints(void)
53{
54 vector<DNSRecord> nsset;
42dcf516 55 if (!t_RC)
f26bf547 56 t_RC = std::unique_ptr<MemRecursorCache>(new MemRecursorCache());
30ee601a
RG
57
58 DNSRecord arr, aaaarr, nsrr;
42dcf516
OM
59 nsrr.d_name = g_rootdnsname;
60 arr.d_type = QType::A;
61 aaaarr.d_type = QType::AAAA;
62 nsrr.d_type = QType::NS;
63 arr.d_ttl = aaaarr.d_ttl = nsrr.d_ttl = time(nullptr) + 3600000;
30ee601a 64
42dcf516 65 for (char c = 'a'; c <= 'm'; ++c) {
e4f772ce 66 char templ[40];
42dcf516
OM
67 strncpy(templ, "a.root-servers.net.", sizeof(templ) - 1);
68 templ[sizeof(templ) - 1] = '\0';
69 *templ = c;
70 aaaarr.d_name = arr.d_name = DNSName(templ);
71 nsrr.d_content = std::make_shared<NSRecordContent>(DNSName(templ));
72 arr.d_content = std::make_shared<ARecordContent>(ComboAddress(rootIps4[c - 'a']));
30ee601a
RG
73 vector<DNSRecord> aset;
74 aset.push_back(arr);
606accb0 75 t_RC->replace(time(nullptr), DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true); // auth, nuke it all
42dcf516
OM
76 if (rootIps6[c - 'a'] != NULL) {
77 aaaarr.d_content = std::make_shared<AAAARecordContent>(ComboAddress(rootIps6[c - 'a']));
30ee601a
RG
78
79 vector<DNSRecord> aaaaset;
80 aaaaset.push_back(aaaarr);
606accb0 81 t_RC->replace(time(nullptr), DNSName(templ), QType(QType::AAAA), aaaaset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true);
30ee601a
RG
82 }
83
84 nsset.push_back(nsrr);
85 }
606accb0 86 t_RC->replace(time(nullptr), g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false); // and stuff in the cache
30ee601a
RG
87}
88
89LuaConfigItems::LuaConfigItems()
90{
42dcf516
OM
91 for (const auto& dsRecord : rootDSs) {
92 auto ds = std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(dsRecord));
30ee601a
RG
93 dsAnchors[g_rootdnsname].insert(*ds);
94 }
95}
96
97/* Some helpers functions */
98
86675669 99void initSR(bool debug)
30ee601a 100{
e6a9dde5
PL
101 g_log.setName("test");
102 g_log.disableSyslog(true);
b4c8789a 103
30ee601a 104 if (debug) {
e6a9dde5
PL
105 g_log.setLoglevel((Logger::Urgency)(6)); // info and up
106 g_log.toConsole(Logger::Info);
30ee601a 107 }
b4c8789a 108 else {
e6a9dde5
PL
109 g_log.setLoglevel(Logger::None);
110 g_log.toConsole(Logger::Error);
b4c8789a 111 }
30ee601a 112
f26bf547 113 t_RC = std::unique_ptr<MemRecursorCache>(new MemRecursorCache());
30ee601a 114
30ee601a 115 SyncRes::s_maxqperq = 50;
42dcf516 116 SyncRes::s_maxtotusec = 1000 * 7000;
30ee601a
RG
117 SyncRes::s_maxdepth = 40;
118 SyncRes::s_maxnegttl = 3600;
b9473937 119 SyncRes::s_maxbogusttl = 3600;
30ee601a
RG
120 SyncRes::s_maxcachettl = 86400;
121 SyncRes::s_packetcachettl = 3600;
122 SyncRes::s_packetcacheservfailttl = 60;
123 SyncRes::s_serverdownmaxfails = 64;
124 SyncRes::s_serverdownthrottletime = 60;
125 SyncRes::s_doIPv6 = true;
e9f9b8ec
RG
126 SyncRes::s_ecsipv4limit = 24;
127 SyncRes::s_ecsipv6limit = 56;
bdceeb7e
RG
128 SyncRes::s_ecsipv4cachelimit = 24;
129 SyncRes::s_ecsipv6cachelimit = 56;
2cbe6a45 130 SyncRes::s_ecscachelimitttl = 0;
f58c8379 131 SyncRes::s_rootNXTrust = true;
d40a915b 132 SyncRes::s_hardenNXD = SyncRes::HardenNXD::DNSSEC;
d6e797b8 133 SyncRes::s_minimumTTL = 0;
5cf4b2e7 134 SyncRes::s_minimumECSTTL = 0;
648bcbd1 135 SyncRes::s_serverID = "PowerDNS Unit Tests Server ID";
2fe3354d
CH
136 SyncRes::clearEDNSLocalSubnets();
137 SyncRes::addEDNSLocalSubnet("0.0.0.0/0");
138 SyncRes::addEDNSLocalSubnet("::/0");
139 SyncRes::clearEDNSRemoteSubnets();
9065eb05
RG
140 SyncRes::clearEDNSDomains();
141 SyncRes::clearDelegationOnly();
142 SyncRes::clearDontQuery();
2fe3354d 143 SyncRes::setECSScopeZeroAddress(Netmask("127.0.0.1/32"));
648bcbd1 144
a712cb56 145 SyncRes::clearNSSpeeds();
690b86b7 146 BOOST_CHECK_EQUAL(SyncRes::getNSSpeedsSize(), 0U);
a712cb56 147 SyncRes::clearEDNSStatuses();
690b86b7 148 BOOST_CHECK_EQUAL(SyncRes::getEDNSStatusesSize(), 0U);
a712cb56 149 SyncRes::clearThrottle();
690b86b7 150 BOOST_CHECK_EQUAL(SyncRes::getThrottledServersSize(), 0U);
a712cb56 151 SyncRes::clearFailedServers();
690b86b7 152 BOOST_CHECK_EQUAL(SyncRes::getFailedServersSize(), 0U);
a712cb56 153
c9783016
RG
154 SyncRes::clearECSStats();
155
648bcbd1
RG
156 auto luaconfsCopy = g_luaconfs.getCopy();
157 luaconfsCopy.dfe.clear();
8455425c 158 luaconfsCopy.dsAnchors.clear();
42dcf516
OM
159 for (const auto& dsRecord : rootDSs) {
160 auto ds = std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(dsRecord));
8455425c
RG
161 luaconfsCopy.dsAnchors[g_rootdnsname].insert(*ds);
162 }
163 luaconfsCopy.negAnchors.clear();
648bcbd1
RG
164 g_luaconfs.setState(luaconfsCopy);
165
8455425c 166 g_dnssecmode = DNSSECMode::Off;
895449a5 167 g_dnssecLOG = debug;
b7c40613 168 g_maxNSEC3Iterations = 2500;
8455425c 169
42dcf516
OM
170 ::arg().set("version-string", "string reported on version.pdns or version.bind") = "PowerDNS Unit Tests";
171 ::arg().set("rng") = "auto";
172 ::arg().set("entropy-source") = "/dev/urandom";
8949a3e0 173 ::arg().setSwitch("qname-minimization", "Use Query Name Minimization") = "yes";
30ee601a
RG
174}
175
86675669 176void initSR(std::unique_ptr<SyncRes>& sr, bool dnssec, bool debug, time_t fakeNow)
30ee601a
RG
177{
178 struct timeval now;
d6e797b8
RG
179 if (fakeNow > 0) {
180 now.tv_sec = fakeNow;
181 now.tv_usec = 0;
182 }
183 else {
184 Utility::gettimeofday(&now, 0);
185 }
186
86675669 187 initSR(debug);
895449a5 188
30ee601a 189 sr = std::unique_ptr<SyncRes>(new SyncRes(now));
895449a5 190 sr->setDoEDNS0(true);
0c43f455
RG
191 if (dnssec) {
192 sr->setDoDNSSEC(dnssec);
193 }
194
895449a5
RG
195 sr->setLogMode(debug == false ? SyncRes::LogNone : SyncRes::Log);
196
a712cb56
RG
197 SyncRes::setDomainMap(std::make_shared<SyncRes::domainmap_t>());
198 SyncRes::clearNegCache();
30ee601a
RG
199}
200
86675669 201void setDNSSECValidation(std::unique_ptr<SyncRes>& sr, const DNSSECMode& mode)
0c43f455
RG
202{
203 sr->setDNSSECValidationRequested(true);
204 g_dnssecmode = mode;
205}
206
86675669 207void setLWResult(LWResult* res, int rcode, bool aa, bool tc, bool edns, bool validpacket)
30ee601a
RG
208{
209 res->d_rcode = rcode;
210 res->d_aabit = aa;
211 res->d_tcbit = tc;
212 res->d_haveEDNS = edns;
269ac73d 213 res->d_validpacket = validpacket;
30ee601a
RG
214}
215
86675669 216void addRecordToLW(LWResult* res, const DNSName& name, uint16_t type, const std::string& content, DNSResourceRecord::Place place, uint32_t ttl)
d6e797b8
RG
217{
218 addRecordToList(res->d_records, name, type, content, place, ttl);
30ee601a
RG
219}
220
86675669 221void addRecordToLW(LWResult* res, const std::string& name, uint16_t type, const std::string& content, DNSResourceRecord::Place place, uint32_t ttl)
30ee601a
RG
222{
223 addRecordToLW(res, DNSName(name), type, content, place, ttl);
224}
225
86675669 226bool isRootServer(const ComboAddress& ip)
30ee601a 227{
8455425c
RG
228 if (ip.isIPv4()) {
229 for (size_t idx = 0; idx < rootIps4Count; idx++) {
230 if (ip.toString() == rootIps4[idx]) {
231 return true;
232 }
30ee601a
RG
233 }
234 }
8455425c
RG
235 else {
236 for (size_t idx = 0; idx < rootIps6Count; idx++) {
237 if (ip.toString() == rootIps6[idx]) {
238 return true;
239 }
30ee601a
RG
240 }
241 }
8455425c 242
30ee601a
RG
243 return false;
244}
245
c1e7b833 246void 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)
8455425c 247{
1e2e06f1
RG
248 if (!now) {
249 now = time(nullptr);
250 }
8455425c
RG
251 DNSKEYRecordContent drc = dpk.getDNSKEY();
252 const std::shared_ptr<DNSCryptoKeyEngine> rc = dpk.getKey();
253
254 rrc.d_type = signQType;
255 rrc.d_labels = signQName.countLabels() - signQName.isWildcard();
256 rrc.d_originalttl = signTTL;
1e2e06f1
RG
257 rrc.d_siginception = inception ? *inception : (*now - 10);
258 rrc.d_sigexpire = *now + sigValidity;
8455425c
RG
259 rrc.d_signer = signer;
260 rrc.d_tag = 0;
261 rrc.d_tag = drc.getTag();
3d5ebf10 262 rrc.d_algorithm = algo ? *algo : drc.d_algorithm;
8455425c
RG
263
264 std::string msg = getMessageForRRSET(signQName, rrc, toSign);
265
266 rrc.d_signature = rc->sign(msg);
267}
268
42dcf516 269typedef std::unordered_map<DNSName, std::pair<DNSSECPrivateKey, DSRecordContent>> testkeysset_t;
b7f378d1 270
86675669 271bool 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)
8455425c
RG
272{
273 if (records.empty()) {
5374b03b 274 return false;
8455425c
RG
275 }
276
277 const auto it = keys.find(signer);
278 if (it == keys.cend()) {
86f1af1c 279 throw std::runtime_error("No DNSKEY found for " + signer.toLogString() + ", unable to compute the requested RRSIG");
8455425c
RG
280 }
281
282 size_t recordsCount = records.size();
42dcf516
OM
283 const DNSName& name = records[recordsCount - 1].d_name;
284 const uint16_t type = records[recordsCount - 1].d_type;
8455425c 285
c1e7b833 286 sortedRecords_t recordcontents;
8455425c
RG
287 for (const auto record : records) {
288 if (record.d_name == name && record.d_type == type) {
c1e7b833 289 recordcontents.insert(record.d_content);
8455425c
RG
290 }
291 }
292
293 RRSIGRecordContent rrc;
42dcf516 294 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);
3d5ebf10
RG
295 if (broken) {
296 rrc.d_signature[0] ^= 42;
297 }
8455425c
RG
298
299 DNSRecord rec;
dbbef467 300 rec.d_type = QType::RRSIG;
42dcf516
OM
301 rec.d_place = records[recordsCount - 1].d_place;
302 rec.d_name = records[recordsCount - 1].d_name;
303 rec.d_ttl = records[recordsCount - 1].d_ttl;
8455425c
RG
304
305 rec.d_content = std::make_shared<RRSIGRecordContent>(rrc);
306 records.push_back(rec);
5374b03b
RG
307
308 return true;
8455425c
RG
309}
310
86675669 311void addDNSKEY(const testkeysset_t& keys, const DNSName& signer, uint32_t ttl, std::vector<DNSRecord>& records)
8455425c
RG
312{
313 const auto it = keys.find(signer);
314 if (it == keys.cend()) {
86f1af1c 315 throw std::runtime_error("No DNSKEY found for " + signer.toLogString());
8455425c
RG
316 }
317
318 DNSRecord rec;
319 rec.d_place = DNSResourceRecord::ANSWER;
320 rec.d_name = signer;
321 rec.d_type = QType::DNSKEY;
322 rec.d_ttl = ttl;
323
b7f378d1 324 rec.d_content = std::make_shared<DNSKEYRecordContent>(it->second.first.getDNSKEY());
8455425c
RG
325 records.push_back(rec);
326}
327
86675669 328bool addDS(const DNSName& domain, uint32_t ttl, std::vector<DNSRecord>& records, const testkeysset_t& keys, DNSResourceRecord::Place place)
8455425c 329{
b7f378d1
RG
330 const auto it = keys.find(domain);
331 if (it == keys.cend()) {
5374b03b 332 return false;
8455425c
RG
333 }
334
b7f378d1
RG
335 DNSRecord rec;
336 rec.d_name = domain;
337 rec.d_type = QType::DS;
a53e8fe3 338 rec.d_place = place;
b7f378d1
RG
339 rec.d_ttl = ttl;
340 rec.d_content = std::make_shared<DSRecordContent>(it->second.second);
8455425c 341
b7f378d1 342 records.push_back(rec);
5374b03b 343 return true;
8455425c
RG
344}
345
42dcf516 346void addNSECRecordToLW(const DNSName& domain, const DNSName& next, const std::set<uint16_t>& types, uint32_t ttl, std::vector<DNSRecord>& records)
8455425c
RG
347{
348 NSECRecordContent nrc;
349 nrc.d_next = next;
27d4a65b
RG
350 for (const auto& type : types) {
351 nrc.set(type);
352 }
8455425c
RG
353
354 DNSRecord rec;
355 rec.d_name = domain;
356 rec.d_ttl = ttl;
357 rec.d_type = QType::NSEC;
27d4a65b 358 rec.d_content = std::make_shared<NSECRecordContent>(std::move(nrc));
8455425c
RG
359 rec.d_place = DNSResourceRecord::AUTHORITY;
360
361 records.push_back(rec);
362}
363
42dcf516 364void 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)
95823c07
RG
365{
366 NSEC3RecordContent nrc;
367 nrc.d_algorithm = 1;
368 nrc.d_flags = 0;
369 nrc.d_iterations = iterations;
370 nrc.d_salt = salt;
371 nrc.d_nexthash = hashedNext;
27d4a65b
RG
372 for (const auto& type : types) {
373 nrc.set(type);
374 }
95823c07
RG
375
376 DNSRecord rec;
377 rec.d_name = hashedName;
378 rec.d_ttl = ttl;
379 rec.d_type = QType::NSEC3;
27d4a65b 380 rec.d_content = std::make_shared<NSEC3RecordContent>(std::move(nrc));
95823c07
RG
381 rec.d_place = DNSResourceRecord::AUTHORITY;
382
383 records.push_back(rec);
384}
385
42dcf516 386void 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)
95823c07
RG
387{
388 static const std::string salt = "deadbeef";
95823c07
RG
389 std::string hashed = hashQNameWithSalt(salt, iterations, domain);
390
9b061cf5 391 addNSEC3RecordToLW(DNSName(toBase32Hex(hashed)) + zone, next, salt, iterations, types, ttl, records);
95823c07
RG
392}
393
42dcf516 394void addNSEC3NarrowRecordToLW(const DNSName& domain, const DNSName& zone, const std::set<uint16_t>& types, uint32_t ttl, std::vector<DNSRecord>& records, unsigned int iterations)
95823c07
RG
395{
396 static const std::string salt = "deadbeef";
95823c07 397 std::string hashed = hashQNameWithSalt(salt, iterations, domain);
95823c07
RG
398 std::string hashedNext(hashed);
399 incrementHash(hashedNext);
400 decrementHash(hashed);
401
9b061cf5 402 addNSEC3RecordToLW(DNSName(toBase32Hex(hashed)) + zone, hashedNext, salt, iterations, types, ttl, records);
95823c07
RG
403}
404
86675669 405void generateKeyMaterial(const DNSName& name, unsigned int algo, uint8_t digest, testkeysset_t& keys)
8455425c
RG
406{
407 auto dcke = std::shared_ptr<DNSCryptoKeyEngine>(DNSCryptoKeyEngine::make(algo));
b7f378d1 408 dcke->create((algo <= 10) ? 2048 : dcke->getBits());
8455425c
RG
409 DNSSECPrivateKey dpk;
410 dpk.d_flags = 256;
411 dpk.setKey(dcke);
8455425c 412 DSRecordContent ds = makeDSFromDNSKey(name, dpk.getDNSKEY(), digest);
42dcf516 413 keys[name] = std::pair<DNSSECPrivateKey, DSRecordContent>(dpk, ds);
b7f378d1
RG
414}
415
42dcf516 416void generateKeyMaterial(const DNSName& name, unsigned int algo, uint8_t digest, testkeysset_t& keys, map<DNSName, dsmap_t>& dsAnchors)
b7f378d1
RG
417{
418 generateKeyMaterial(name, algo, digest, keys);
419 dsAnchors[name].insert(keys[name].second);
8455425c
RG
420}
421
7ced0738 422int genericDSAndDNSKEYHandler(LWResult* res, const DNSName& domain, DNSName auth, int type, const testkeysset_t& keys, bool proveCut, boost::optional<time_t> now)
5374b03b
RG
423{
424 if (type == QType::DS) {
425 auth.chopOff();
426
427 setLWResult(res, 0, true, false, true);
428
429 if (addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER)) {
7ced0738 430 addRRSIG(keys, res->d_records, auth, 300, false, boost::none, boost::none, now);
5374b03b
RG
431 }
432 else {
433 addRecordToLW(res, auth, QType::SOA, "foo. bar. 2017032800 1800 900 604800 86400", DNSResourceRecord::AUTHORITY, 86400);
434
435 /* if the auth zone is signed, we need to provide a secure denial */
436 const auto it = keys.find(auth);
437 if (it != keys.cend()) {
438 /* sign the SOA */
7ced0738 439 addRRSIG(keys, res->d_records, auth, 300, false, boost::none, boost::none, now);
5374b03b 440 /* add a NSEC denying the DS */
42dcf516 441 std::set<uint16_t> types = {QType::NSEC};
f4de85a3
RG
442 if (proveCut) {
443 types.insert(QType::NS);
444 }
445
446 addNSECRecordToLW(domain, DNSName("z") + domain, types, 600, res->d_records);
7ced0738 447 addRRSIG(keys, res->d_records, auth, 300, false, boost::none, boost::none, now);
5374b03b
RG
448 }
449 }
450
451 return 1;
452 }
453
454 if (type == QType::DNSKEY) {
455 setLWResult(res, 0, true, false, true);
dbbef467
RG
456 addDNSKEY(keys, domain, 300, res->d_records);
457 addRRSIG(keys, res->d_records, domain, 300);
5374b03b
RG
458 return 1;
459 }
460
461 return 0;
462}
463
42dcf516
OM
464int basicRecordsForQnameMinimization(LWResult* res, const DNSName& domain, int type)
465{
86675669
OM
466 if (domain == DNSName(".") && type == QType::A) {
467 setLWResult(res, 0, true);
468 addRecordToLW(res, DNSName("."), QType::SOA, "a.root-servers.net. nstld.verisign-grs.com. 2019042400 1800 900 604800 86400", DNSResourceRecord::AUTHORITY);
469 return 1;
648bcbd1 470 }
86675669
OM
471 if (domain == DNSName("com") && type == QType::A) {
472 setLWResult(res, 0, true);
473 addRecordToLW(res, DNSName("com"), QType::NS, "ns1.com", DNSResourceRecord::AUTHORITY);
474 addRecordToLW(res, DNSName("ns1.com"), QType::A, "1.2.3.4", DNSResourceRecord::ADDITIONAL);
475 return 1;
c9783016 476 }
86675669
OM
477 if (domain == DNSName("ns1.com") && type == QType::A) {
478 setLWResult(res, 0, true);
479 addRecordToLW(res, DNSName("ns1.com"), QType::A, "1.2.3.4");
480 return 1;
c9783016 481 }
86675669
OM
482 if (domain == DNSName("powerdns.com") && type == QType::A) {
483 setLWResult(res, 0, true);
484 addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com", DNSResourceRecord::AUTHORITY);
485 addRecordToLW(res, DNSName("ns1.powerdns.com"), QType::A, "4.5.6.7", DNSResourceRecord::ADDITIONAL);
486 return 1;
c9783016 487 }
86675669
OM
488 if (domain == DNSName("powerdns.com") && type == QType::NS) {
489 setLWResult(res, 0, true);
490 addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com");
491 addRecordToLW(res, DNSName("ns1.powerdns.com"), QType::A, "4.5.6.7", DNSResourceRecord::ADDITIONAL);
492 return 1;
c9783016 493 }
86675669 494 return 0;
778bcea6 495}