]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/test-dnsname_cc.cc
Merge pull request #6117 from rgacogne/ddist-dns-over-tls
[thirdparty/pdns.git] / pdns / test-dnsname_cc.cc
1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
3 #include <boost/test/unit_test.hpp>
4 #include <boost/assign/std/map.hpp>
5 #include <numeric>
6 #include <math.h>
7 #include "dnsname.hh"
8 #include "misc.hh"
9 #include "dnswriter.hh"
10 #include "dnsrecords.hh"
11 #include <unordered_set>
12 using namespace boost;
13 using std::string;
14
15 BOOST_AUTO_TEST_SUITE(dnsname_cc)
16
17 BOOST_AUTO_TEST_CASE(test_basic) {
18 string before("www.ds9a.nl.");
19 DNSName b(before);
20 BOOST_CHECK_EQUAL(b.getRawLabels().size(), 3);
21 string after(b.toString());
22 BOOST_CHECK_EQUAL(before, after);
23
24 DNSName jpmens("ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.test.xxx.yyy-yyyy.zzzzzzzzz-test.");
25
26 BOOST_CHECK_EQUAL(jpmens.toString(), "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.test.xxx.yyy-yyyy.zzzzzzzzz-test.");
27
28 DNSName wwwds9anl("www.ds9a.nl.");
29 DNSName wwwds9anl1("www.ds9a\002nl.");
30 DNSName nl("nl.");
31 BOOST_CHECK(wwwds9anl.isPartOf(nl));
32 BOOST_CHECK(!wwwds9anl1.isPartOf(nl));
33 BOOST_CHECK(wwwds9anl.isPartOf(wwwds9anl));
34
35 BOOST_CHECK(!nl.isPartOf(wwwds9anl));
36
37 BOOST_CHECK(wwwds9anl == wwwds9anl);
38
39 BOOST_CHECK(DNSName("wWw.ds9A.Nl.") == DNSName("www.ds9a.nl."));
40 BOOST_CHECK(DNSName("www.ds9a.nl.") == DNSName("www.ds9a.nl."));
41
42 BOOST_CHECK(DNSName("www.ds9a.nl.").toString() == "www.ds9a.nl.");
43
44
45 { // Check root vs empty
46 DNSName name("."); // root
47 DNSName parent; // empty
48 BOOST_CHECK(name != parent);
49 }
50
51 { // Check name part of root
52 DNSName name("a.");
53 DNSName parent(".");
54 BOOST_CHECK(name.isPartOf(parent));
55 }
56
57 { // Label boundary
58 DNSName name("a\002bb.");
59 DNSName parent("bb.");
60 BOOST_CHECK(!name.isPartOf(parent));
61 }
62
63 { // Multi label parent
64 DNSName name("a.bb.ccc.dddd.");
65 DNSName parent("ccc.dddd.");
66 BOOST_CHECK(name.isPartOf(parent));
67 }
68
69 { // Last char diff
70 DNSName name("a.bb.ccc.dddd.");
71 DNSName parent("ccc.dddx.");
72 BOOST_CHECK(!name.isPartOf(parent));
73 }
74
75 { // Equal length identical
76 DNSName name("aaaa.bbb.cc.d.");
77 DNSName parent("aaaa.bbb.cc.d.");
78 BOOST_CHECK(name.isPartOf(parent));
79 }
80
81 { // Equal length first char diff
82 DNSName name("xaaa.bbb.cc.d.");
83 DNSName parent("aaaa.bbb.cc.d.");
84 BOOST_CHECK(!name.isPartOf(parent));
85 }
86
87 { // Make relative
88 DNSName name("aaaa.bbb.cc.d.");
89 DNSName parent("cc.d.");
90 BOOST_CHECK_EQUAL( name.makeRelative(parent), DNSName("aaaa.bbb."));
91 }
92
93 { // Labelreverse
94 DNSName name("aaaa.bbb.cc.d.");
95 BOOST_CHECK( name.labelReverse() == DNSName("d.cc.bbb.aaaa."));
96 }
97
98 { // empty() empty
99 DNSName name;
100 BOOST_CHECK(name.empty());
101 }
102
103 { // empty() root
104 DNSName name(".");
105 BOOST_CHECK(!name.empty());
106
107 DNSName rootnodot("");
108 BOOST_CHECK_EQUAL(name, rootnodot);
109
110 string empty;
111 DNSName rootnodot2(empty);
112 BOOST_CHECK_EQUAL(rootnodot2, name);
113 }
114
115 DNSName left("ds9a.nl.");
116 left.prependRawLabel("www");
117 BOOST_CHECK( left == DNSName("WwW.Ds9A.Nl."));
118
119 left.appendRawLabel("com");
120
121 BOOST_CHECK( left == DNSName("WwW.Ds9A.Nl.com."));
122
123 DNSName unset;
124
125 unset.appendRawLabel("www");
126 unset.appendRawLabel("powerdns.com");
127 unset.appendRawLabel("com");
128
129 BOOST_CHECK_EQUAL(unset.toString(), "www.powerdns\\.com.com.");
130
131 DNSName rfc4343_2_1("~!.example.");
132 DNSName rfc4343_2_2(R"(Donald\032E\.\032Eastlake\0323rd.example.)");
133 DNSName example("example.");
134 BOOST_CHECK(rfc4343_2_1.isPartOf(example));
135 BOOST_CHECK(rfc4343_2_2.isPartOf(example));
136 BOOST_CHECK_EQUAL(rfc4343_2_1.toString(), "~!.example.");
137
138 auto labels=rfc4343_2_2.getRawLabels();
139 BOOST_CHECK_EQUAL(*labels.begin(), "Donald E. Eastlake 3rd");
140 BOOST_CHECK_EQUAL(*labels.rbegin(), "example");
141 BOOST_CHECK_EQUAL(labels.size(), 2);
142
143 DNSName build;
144 build.appendRawLabel("Donald E. Eastlake 3rd");
145 build.appendRawLabel("example");
146 BOOST_CHECK_EQUAL(build.toString(), R"(Donald\032E\.\032Eastlake\0323rd.example.)");
147 BOOST_CHECK_THROW(DNSName broken("bert..hubert."), std::runtime_error);
148
149 DNSName n;
150 n.appendRawLabel("powerdns.dnsmaster");
151 n.appendRawLabel("powerdns");
152 n.appendRawLabel("com");
153
154 BOOST_CHECK_EQUAL(n.toString(), "powerdns\\.dnsmaster.powerdns.com.");
155
156 // BOOST_CHECK(DNSName().toString() != ".");
157
158 DNSName p;
159 string label("power");
160 label.append(1, (char)0);
161 label.append("dns");
162 p.appendRawLabel(label);
163 p.appendRawLabel("com");
164
165 BOOST_CHECK_EQUAL(p.toString(), "power\\000dns.com.");
166 }
167
168 BOOST_AUTO_TEST_CASE(test_trim) {
169 DNSName w("www.powerdns.com.");
170 BOOST_CHECK_EQUAL(w.countLabels(), 3);
171 w.trimToLabels(2);
172 BOOST_CHECK_EQUAL(w.toString(), "powerdns.com.");
173 DNSName w2("powerdns.com.");
174 BOOST_CHECK(w==w2);
175
176 DNSName root(".");
177 BOOST_CHECK_EQUAL(root.countLabels(), 0);
178 }
179
180 BOOST_AUTO_TEST_CASE(test_toolong) {
181
182 BOOST_CHECK_THROW(DNSName w("1234567890123456789012345678901234567890123456789012345678901234567890.com."), std::range_error);
183
184 BOOST_CHECK_THROW(DNSName w("12345678901234567890.12345678901234567890123456.789012345678901.234567890.12345678901234567890.12345678901234567890123456.789012345678901.234567890.12345678901234567890.12345678901234567890123456.789012345678901.234567890.234567890.789012345678901.234567890.234567890.789012345678901.234567890.234567890.com."), std::range_error);
185 }
186
187 BOOST_AUTO_TEST_CASE(test_dnsstrings) {
188 DNSName w("www.powerdns.com.");
189 BOOST_CHECK_EQUAL(w.toDNSString(), string("\003www\010powerdns\003com\000", 18));
190 }
191
192 BOOST_AUTO_TEST_CASE(test_empty) {
193 DNSName empty;
194 BOOST_CHECK_THROW(empty.toString(), std::out_of_range);
195 BOOST_CHECK_THROW(empty.toStringNoDot(), std::out_of_range);
196 BOOST_CHECK_THROW(empty.toDNSString(), std::out_of_range);
197 BOOST_CHECK(empty.empty());
198 BOOST_CHECK(!empty.isRoot());
199 BOOST_CHECK(!empty.isWildcard());
200 BOOST_CHECK_EQUAL(empty, empty);
201 BOOST_CHECK(!(empty < empty));
202
203 DNSName root(".");
204 BOOST_CHECK(empty < root);
205
206 BOOST_CHECK_THROW(empty.isPartOf(root), std::out_of_range);
207 BOOST_CHECK_THROW(root.isPartOf(empty), std::out_of_range);
208 }
209
210 BOOST_AUTO_TEST_CASE(test_specials) {
211 DNSName root(".");
212
213 BOOST_CHECK(root.isRoot());
214 BOOST_CHECK(root != DNSName());
215
216 DNSName wcard("*.powerdns.com");
217 BOOST_CHECK(wcard.isWildcard());
218
219 DNSName notwcard("www.powerdns.com");
220 BOOST_CHECK(!notwcard.isWildcard());
221 }
222
223
224 BOOST_AUTO_TEST_CASE(test_chopping) {
225 DNSName w("www.powerdns.com.");
226 BOOST_CHECK_EQUAL(w.toString(), "www.powerdns.com.");
227 BOOST_CHECK(w.chopOff());
228 BOOST_CHECK_EQUAL(w.toString(), "powerdns.com.");
229 BOOST_CHECK(w.chopOff());
230 BOOST_CHECK_EQUAL(w.toString(), "com.");
231 BOOST_CHECK(w.chopOff());
232 BOOST_CHECK_EQUAL(w.toString(), ".");
233 BOOST_CHECK(!w.chopOff());
234 BOOST_CHECK(!w.chopOff());
235
236 w.prependRawLabel("net");
237 w.prependRawLabel("root-servers");
238 w.prependRawLabel("a");
239 BOOST_CHECK_EQUAL(w.toString(), "a.root-servers.net.");
240 }
241
242 BOOST_AUTO_TEST_CASE(test_Append) {
243 DNSName dn("www."), powerdns("powerdns.com.");
244 DNSName tot=dn+powerdns;
245
246 BOOST_CHECK_EQUAL(tot.toString(), "www.powerdns.com.");
247 BOOST_CHECK(tot == DNSName("www.powerdns.com."));
248
249 dn+=powerdns;
250
251 BOOST_CHECK(dn == DNSName("www.powerdns.com."));
252 }
253
254 BOOST_AUTO_TEST_CASE(test_packetCompress) {
255 reportBasicTypes();
256 vector<unsigned char> packet;
257 DNSPacketWriter dpw(packet, DNSName("www.ds9a.nl."), QType::AAAA);
258 dpw.startRecord(DNSName("ds9a.nl"), QType::SOA);
259 SOARecordContent src("ns1.powerdns.nl admin.powerdns.nl 1 2 3 4 5");
260 src.toPacket(dpw);
261 AAAARecordContent aaaa("::1");
262 dpw.startRecord(DNSName("www.dS9A.nl"), QType::AAAA);
263 aaaa.toPacket(dpw);
264 dpw.startRecord(DNSName("www.ds9A.nl"), QType::AAAA);
265 aaaa.toPacket(dpw);
266 dpw.startRecord(DNSName("www.dS9a.nl"), QType::AAAA);
267 aaaa.toPacket(dpw);
268 dpw.startRecord(DNSName("www2.DS9a.nl"), QType::AAAA);
269 aaaa.toPacket(dpw);
270 dpw.startRecord(DNSName("www2.dS9a.nl"), QType::AAAA);
271 aaaa.toPacket(dpw);
272 dpw.commit();
273 string str((const char*)&packet[0], (const char*)&packet[0] + packet.size());
274 size_t pos = 0;
275 int count=0;
276 while((pos = str.find("ds9a", pos)) != string::npos) {
277 ++pos;
278 ++count;
279 }
280 BOOST_CHECK_EQUAL(count, 1);
281 pos = 0;
282 count=0;
283 while((pos = str.find("powerdns", pos)) != string::npos) {
284 ++pos;
285 ++count;
286 }
287 BOOST_CHECK_EQUAL(count, 1);
288
289 }
290
291 BOOST_AUTO_TEST_CASE(test_packetCompressLong) {
292 reportBasicTypes();
293 vector<unsigned char> packet;
294 DNSName loopback("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");
295 DNSPacketWriter dpw(packet, loopback, QType::PTR);
296
297 dpw.startRecord(loopback, QType::PTR);
298 PTRRecordContent prc(DNSName("localhost"));
299 prc.toPacket(dpw);
300 dpw.commit();
301 DNSName roundtrip((char*)&packet[0], packet.size(), 12, false);
302 BOOST_CHECK_EQUAL(loopback,roundtrip);
303
304 packet.clear();
305 DNSName longer("1.2.3.4.5.6.7.8.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");
306 DNSPacketWriter dpw2(packet, longer, QType::PTR);
307
308 dpw2.startRecord(DNSName("a.b.c.d.e")+longer, QType::PTR);
309 PTRRecordContent prc2(DNSName("localhost"));
310 prc2.toPacket(dpw2);
311 dpw2.commit();
312
313 }
314
315
316
317
318 BOOST_AUTO_TEST_CASE(test_PacketParse) {
319 vector<unsigned char> packet;
320 reportBasicTypes();
321 DNSName root(".");
322 DNSPacketWriter dpw1(packet, g_rootdnsname, QType::AAAA);
323 DNSName p((char*)&packet[0], packet.size(), 12, false);
324 BOOST_CHECK_EQUAL(p, root);
325 unsigned char* buffer=&packet[0];
326 /* set invalid label len:
327 - packet.size() == 17 (sizeof(dnsheader) + 1 + 2 + 2)
328 - label len < packet.size() but
329 - offset is 12, label len of 15 should be rejected
330 because offset + 15 >= packet.size()
331 */
332 buffer[sizeof(dnsheader)] = 15;
333 BOOST_CHECK_THROW(DNSName((char*)&packet[0], packet.size(), 12, false), std::range_error);
334 }
335
336
337 BOOST_AUTO_TEST_CASE(test_hash) {
338 DNSName a("wwW.Ds9A.Nl"), b("www.ds9a.nl");
339 BOOST_CHECK_EQUAL(a.hash(), b.hash());
340
341 vector<uint32_t> counts(1500);
342
343 for(unsigned int n=0; n < 100000; ++n) {
344 DNSName dn(std::to_string(n)+"."+std::to_string(n*2)+"ds9a.nl");
345 DNSName dn2(std::to_string(n)+"."+std::to_string(n*2)+"Ds9a.nL");
346 BOOST_CHECK_EQUAL(dn.hash(), dn2.hash());
347 counts[dn.hash() % counts.size()]++;
348 }
349
350 double sum = std::accumulate(std::begin(counts), std::end(counts), 0.0);
351 double m = sum / counts.size();
352
353 double accum = 0.0;
354 std::for_each (std::begin(counts), std::end(counts), [&](const double d) {
355 accum += (d - m) * (d - m);
356 });
357
358 double stdev = sqrt(accum / (counts.size()-1));
359 BOOST_CHECK(stdev < 10);
360 }
361
362 BOOST_AUTO_TEST_CASE(test_hashContainer) {
363 std::unordered_set<DNSName> s;
364 s.insert(DNSName("www.powerdns.com"));
365 BOOST_CHECK(s.count(DNSName("WwW.PoWerDNS.CoM")));
366 BOOST_CHECK_EQUAL(s.size(), 1);
367 s.insert(DNSName("www.POWERDNS.com"));
368 BOOST_CHECK_EQUAL(s.size(), 1);
369 s.insert(DNSName("www2.POWERDNS.com"));
370 BOOST_CHECK_EQUAL(s.size(), 2);
371
372 s.clear();
373 unsigned int n=0;
374 for(; n < 100000; ++n)
375 s.insert(DNSName(std::to_string(n)+".test.nl"));
376 BOOST_CHECK_EQUAL(s.size(), n);
377
378 }
379
380
381 BOOST_AUTO_TEST_CASE(test_QuestionHash) {
382 vector<unsigned char> packet;
383 reportBasicTypes();
384 DNSPacketWriter dpw1(packet, DNSName("www.ds9a.nl."), QType::AAAA);
385
386 auto hash1=hashQuestion((char*)&packet[0], packet.size(), 0);
387 DNSPacketWriter dpw2(packet, DNSName("wWw.Ds9A.nL."), QType::AAAA);
388 auto hash2=hashQuestion((char*)&packet[0], packet.size(), 0);
389 BOOST_CHECK_EQUAL(hash1, hash2);
390
391 vector<uint32_t> counts(1500);
392
393 for(unsigned int n=0; n < 100000; ++n) {
394 packet.clear();
395 DNSPacketWriter dpw3(packet, DNSName(std::to_string(n)+"."+std::to_string(n*2)+"."), QType::AAAA);
396 counts[hashQuestion((char*)&packet[0], packet.size(), 0) % counts.size()]++;
397 }
398
399 double sum = std::accumulate(std::begin(counts), std::end(counts), 0.0);
400 double m = sum / counts.size();
401
402 double accum = 0.0;
403 std::for_each (std::begin(counts), std::end(counts), [&](const double d) {
404 accum += (d - m) * (d - m);
405 });
406
407 double stdev = sqrt(accum / (counts.size()-1));
408 BOOST_CHECK(stdev < 10);
409 }
410
411
412 BOOST_AUTO_TEST_CASE(test_packetParse) {
413 vector<unsigned char> packet;
414 reportBasicTypes();
415 DNSPacketWriter dpw(packet, DNSName("www.ds9a.nl."), QType::AAAA);
416
417 uint16_t qtype, qclass;
418 DNSName dn((char*)&packet[0], packet.size(), 12, false, &qtype, &qclass);
419 BOOST_CHECK_EQUAL(dn.toString(), "www.ds9a.nl.");
420 BOOST_CHECK(qtype == QType::AAAA);
421 BOOST_CHECK_EQUAL(qclass, 1);
422
423 dpw.startRecord(DNSName("ds9a.nl."), DNSRecordContent::TypeToNumber("NS"));
424 NSRecordContent nrc("ns1.powerdns.com");
425 nrc.toPacket(dpw);
426
427 dpw.commit();
428
429 /* packet now looks like this:
430 012345678901 12 bytes of header
431 3www4ds9a2nl0 13 bytes of name
432 0001 0001 4 bytes of qtype and qclass
433 answername 2 bytes
434 0001 0001 4 bytes of qtype and class
435 0000 0000 4 bytes of TTL
436 0000 2 bytes of content length
437 content name */
438
439 DNSName dn2((char*)&packet[0], packet.size(), 12+13+4, true, &qtype, &qclass);
440 BOOST_CHECK_EQUAL(dn2.toString(), "ds9a.nl.");
441 BOOST_CHECK(qtype == QType::NS);
442 BOOST_CHECK_EQUAL(qclass, 1);
443
444 DNSName dn3((char*)&packet[0], packet.size(), 12+13+4+2 + 4 + 4 + 2, true);
445 BOOST_CHECK_EQUAL(dn3.toString(), "ns1.powerdns.com.");
446 try {
447 DNSName dn4((char*)&packet[0], packet.size(), 12+13+4, false); // compressed, should fail
448 BOOST_CHECK(0);
449 }
450 catch(...){}
451 }
452
453 BOOST_AUTO_TEST_CASE(test_escaping) {
454 DNSName n;
455 string label;
456
457 for(int i = 0; i < 250; ++i) {
458 if(!((i+1)%63)) {
459 n.appendRawLabel(label);
460 label.clear();
461 }
462 label.append(1,(char)i);
463 }
464 if(!label.empty())
465 n.appendRawLabel(label);
466
467 DNSName n2(n.toString());
468 BOOST_CHECK(n==n2);
469 }
470
471 BOOST_AUTO_TEST_CASE(test_suffixmatch) {
472 SuffixMatchNode smn;
473 DNSName ezdns("ezdns.it.");
474 smn.add(ezdns.getRawLabels());
475
476 smn.add(DNSName("org.").getRawLabels());
477
478 DNSName wwwpowerdnscom("www.powerdns.com.");
479 DNSName wwwezdnsit("www.ezdns.it.");
480 BOOST_CHECK(smn.check(wwwezdnsit));
481 BOOST_CHECK(!smn.check(wwwpowerdnscom));
482
483 BOOST_CHECK(smn.check(DNSName("www.powerdns.org.")));
484 BOOST_CHECK(smn.check(DNSName("www.powerdns.oRG.")));
485
486 smn.add(DNSName("news.bbc.co.uk."));
487 BOOST_CHECK(smn.check(DNSName("news.bbc.co.uk.")));
488 BOOST_CHECK(smn.check(DNSName("www.news.bbc.co.uk.")));
489 BOOST_CHECK(smn.check(DNSName("www.www.www.www.www.news.bbc.co.uk.")));
490 BOOST_CHECK(!smn.check(DNSName("images.bbc.co.uk.")));
491
492 BOOST_CHECK(!smn.check(DNSName("www.news.gov.uk.")));
493
494 smn.add(g_rootdnsname); // block the root
495 BOOST_CHECK(smn.check(DNSName("a.root-servers.net.")));
496
497 DNSName examplenet("example.net.");
498 DNSName net("net.");
499 smn.add(examplenet);
500 smn.add(net);
501 BOOST_CHECK(smn.check(examplenet));
502 BOOST_CHECK(smn.check(net));
503 }
504
505 BOOST_AUTO_TEST_CASE(test_suffixmatch_tree) {
506 SuffixMatchTree<DNSName> smt;
507 DNSName ezdns("ezdns.it.");
508 smt.add(ezdns, ezdns);
509
510 smt.add(DNSName("org.").getRawLabels(), DNSName("org."));
511
512 DNSName wwwpowerdnscom("www.powerdns.com.");
513 DNSName wwwezdnsit("www.ezdns.it.");
514 BOOST_REQUIRE(smt.lookup(wwwezdnsit));
515 BOOST_CHECK_EQUAL(*smt.lookup(wwwezdnsit), ezdns);
516 BOOST_CHECK(smt.lookup(wwwpowerdnscom) == nullptr);
517
518 BOOST_REQUIRE(smt.lookup(DNSName("www.powerdns.org.")));
519 BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.powerdns.org.")), DNSName("org."));
520 BOOST_REQUIRE(smt.lookup(DNSName("www.powerdns.oRG.")));
521 BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.powerdns.oRG.")), DNSName("org."));
522
523 smt.add(DNSName("news.bbc.co.uk."), DNSName("news.bbc.co.uk."));
524 BOOST_REQUIRE(smt.lookup(DNSName("news.bbc.co.uk.")));
525 BOOST_CHECK_EQUAL(*smt.lookup(DNSName("news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
526 BOOST_REQUIRE(smt.lookup(DNSName("www.news.bbc.co.uk.")));
527 BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
528 BOOST_REQUIRE(smt.lookup(DNSName("www.www.www.www.www.news.bbc.co.uk.")));
529 BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.www.www.www.www.news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
530 BOOST_CHECK(smt.lookup(DNSName("images.bbc.co.uk.")) == nullptr);
531 BOOST_CHECK(smt.lookup(DNSName("www.news.gov.uk.")) == nullptr);
532
533 smt.add(g_rootdnsname, g_rootdnsname); // block the root
534 BOOST_REQUIRE(smt.lookup(DNSName("a.root-servers.net.")));
535 BOOST_CHECK_EQUAL(*smt.lookup(DNSName("a.root-servers.net.")), g_rootdnsname);
536
537 DNSName apowerdnscom("a.powerdns.com.");
538 DNSName bpowerdnscom("b.powerdns.com.");
539 smt.add(apowerdnscom, apowerdnscom);
540 smt.add(bpowerdnscom, bpowerdnscom);
541 BOOST_REQUIRE(smt.lookup(apowerdnscom));
542 BOOST_CHECK_EQUAL(*smt.lookup(apowerdnscom), apowerdnscom);
543 BOOST_REQUIRE(smt.lookup(bpowerdnscom));
544 BOOST_CHECK_EQUAL(*smt.lookup(bpowerdnscom), bpowerdnscom);
545
546 DNSName examplenet("example.net.");
547 DNSName net("net.");
548 smt.add(examplenet, examplenet);
549 smt.add(net, net);
550 BOOST_REQUIRE(smt.lookup(examplenet));
551 BOOST_CHECK_EQUAL(*smt.lookup(examplenet), examplenet);
552 BOOST_REQUIRE(smt.lookup(net));
553 BOOST_CHECK_EQUAL(*smt.lookup(net), net);
554 }
555
556
557 BOOST_AUTO_TEST_CASE(test_concat) {
558 DNSName first("www."), second("powerdns.com.");
559 BOOST_CHECK_EQUAL((first+second).toString(), "www.powerdns.com.");
560 }
561
562 BOOST_AUTO_TEST_CASE(test_compare_naive) {
563 BOOST_CHECK(DNSName("abc.com.") < DNSName("zdf.com."));
564 BOOST_CHECK(DNSName("Abc.com.") < DNSName("zdf.com."));
565 BOOST_CHECK(DNSName("Abc.com.") < DNSName("Zdf.com."));
566 BOOST_CHECK(DNSName("abc.com.") < DNSName("Zdf.com."));
567 }
568
569 BOOST_AUTO_TEST_CASE(test_compare_empty) {
570 DNSName a, b;
571 BOOST_CHECK(!(a<b));
572 BOOST_CHECK(!a.canonCompare(b));
573 }
574
575 BOOST_AUTO_TEST_CASE(test_casing) {
576 DNSName a("WwW.PoWeRdNS.Com"), b("www.powerdns.com.");
577 BOOST_CHECK_EQUAL(a,b);
578 BOOST_CHECK_EQUAL(a.toString(), "WwW.PoWeRdNS.Com.");
579 DNSName c=a.makeLowerCase();
580 BOOST_CHECK_EQUAL(a,c);
581 BOOST_CHECK_EQUAL(b,c);
582 BOOST_CHECK_EQUAL(c.toString(), b.toString());
583 BOOST_CHECK_EQUAL(c.toString(), "www.powerdns.com.");
584 }
585
586
587
588 BOOST_AUTO_TEST_CASE(test_compare_canonical) {
589 DNSName lower("bert.com."), higher("alpha.nl.");
590 BOOST_CHECK(lower.canonCompare(higher));
591
592 BOOST_CHECK(DNSName("bert.com").canonCompare(DNSName("www.bert.com")));
593 BOOST_CHECK(DNSName("BeRt.com").canonCompare(DNSName("WWW.berT.com")));
594 BOOST_CHECK(!DNSName("www.BeRt.com").canonCompare(DNSName("WWW.berT.com")));
595
596 CanonDNSNameCompare a;
597 BOOST_CHECK(a(g_rootdnsname, DNSName("www.powerdns.com")));
598 BOOST_CHECK(a(g_rootdnsname, DNSName("www.powerdns.net")));
599 BOOST_CHECK(!a(DNSName("www.powerdns.net"), g_rootdnsname));
600
601 vector<DNSName> vec;
602 for(const std::string& b : {"bert.com.", "alpha.nl.", "articles.xxx.",
603 "Aleph1.powerdns.com.", "ZOMG.powerdns.com.", "aaa.XXX.", "yyy.XXX.",
604 "test.powerdns.com.", "\\128.com"}) {
605 vec.push_back(DNSName(b));
606 }
607 sort(vec.begin(), vec.end(), CanonDNSNameCompare());
608 // for(const auto& v : vec)
609 // cerr<<'"'<<v<<'"'<<endl;
610
611 vector<DNSName> right;
612 for(const auto& b: {"bert.com.", "Aleph1.powerdns.com.",
613 "test.powerdns.com.",
614 "ZOMG.powerdns.com.",
615 "\\128.com.",
616 "alpha.nl.",
617 "aaa.XXX.",
618 "articles.xxx.",
619 "yyy.XXX."})
620 right.push_back(DNSName(b));
621
622
623 BOOST_CHECK(vec==right);
624 }
625
626
627 BOOST_AUTO_TEST_CASE(test_empty_label) { // empty label
628
629 { // append
630 DNSName dn("www.");
631 BOOST_CHECK_THROW(dn.appendRawLabel(""), std::range_error);
632 }
633
634 { // prepend
635 DNSName dn("www.");
636 BOOST_CHECK_THROW(dn.prependRawLabel(""), std::range_error);
637 }
638 }
639
640 BOOST_AUTO_TEST_CASE(test_label_length_max) { // 63 char label
641
642 string label("123456789012345678901234567890123456789012345678901234567890123");
643
644 { // append
645 DNSName dn("www.");
646 dn.appendRawLabel(label);
647 BOOST_CHECK_EQUAL(dn.toString(), "www." + label + ".");
648 }
649
650 { // prepend
651 DNSName dn("www.");
652 dn.prependRawLabel(label);
653 BOOST_CHECK_EQUAL(dn.toString(), label + ".www.");
654 }
655 }
656
657 BOOST_AUTO_TEST_CASE(test_label_length_too_long) { // 64 char label
658
659 string label("1234567890123456789012345678901234567890123456789012345678901234");
660
661 { // append
662 DNSName dn("www.");
663 BOOST_CHECK_THROW(dn.appendRawLabel(label), std::range_error);
664 }
665
666 { // prepend
667 DNSName dn("www.");
668 BOOST_CHECK_THROW(dn.prependRawLabel(label), std::range_error);
669 }
670 }
671
672 BOOST_AUTO_TEST_CASE(test_name_length_max) { // 255 char name
673
674 string name("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
675 "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
676 "123456789.123456789.123456789.123456789.123456789.");
677 string label("123");
678
679 { // append
680 DNSName dn(name);
681 dn.appendRawLabel(label);
682 BOOST_CHECK_EQUAL(dn.toString().size(), 254);
683 }
684
685 { // prepend
686 DNSName dn(name);
687 dn.prependRawLabel(label);
688 BOOST_CHECK_EQUAL(dn.toString().size(), 254);
689 }
690
691 { // concat
692 DNSName dn(name);
693
694 dn += DNSName(label + ".");
695 BOOST_CHECK_EQUAL(dn.toString().size(), 254);
696 }
697 }
698
699 BOOST_AUTO_TEST_CASE(test_name_length_too_long) { // 256 char name
700
701 string name("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
702 "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
703 "123456789.123456789.123456789.123456789.123456789.");
704 string label("1234");
705
706 { // append
707 DNSName dn(name);
708 BOOST_CHECK_THROW(dn.appendRawLabel(label), std::range_error);
709 }
710
711 { // prepend
712 DNSName dn(name);
713 BOOST_CHECK_THROW(dn.prependRawLabel(label), std::range_error);
714 }
715
716 { // concat
717 DNSName dn(name);
718 BOOST_CHECK_THROW(dn += DNSName(label + "."), std::range_error);
719 }
720 }
721
722
723 BOOST_AUTO_TEST_CASE(test_invalid_label_length) { // Invalid label length in qname
724
725 string name("\x02""ns\x07""example\x04""com\x00", 16);
726
727 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 0, true), std::range_error);
728 }
729
730 BOOST_AUTO_TEST_CASE(test_compression) { // Compression test
731
732 string name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05", 21);
733
734 DNSName dn(name.c_str(), name.size(), 15, true);
735 BOOST_CHECK_EQUAL(dn.toString(), "www.example.com.");
736 }
737
738 BOOST_AUTO_TEST_CASE(test_compression_qtype_qclass) { // Compression test with QClass and QType extraction
739
740 uint16_t qtype = 0;
741 uint16_t qclass = 0;
742
743 {
744 string name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05""\x00""\x01""\x00""\x01", 25);
745 DNSName dn(name.c_str(), name.size(), 15, true, &qtype, &qclass);
746 BOOST_CHECK_EQUAL(dn.toString(), "www.example.com.");
747 BOOST_CHECK_EQUAL(qtype, 1);
748 BOOST_CHECK_EQUAL(qclass, 1);
749 }
750
751 {
752 /* same but this time we are one byte short for the qclass */
753 string name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05""\x00""\x01""\x00""", 24);
754 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 15, true, &qtype, &qclass), std::range_error);
755 }
756
757 {
758 /* this time with a compression pointer such as (labellen << 8) != 0, see #4718 */
759 string name("\x03""com\x00""\x07""example\xc1""\x00""\x03""www\xc1""\x05""\x00""\x01""\x00""\x01", 25);
760 name.insert(0, 256, '0');
761
762 DNSName dn(name.c_str(), name.size(), 271, true, &qtype, &qclass);
763 BOOST_CHECK_EQUAL(dn.toString(), "www.example.com.");
764 BOOST_CHECK_EQUAL(qtype, 1);
765 BOOST_CHECK_EQUAL(qclass, 1);
766 }
767
768 {
769 /* same but this time we are one byte short for the qclass */
770 string name("\x03""com\x00""\x07""example\xc1""\x00""\x03""www\xc1""\x05""\x00""\x01""\x00", 24);
771 name.insert(0, 256, '0');
772
773 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 271, true, &qtype, &qclass), std::range_error);
774 }
775 }
776
777 BOOST_AUTO_TEST_CASE(test_compression_single_bit_set) { // first 2 bits as 10 or 01, not 11
778
779 // first 2 bits: 10
780 {
781 string name("\x03""com\x00""\x07""example\x80""\x00""\x03""www\x80""\x05", 21);
782
783 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 15, true), std::range_error);
784 }
785
786 // first 2 bits: 01
787 {
788 string name("\x03""com\x00""\x07""example\x40""\x00""\x03""www\x40""\x05", 21);
789
790 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 15, true), std::range_error);
791 }
792
793 }
794
795 BOOST_AUTO_TEST_CASE(test_pointer_pointer_root) { // Pointer to pointer to root
796
797 string name("\x00""\xc0""\x00""\x03""com\xc0""\x01",9);
798
799 DNSName dn(name.c_str(), name.size(), 3, true);
800 BOOST_CHECK_EQUAL(dn.toString(), "com.");
801 }
802
803 BOOST_AUTO_TEST_CASE(test_bad_compression_pointer) { // Pointing beyond packet boundary
804
805 std::string name("\x03""com\x00""\x07""example\xc0""\x11""xc0""\x00", 17);
806
807 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.length(), 5, true), std::range_error);
808 }
809
810 BOOST_AUTO_TEST_CASE(test_compression_loop) { // Compression loop (add one label)
811
812 std::string name("\x03""www\xc0""\x00", 6);
813
814 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.length(), 0, true), std::range_error);
815 }
816
817 BOOST_AUTO_TEST_CASE(test_compression_loop1) { // Compression loop (pointer loop)
818
819 string name("\xc0""\x00", 2);
820
821 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 0, true), std::range_error);
822 }
823
824 BOOST_AUTO_TEST_CASE(test_compression_loop2) { // Compression loop (deep recursion)
825
826 int i;
827 string name("\x00\xc0\x00", 3);
828 for (i=0; i<98; ++i) {
829 name.append( 1, ((i >> 7) & 0xff) | 0xc0);
830 name.append( 1, ((i << 1) & 0xff) | 0x01);
831 }
832 BOOST_CHECK_NO_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true));
833
834 ++i;
835 name.append( 1, ((i >> 7) & 0xff) | 0xc0);
836 name.append( 1, ((i << 1) & 0xff) | 0x01);
837
838 BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true), std::range_error);
839 }
840
841 BOOST_AUTO_TEST_CASE(test_wirelength) { // Testing if we get the correct value from the wirelength function
842 DNSName name("www.powerdns.com");
843 BOOST_CHECK_EQUAL(name.wirelength(), 18);
844
845 DNSName sname("powerdns.com");
846 sname.prependRawLabel(string("ww\x00""w", 4));
847 BOOST_CHECK_EQUAL(sname.wirelength(), 19);
848
849 sname = DNSName("powerdns.com");
850 sname.prependRawLabel(string("www\x00", 4));
851 BOOST_CHECK_EQUAL(sname.wirelength(), 19);
852 }
853
854 BOOST_AUTO_TEST_CASE(test_getrawlabel) {
855 DNSName name("a.bb.ccc.dddd.");
856 BOOST_CHECK_EQUAL(name.getRawLabel(0), "a");
857 BOOST_CHECK_EQUAL(name.getRawLabel(1), "bb");
858 BOOST_CHECK_EQUAL(name.getRawLabel(2), "ccc");
859 BOOST_CHECK_EQUAL(name.getRawLabel(3), "dddd");
860 BOOST_CHECK_THROW(name.getRawLabel(name.countLabels()), std::out_of_range);
861 }
862
863 BOOST_AUTO_TEST_CASE(test_getlastlabel) {
864 DNSName name("www.powerdns.com");
865 DNSName ans = name.getLastLabel();
866
867 // Check the const-ness
868 BOOST_CHECK_EQUAL(name, DNSName("www.powerdns.com"));
869
870 // Check if the last label is indeed returned
871 BOOST_CHECK_EQUAL(ans, DNSName("com"));
872 }
873
874 BOOST_AUTO_TEST_CASE(test_getcommonlabels) {
875 const DNSName name1("www.powerdns.com");
876 const DNSName name2("a.long.list.of.labels.powerdns.com");
877
878 BOOST_CHECK_EQUAL(name1.getCommonLabels(name1), name1);
879 BOOST_CHECK_EQUAL(name2.getCommonLabels(name2), name2);
880
881 BOOST_CHECK_EQUAL(name1.getCommonLabels(name2), DNSName("powerdns.com"));
882 BOOST_CHECK_EQUAL(name2.getCommonLabels(name1), DNSName("powerdns.com"));
883
884 const DNSName name3("www.powerdns.org");
885 BOOST_CHECK_EQUAL(name1.getCommonLabels(name3), DNSName());
886 BOOST_CHECK_EQUAL(name2.getCommonLabels(name3), DNSName());
887 BOOST_CHECK_EQUAL(name3.getCommonLabels(name1), DNSName());
888 BOOST_CHECK_EQUAL(name3.getCommonLabels(name2), DNSName());
889
890 const DNSName name4("WWw.PowErDnS.org");
891 BOOST_CHECK_EQUAL(name3.getCommonLabels(name4), name3);
892 BOOST_CHECK_EQUAL(name4.getCommonLabels(name3), name4);
893 }
894
895 BOOST_AUTO_TEST_SUITE_END()