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_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.");
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);
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
);
150 n
.appendRawLabel("powerdns.dnsmaster");
151 n
.appendRawLabel("powerdns");
152 n
.appendRawLabel("com");
154 BOOST_CHECK_EQUAL(n
.toString(), "powerdns\\.dnsmaster.powerdns.com.");
156 // BOOST_CHECK(DNSName().toString() != ".");
159 string
label("power");
160 label
.append(1, (char)0);
162 p
.appendRawLabel(label
);
163 p
.appendRawLabel("com");
165 BOOST_CHECK_EQUAL(p
.toString(), "power\\000dns.com.");
168 BOOST_AUTO_TEST_CASE(test_trim
) {
169 DNSName
w("www.powerdns.com.");
170 BOOST_CHECK_EQUAL(w
.countLabels(), 3);
172 BOOST_CHECK_EQUAL(w
.toString(), "powerdns.com.");
173 DNSName
w2("powerdns.com.");
177 BOOST_CHECK_EQUAL(root
.countLabels(), 0);
180 BOOST_AUTO_TEST_CASE(test_toolong
) {
182 BOOST_CHECK_THROW(DNSName
w("1234567890123456789012345678901234567890123456789012345678901234567890.com."), std::range_error
);
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
);
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));
192 BOOST_AUTO_TEST_CASE(test_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
));
204 BOOST_CHECK(empty
< root
);
206 BOOST_CHECK_THROW(empty
.isPartOf(root
), std::out_of_range
);
207 BOOST_CHECK_THROW(root
.isPartOf(empty
), std::out_of_range
);
210 BOOST_AUTO_TEST_CASE(test_specials
) {
213 BOOST_CHECK(root
.isRoot());
214 BOOST_CHECK(root
!= DNSName());
216 DNSName
wcard("*.powerdns.com");
217 BOOST_CHECK(wcard
.isWildcard());
219 DNSName
notwcard("www.powerdns.com");
220 BOOST_CHECK(!notwcard
.isWildcard());
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());
236 w
.prependRawLabel("net");
237 w
.prependRawLabel("root-servers");
238 w
.prependRawLabel("a");
239 BOOST_CHECK_EQUAL(w
.toString(), "a.root-servers.net.");
242 BOOST_AUTO_TEST_CASE(test_Append
) {
243 DNSName
dn("www."), powerdns("powerdns.com.");
244 DNSName tot
=dn
+powerdns
;
246 BOOST_CHECK_EQUAL(tot
.toString(), "www.powerdns.com.");
247 BOOST_CHECK(tot
== DNSName("www.powerdns.com."));
251 BOOST_CHECK(dn
== DNSName("www.powerdns.com."));
254 BOOST_AUTO_TEST_CASE(test_packetCompress
) {
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");
261 AAAARecordContent
aaaa("::1");
262 dpw
.startRecord(DNSName("www.dS9A.nl"), QType::AAAA
);
264 dpw
.startRecord(DNSName("www.ds9A.nl"), QType::AAAA
);
266 dpw
.startRecord(DNSName("www.dS9a.nl"), QType::AAAA
);
268 dpw
.startRecord(DNSName("www2.DS9a.nl"), QType::AAAA
);
270 dpw
.startRecord(DNSName("www2.dS9a.nl"), QType::AAAA
);
273 string
str((const char*)&packet
[0], (const char*)&packet
[0] + packet
.size());
276 while((pos
= str
.find("ds9a", pos
)) != string::npos
) {
280 BOOST_CHECK_EQUAL(count
, 1);
283 while((pos
= str
.find("powerdns", pos
)) != string::npos
) {
287 BOOST_CHECK_EQUAL(count
, 1);
291 BOOST_AUTO_TEST_CASE(test_packetCompressLong
) {
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
);
297 dpw
.startRecord(loopback
, QType::PTR
);
298 PTRRecordContent
prc(DNSName("localhost"));
301 DNSName
roundtrip((char*)&packet
[0], packet
.size(), 12, false);
302 BOOST_CHECK_EQUAL(loopback
,roundtrip
);
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
);
308 dpw2
.startRecord(DNSName("a.b.c.d.e")+longer
, QType::PTR
);
309 PTRRecordContent
prc2(DNSName("localhost"));
318 BOOST_AUTO_TEST_CASE(test_PacketParse
) {
319 vector
<unsigned char> packet
;
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()
332 buffer
[sizeof(dnsheader
)] = 15;
333 BOOST_CHECK_THROW(DNSName((char*)&packet
[0], packet
.size(), 12, false), std::range_error
);
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());
341 vector
<uint32_t> counts(1500);
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()]++;
350 double sum
= std::accumulate(std::begin(counts
), std::end(counts
), 0.0);
351 double m
= sum
/ counts
.size();
354 std::for_each (std::begin(counts
), std::end(counts
), [&](const double d
) {
355 accum
+= (d
- m
) * (d
- m
);
358 double stdev
= sqrt(accum
/ (counts
.size()-1));
359 BOOST_CHECK(stdev
< 10);
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);
374 for(; n
< 100000; ++n
)
375 s
.insert(DNSName(std::to_string(n
)+".test.nl"));
376 BOOST_CHECK_EQUAL(s
.size(), n
);
381 BOOST_AUTO_TEST_CASE(test_QuestionHash
) {
382 vector
<unsigned char> packet
;
384 DNSPacketWriter
dpw1(packet
, DNSName("www.ds9a.nl."), QType::AAAA
);
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
);
391 vector
<uint32_t> counts(1500);
393 for(unsigned int n
=0; n
< 100000; ++n
) {
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()]++;
399 double sum
= std::accumulate(std::begin(counts
), std::end(counts
), 0.0);
400 double m
= sum
/ counts
.size();
403 std::for_each (std::begin(counts
), std::end(counts
), [&](const double d
) {
404 accum
+= (d
- m
) * (d
- m
);
407 double stdev
= sqrt(accum
/ (counts
.size()-1));
408 BOOST_CHECK(stdev
< 10);
412 BOOST_AUTO_TEST_CASE(test_packetParse
) {
413 vector
<unsigned char> packet
;
415 DNSPacketWriter
dpw(packet
, DNSName("www.ds9a.nl."), QType::AAAA
);
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);
423 dpw
.startRecord(DNSName("ds9a.nl."), DNSRecordContent::TypeToNumber("NS"));
424 NSRecordContent
nrc("ns1.powerdns.com");
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
434 0001 0001 4 bytes of qtype and class
435 0000 0000 4 bytes of TTL
436 0000 2 bytes of content length
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);
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.");
447 DNSName
dn4((char*)&packet
[0], packet
.size(), 12+13+4, false); // compressed, should fail
453 BOOST_AUTO_TEST_CASE(test_escaping
) {
457 for(int i
= 0; i
< 250; ++i
) {
459 n
.appendRawLabel(label
);
462 label
.append(1,(char)i
);
465 n
.appendRawLabel(label
);
467 DNSName
n2(n
.toString());
471 BOOST_AUTO_TEST_CASE(test_suffixmatch
) {
473 DNSName
ezdns("ezdns.it.");
474 smn
.add(ezdns
.getRawLabels());
476 smn
.add(DNSName("org.").getRawLabels());
478 DNSName
wwwpowerdnscom("www.powerdns.com.");
479 DNSName
wwwezdnsit("www.ezdns.it.");
480 BOOST_CHECK(smn
.check(wwwezdnsit
));
481 BOOST_CHECK(!smn
.check(wwwpowerdnscom
));
483 BOOST_CHECK(smn
.check(DNSName("www.powerdns.org.")));
484 BOOST_CHECK(smn
.check(DNSName("www.powerdns.oRG.")));
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.")));
492 BOOST_CHECK(!smn
.check(DNSName("www.news.gov.uk.")));
494 smn
.add(g_rootdnsname
); // block the root
495 BOOST_CHECK(smn
.check(DNSName("a.root-servers.net.")));
497 DNSName
examplenet("example.net.");
501 BOOST_CHECK(smn
.check(examplenet
));
502 BOOST_CHECK(smn
.check(net
));
505 BOOST_AUTO_TEST_CASE(test_suffixmatch_tree
) {
506 SuffixMatchTree
<DNSName
> smt
;
507 DNSName
ezdns("ezdns.it.");
508 smt
.add(ezdns
, ezdns
);
510 smt
.add(DNSName("org.").getRawLabels(), DNSName("org."));
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);
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."));
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);
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
);
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
);
546 DNSName
examplenet("example.net.");
548 smt
.add(examplenet
, examplenet
);
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
);
557 BOOST_AUTO_TEST_CASE(test_concat
) {
558 DNSName
first("www."), second("powerdns.com.");
559 BOOST_CHECK_EQUAL((first
+second
).toString(), "www.powerdns.com.");
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."));
569 BOOST_AUTO_TEST_CASE(test_compare_empty
) {
572 BOOST_CHECK(!a
.canonCompare(b
));
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.");
588 BOOST_AUTO_TEST_CASE(test_compare_canonical
) {
589 DNSName
lower("bert.com."), higher("alpha.nl.");
590 BOOST_CHECK(lower
.canonCompare(higher
));
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")));
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
));
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
));
607 sort(vec
.begin(), vec
.end(), CanonDNSNameCompare());
608 // for(const auto& v : vec)
609 // cerr<<'"'<<v<<'"'<<endl;
611 vector
<DNSName
> right
;
612 for(const auto& b
: {"bert.com.", "Aleph1.powerdns.com.",
613 "test.powerdns.com.",
614 "ZOMG.powerdns.com.",
620 right
.push_back(DNSName(b
));
623 BOOST_CHECK(vec
==right
);
627 BOOST_AUTO_TEST_CASE(test_empty_label
) { // empty label
631 BOOST_CHECK_THROW(dn
.appendRawLabel(""), std::range_error
);
636 BOOST_CHECK_THROW(dn
.prependRawLabel(""), std::range_error
);
640 BOOST_AUTO_TEST_CASE(test_label_length_max
) { // 63 char label
642 string
label("123456789012345678901234567890123456789012345678901234567890123");
646 dn
.appendRawLabel(label
);
647 BOOST_CHECK_EQUAL(dn
.toString(), "www." + label
+ ".");
652 dn
.prependRawLabel(label
);
653 BOOST_CHECK_EQUAL(dn
.toString(), label
+ ".www.");
657 BOOST_AUTO_TEST_CASE(test_label_length_too_long
) { // 64 char label
659 string
label("1234567890123456789012345678901234567890123456789012345678901234");
663 BOOST_CHECK_THROW(dn
.appendRawLabel(label
), std::range_error
);
668 BOOST_CHECK_THROW(dn
.prependRawLabel(label
), std::range_error
);
672 BOOST_AUTO_TEST_CASE(test_name_length_max
) { // 255 char name
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.");
681 dn
.appendRawLabel(label
);
682 BOOST_CHECK_EQUAL(dn
.toString().size(), 254);
687 dn
.prependRawLabel(label
);
688 BOOST_CHECK_EQUAL(dn
.toString().size(), 254);
694 dn
+= DNSName(label
+ ".");
695 BOOST_CHECK_EQUAL(dn
.toString().size(), 254);
699 BOOST_AUTO_TEST_CASE(test_name_length_too_long
) { // 256 char name
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");
708 BOOST_CHECK_THROW(dn
.appendRawLabel(label
), std::range_error
);
713 BOOST_CHECK_THROW(dn
.prependRawLabel(label
), std::range_error
);
718 BOOST_CHECK_THROW(dn
+= DNSName(label
+ "."), std::range_error
);
723 BOOST_AUTO_TEST_CASE(test_invalid_label_length
) { // Invalid label length in qname
725 string
name("\x02""ns\x07""example\x04""com\x00", 16);
727 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 0, true), std::range_error
);
730 BOOST_AUTO_TEST_CASE(test_compression
) { // Compression test
732 string
name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05", 21);
734 DNSName
dn(name
.c_str(), name
.size(), 15, true);
735 BOOST_CHECK_EQUAL(dn
.toString(), "www.example.com.");
738 BOOST_AUTO_TEST_CASE(test_compression_qtype_qclass
) { // Compression test with QClass and QType extraction
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);
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
);
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');
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);
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');
773 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 271, true, &qtype
, &qclass
), std::range_error
);
777 BOOST_AUTO_TEST_CASE(test_compression_single_bit_set
) { // first 2 bits as 10 or 01, not 11
781 string
name("\x03""com\x00""\x07""example\x80""\x00""\x03""www\x80""\x05", 21);
783 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 15, true), std::range_error
);
788 string
name("\x03""com\x00""\x07""example\x40""\x00""\x03""www\x40""\x05", 21);
790 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 15, true), std::range_error
);
795 BOOST_AUTO_TEST_CASE(test_pointer_pointer_root
) { // Pointer to pointer to root
797 string
name("\x00""\xc0""\x00""\x03""com\xc0""\x01",9);
799 DNSName
dn(name
.c_str(), name
.size(), 3, true);
800 BOOST_CHECK_EQUAL(dn
.toString(), "com.");
803 BOOST_AUTO_TEST_CASE(test_bad_compression_pointer
) { // Pointing beyond packet boundary
805 std::string
name("\x03""com\x00""\x07""example\xc0""\x11""xc0""\x00", 17);
807 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.length(), 5, true), std::range_error
);
810 BOOST_AUTO_TEST_CASE(test_compression_loop
) { // Compression loop (add one label)
812 std::string
name("\x03""www\xc0""\x00", 6);
814 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.length(), 0, true), std::range_error
);
817 BOOST_AUTO_TEST_CASE(test_compression_loop1
) { // Compression loop (pointer loop)
819 string
name("\xc0""\x00", 2);
821 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), 0, true), std::range_error
);
824 BOOST_AUTO_TEST_CASE(test_compression_loop2
) { // Compression loop (deep recursion)
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);
832 BOOST_CHECK_NO_THROW(DNSName
dn(name
.c_str(), name
.size(), name
.size()-2, true));
835 name
.append( 1, ((i
>> 7) & 0xff) | 0xc0);
836 name
.append( 1, ((i
<< 1) & 0xff) | 0x01);
838 BOOST_CHECK_THROW(DNSName
dn(name
.c_str(), name
.size(), name
.size()-2, true), std::range_error
);
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);
845 DNSName
sname("powerdns.com");
846 sname
.prependRawLabel(string("ww\x00""w", 4));
847 BOOST_CHECK_EQUAL(sname
.wirelength(), 19);
849 sname
= DNSName("powerdns.com");
850 sname
.prependRawLabel(string("www\x00", 4));
851 BOOST_CHECK_EQUAL(sname
.wirelength(), 19);
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
);
863 BOOST_AUTO_TEST_CASE(test_getlastlabel
) {
864 DNSName
name("www.powerdns.com");
865 DNSName ans
= name
.getLastLabel();
867 // Check the const-ness
868 BOOST_CHECK_EQUAL(name
, DNSName("www.powerdns.com"));
870 // Check if the last label is indeed returned
871 BOOST_CHECK_EQUAL(ans
, DNSName("com"));
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");
878 BOOST_CHECK_EQUAL(name1
.getCommonLabels(name1
), name1
);
879 BOOST_CHECK_EQUAL(name2
.getCommonLabels(name2
), name2
);
881 BOOST_CHECK_EQUAL(name1
.getCommonLabels(name2
), DNSName("powerdns.com"));
882 BOOST_CHECK_EQUAL(name2
.getCommonLabels(name1
), DNSName("powerdns.com"));
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());
890 const DNSName
name4("WWw.PowErDnS.org");
891 BOOST_CHECK_EQUAL(name3
.getCommonLabels(name4
), name3
);
892 BOOST_CHECK_EQUAL(name4
.getCommonLabels(name3
), name4
);
895 BOOST_AUTO_TEST_SUITE_END()