]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/test-dnsparser_cc.cc
Merge pull request #14021 from Habbie/auth-lua-join-whitespace
[thirdparty/pdns.git] / pdns / test-dnsparser_cc.cc
CommitLineData
1c2d079d 1#ifndef BOOST_TEST_DYN_LINK
47698274 2#define BOOST_TEST_DYN_LINK
1c2d079d
FM
3#endif
4
47698274
RG
5#define BOOST_TEST_NO_MAIN
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include <boost/test/unit_test.hpp>
12
13#include "dnsparser.hh"
14
15BOOST_AUTO_TEST_SUITE(test_dnsparser_cc)
16
17BOOST_AUTO_TEST_CASE(test_editDNSPacketTTL) {
18
19 auto generatePacket = [](uint32_t ttl) {
20 DNSName name("powerdns.com.");
21 ComboAddress v4("1.2.3.4");
22 ComboAddress v6("2001:db8::1");
23
24 vector<uint8_t> packet;
25 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
26 pwR.getHeader()->qr = 1;
27
28 /* record we want to see altered */
29 pwR.startRecord(name, QType::A, ttl, QClass::IN, DNSResourceRecord::ANSWER);
30 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
31 pwR.commit();
32
33 /* same record but different TTL (yeah, don't do that but it's just a test) */
34 pwR.startRecord(name, QType::A, 100, QClass::IN, DNSResourceRecord::ANSWER);
35 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
36 pwR.commit();
37
38 /* different type */
39 pwR.startRecord(name, QType::AAAA, 42, QClass::IN, DNSResourceRecord::ANSWER);
40 pwR.xfrIP6(std::string(reinterpret_cast<const char*>(v6.sin6.sin6_addr.s6_addr), 16));
41 pwR.commit();
42
43 /* different class */
44 pwR.startRecord(name, QType::A, 42, QClass::CHAOS, DNSResourceRecord::ANSWER);
45 pwR.commit();
46
47 /* different section */
48 pwR.startRecord(name, QType::A, 42, QClass::IN, DNSResourceRecord::AUTHORITY);
49 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
50 pwR.commit();
51
52 return packet;
53 };
54
55 auto firstPacket = generatePacket(42);
56 auto expectedAlteredPacket = generatePacket(84);
57
58 size_t called = 0;
59 editDNSPacketTTL(reinterpret_cast<char*>(firstPacket.data()), firstPacket.size(), [&called](uint8_t section, uint16_t class_, uint16_t type, uint32_t ttl) {
60
61 called++;
62
63 /* only updates the TTL of IN/A, in answer, with an existing ttl of 42 */
64 if (section == 1 && class_ == QClass::IN && type == QType::A && ttl == 42) {
65 return 84;
66 }
67 return 0;
68 });
69
70 /* check that we have been for all records */
690b86b7 71 BOOST_CHECK_EQUAL(called, 5U);
47698274
RG
72
73 BOOST_REQUIRE_EQUAL(firstPacket.size(), expectedAlteredPacket.size());
74 for (size_t idx = 0; idx < firstPacket.size(); idx++) {
75 BOOST_CHECK_EQUAL(firstPacket.at(idx), expectedAlteredPacket.at(idx));
76 }
77 BOOST_CHECK(firstPacket == expectedAlteredPacket);
78
79 /* now call it with a truncated packet, missing the last TTL and rdata,
80 we should only be called 4 times but everything else should be fine. */
81 called = 0;
82 editDNSPacketTTL(reinterpret_cast<char*>(firstPacket.data()), firstPacket.size() - sizeof(uint32_t) - /* rdata length */ sizeof (uint16_t) - /* IPv4 payload in rdata */ 4, [&called](uint8_t section, uint16_t class_, uint16_t type, uint32_t ttl) {
83
84 called++;
85
86 /* only updates the TTL of IN/A, in answer, with an existing ttl of 42 */
87 if (section == 1 && class_ == QClass::IN && type == QType::A && ttl == 42) {
88 return 84;
89 }
90 return 0;
91 });
92
93 /* check that we have been for all records */
690b86b7 94 BOOST_CHECK_EQUAL(called, 4U);
47698274
RG
95 BOOST_CHECK(firstPacket == expectedAlteredPacket);
96}
97
98BOOST_AUTO_TEST_CASE(test_ageDNSPacket) {
99
100 auto generatePacket = [](uint32_t ttl) {
101 DNSName name("powerdns.com.");
102 ComboAddress v4("1.2.3.4");
103 ComboAddress v6("2001:db8::1");
104
105 vector<uint8_t> packet;
106 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
107 pwR.getHeader()->qr = 1;
108
109 /* record we want to see altered */
110 pwR.startRecord(name, QType::A, ttl, QClass::IN, DNSResourceRecord::ANSWER);
111 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
112 pwR.commit();
113
114 pwR.addOpt(4096, 0, 0);
115 pwR.commit();
116
117 return packet;
118 };
119
120 auto firstPacket = generatePacket(3600);
121 auto expectedAlteredPacket = generatePacket(1800);
122
100ff9c7
OM
123 dnsheader_aligned dh_aligned(firstPacket.data());
124 ageDNSPacket(reinterpret_cast<char*>(firstPacket.data()), firstPacket.size(), 1800, dh_aligned);
47698274
RG
125
126 BOOST_REQUIRE_EQUAL(firstPacket.size(), expectedAlteredPacket.size());
127 for (size_t idx = 0; idx < firstPacket.size(); idx++) {
128 BOOST_CHECK_EQUAL(firstPacket.at(idx), expectedAlteredPacket.at(idx));
129 }
130 BOOST_CHECK(firstPacket == expectedAlteredPacket);
131
132 /* now call it with a truncated packet, missing the last TTL and rdata,
133 the packet should not be altered. */
100ff9c7 134 ageDNSPacket(reinterpret_cast<char*>(firstPacket.data()), firstPacket.size() - sizeof(uint32_t) - /* rdata length */ sizeof (uint16_t) - /* IPv4 payload in rdata */ 4 - /* size of OPT record */ 11, 900, dh_aligned);
47698274
RG
135
136 BOOST_CHECK(firstPacket == expectedAlteredPacket);
137
9a3abf5a
O
138 /* now remove more than the remaining TTL. We expect ageDNSPacket
139 to cap this at zero and not cause an unsigned underflow into
140 the 2^32-1 neighbourhood */
100ff9c7 141 ageDNSPacket(reinterpret_cast<char*>(firstPacket.data()), firstPacket.size(), 1801, dh_aligned);
47698274 142
9a3abf5a 143 uint32_t ttl = 0;
47698274
RG
144
145 expectedAlteredPacket = generatePacket(ttl);
146 BOOST_REQUIRE_EQUAL(firstPacket.size(), expectedAlteredPacket.size());
147 for (size_t idx = 0; idx < firstPacket.size(); idx++) {
148 BOOST_CHECK_EQUAL(firstPacket.at(idx), expectedAlteredPacket.at(idx));
149 }
150 BOOST_CHECK(firstPacket == expectedAlteredPacket);
151}
152
153BOOST_AUTO_TEST_CASE(test_getDNSPacketMinTTL) {
154
155 const DNSName name("powerdns.com.");
156 const ComboAddress v4("1.2.3.4");
157 const ComboAddress v6("2001:db8::1");
158
159 {
160 /* no records */
161 vector<uint8_t> packet;
162 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
163 pwR.getHeader()->qr = 1;
164 pwR.commit();
165
166 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), nullptr);
167 BOOST_CHECK_EQUAL(result, std::numeric_limits<uint32_t>::max());
168 }
169
170 {
171 /* only one record, not an OPT one */
172 uint32_t ttl = 42;
173 vector<uint8_t> packet;
174 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
175 pwR.getHeader()->qr = 1;
176 pwR.commit();
177
178 pwR.startRecord(name, QType::A, ttl, QClass::IN, DNSResourceRecord::ANSWER);
179 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
180 pwR.commit();
181
182 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), nullptr);
183 BOOST_CHECK_EQUAL(result, ttl);
184 }
185
186 {
187 /* only one record, an OPT one */
188 vector<uint8_t> packet;
189 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
190 pwR.getHeader()->qr = 1;
191 pwR.commit();
192
193 pwR.addOpt(4096, 0, 0);
194 pwR.commit();
195
196 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), nullptr);
197 BOOST_CHECK_EQUAL(result, std::numeric_limits<uint32_t>::max());
198 }
199
200 {
201 /* records with different TTLs, should return the lower */
202 vector<uint8_t> packet;
203 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
204 pwR.getHeader()->qr = 1;
205 pwR.commit();
206
207 pwR.startRecord(name, QType::A, 257, QClass::IN, DNSResourceRecord::ANSWER);
208 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
209 pwR.commit();
210
211 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::AUTHORITY);
212 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
213 pwR.commit();
214
215 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
216 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
217 pwR.commit();
218
219 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), nullptr);
690b86b7 220 BOOST_CHECK_EQUAL(result, 255U);
47698274
RG
221 }
222
223 {
224 /* SOA record in answer, seenAuthSOA should not be set */
225 vector<uint8_t> packet;
226 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
227 pwR.getHeader()->qr = 1;
228 pwR.commit();
229
230 pwR.startRecord(name, QType::SOA, 257, QClass::IN, DNSResourceRecord::ANSWER);
231 pwR.commit();
232
233 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::AUTHORITY);
234 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
235 pwR.commit();
236
237 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
238 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
239 pwR.commit();
240
241 bool seenAuthSOA = false;
242 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), &seenAuthSOA);
690b86b7 243 BOOST_CHECK_EQUAL(result, 255U);
47698274
RG
244 BOOST_CHECK_EQUAL(seenAuthSOA, false);
245 }
246
247 {
248 /* one SOA record in auth, seenAuthSOA should be set */
249 vector<uint8_t> packet;
250 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
251 pwR.getHeader()->qr = 1;
252 pwR.commit();
253
254 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
255 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
256 pwR.commit();
257
258 pwR.startRecord(name, QType::SOA, 257, QClass::IN, DNSResourceRecord::AUTHORITY);
259 pwR.commit();
260
261 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
262 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
263 pwR.commit();
264
265 bool seenAuthSOA = false;
266 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), &seenAuthSOA);
690b86b7 267 BOOST_CHECK_EQUAL(result, 255U);
47698274
RG
268 BOOST_CHECK_EQUAL(seenAuthSOA, true);
269 }
270
271 {
272 /* one SOA record of the wrong qclass in auth, seenAuthSOA should not be set */
273 vector<uint8_t> packet;
274 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
275 pwR.getHeader()->qr = 1;
276 pwR.commit();
277
278 pwR.startRecord(name, QType::A, 257, QClass::IN, DNSResourceRecord::ANSWER);
279 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
280 pwR.commit();
281
282 pwR.startRecord(name, QType::SOA, 255, QClass::CHAOS, DNSResourceRecord::AUTHORITY);
283 pwR.commit();
284
285 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
286 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
287 pwR.commit();
288
289 bool seenAuthSOA = false;
290 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), &seenAuthSOA);
690b86b7 291 BOOST_CHECK_EQUAL(result, 255U);
47698274
RG
292 BOOST_CHECK_EQUAL(seenAuthSOA, false);
293 }
294
295 {
296 /* one A record in auth, seenAuthSOA should not be set */
297 vector<uint8_t> packet;
298 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
299 pwR.getHeader()->qr = 1;
300 pwR.commit();
301
302 pwR.startRecord(name, QType::A, 257, QClass::IN, DNSResourceRecord::AUTHORITY);
303 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
304 pwR.commit();
305
306 bool seenAuthSOA = false;
307 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), &seenAuthSOA);
690b86b7 308 BOOST_CHECK_EQUAL(result, 257U);
47698274
RG
309 BOOST_CHECK_EQUAL(seenAuthSOA, false);
310 }
311
312 {
313 /* one SOA record in additional, seenAuthSOA should not be set */
314 vector<uint8_t> packet;
315 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
316 pwR.getHeader()->qr = 1;
317 pwR.commit();
318
cfd669b4 319 pwR.startRecord(name, QType::SOA, 255, QClass::IN, DNSResourceRecord::ADDITIONAL);
47698274
RG
320 pwR.commit();
321
322 bool seenAuthSOA = false;
323 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size(), &seenAuthSOA);
690b86b7 324 BOOST_CHECK_EQUAL(result, 255U);
47698274
RG
325 BOOST_CHECK_EQUAL(seenAuthSOA, false);
326 }
327
328 {
329 /* truncated packet, no exception should be raised */
330 /* one SOA record in auth, seenAuthSOA should be set */
331 vector<uint8_t> packet;
332 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
333 pwR.getHeader()->qr = 1;
334 pwR.commit();
335
336 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
337 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
338 pwR.commit();
339
340 pwR.startRecord(name, QType::SOA, 257, QClass::IN, DNSResourceRecord::AUTHORITY);
341 pwR.commit();
342
343 pwR.startRecord(name, QType::A, 254, QClass::IN, DNSResourceRecord::ADDITIONAL);
344 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
345 pwR.commit();
346
347 bool seenAuthSOA = false;
348 auto result = getDNSPacketMinTTL(reinterpret_cast<char*>(packet.data()), packet.size() - sizeof(uint32_t) - /* rdata length */ sizeof (uint16_t) - /* IPv4 payload in rdata */ 4, &seenAuthSOA);
690b86b7 349 BOOST_CHECK_EQUAL(result, 255U);
47698274
RG
350 BOOST_CHECK_EQUAL(seenAuthSOA, true);
351 }
352}
353
354BOOST_AUTO_TEST_CASE(test_getDNSPacketLength) {
355
356 const DNSName name("powerdns.com.");
357 const ComboAddress v4("1.2.3.4");
358 const ComboAddress v6("2001:db8::1");
359
360 {
361 /* no records */
362 vector<uint8_t> packet;
363 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
364 pwR.getHeader()->qr = 1;
365 pwR.commit();
366
367 auto result = getDNSPacketLength(reinterpret_cast<char*>(packet.data()), packet.size());
368 BOOST_CHECK_EQUAL(result, packet.size());
369 }
370
371 {
372 /* several records */
373 vector<uint8_t> packet;
374 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
375 pwR.getHeader()->qr = 1;
376 pwR.commit();
377
378 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
379 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
380 pwR.commit();
381
382 pwR.startRecord(name, QType::SOA, 257, QClass::IN, DNSResourceRecord::AUTHORITY);
383 pwR.commit();
384
385 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
386 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
387 pwR.commit();
388
389 pwR.addOpt(4096, 0, 0);
390 pwR.commit();
391
392 auto result = getDNSPacketLength(reinterpret_cast<char*>(packet.data()), packet.size());
393 BOOST_CHECK_EQUAL(result, packet.size());
394 }
395
396 {
397 /* trailing data */
398 vector<uint8_t> packet;
399 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
400 pwR.getHeader()->qr = 1;
401 pwR.commit();
402
403 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
404 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
405 pwR.commit();
406
407 pwR.startRecord(name, QType::SOA, 257, QClass::IN, DNSResourceRecord::AUTHORITY);
408 pwR.commit();
409
410 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
411 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
412 pwR.commit();
413
414 pwR.addOpt(4096, 0, 0);
415 pwR.commit();
416
417 auto realSize = packet.size();
418 packet.resize(realSize + 512);
419 auto result = getDNSPacketLength(reinterpret_cast<char*>(packet.data()), packet.size());
420 BOOST_CHECK_EQUAL(result, realSize);
421 }
422
53c57da7
RG
423 {
424 /* truncated packet, should return the full size */
425 vector<uint8_t> packet;
426 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
427 pwR.getHeader()->qr = 1;
428 pwR.commit();
429
430 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
431 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
432 pwR.commit();
433
434 pwR.startRecord(name, QType::SOA, 257, QClass::IN, DNSResourceRecord::AUTHORITY);
435 pwR.commit();
436
437 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
438 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
439 pwR.commit();
440
441 pwR.addOpt(4096, 0, 0);
442 pwR.commit();
443
444 size_t fakeSize = packet.size()-1;
445 auto result = getDNSPacketLength(reinterpret_cast<char*>(packet.data()), fakeSize);
446 BOOST_CHECK_EQUAL(result, fakeSize);
447 }
448
47698274
RG
449}
450
451BOOST_AUTO_TEST_CASE(test_getRecordsOfTypeCount) {
452 const DNSName name("powerdns.com.");
453 const ComboAddress v4("1.2.3.4");
454 const ComboAddress v6("2001:db8::1");
455
456 {
457 vector<uint8_t> packet;
458 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
459 pwR.getHeader()->qr = 1;
460 pwR.commit();
461
462 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
463 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
464 pwR.commit();
465
466 pwR.startRecord(name, QType::SOA, 257, QClass::IN, DNSResourceRecord::AUTHORITY);
467 pwR.commit();
468
469 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
470 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
471 pwR.commit();
472
473 pwR.addOpt(4096, 0, 0);
474 pwR.commit();
475
476 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 0, QType::A), 1);
477 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 0, QType::SOA), 0);
478 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 1);
479 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::SOA), 0);
480 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 2, QType::A), 0);
481 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 2, QType::SOA), 1);
482 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 1);
483 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::SOA), 0);
484
485 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 4, QType::SOA), 0);
bd98d61b
CHB
486 }
487
47698274
RG
488}
489
bd98d61b
CHB
490BOOST_AUTO_TEST_CASE(test_clearDNSPacketRecordTypes) {
491 {
492 auto generatePacket = []() {
493 const DNSName name("powerdns.com.");
494 const ComboAddress v4("1.2.3.4");
495 const ComboAddress v6("2001:db8::1");
496
497 vector<uint8_t> packet;
498 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
499 pwR.getHeader()->qr = 1;
500 pwR.commit();
501
502 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
503 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
504 pwR.commit();
505
506 /* different type */
507 pwR.startRecord(name, QType::AAAA, 42, QClass::IN, DNSResourceRecord::ANSWER);
508 pwR.xfrIP6(std::string(reinterpret_cast<const char*>(v6.sin6.sin6_addr.s6_addr), 16));
509 pwR.commit();
510
bd98d61b
CHB
511 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
512 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
513 pwR.commit();
514
515 pwR.addOpt(4096, 0, 0);
516 pwR.commit();
517 return packet;
518 };
519
520 auto packet = generatePacket();
521
522 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 1);
523 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 1);
bd98d61b
CHB
524 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 1);
525
953708cb 526 std::unordered_set<QType> toremove{QType::AAAA};
bd98d61b
CHB
527 clearDNSPacketRecordTypes(packet, toremove);
528
529 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 1);
530 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 0);
bd98d61b
CHB
531 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 1);
532
533 toremove = {QType::A};
534 clearDNSPacketRecordTypes(packet, toremove);
535
536 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 0);
537 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 0);
bd98d61b
CHB
538 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 0);
539
540 packet = generatePacket();
541
542 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 1);
543 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 1);
bd98d61b
CHB
544 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 1);
545
546 toremove = {QType::A, QType::AAAA};
547 clearDNSPacketRecordTypes(packet, toremove);
548
549 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 0);
550 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 0);
bd98d61b
CHB
551 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 0);
552 }
553
47698274
RG
554}
555
62fdccd0
CHB
556BOOST_AUTO_TEST_CASE(test_clearDNSPacketUnsafeRecordTypes) {
557 {
558 auto generatePacket = []() {
559 const DNSName name("powerdns.com.");
560 const DNSName mxname("mx.powerdns.com.");
561 const ComboAddress v4("1.2.3.4");
562 const ComboAddress v6("2001:db8::1");
563
564 vector<uint8_t> packet;
565 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
566 pwR.getHeader()->qr = 1;
567 pwR.commit();
568
569 pwR.startRecord(name, QType::A, 255, QClass::IN, DNSResourceRecord::ANSWER);
570 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
571 pwR.commit();
572
573 /* different type */
574 pwR.startRecord(name, QType::AAAA, 42, QClass::IN, DNSResourceRecord::ANSWER);
575 pwR.xfrIP6(std::string(reinterpret_cast<const char*>(v6.sin6.sin6_addr.s6_addr), 16));
576 pwR.commit();
577
578 pwR.startRecord(name, QType::A, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
579 pwR.xfrIP(v4.sin4.sin_addr.s_addr);
580 pwR.commit();
581
582 pwR.startRecord(name, QType::MX, 256, QClass::IN, DNSResourceRecord::ADDITIONAL);
583 pwR.xfrName(mxname, false);
584 pwR.commit();
585
586 pwR.addOpt(4096, 0, 0);
587 pwR.commit();
588 return packet;
589 };
590
591 auto packet = generatePacket();
592
593 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 1);
594 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 1);
595 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 1);
596 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::MX), 1);
597
953708cb 598 std::unordered_set<QType> toremove{QType::AAAA};
62fdccd0
CHB
599 clearDNSPacketRecordTypes(packet, toremove);
600
601 // nothing should have been removed as an "unsafe" MX RR is in the packet
602 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 1);
603 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 1);
604 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 1);
605 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::MX), 1);
606
607 toremove = {QType::MX, QType::AAAA};
608 clearDNSPacketRecordTypes(packet, toremove);
609
610 // MX is unsafe, but we asked to remove it
611 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::A), 1);
612 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 1, QType::AAAA), 0);
d5ef463e 613 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::A), 1);
62fdccd0
CHB
614 BOOST_CHECK_EQUAL(getRecordsOfTypeCount(reinterpret_cast<char*>(packet.data()), packet.size(), 3, QType::MX), 0);
615 }
616
617}
618
47698274 619BOOST_AUTO_TEST_SUITE_END()