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>
9 #include "dnswriter.hh"
10 #include "dnsrecords.hh"
11 #include <unordered_set>
12 using namespace boost
;
15 BOOST_AUTO_TEST_SUITE(dnsname_cc
)
17 BOOST_AUTO_TEST_CASE(test_basic
) {
18 string
before("www.ds9a.nl.");
20 BOOST_CHECK_EQUAL(b
.getRawLabels().size(), 3);
21 string
after(b
.toString());
22 BOOST_CHECK_EQUAL(before
, after
);
24 DNSName
jpmens("ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.test.xxx.yyy-yyyy.zzzzzzzzz-test.");
26 BOOST_CHECK_EQUAL(jpmens
.toString(), "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.test.xxx.yyy-yyyy.zzzzzzzzz-test.");
28 DNSName
wwwds9anl("www.ds9a.nl.");
29 DNSName
wwwds9anl1("www.ds9a\002nl.");
31 BOOST_CHECK(wwwds9anl
.isPartOf(nl
));
32 BOOST_CHECK(!wwwds9anl1
.isPartOf(nl
));
33 BOOST_CHECK(wwwds9anl
.isPartOf(wwwds9anl
));
35 BOOST_CHECK(!nl
.isPartOf(wwwds9anl
));
37 BOOST_CHECK(wwwds9anl
== wwwds9anl
);
39 BOOST_CHECK(DNSName("wWw.ds9A.Nl.") == DNSName("www.ds9a.nl."));
40 BOOST_CHECK(DNSName("www.ds9a.nl.") == DNSName("www.ds9a.nl."));
42 BOOST_CHECK(DNSName("www.ds9a.nl.").toString() == "www.ds9a.nl.");
45 { // Check root vs empty
46 DNSName
name("."); // root
47 DNSName parent
; // empty
48 BOOST_CHECK(name
!= parent
);
51 { // Check name part of root
54 BOOST_CHECK(name
.isPartOf(parent
));
58 DNSName
name("a\002bb.");
59 DNSName
parent("bb.");
60 BOOST_CHECK(!name
.isPartOf(parent
));
63 { // Multi label parent
64 DNSName
name("a.bb.ccc.dddd.");
65 DNSName
parent("ccc.dddd.");
66 BOOST_CHECK(name
.isPartOf(parent
));
70 DNSName
name("a.bb.ccc.dddd.");
71 DNSName
parent("ccc.dddx.");
72 BOOST_CHECK(!name
.isPartOf(parent
));
75 { // Equal length identical
76 DNSName
name("aaaa.bbb.cc.d.");
77 DNSName
parent("aaaa.bbb.cc.d.");
78 BOOST_CHECK(name
.isPartOf(parent
));
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
));
88 DNSName
name("aaaa.bbb.cc.d.");
89 DNSName
parent("cc.d.");
90 BOOST_CHECK_EQUAL( name
.makeRelative(parent
), DNSName("aaaa.bbb."));
94 DNSName
name("aaaa.bbb.cc.d.");
95 BOOST_CHECK( name
.labelReverse() == DNSName("d.cc.bbb.aaaa."));
100 BOOST_CHECK(name
.empty());
105 BOOST_CHECK(!name
.empty());
107 DNSName
rootnodot("");
108 BOOST_CHECK_EQUAL(name
, rootnodot
);
111 DNSName
rootnodot2(empty
);
112 BOOST_CHECK_EQUAL(rootnodot2
, name
);
115 DNSName
left("ds9a.nl.");
116 left
.prependRawLabel("www");
117 BOOST_CHECK( left
== DNSName("WwW.Ds9A.Nl."));
119 left
.appendRawLabel("com");
121 BOOST_CHECK( left
== DNSName("WwW.Ds9A.Nl.com."));
125 unset
.appendRawLabel("www");
126 unset
.appendRawLabel("powerdns.com");
127 unset
.appendRawLabel("com");
129 BOOST_CHECK_EQUAL(unset
.toString(), "www.powerdns\\.com.com.");
131 DNSName
rfc4343_2_2(R
"(Donald\032E\.\032Eastlake\0323rd.example.)");
132 DNSName
example("example.");
133 BOOST_CHECK(rfc4343_2_2
.isPartOf(example
));
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);
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
);
148 n
.appendRawLabel("powerdns.dnsmaster");
149 n
.appendRawLabel("powerdns");
150 n
.appendRawLabel("com");
152 BOOST_CHECK_EQUAL(n
.toString(), "powerdns\\.dnsmaster.powerdns.com.");
154 // BOOST_CHECK(DNSName().toString() != ".");
157 string
label("power");
158 label
.append(1, (char)0);
160 p
.appendRawLabel(label
);
161 p
.appendRawLabel("com");
163 BOOST_CHECK_EQUAL(p
.toString(), "power\\000dns.com.");
166 BOOST_AUTO_TEST_CASE(test_trim
) {
167 DNSName
w("www.powerdns.com.");
168 BOOST_CHECK_EQUAL(w
.countLabels(), 3);
170 BOOST_CHECK_EQUAL(w
.toString(), "powerdns.com.");
171 DNSName
w2("powerdns.com.");
175 BOOST_CHECK_EQUAL(root
.countLabels(), 0);
178 BOOST_AUTO_TEST_CASE(test_toolong
) {
180 BOOST_CHECK_THROW(DNSName
w("1234567890123456789012345678901234567890123456789012345678901234567890.com."), std::range_error
);
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
);
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));
190 BOOST_AUTO_TEST_CASE(test_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
));
202 BOOST_CHECK(empty
< root
);
204 BOOST_CHECK_THROW(empty
.isPartOf(root
), std::out_of_range
);
205 BOOST_CHECK_THROW(root
.isPartOf(empty
), std::out_of_range
);
208 BOOST_AUTO_TEST_CASE(test_specials
) {
211 BOOST_CHECK(root
.isRoot());
212 BOOST_CHECK(root
!= DNSName());
214 DNSName
wcard("*.powerdns.com");
215 BOOST_CHECK(wcard
.isWildcard());
217 DNSName
notwcard("www.powerdns.com");
218 BOOST_CHECK(!notwcard
.isWildcard());
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());
234 w
.prependRawLabel("net");
235 w
.prependRawLabel("root-servers");
236 w
.prependRawLabel("a");
237 BOOST_CHECK_EQUAL(w
.toString(), "a.root-servers.net.");
240 BOOST_AUTO_TEST_CASE(test_Append
) {
241 DNSName
dn("www."), powerdns("powerdns.com.");
242 DNSName tot
=dn
+powerdns
;
244 BOOST_CHECK_EQUAL(tot
.toString(), "www.powerdns.com.");
245 BOOST_CHECK(tot
== DNSName("www.powerdns.com."));
249 BOOST_CHECK(dn
== DNSName("www.powerdns.com."));
252 BOOST_AUTO_TEST_CASE(test_packetCompress
) {
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");
259 AAAARecordContent
aaaa("::1");
260 dpw
.startRecord(DNSName("www.dS9A.nl"), QType::AAAA
);
262 dpw
.startRecord(DNSName("www.ds9A.nl"), QType::AAAA
);
264 dpw
.startRecord(DNSName("www.dS9a.nl"), QType::AAAA
);
266 dpw
.startRecord(DNSName("www2.DS9a.nl"), QType::AAAA
);
268 dpw
.startRecord(DNSName("www2.dS9a.nl"), QType::AAAA
);
271 string
str((const char*)&packet
[0], (const char*)&packet
[0] + packet
.size());
274 while((pos
= str
.find("ds9a", pos
)) != string::npos
) {
278 BOOST_CHECK_EQUAL(count
, 1);
281 while((pos
= str
.find("powerdns", pos
)) != string::npos
) {
285 BOOST_CHECK_EQUAL(count
, 1);
289 BOOST_AUTO_TEST_CASE(test_packetCompressLong
) {
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
);
295 dpw
.startRecord(loopback
, QType::PTR
);
296 PTRRecordContent
prc(DNSName("localhost"));
299 DNSName
roundtrip((char*)&packet
[0], packet
.size(), 12, false);
300 BOOST_CHECK_EQUAL(loopback
,roundtrip
);
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
);
306 dpw2
.startRecord(DNSName("a.b.c.d.e")+longer
, QType::PTR
);
307 PTRRecordContent
prc2(DNSName("localhost"));
316 BOOST_AUTO_TEST_CASE(test_PacketParse
) {
317 vector
<unsigned char> packet
;
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()
330 buffer
[sizeof(dnsheader
)] = 15;
331 BOOST_CHECK_THROW(DNSName((char*)&packet
[0], packet
.size(), 12, false), std::range_error
);
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());
339 vector
<uint32_t> counts(1500);
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()]++;
348 double sum
= std::accumulate(std::begin(counts
), std::end(counts
), 0.0);
349 double m
= sum
/ counts
.size();
352 std::for_each (std::begin(counts
), std::end(counts
), [&](const double d
) {
353 accum
+= (d
- m
) * (d
- m
);
356 double stdev
= sqrt(accum
/ (counts
.size()-1));
357 BOOST_CHECK(stdev
< 10);
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);
372 for(; n
< 100000; ++n
)
373 s
.insert(DNSName(std::to_string(n
)+".test.nl"));
374 BOOST_CHECK_EQUAL(s
.size(), n
);
379 BOOST_AUTO_TEST_CASE(test_QuestionHash
) {
380 vector
<unsigned char> packet
;
382 DNSPacketWriter
dpw1(packet
, DNSName("www.ds9a.nl."), QType::AAAA
);
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
);
389 vector
<uint32_t> counts(1500);
391 for(unsigned int n
=0; n
< 100000; ++n
) {
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()]++;
397 double sum
= std::accumulate(std::begin(counts
), std::end(counts
), 0.0);
398 double m
= sum
/ counts
.size();
401 std::for_each (std::begin(counts
), std::end(counts
), [&](const double d
) {
402 accum
+= (d
- m
) * (d
- m
);
405 double stdev
= sqrt(accum
/ (counts
.size()-1));
406 BOOST_CHECK(stdev
< 10);
410 BOOST_AUTO_TEST_CASE(test_packetParse
) {
411 vector
<unsigned char> packet
;
413 DNSPacketWriter
dpw(packet
, DNSName("www.ds9a.nl."), QType::AAAA
);
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);
421 dpw
.startRecord(DNSName("ds9a.nl."), DNSRecordContent::TypeToNumber("NS"));
422 NSRecordContent
nrc("ns1.powerdns.com");
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
432 0001 0001 4 bytes of qtype and class
433 0000 0000 4 bytes of TTL
434 0000 2 bytes of content length
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);
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.");
445 DNSName
dn4((char*)&packet
[0], packet
.size(), 12+13+4, false); // compressed, should fail
451 BOOST_AUTO_TEST_CASE(test_escaping
) {
455 for(int i
= 0; i
< 250; ++i
) {
457 n
.appendRawLabel(label
);
460 label
.append(1,(char)i
);
463 n
.appendRawLabel(label
);
465 DNSName
n2(n
.toString());
469 BOOST_AUTO_TEST_CASE(test_suffixmatch
) {
471 DNSName
ezdns("ezdns.it.");
472 smn
.add(ezdns
.getRawLabels());
474 smn
.add(DNSName("org.").getRawLabels());
476 DNSName
wwwpowerdnscom("www.powerdns.com.");
477 DNSName
wwwezdnsit("www.ezdns.it.");
478 BOOST_CHECK(smn
.check(wwwezdnsit
));
479 BOOST_CHECK(!smn
.check(wwwpowerdnscom
));
481 BOOST_CHECK(smn
.check(DNSName("www.powerdns.org.")));
482 BOOST_CHECK(smn
.check(DNSName("www.powerdns.oRG.")));
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.")));
490 BOOST_CHECK(!smn
.check(DNSName("www.news.gov.uk.")));
492 smn
.add(g_rootdnsname
); // block the root
493 BOOST_CHECK(smn
.check(DNSName("a.root-servers.net.")));
495 DNSName
examplenet("example.net.");
499 BOOST_CHECK(smn
.check(examplenet
));
500 BOOST_CHECK(smn
.check(net
));
503 BOOST_AUTO_TEST_CASE(test_suffixmatch_tree
) {
504 SuffixMatchTree
<DNSName
> smt
;
505 DNSName
ezdns("ezdns.it.");
506 smt
.add(ezdns
, ezdns
);
508 smt
.add(DNSName("org.").getRawLabels(), DNSName("org."));
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);
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."));
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);
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
);
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
);
544 DNSName
examplenet("example.net.");
546 smt
.add(examplenet
, examplenet
);
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
);
555 BOOST_AUTO_TEST_CASE(test_concat
) {
556 DNSName
first("www."), second("powerdns.com.");
557 BOOST_CHECK_EQUAL((first
+second
).toString(), "www.powerdns.com.");
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."));
567 BOOST_AUTO_TEST_CASE(test_compare_empty
) {
570 BOOST_CHECK(!a
.canonCompare(b
));
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.");
586 BOOST_AUTO_TEST_CASE(test_compare_canonical
) {
587 DNSName
lower("bert.com."), higher("alpha.nl.");
588 BOOST_CHECK(lower
.canonCompare(higher
));
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")));
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
));
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
));
605 sort(vec
.begin(), vec
.end(), CanonDNSNameCompare());
606 // for(const auto& v : vec)
607 // cerr<<'"'<<v.toString()<<'"'<<endl;
609 vector
<DNSName
> right
;
610 for(const auto& a
: {"bert.com.", "Aleph1.powerdns.com.",
611 "test.powerdns.com.",
612 "ZOMG.powerdns.com.",
618 right
.push_back(DNSName(a
));
621 BOOST_CHECK(vec
==right
);
625 BOOST_AUTO_TEST_CASE(test_empty_label
) { // empty label
629 BOOST_CHECK_THROW(dn
.appendRawLabel(""), std::range_error
);
634 BOOST_CHECK_THROW(dn
.prependRawLabel(""), std::range_error
);
638 BOOST_AUTO_TEST_CASE(test_label_length_max
) { // 63 char label
640 string
label("123456789012345678901234567890123456789012345678901234567890123");
644 dn
.appendRawLabel(label
);
645 BOOST_CHECK_EQUAL(dn
.toString(), "www." + label
+ ".");
650 dn
.prependRawLabel(label
);
651 BOOST_CHECK_EQUAL(dn
.toString(), label
+ ".www.");
655 BOOST_AUTO_TEST_CASE(test_label_length_too_long
) { // 64 char label
657 string
label("1234567890123456789012345678901234567890123456789012345678901234");
661 BOOST_CHECK_THROW(dn
.appendRawLabel(label
), std::range_error
);
666 BOOST_CHECK_THROW(dn
.prependRawLabel(label
), std::range_error
);
670 BOOST_AUTO_TEST_CASE(test_name_length_max
) { // 255 char name
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.");
679 dn
.appendRawLabel(label
);
680 BOOST_CHECK_EQUAL(dn
.toString().size(), 254);
685 dn
.prependRawLabel(label
);
686 BOOST_CHECK_EQUAL(dn
.toString().size(), 254);
692 dn
+= DNSName(label
+ ".");
693 BOOST_CHECK_EQUAL(dn
.toString().size(), 254);
697 BOOST_AUTO_TEST_CASE(test_name_length_too_long
) { // 256 char name
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");
706 BOOST_CHECK_THROW(dn
.appendRawLabel(label
), std::range_error
);
711 BOOST_CHECK_THROW(dn
.prependRawLabel(label
), std::range_error
);
716 BOOST_CHECK_THROW(dn
+= DNSName(label
+ "."), std::range_error
);
721 BOOST_AUTO_TEST_CASE(test_invalid_label_length
) { // Invalid label length in qname
723 string
name("\x02""ns\x07""example\x04""com\x00", 16);
725 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 0, true), std::range_error
);
728 BOOST_AUTO_TEST_CASE(test_compression
) { // Compression test
730 string
name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05", 21);
732 DNSName
dn(name
.c_str(), name
.size(), 15, true);
733 BOOST_CHECK_EQUAL(dn
.toString(), "www.example.com.");
736 BOOST_AUTO_TEST_CASE(test_compression_qtype_qclass
) { // Compression test with QClass and QType extraction
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);
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
);
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');
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);
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');
771 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 271, true, &qtype
, &qclass
), std::range_error
);
775 BOOST_AUTO_TEST_CASE(test_compression_single_bit_set
) { // first 2 bits as 10 or 01, not 11
779 string
name("\x03""com\x00""\x07""example\x80""\x00""\x03""www\x80""\x05", 21);
781 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 15, true), std::range_error
);
786 string
name("\x03""com\x00""\x07""example\x40""\x00""\x03""www\x40""\x05", 21);
788 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 15, true), std::range_error
);
793 BOOST_AUTO_TEST_CASE(test_pointer_pointer_root
) { // Pointer to pointer to root
795 string
name("\x00""\xc0""\x00""\x03""com\xc0""\x01",9);
797 DNSName
dn(name
.c_str(), name
.size(), 3, true);
798 BOOST_CHECK_EQUAL(dn
.toString(), "com.");
801 BOOST_AUTO_TEST_CASE(test_bad_compression_pointer
) { // Pointing beyond packet boundary
803 std::string
name("\x03""com\x00""\x07""example\xc0""\x11""xc0""\x00", 17);
805 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.length(), 5, true), std::range_error
);
808 BOOST_AUTO_TEST_CASE(test_compression_loop
) { // Compression loop (add one label)
810 std::string
name("\x03""www\xc0""\x00", 6);
812 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.length(), 0, true), std::range_error
);
815 BOOST_AUTO_TEST_CASE(test_compression_loop1
) { // Compression loop (pointer loop)
817 string
name("\xc0""\x00", 2);
819 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 0, true), std::range_error
);
822 BOOST_AUTO_TEST_CASE(test_compression_loop2
) { // Compression loop (deep recursion)
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);
830 BOOST_CHECK_NO_THROW(DNSName
dn(name
.c_str(), name
.size(), name
.size()-2, true));
833 name
.append( 1, ((i
>> 7) & 0xff) | 0xc0);
834 name
.append( 1, ((i
<< 1) & 0xff) | 0x01);
836 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), name
.size()-2, true), std::range_error
);
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);
843 DNSName
sname("powerdns.com");
844 sname
.prependRawLabel(string("ww\x00""w", 4));
845 BOOST_CHECK_EQUAL(sname
.wirelength(), 19);
847 sname
= DNSName("powerdns.com");
848 sname
.prependRawLabel(string("www\x00", 4));
849 BOOST_CHECK_EQUAL(sname
.wirelength(), 19);
853 BOOST_AUTO_TEST_SUITE_END()