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