• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 12595591960

03 Jan 2025 09:27AM UTC coverage: 62.774% (+2.5%) from 60.245%
12595591960

Pull #15008

github

web-flow
Merge c2a2749d3 into 788f396a7
Pull Request #15008: Do not follow CNAME records for ANY or CNAME queries

30393 of 78644 branches covered (38.65%)

Branch coverage included in aggregate %.

105822 of 138350 relevant lines covered (76.49%)

4613078.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.49
/pdns/test-dnsname_cc.cc
1
#ifndef BOOST_TEST_DYN_LINK
2
#define BOOST_TEST_DYN_LINK
3
#endif
4

5
#define BOOST_TEST_NO_MAIN
6

7
#include <boost/test/unit_test.hpp>
8

9
#include <cmath>
10
#include <numeric>
11
#include <unordered_set>
12

13
#include "dnsname.hh"
14
#include "misc.hh"
15
#include "dnswriter.hh"
16
#include "dnsrecords.hh"
17

18
using namespace boost;
19
using std::string;
20

21
BOOST_AUTO_TEST_SUITE(test_dnsname_cc)
22

23
BOOST_AUTO_TEST_CASE(test_basic) {
3✔
24
  DNSName aroot("a.root-servers.net"), broot("b.root-servers.net");
3✔
25
  BOOST_CHECK(aroot < broot);
3✔
26
  BOOST_CHECK(!(broot < aroot));
3✔
27
  BOOST_CHECK(aroot.canonCompare(broot));
3✔
28
  BOOST_CHECK(!broot.canonCompare(aroot));
3✔
29

30

31
  string before("www.ds9a.nl.");
3✔
32
  DNSName b(before);
3✔
33
  BOOST_CHECK_EQUAL(b.getRawLabels().size(), 3U);
3✔
34
  string after(b.toString());
3✔
35
  BOOST_CHECK_EQUAL(before, after);
3✔
36

37
  DNSName jpmens("ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.test.xxx.yyy-yyyy.zzzzzzzzz-test.");
3✔
38

39
  BOOST_CHECK_EQUAL(jpmens.toString(), "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.test.xxx.yyy-yyyy.zzzzzzzzz-test.");
3✔
40

41
  DNSName wwwds9anl("www.ds9a.nl.");
3✔
42
  DNSName wwwds9anl1("www.ds9a\002nl.");
3✔
43
  DNSName nl("nl.");
3✔
44
  BOOST_CHECK(wwwds9anl.isPartOf(nl));
3✔
45
  BOOST_CHECK(!wwwds9anl1.isPartOf(nl));
3✔
46
  BOOST_CHECK(wwwds9anl.isPartOf(wwwds9anl));
3✔
47

48
  BOOST_CHECK(!nl.isPartOf(wwwds9anl));
3✔
49

50
  BOOST_CHECK(wwwds9anl == wwwds9anl);
3✔
51

52
  BOOST_CHECK(DNSName("wWw.ds9A.Nl.") == DNSName("www.ds9a.nl."));
3✔
53
  BOOST_CHECK(DNSName("www.ds9a.nl.") == DNSName("www.ds9a.nl."));
3✔
54

55
  BOOST_CHECK(DNSName("www.ds9a.nl.").toString() == "www.ds9a.nl.");
3✔
56

57

58
  { // Check root vs empty
3✔
59
    DNSName name("."); // root
3✔
60
    DNSName parent; // empty
3✔
61
    BOOST_CHECK(name != parent);
3✔
62
  }
3✔
63

64
  { // Check name part of root
3✔
65
    DNSName name("a.");
3✔
66
    DNSName parent(".");
3✔
67
    BOOST_CHECK(name.isPartOf(parent));
3✔
68
  }
3✔
69

70
  { // Label boundary
3✔
71
    DNSName name("a\002bb.");
3✔
72
    DNSName parent("bb.");
3✔
73
    BOOST_CHECK(!name.isPartOf(parent));
3✔
74
  }
3✔
75

76
  { // Multi label parent
3✔
77
    DNSName name("a.bb.ccc.dddd.");
3✔
78
    DNSName parent("ccc.dddd.");
3✔
79
    BOOST_CHECK(name.isPartOf(parent));
3✔
80
  }
3✔
81

82
  { // Last char diff
3✔
83
    DNSName name("a.bb.ccc.dddd.");
3✔
84
    DNSName parent("ccc.dddx.");
3✔
85
    BOOST_CHECK(!name.isPartOf(parent));
3✔
86
  }
3✔
87

88
  { // Equal length identical
3✔
89
    DNSName name("aaaa.bbb.cc.d.");
3✔
90
    DNSName parent("aaaa.bbb.cc.d.");
3✔
91
    BOOST_CHECK(name.isPartOf(parent));
3✔
92
  }
3✔
93

94
  { // Equal length first char diff
3✔
95
    DNSName name("xaaa.bbb.cc.d.");
3✔
96
    DNSName parent("aaaa.bbb.cc.d.");
3✔
97
    BOOST_CHECK(!name.isPartOf(parent));
3✔
98
  }
3✔
99

100
  { // Make relative
3✔
101
    DNSName name("aaaa.bbb.cc.d.");
3✔
102
    DNSName parent("cc.d.");
3✔
103
    BOOST_CHECK_EQUAL( name.makeRelative(parent), DNSName("aaaa.bbb."));
3✔
104
  }
3✔
105

106
  { // Labelreverse
3✔
107
    DNSName name("aaaa.bbb.cc.d.");
3✔
108
    BOOST_CHECK( name.labelReverse() == DNSName("d.cc.bbb.aaaa."));
3✔
109
  }
3✔
110

111
  { // empty() empty
3✔
112
    DNSName name;
3✔
113
    BOOST_CHECK(name.empty());
3✔
114
  }
3✔
115

116
  { // empty() root
3✔
117
    DNSName name(".");
3✔
118
    BOOST_CHECK(!name.empty());
3✔
119

120
    DNSName rootnodot("");
3✔
121
    BOOST_CHECK_EQUAL(name, rootnodot);
3✔
122

123
    string empty;
3✔
124
    DNSName rootnodot2(empty);
3✔
125
    BOOST_CHECK_EQUAL(rootnodot2, name);
3✔
126
  }
3✔
127

128
  DNSName left("ds9a.nl.");
3✔
129
  left.prependRawLabel("www");
3✔
130
  BOOST_CHECK( left == DNSName("WwW.Ds9A.Nl."));
3✔
131

132
  left.appendRawLabel("com");
3✔
133

134
  BOOST_CHECK( left == DNSName("WwW.Ds9A.Nl.com."));
3✔
135

136
  DNSName unset;
3✔
137

138
  unset.appendRawLabel("www");
3✔
139
  unset.appendRawLabel("powerdns.com");
3✔
140
  unset.appendRawLabel("com");
3✔
141

142
  BOOST_CHECK_EQUAL(unset.toString(), "www.powerdns\\.com.com.");
3✔
143

144
  DNSName rfc4343_2_1("~!.example.");
3✔
145
  DNSName rfc4343_2_2(R"(Donald\032E\.\032Eastlake\0323rd.example.)");
3✔
146
  DNSName example("example.");
3✔
147
  BOOST_CHECK(rfc4343_2_1.isPartOf(example));
3✔
148
  BOOST_CHECK(rfc4343_2_2.isPartOf(example));
3✔
149
  BOOST_CHECK_EQUAL(rfc4343_2_1.toString(), "~!.example.");
3✔
150

151
  auto labels=rfc4343_2_2.getRawLabels();
3✔
152
  BOOST_CHECK_EQUAL(*labels.begin(), "Donald E. Eastlake 3rd");
3✔
153
  BOOST_CHECK_EQUAL(*labels.rbegin(), "example");
3✔
154
  BOOST_CHECK_EQUAL(labels.size(), 2U);
3✔
155

156
  DNSName build;
3✔
157
  build.appendRawLabel("Donald E. Eastlake 3rd");
3✔
158
  build.appendRawLabel("example");
3✔
159
  BOOST_CHECK_EQUAL(build.toString(), R"(Donald\032E\.\032Eastlake\0323rd.example.)");
3✔
160
  BOOST_CHECK_THROW(DNSName broken("bert..hubert."), std::runtime_error);
3✔
161

162
  DNSName n;
3✔
163
  n.appendRawLabel("powerdns.dnsmaster");
3✔
164
  n.appendRawLabel("powerdns");
3✔
165
  n.appendRawLabel("com");
3✔
166

167
  BOOST_CHECK_EQUAL(n.toString(), "powerdns\\.dnsmaster.powerdns.com.");
3✔
168

169
  //  BOOST_CHECK(DNSName().toString() != ".");
170

171
  DNSName p;
3✔
172
  string label("power");
3✔
173
  label.append(1, (char)0);
3✔
174
  label.append("dns");
3✔
175
  p.appendRawLabel(label);
3✔
176
  p.appendRawLabel("com");
3✔
177

178
  BOOST_CHECK_EQUAL(p.toString(), "power\\000dns.com.");
3✔
179
}
3✔
180

181
BOOST_AUTO_TEST_CASE(test_trim) {
3✔
182
  DNSName w("www.powerdns.com.");
3✔
183
  BOOST_CHECK_EQUAL(w.countLabels(), 3U);
3✔
184
  w.trimToLabels(2);
3✔
185
  BOOST_CHECK_EQUAL(w.toString(), "powerdns.com.");
3✔
186
  DNSName w2("powerdns.com.");
3✔
187
  BOOST_CHECK(w==w2);
3✔
188

189
  DNSName root(".");
3✔
190
  BOOST_CHECK_EQUAL(root.countLabels(), 0U);
3✔
191
}
3✔
192

193
BOOST_AUTO_TEST_CASE(test_toolong) {
3✔
194

195
  BOOST_CHECK_THROW(DNSName w("1234567890123456789012345678901234567890123456789012345678901234567890.com."), std::range_error);
3✔
196

197
  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);
3✔
198
}
3✔
199

200
BOOST_AUTO_TEST_CASE(test_dnsstrings) {
3✔
201
  DNSName w("www.powerdns.com.");
3✔
202
  BOOST_CHECK_EQUAL(w.toDNSString(), string("\003www\010powerdns\003com\000", 18));
3✔
203
}
3✔
204

205
BOOST_AUTO_TEST_CASE(test_empty) {
3✔
206
  DNSName empty;
3✔
207
  BOOST_CHECK_THROW(empty.toString(), std::out_of_range);
3✔
208
  BOOST_CHECK_THROW(empty.toStringNoDot(), std::out_of_range);
3✔
209
  BOOST_CHECK_THROW(empty.toDNSString(), std::out_of_range);
3✔
210
  BOOST_CHECK(empty.empty());
3✔
211
  BOOST_CHECK(!empty.isRoot());
3✔
212
  BOOST_CHECK(!empty.isWildcard());
3✔
213
  BOOST_CHECK_EQUAL(empty, empty);
3✔
214
  BOOST_CHECK(!(empty < empty));
3✔
215

216
  DNSName root(".");
3✔
217
  BOOST_CHECK(empty < root);
3✔
218

219
  BOOST_CHECK_THROW(empty.isPartOf(root), std::out_of_range);
3✔
220
  BOOST_CHECK_THROW(root.isPartOf(empty), std::out_of_range);
3✔
221
}
3✔
222

223
BOOST_AUTO_TEST_CASE(test_specials) {
3✔
224
  DNSName root(".");
3✔
225

226
  BOOST_CHECK(root.isRoot());
3✔
227
  BOOST_CHECK(root != DNSName());
3✔
228

229
  DNSName wcard("*.powerdns.com");
3✔
230
  BOOST_CHECK(wcard.isWildcard());
3✔
231

232
  DNSName notwcard("www.powerdns.com");
3✔
233
  BOOST_CHECK(!notwcard.isWildcard());
3✔
234
}
3✔
235

236

237
BOOST_AUTO_TEST_CASE(test_chopping) {
3✔
238
  DNSName w("www.powerdns.com.");
3✔
239
  BOOST_CHECK_EQUAL(w.toString(), "www.powerdns.com.");
3✔
240
  BOOST_CHECK(w.chopOff());
3✔
241
  BOOST_CHECK_EQUAL(w.toString(), "powerdns.com.");
3✔
242
  BOOST_CHECK(w.chopOff());
3✔
243
  BOOST_CHECK_EQUAL(w.toString(), "com.");
3✔
244
  BOOST_CHECK(w.chopOff());
3✔
245
  BOOST_CHECK_EQUAL(w.toString(), ".");
3✔
246
  BOOST_CHECK(!w.chopOff());
3✔
247
  BOOST_CHECK(!w.chopOff());
3✔
248

249
  w.prependRawLabel("net");
3✔
250
  w.prependRawLabel("root-servers");
3✔
251
  w.prependRawLabel("a");
3✔
252
  BOOST_CHECK_EQUAL(w.toString(), "a.root-servers.net.");
3✔
253
}
3✔
254

255
BOOST_AUTO_TEST_CASE(test_Append) {
3✔
256
  DNSName dn("www."), powerdns("powerdns.com.");
3✔
257
  DNSName tot=dn+powerdns;
3✔
258

259
  BOOST_CHECK_EQUAL(tot.toString(), "www.powerdns.com.");
3✔
260
  BOOST_CHECK(tot == DNSName("www.powerdns.com."));
3✔
261

262
  dn+=powerdns;
3✔
263

264
  BOOST_CHECK(dn == DNSName("www.powerdns.com."));
3✔
265
}
3✔
266

267
BOOST_AUTO_TEST_CASE(test_packetCompress) {
3✔
268
  vector<unsigned char> packet;
3✔
269
  DNSPacketWriter dpw(packet, DNSName("www.ds9a.nl."), QType::AAAA);
3✔
270
  dpw.startRecord(DNSName("ds9a.nl"), QType::SOA);
3✔
271
  SOARecordContent src("ns1.powerdns.nl admin.powerdns.nl 1 2 3 4 5");
3✔
272
  src.toPacket(dpw);
3✔
273
  AAAARecordContent aaaa("::1");
3✔
274
  dpw.startRecord(DNSName("www.dS9A.nl"), QType::AAAA);
3✔
275
  aaaa.toPacket(dpw);
3✔
276
  dpw.startRecord(DNSName("www.ds9A.nl"), QType::AAAA);
3✔
277
  aaaa.toPacket(dpw);
3✔
278
  dpw.startRecord(DNSName("www.dS9a.nl"), QType::AAAA);
3✔
279
  aaaa.toPacket(dpw);
3✔
280
  dpw.startRecord(DNSName("www2.DS9a.nl"), QType::AAAA);
3✔
281
  aaaa.toPacket(dpw);
3✔
282
  dpw.startRecord(DNSName("www2.dS9a.nl"), QType::AAAA);
3✔
283
  aaaa.toPacket(dpw);
3✔
284
  dpw.commit();
3✔
285
  string str((const char*)&packet[0], (const char*)&packet[0] + packet.size());
3✔
286
  size_t pos = 0;
3✔
287
  int count=0;
3✔
288
  while((pos = str.find("ds9a", pos)) != string::npos) {
6✔
289
    ++pos;
3✔
290
    ++count;
3✔
291
  }
3✔
292
  BOOST_CHECK_EQUAL(count, 1);
3✔
293
  pos = 0;
3✔
294
  count=0;
3✔
295
  while((pos = str.find("powerdns", pos)) != string::npos) {
6✔
296
    ++pos;
3✔
297
    ++count;
3✔
298
  }
3✔
299
  BOOST_CHECK_EQUAL(count, 1);
3✔
300

301
}
3✔
302

303
BOOST_AUTO_TEST_CASE(test_packetCompressLong) {
3✔
304
  vector<unsigned char> packet;
3✔
305
  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");
3✔
306
  DNSPacketWriter dpw(packet, loopback, QType::PTR);
3✔
307

308
  dpw.startRecord(loopback, QType::PTR);
3✔
309
  PTRRecordContent prc(DNSName("localhost"));
3✔
310
  prc.toPacket(dpw);
3✔
311
  dpw.commit();
3✔
312
  DNSName roundtrip((char*)&packet[0], packet.size(), 12, false);
3✔
313
  BOOST_CHECK_EQUAL(loopback,roundtrip);
3✔
314

315
  packet.clear();
3✔
316
  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");
3✔
317
  DNSPacketWriter dpw2(packet, longer, QType::PTR);
3✔
318

319
  dpw2.startRecord(DNSName("a.b.c.d.e")+longer, QType::PTR);
3✔
320
  PTRRecordContent prc2(DNSName("localhost"));
3✔
321
  prc2.toPacket(dpw2);
3✔
322
  dpw2.commit();
3✔
323

324
}
3✔
325

326

327

328

329
BOOST_AUTO_TEST_CASE(test_PacketParse) {
3✔
330
  vector<unsigned char> packet;
3✔
331
  DNSName root(".");
3✔
332
  DNSPacketWriter dpw1(packet, g_rootdnsname, QType::AAAA);
3✔
333
  DNSName p((char*)&packet[0], packet.size(), 12, false);
3✔
334
  BOOST_CHECK_EQUAL(p, root);
3✔
335
  unsigned char* buffer=&packet[0];
3✔
336
  /* set invalid label len:
337
     - packet.size() == 17 (sizeof(dnsheader) + 1 + 2 + 2)
338
     - label len < packet.size() but
339
     - offset is 12, label len of 15 should be rejected
340
     because offset + 15 >= packet.size()
341
  */
342
  buffer[sizeof(dnsheader)] = 15;
3✔
343
  BOOST_CHECK_THROW(DNSName((char*)&packet[0], packet.size(), 12, false), std::range_error);
3✔
344
}
3✔
345

346

347
BOOST_AUTO_TEST_CASE(test_hash) {
3✔
348
  DNSName a("wwW.Ds9A.Nl"), b("www.ds9a.nl");
3✔
349
  BOOST_CHECK_EQUAL(a.hash(), b.hash());
3✔
350

351
  vector<uint32_t> counts(1500);
3✔
352

353
  for(unsigned int n=0; n < 100000; ++n) {
300,003✔
354
    DNSName dn(std::to_string(n)+"."+std::to_string(n*2)+"ds9a.nl");
300,000✔
355
    DNSName dn2(std::to_string(n)+"."+std::to_string(n*2)+"Ds9a.nL");
300,000✔
356
    BOOST_CHECK_EQUAL(dn.hash(), dn2.hash());
300,000✔
357
    counts[dn.hash() % counts.size()]++;
300,000✔
358
  }
300,000✔
359

360
  double sum = std::accumulate(std::begin(counts), std::end(counts), 0.0);
3✔
361
  double m =  sum / counts.size();
3✔
362

363
  double accum = 0.0;
3✔
364
  std::for_each (std::begin(counts), std::end(counts), [&](const double d) {
4,500✔
365
      accum += (d - m) * (d - m);
4,500✔
366
  });
4,500✔
367

368
  double stdev = sqrt(accum / (counts.size()-1));
3✔
369
  BOOST_CHECK(stdev < 10);
3✔
370
}
3✔
371

372
BOOST_AUTO_TEST_CASE(test_hashContainer) {
3✔
373
  std::unordered_set<DNSName> s;
3✔
374
  s.insert(DNSName("www.powerdns.com"));
3✔
375
  BOOST_CHECK(s.count(DNSName("WwW.PoWerDNS.CoM")));
3✔
376
  BOOST_CHECK_EQUAL(s.size(), 1U);
3✔
377
  s.insert(DNSName("www.POWERDNS.com"));
3✔
378
  BOOST_CHECK_EQUAL(s.size(), 1U);
3✔
379
  s.insert(DNSName("www2.POWERDNS.com"));
3✔
380
  BOOST_CHECK_EQUAL(s.size(), 2U);
3✔
381

382
  s.clear();
3✔
383
  unsigned int n=0;
3✔
384
  for(; n < 100000; ++n)
300,003✔
385
    s.insert(DNSName(std::to_string(n)+".test.nl"));
300,000✔
386
  BOOST_CHECK_EQUAL(s.size(), n);
3✔
387

388
}
3✔
389

390

391
BOOST_AUTO_TEST_CASE(test_QuestionHash) {
3✔
392
  vector<unsigned char> packet(sizeof(dnsheader));
3✔
393

394
  bool ok;
3✔
395
  // A return init case
396
  BOOST_CHECK_EQUAL(hashQuestion(packet.data(), sizeof(dnsheader), 0xffU, ok), 0xffU);
3✔
397
  BOOST_CHECK(!ok);
3✔
398

399
  // We subtract 4 from the packet sizes since DNSPacketWriter adds a type and a class
400
  // We expect the hash of the root to be unequal to the burtle init value
401
  DNSPacketWriter dpw0(packet, DNSName("."), QType::AAAA);
3✔
402
  BOOST_CHECK(hashQuestion(packet.data(), packet.size() - 4, 0xffU, ok) != 0xffU);
3✔
403
  BOOST_CHECK(ok);
3✔
404

405
  // A truncated buffer should return the init value
406
  DNSPacketWriter dpw1(packet, DNSName("."), QType::AAAA);
3✔
407
  BOOST_CHECK_EQUAL(hashQuestion(packet.data(), packet.size() - 5, 0xffU, ok), 0xffU);
3✔
408
  BOOST_CHECK(!ok);
3✔
409

410
  DNSPacketWriter dpw2(packet, DNSName("www.ds9a.nl."), QType::AAAA);
3✔
411
  // Let's make an invalid name by overwriting the length of the second label just outside the buffer
412
  packet[sizeof(dnsheader) + 4] = 8;
3✔
413
  BOOST_CHECK_EQUAL(hashQuestion(packet.data(), packet.size() - 4, 0xffU, ok), 0xffU);
3✔
414
  BOOST_CHECK(!ok);
3✔
415

416
  DNSPacketWriter dpw3(packet, DNSName("www.ds9a.nl."), QType::AAAA);
3✔
417
  // Let's make an invalid name by overwriting the length of the second label way outside the buffer
418
  packet[sizeof(dnsheader) + 4] = 0xff;
3✔
419
  BOOST_CHECK_EQUAL(hashQuestion(packet.data(), packet.size() - 4, 0xffU, ok), 0xffU);
3✔
420
  BOOST_CHECK(!ok);
3✔
421

422
  DNSPacketWriter dpw4(packet, DNSName("www.ds9a.nl."), QType::AAAA);
3✔
423
  auto hash1 = hashQuestion(&packet[0], packet.size() - 4, 0, ok);
3✔
424
  BOOST_CHECK(ok);
3✔
425
  DNSPacketWriter dpw5(packet, DNSName("wWw.Ds9A.nL."), QType::AAAA);
3✔
426
  auto hash2 = hashQuestion(&packet[0], packet.size() - 4, 0, ok);
3✔
427
  BOOST_CHECK_EQUAL(hash1, hash2);
3✔
428
  BOOST_CHECK(ok);
3✔
429

430
  vector<uint32_t> counts(1500);
3✔
431
  for(unsigned int n = 0; n < 100000; ++n) {
300,003✔
432
    packet.clear();
300,000✔
433
    DNSPacketWriter dpw(packet, DNSName(std::to_string(n) + "." + std::to_string(n*2) + "."), QType::AAAA);
300,000✔
434
    assert(ok);
300,000✔
435
    counts[hashQuestion(&packet[0], packet.size() - 4, 0, ok) % counts.size()]++;
×
436
  }
300,000✔
437

438
  double sum = std::accumulate(std::begin(counts), std::end(counts), 0.0);
3✔
439
  double m =  sum / counts.size();
3✔
440

441
  double accum = 0.0;
3✔
442
  std::for_each (std::begin(counts), std::end(counts), [&](const double d) {
4,500✔
443
      accum += (d - m) * (d - m);
4,500✔
444
  });
4,500✔
445

446
  double stdev = sqrt(accum / (counts.size()-1));
3✔
447
  BOOST_CHECK(stdev < 10);
3✔
448
}
3✔
449

450
BOOST_AUTO_TEST_CASE(test_packetParse) {
3✔
451
  vector<unsigned char> packet;
3✔
452
  DNSPacketWriter dpw(packet, DNSName("www.ds9a.nl."), QType::AAAA);
3✔
453

454
  uint16_t qtype, qclass;
3✔
455
  DNSName dn((char*)&packet[0], packet.size(), 12, false, &qtype, &qclass);
3✔
456
  BOOST_CHECK_EQUAL(dn.toString(), "www.ds9a.nl.");
3✔
457
  BOOST_CHECK(qtype == QType::AAAA);
3✔
458
  BOOST_CHECK_EQUAL(qclass, 1);
3✔
459

460
  dpw.startRecord(DNSName("ds9a.nl."), DNSRecordContent::TypeToNumber("NS"));
3✔
461
  NSRecordContent nrc("ns1.powerdns.com");
3✔
462
  nrc.toPacket(dpw);
3✔
463

464
  dpw.commit();
3✔
465

466
  /* packet now looks like this:
467
     012345678901 12 bytes of header
468
     3www4ds9a2nl0 13 bytes of name
469
     0001 0001      4 bytes of qtype and qclass
470
     answername     2 bytes
471
     0001 0001      4 bytes of qtype and class
472
     0000 0000      4 bytes of TTL
473
     0000           2 bytes of content length
474
     content name */
475

476
  DNSName dn2((char*)&packet[0], packet.size(), 12+13+4, true, &qtype, &qclass);
3✔
477
  BOOST_CHECK_EQUAL(dn2.toString(), "ds9a.nl.");
3✔
478
  BOOST_CHECK(qtype == QType::NS);
3✔
479
  BOOST_CHECK_EQUAL(qclass, 1);
3✔
480

481
  DNSName dn3((char*)&packet[0], packet.size(), 12+13+4+2 + 4 + 4 + 2, true);
3✔
482
  BOOST_CHECK_EQUAL(dn3.toString(), "ns1.powerdns.com.");
3✔
483
  try {
3✔
484
    DNSName dn4((char*)&packet[0], packet.size(), 12+13+4, false); // compressed, should fail
3✔
485
    BOOST_CHECK(0);
3✔
486
  }
3✔
487
  catch(...){}
3✔
488
}
3✔
489

490
BOOST_AUTO_TEST_CASE(test_escaping) {
3✔
491
  DNSName n;
3✔
492
  string label;
3✔
493

494
  for(int i = 0; i < 250; ++i) {
753✔
495
    if(!((i+1)%63)) {
750✔
496
      n.appendRawLabel(label);
9✔
497
      label.clear();
9✔
498
    }
9✔
499
    label.append(1,(char)i);
750✔
500
  }
750✔
501
  if(!label.empty())
3!
502
    n.appendRawLabel(label);
3✔
503

504
  DNSName n2(n.toString());
3✔
505
  BOOST_CHECK(n==n2);
3✔
506
}
3✔
507

508
BOOST_AUTO_TEST_CASE(test_suffixmatch) {
3✔
509
  SuffixMatchNode smn;
3✔
510
  DNSName ezdns("ezdns.it.");
3✔
511
  smn.add(ezdns.getRawLabels());
3✔
512

513
  smn.add(DNSName("org.").getRawLabels());
3✔
514

515
  DNSName wwwpowerdnscom("www.powerdns.com.");
3✔
516
  DNSName wwwezdnsit("www.ezdns.it.");
3✔
517
  BOOST_CHECK(smn.check(wwwezdnsit));
3✔
518
  BOOST_CHECK(!smn.check(wwwpowerdnscom));
3✔
519

520
  BOOST_CHECK(smn.check(DNSName("www.powerdns.org.")));
3✔
521
  BOOST_CHECK(smn.check(DNSName("www.powerdns.oRG.")));
3✔
522

523
  smn.add(DNSName("news.bbc.co.uk."));
3✔
524
  BOOST_CHECK(smn.check(DNSName("news.bbc.co.uk.")));
3✔
525
  BOOST_CHECK(smn.getBestMatch(DNSName("news.bbc.co.uk")) == DNSName("news.bbc.co.uk."));
3✔
526
  BOOST_CHECK(smn.check(DNSName("www.news.bbc.co.uk.")));
3✔
527
  BOOST_CHECK(smn.getBestMatch(DNSName("www.news.bbc.co.uk")) == DNSName("news.bbc.co.uk."));
3✔
528
  BOOST_CHECK(smn.check(DNSName("www.www.www.www.www.news.bbc.co.uk.")));
3✔
529
  BOOST_CHECK(!smn.check(DNSName("images.bbc.co.uk.")));
3✔
530
  BOOST_CHECK(smn.getBestMatch(DNSName("images.bbc.co.uk")) == std::nullopt);
3✔
531

532
  BOOST_CHECK(!smn.check(DNSName("www.news.gov.uk.")));
3✔
533
  BOOST_CHECK(smn.getBestMatch(DNSName("www.news.gov.uk")) == std::nullopt);
3✔
534

535
  smn.add(g_rootdnsname); // block the root
3✔
536
  BOOST_CHECK(smn.check(DNSName("a.root-servers.net.")));
3✔
537
  BOOST_CHECK(smn.getBestMatch(DNSName("a.root-servers.net.")) == g_rootdnsname);
3✔
538

539
  DNSName examplenet("example.net.");
3✔
540
  DNSName net("net.");
3✔
541
  smn.add(examplenet);
3✔
542
  smn.add(net);
3✔
543
  BOOST_CHECK(smn.check(examplenet));
3✔
544
  BOOST_CHECK(smn.check(net));
3✔
545

546
  // Remove .net and the root, and check that example.net still exists
547
  smn.remove(g_rootdnsname);
3✔
548
  smn.remove(net);
3✔
549
  BOOST_CHECK_EQUAL(smn.check(net), false);
3✔
550
  BOOST_CHECK(smn.check(examplenet));
3✔
551

552
  smn.add(DNSName("fr."));
3✔
553
  smn.add(DNSName("www.sub.domain.fr."));
3✔
554
  // should not match www.sub.domain.fr. but should still match fr.
555
  BOOST_CHECK(smn.check(DNSName("sub.domain.fr.")));
3✔
556
}
3✔
557

558
BOOST_AUTO_TEST_CASE(test_suffixmatch_tree) {
3✔
559
  SuffixMatchTree<DNSName> smt;
3✔
560
  DNSName ezdns("ezdns.it.");
3✔
561
  smt.add(ezdns, DNSName(ezdns));
3✔
562

563
  auto labels = DNSName("org.").getRawLabels();
3✔
564
  smt.add(labels, DNSName("org."));
3✔
565

566
  DNSName wwwpowerdnscom("www.powerdns.com.");
3✔
567
  DNSName wwwezdnsit("www.ezdns.it.");
3✔
568
  BOOST_REQUIRE(smt.lookup(wwwezdnsit));
3✔
569
  BOOST_CHECK_EQUAL(*smt.lookup(wwwezdnsit), ezdns);
3✔
570
  BOOST_CHECK(smt.lookup(wwwpowerdnscom) == nullptr);
3✔
571

572
  BOOST_REQUIRE(smt.lookup(DNSName("www.powerdns.org.")));
3✔
573
  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.powerdns.org.")), DNSName("org."));
3✔
574
  BOOST_REQUIRE(smt.lookup(DNSName("www.powerdns.oRG.")));
3✔
575
  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.powerdns.oRG.")), DNSName("org."));
3✔
576

577
  smt.add(DNSName("news.bbc.co.uk."), DNSName("news.bbc.co.uk."));
3✔
578
  BOOST_REQUIRE(smt.lookup(DNSName("news.bbc.co.uk.")));
3✔
579
  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
3✔
580
  BOOST_REQUIRE(smt.lookup(DNSName("www.news.bbc.co.uk.")));
3✔
581
  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
3✔
582
  BOOST_REQUIRE(smt.lookup(DNSName("www.www.www.www.www.news.bbc.co.uk.")));
3✔
583
  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.www.www.www.www.news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
3✔
584
  BOOST_CHECK(smt.lookup(DNSName("images.bbc.co.uk.")) == nullptr);
3✔
585
  BOOST_CHECK(smt.lookup(DNSName("www.news.gov.uk.")) == nullptr);
3✔
586

587
  smt.add(g_rootdnsname, DNSName(g_rootdnsname)); // block the root
3✔
588
  BOOST_REQUIRE(smt.lookup(DNSName("a.root-servers.net.")));
3✔
589
  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("a.root-servers.net.")), g_rootdnsname);
3✔
590

591
  DNSName apowerdnscom("a.powerdns.com.");
3✔
592
  DNSName bpowerdnscom("b.powerdns.com.");
3✔
593
  smt.add(apowerdnscom, DNSName(apowerdnscom));
3✔
594
  smt.add(bpowerdnscom, DNSName(bpowerdnscom));
3✔
595
  BOOST_REQUIRE(smt.lookup(apowerdnscom));
3✔
596
  BOOST_CHECK_EQUAL(*smt.lookup(apowerdnscom), apowerdnscom);
3✔
597
  BOOST_REQUIRE(smt.lookup(bpowerdnscom));
3✔
598
  BOOST_CHECK_EQUAL(*smt.lookup(bpowerdnscom), bpowerdnscom);
3✔
599

600
  DNSName examplenet("example.net.");
3✔
601
  DNSName net("net.");
3✔
602
  smt.add(examplenet, DNSName(examplenet));
3✔
603
  smt.add(net, DNSName(net));
3✔
604
  BOOST_REQUIRE(smt.lookup(examplenet));
3✔
605
  BOOST_CHECK_EQUAL(*smt.lookup(examplenet), examplenet);
3✔
606
  BOOST_REQUIRE(smt.lookup(net));
3✔
607
  BOOST_CHECK_EQUAL(*smt.lookup(net), net);
3✔
608

609
  // Remove .net and the root, and check that example.net remains
610
  smt.remove(g_rootdnsname);
3✔
611
  smt.remove(net);
3✔
612
  BOOST_CHECK(smt.lookup(net) == nullptr);
3✔
613
  BOOST_CHECK_EQUAL(*smt.lookup(examplenet), examplenet);
3✔
614

615
  smt = SuffixMatchTree<DNSName>();
3✔
616
  smt.add(examplenet, DNSName(examplenet));
3✔
617
  smt.add(net, DNSName(net));
3✔
618
  smt.add(DNSName("news.bbc.co.uk."), DNSName("news.bbc.co.uk."));
3✔
619
  smt.add(apowerdnscom, DNSName(apowerdnscom));
3✔
620

621
  smt.remove(DNSName("not-such-entry.news.bbc.co.uk."));
3✔
622
  BOOST_REQUIRE(smt.lookup(DNSName("news.bbc.co.uk.")));
3✔
623
  smt.remove(DNSName("news.bbc.co.uk."));
3✔
624
  BOOST_CHECK(smt.lookup(DNSName("news.bbc.co.uk.")) == nullptr);
3✔
625

626
  smt.remove(net);
3✔
627
  BOOST_REQUIRE(smt.lookup(examplenet));
3✔
628
  BOOST_CHECK_EQUAL(*smt.lookup(examplenet), examplenet);
3✔
629
  BOOST_CHECK(smt.lookup(net) == nullptr);
3✔
630

631
  smt.remove(examplenet);
3✔
632
  BOOST_CHECK(smt.lookup(net) == nullptr);
3✔
633
  BOOST_CHECK(smt.lookup(examplenet) == nullptr);
3✔
634

635
  smt.add(examplenet, DNSName(examplenet));
3✔
636
  smt.add(net, DNSName(net));
3✔
637
  BOOST_REQUIRE(smt.lookup(examplenet));
3✔
638
  BOOST_CHECK_EQUAL(*smt.lookup(examplenet), examplenet);
3✔
639
  BOOST_REQUIRE(smt.lookup(net));
3✔
640
  BOOST_CHECK_EQUAL(*smt.lookup(net), net);
3✔
641

642
  smt.remove(examplenet);
3✔
643
  BOOST_CHECK_EQUAL(*smt.lookup(examplenet), net);
3✔
644
  BOOST_CHECK_EQUAL(*smt.lookup(net), net);
3✔
645
  smt.remove(examplenet);
3✔
646
  BOOST_CHECK_EQUAL(*smt.lookup(examplenet), net);
3✔
647
  BOOST_CHECK_EQUAL(*smt.lookup(net), net);
3✔
648
  smt.remove(net);
3✔
649
  BOOST_CHECK(smt.lookup(net) == nullptr);
3✔
650
  BOOST_CHECK(smt.lookup(examplenet) == nullptr);
3✔
651
  smt.remove(net);
3✔
652

653
  size_t count = 0;
3✔
654
  smt.visit([apowerdnscom, &count](const SuffixMatchTree<DNSName>& smtarg) {
3✔
655
      count++;
3✔
656
      BOOST_CHECK_EQUAL(smtarg.d_value, apowerdnscom);
3✔
657
    });
3✔
658
  BOOST_CHECK_EQUAL(count, 1U);
3✔
659

660
  BOOST_CHECK_EQUAL(*smt.lookup(apowerdnscom), apowerdnscom);
3✔
661
  smt.remove(apowerdnscom);
3✔
662
  BOOST_CHECK(smt.lookup(apowerdnscom) == nullptr);
3✔
663

664
  count = 0;
3✔
665
  smt.visit([&count](const SuffixMatchTree<DNSName>&) {
3✔
666
      count++;
×
667
    });
×
668
  BOOST_CHECK_EQUAL(count, 0U);
3✔
669
}
3✔
670

671

672
BOOST_AUTO_TEST_CASE(test_concat) {
3✔
673
  DNSName first("www."), second("powerdns.com.");
3✔
674
  BOOST_CHECK_EQUAL((first+second).toString(), "www.powerdns.com.");
3✔
675
}
3✔
676

677
BOOST_AUTO_TEST_CASE(test_compare_naive) {
3✔
678
  BOOST_CHECK(DNSName("abc.com.") < DNSName("zdf.com."));
3✔
679
  BOOST_CHECK(DNSName("Abc.com.") < DNSName("zdf.com."));
3✔
680
  BOOST_CHECK(DNSName("Abc.com.") < DNSName("Zdf.com."));
3✔
681
  BOOST_CHECK(DNSName("abc.com.") < DNSName("Zdf.com."));
3✔
682
}
3✔
683

684
BOOST_AUTO_TEST_CASE(test_compare_empty) {
3✔
685
  DNSName a, b;
3✔
686
  BOOST_CHECK(!(a<b));
3✔
687
  BOOST_CHECK(!a.canonCompare(b));
3✔
688
}
3✔
689

690
BOOST_AUTO_TEST_CASE(test_casing) {
3✔
691
  DNSName a("WwW.PoWeRdNS.Com"), b("www.powerdns.com.");
3✔
692
  BOOST_CHECK_EQUAL(a,b);
3✔
693
  BOOST_CHECK_EQUAL(a.toString(), "WwW.PoWeRdNS.Com.");
3✔
694
  DNSName c=a.makeLowerCase();
3✔
695
  BOOST_CHECK_EQUAL(a,c);
3✔
696
  BOOST_CHECK_EQUAL(b,c);
3✔
697
  BOOST_CHECK_EQUAL(c.toString(), b.toString());
3✔
698
  BOOST_CHECK_EQUAL(c.toString(), "www.powerdns.com.");
3✔
699
}
3✔
700

701

702

703
BOOST_AUTO_TEST_CASE(test_compare_canonical) {
3✔
704
  DNSName lower("bert.com."), higher("alpha.nl.");
3✔
705
  BOOST_CHECK(lower.canonCompare(higher));
3✔
706

707
  BOOST_CHECK(DNSName("bert.com").canonCompare(DNSName("www.bert.com")));
3✔
708
  BOOST_CHECK(DNSName("BeRt.com").canonCompare(DNSName("WWW.berT.com")));
3✔
709
  BOOST_CHECK(!DNSName("www.BeRt.com").canonCompare(DNSName("WWW.berT.com")));
3✔
710

711
  CanonDNSNameCompare a;
3✔
712
  BOOST_CHECK(a(g_rootdnsname, DNSName("www.powerdns.com")));
3✔
713
  BOOST_CHECK(a(g_rootdnsname, DNSName("www.powerdns.net")));
3✔
714
  BOOST_CHECK(!a(DNSName("www.powerdns.net"), g_rootdnsname));
3✔
715

716
  vector<DNSName> vec;
3✔
717
  for(const char* b : {"bert.com.", "alpha.nl.", "articles.xxx.",
3✔
718
        "Aleph1.powerdns.com.", "ZOMG.powerdns.com.", "aaa.XXX.", "yyy.XXX.",
3✔
719
        "test.powerdns.com.", "\\128.com"}) {
27✔
720
    vec.push_back(DNSName(b));
27✔
721
  }
27✔
722
  sort(vec.begin(), vec.end(), CanonDNSNameCompare());
3✔
723
  //  for(const auto& v : vec)
724
  //    cerr<<'"'<<v<<'"'<<endl;
725

726
  vector<DNSName> right;
3✔
727
  for(const auto& b: {"bert.com.",  "Aleph1.powerdns.com.",
3✔
728
        "test.powerdns.com.",
3✔
729
        "ZOMG.powerdns.com.",
3✔
730
        "\\128.com.",
3✔
731
        "alpha.nl.",
3✔
732
        "aaa.XXX.",
3✔
733
        "articles.xxx.",
3✔
734
        "yyy.XXX."})
3✔
735
    right.push_back(DNSName(b));
27✔
736

737

738
  BOOST_CHECK(vec==right);
3✔
739
}
3✔
740

741

742
BOOST_AUTO_TEST_CASE(test_empty_label) { // empty label
3✔
743

744
  { // append
3✔
745
    DNSName dn("www.");
3✔
746
    BOOST_CHECK_THROW(dn.appendRawLabel(""), std::range_error);
3✔
747
  }
3✔
748

749
  { // prepend
3✔
750
    DNSName dn("www.");
3✔
751
    BOOST_CHECK_THROW(dn.prependRawLabel(""), std::range_error);
3✔
752
  }
3✔
753
}
3✔
754

755
BOOST_AUTO_TEST_CASE(test_label_length_max) { // 63 char label
3✔
756

757
  string label("123456789012345678901234567890123456789012345678901234567890123");
3✔
758

759
  { // append
3✔
760
    DNSName dn("www.");
3✔
761
    dn.appendRawLabel(label);
3✔
762
    BOOST_CHECK_EQUAL(dn.toString(), "www." + label + ".");
3✔
763
  }
3✔
764

765
  { // prepend
3✔
766
    DNSName dn("www.");
3✔
767
    dn.prependRawLabel(label);
3✔
768
    BOOST_CHECK_EQUAL(dn.toString(), label + ".www.");
3✔
769
  }
3✔
770
}
3✔
771

772
BOOST_AUTO_TEST_CASE(test_label_length_too_long) { // 64 char label
3✔
773

774
  string label("1234567890123456789012345678901234567890123456789012345678901234");
3✔
775

776
  { // append
3✔
777
    DNSName dn("www.");
3✔
778
    BOOST_CHECK_THROW(dn.appendRawLabel(label), std::range_error);
3✔
779
  }
3✔
780

781
  { // prepend
3✔
782
    DNSName dn("www.");
3✔
783
    BOOST_CHECK_THROW(dn.prependRawLabel(label), std::range_error);
3✔
784
  }
3✔
785
}
3✔
786

787
BOOST_AUTO_TEST_CASE(test_name_length_max) { // 255 char name
3✔
788

789
  string name("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
3✔
790
              "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
3✔
791
              "123456789.123456789.123456789.123456789.123456789.");
3✔
792
  string label("123");
3✔
793

794
  { // append
3✔
795
    DNSName dn(name);
3✔
796
    dn.appendRawLabel(label);
3✔
797
    BOOST_CHECK_EQUAL(dn.toString().size(), 254U);
3✔
798
  }
3✔
799

800
  { // prepend
3✔
801
    DNSName dn(name);
3✔
802
    dn.prependRawLabel(label);
3✔
803
    BOOST_CHECK_EQUAL(dn.toString().size(), 254U);
3✔
804
  }
3✔
805

806
  { // concat
3✔
807
    DNSName dn(name);
3✔
808

809
    dn += DNSName(label + ".");
3✔
810
    BOOST_CHECK_EQUAL(dn.toString().size(), 254U);
3✔
811
  }
3✔
812
}
3✔
813

814
BOOST_AUTO_TEST_CASE(test_name_length_too_long) { // 256 char name
3✔
815

816
  string name("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
3✔
817
              "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789."
3✔
818
              "123456789.123456789.123456789.123456789.123456789.");
3✔
819
  string label("1234");
3✔
820

821
  { // append
3✔
822
    DNSName dn(name);
3✔
823
    BOOST_CHECK_THROW(dn.appendRawLabel(label), std::range_error);
3✔
824
  }
3✔
825

826
  { // prepend
3✔
827
    DNSName dn(name);
3✔
828
    BOOST_CHECK_THROW(dn.prependRawLabel(label), std::range_error);
3✔
829
  }
3✔
830

831
  { // concat
3✔
832
    DNSName dn(name);
3✔
833
    BOOST_CHECK_THROW(dn += DNSName(label + "."), std::range_error);
3✔
834
  }
3✔
835
}
3✔
836

837

838
BOOST_AUTO_TEST_CASE(test_invalid_label_length) { // Invalid label length in qname
3✔
839

840
  string name("\x02""ns\x07""example\x04""com\x00", 16);
3✔
841

842
  BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 0, true), std::range_error);
3✔
843
}
3✔
844

845
BOOST_AUTO_TEST_CASE(test_compression) { // Compression test
3✔
846

847
  string name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05", 21);
3✔
848

849
  DNSName dn(name.c_str(), name.size(), 15, true);
3✔
850
  BOOST_CHECK_EQUAL(dn.toString(), "www.example.com.");
3✔
851
}
3✔
852

853
BOOST_AUTO_TEST_CASE(test_compression_qtype_qclass) { // Compression test with QClass and QType extraction
3✔
854

855
  uint16_t qtype = 0;
3✔
856
  uint16_t qclass = 0;
3✔
857

858
  {
3✔
859
    string name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05""\x00""\x01""\x00""\x01", 25);
3✔
860
    DNSName dn(name.c_str(), name.size(), 15, true, &qtype, &qclass);
3✔
861
    BOOST_CHECK_EQUAL(dn.toString(), "www.example.com.");
3✔
862
    BOOST_CHECK_EQUAL(qtype, 1);
3✔
863
    BOOST_CHECK_EQUAL(qclass, 1);
3✔
864
  }
3✔
865

866
  {
3✔
867
    /* same but this time we are one byte short for the qclass */
868
    string name("\x03""com\x00""\x07""example\xc0""\x00""\x03""www\xc0""\x05""\x00""\x01""\x00""", 24);
3✔
869
    BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 15, true, &qtype, &qclass), std::range_error);
3✔
870
  }
3✔
871

872
  {
3✔
873
    /* this time with a compression pointer such as (labellen << 8) != 0, see #4718 */
874
    string name("\x03""com\x00""\x07""example\xc1""\x00""\x03""www\xc1""\x05""\x00""\x01""\x00""\x01", 25);
3✔
875
    name.insert(0, 256, '0');
3✔
876

877
    DNSName dn(name.c_str(), name.size(), 271, true, &qtype, &qclass);
3✔
878
    BOOST_CHECK_EQUAL(dn.toString(), "www.example.com.");
3✔
879
    BOOST_CHECK_EQUAL(qtype, 1);
3✔
880
    BOOST_CHECK_EQUAL(qclass, 1);
3✔
881
  }
3✔
882

883
  {
3✔
884
    /* same but this time we are one byte short for the qclass */
885
    string name("\x03""com\x00""\x07""example\xc1""\x00""\x03""www\xc1""\x05""\x00""\x01""\x00", 24);
3✔
886
    name.insert(0, 256, '0');
3✔
887

888
    BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 271, true, &qtype, &qclass), std::range_error);
3✔
889
  }
3✔
890
}
3✔
891

892
BOOST_AUTO_TEST_CASE(test_compression_single_bit_set) { // first 2 bits as 10 or 01, not 11
3✔
893

894
  // first 2 bits: 10
895
  {
3✔
896
    string name("\x03""com\x00""\x07""example\x80""\x00""\x03""www\x80""\x05", 21);
3✔
897

898
    BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 15, true), std::range_error);
3✔
899
  }
3✔
900

901
  // first 2 bits: 01
902
  {
3✔
903
    string name("\x03""com\x00""\x07""example\x40""\x00""\x03""www\x40""\x05", 21);
3✔
904

905
    BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 15, true), std::range_error);
3✔
906
  }
3✔
907

908
}
3✔
909

910
BOOST_AUTO_TEST_CASE(test_pointer_pointer_root) { // Pointer to pointer to root
3✔
911

912
  string name("\x00""\xc0""\x00""\x03""com\xc0""\x01",9);
3✔
913

914
  DNSName dn(name.c_str(), name.size(), 3, true);
3✔
915
  BOOST_CHECK_EQUAL(dn.toString(), "com.");
3✔
916
}
3✔
917

918
BOOST_AUTO_TEST_CASE(test_bad_compression_pointer) { // Pointing beyond packet boundary
3✔
919

920
  std::string name("\x03""com\x00""\x07""example\xc0""\x11""xc0""\x00", 17);
3✔
921

922
  BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.length(), 5, true), std::range_error);
3✔
923
}
3✔
924

925
BOOST_AUTO_TEST_CASE(test_compression_loop) { // Compression loop (add one label)
3✔
926

927
  std::string name("\x03""www\xc0""\x00", 6);
3✔
928

929
  BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.length(), 0, true), std::range_error);
3✔
930
}
3✔
931

932
BOOST_AUTO_TEST_CASE(test_compression_loop1) { // Compression loop (pointer loop)
3✔
933

934
  string name("\xc0""\x00", 2);
3✔
935

936
  BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 0, true), std::range_error);
3✔
937
}
3✔
938

939
BOOST_AUTO_TEST_CASE(test_compression_loop2) { // Compression loop (deep recursion)
3✔
940

941
  int i;
3✔
942
  string name("\x00\xc0\x00", 3);
3✔
943
  for (i=0; i<98; ++i) {
297✔
944
    name.append( 1, ((i >> 7) & 0xff) | 0xc0);
294✔
945
    name.append( 1, ((i << 1) & 0xff) | 0x01);
294✔
946
  }
294✔
947
  BOOST_CHECK_NO_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true));
3✔
948

949
  ++i;
3✔
950
  name.append( 1, ((i >> 7) & 0xff) | 0xc0);
3✔
951
  name.append( 1, ((i << 1) & 0xff) | 0x01);
3✔
952

953
  BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true), std::range_error);
3✔
954
}
3✔
955

956
BOOST_AUTO_TEST_CASE(test_wirelength) { // Testing if we get the correct value from the wirelength function
3✔
957
  DNSName name("www.powerdns.com");
3✔
958
  BOOST_CHECK_EQUAL(name.wirelength(), 18U);
3✔
959

960
  DNSName sname("powerdns.com");
3✔
961
  sname.prependRawLabel(string("ww\x00""w", 4));
3✔
962
  BOOST_CHECK_EQUAL(sname.wirelength(), 19U);
3✔
963

964
  sname = DNSName("powerdns.com");
3✔
965
  sname.prependRawLabel(string("www\x00", 4));
3✔
966
  BOOST_CHECK_EQUAL(sname.wirelength(), 19U);
3✔
967
}
3✔
968

969
BOOST_AUTO_TEST_CASE(test_getrawlabel) {
3✔
970
  DNSName name("a.bb.ccc.dddd.");
3✔
971
  BOOST_CHECK_EQUAL(name.getRawLabel(0), "a");
3✔
972
  BOOST_CHECK_EQUAL(name.getRawLabel(1), "bb");
3✔
973
  BOOST_CHECK_EQUAL(name.getRawLabel(2), "ccc");
3✔
974
  BOOST_CHECK_EQUAL(name.getRawLabel(3), "dddd");
3✔
975
  BOOST_CHECK_THROW(name.getRawLabel(name.countLabels()), std::out_of_range);
3✔
976
}
3✔
977

978
BOOST_AUTO_TEST_CASE(test_getrawlabels_visitor) {
3✔
979
  DNSName name("a.bb.ccc.dddd.");
3✔
980
  auto visitor = name.getRawLabelsVisitor();
3✔
981
  BOOST_CHECK(!visitor.empty());
3✔
982
  BOOST_CHECK_EQUAL(visitor.front(), *name.getRawLabels().begin());
3✔
983
  BOOST_CHECK_EQUAL(visitor.back(), *name.getRawLabels().rbegin());
3✔
984

985
  BOOST_CHECK_EQUAL(visitor.back(), "dddd");
3✔
986
  BOOST_CHECK(visitor.pop_back());
3✔
987
  BOOST_CHECK_EQUAL(visitor.back(), "ccc");
3✔
988
  BOOST_CHECK(visitor.pop_back());
3✔
989
  BOOST_CHECK_EQUAL(visitor.back(), "bb");
3✔
990
  BOOST_CHECK(visitor.pop_back());
3✔
991
  BOOST_CHECK_EQUAL(visitor.back(), "a");
3✔
992
  BOOST_CHECK(visitor.pop_back());
3✔
993
  BOOST_CHECK(visitor.empty());
3✔
994
  BOOST_CHECK(!visitor.pop_back());
3✔
995
  BOOST_CHECK_THROW(visitor.front(), std::out_of_range);
3✔
996
  BOOST_CHECK_THROW(visitor.back(), std::out_of_range);
3✔
997
}
3✔
998

999
BOOST_AUTO_TEST_CASE(test_getlastlabel) {
3✔
1000
  DNSName name("www.powerdns.com");
3✔
1001
  DNSName ans = name.getLastLabel();
3✔
1002

1003
  // Check the const-ness
1004
  BOOST_CHECK_EQUAL(name, DNSName("www.powerdns.com"));
3✔
1005

1006
  // Check if the last label is indeed returned
1007
  BOOST_CHECK_EQUAL(ans, DNSName("com"));
3✔
1008
}
3✔
1009

1010
BOOST_AUTO_TEST_CASE(test_getcommonlabels) {
3✔
1011
  const DNSName name1("www.powerdns.com");
3✔
1012
  const DNSName name2("a.long.list.of.labels.powerdns.com");
3✔
1013

1014
  BOOST_CHECK_EQUAL(name1.getCommonLabels(name1), name1);
3✔
1015
  BOOST_CHECK_EQUAL(name2.getCommonLabels(name2), name2);
3✔
1016

1017
  BOOST_CHECK_EQUAL(name1.getCommonLabels(name2), DNSName("powerdns.com"));
3✔
1018
  BOOST_CHECK_EQUAL(name2.getCommonLabels(name1), DNSName("powerdns.com"));
3✔
1019

1020
  const DNSName name3("www.powerdns.org");
3✔
1021
  BOOST_CHECK_EQUAL(name1.getCommonLabels(name3), g_rootdnsname);
3✔
1022
  BOOST_CHECK_EQUAL(name2.getCommonLabels(name3), g_rootdnsname);
3✔
1023
  BOOST_CHECK_EQUAL(name3.getCommonLabels(name1), g_rootdnsname);
3✔
1024
  BOOST_CHECK_EQUAL(name3.getCommonLabels(name2), g_rootdnsname);
3✔
1025

1026
  const DNSName name4("WWw.PowErDnS.org");
3✔
1027
  BOOST_CHECK_EQUAL(name3.getCommonLabels(name4), name3);
3✔
1028
  BOOST_CHECK_EQUAL(name4.getCommonLabels(name3), name4);
3✔
1029

1030
  const DNSName name5;
3✔
1031
  BOOST_CHECK_EQUAL(name1.getCommonLabels(name5), DNSName());
3✔
1032
  BOOST_CHECK_EQUAL(name5.getCommonLabels(name1), DNSName());
3✔
1033
}
3✔
1034

1035
BOOST_AUTO_TEST_SUITE_END()
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc