1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
8 #include <boost/test/unit_test.hpp>
11 #include "dnswriter.hh"
12 #include "dnsparser.hh"
14 BOOST_AUTO_TEST_SUITE(test_dnswriter_cc
)
16 BOOST_AUTO_TEST_CASE(test_compressionBool
) {
17 auto testCompressionBool
= [](bool compress
, size_t size1
, size_t size2
) {
18 DNSName
name("powerdns.com.");
20 vector
<uint8_t> packet
;
21 DNSPacketWriter
pwR(packet
, name
, QType::A
, QClass::IN
, 0);
22 pwR
.getHeader()->qr
= 1;
24 pwR
.startRecord(DNSName("mediumsizedlabel.example.net"), QType::A
, 3600, QClass::IN
, DNSResourceRecord::ANSWER
, compress
);
30 BOOST_CHECK_EQUAL(pwR
.size(), size1
);
32 pwR
.startRecord(DNSName("adifferentlabel.example.net"), QType::NS
, 3600, QClass::IN
, DNSResourceRecord::ANSWER
, compress
);
33 pwR
.xfrName(DNSName("target.example.net"), true);
35 BOOST_CHECK_EQUAL(pwR
.size(), size2
);
37 string
spacket(packet
.begin(), packet
.end());
39 BOOST_CHECK_NO_THROW(MOADNSParser
mdp(false, spacket
));
42 testCompressionBool(true, 74, 111);
43 testCompressionBool(false, 74, 133);
46 BOOST_AUTO_TEST_CASE(test_compressionBoundary
) {
47 DNSName
name("powerdns.com.");
49 vector
<uint8_t> packet
;
50 DNSPacketWriter
pwR(packet
, name
, QType::A
, QClass::IN
, 0);
51 pwR
.getHeader()->qr
= 1;
53 /* record we want to see altered */
54 pwR
.startRecord(name
, QType::TXT
, 3600, QClass::IN
, DNSResourceRecord::ANSWER
);
55 auto txt
= string("\"")+string(16262, 'A')+string("\"");
58 BOOST_CHECK_EQUAL(pwR
.size(), 16368U);
60 pwR
.startRecord(DNSName("mediumsizedlabel.example.net"), QType::A
, 3600, QClass::IN
, DNSResourceRecord::ANSWER
);
66 BOOST_CHECK_EQUAL(pwR
.size(), 16412U); // 16412 (0x401c) puts '7example3net' at 0x4001
68 pwR
.startRecord(DNSName("adifferentlabel.example.net"), QType::A
, 3600, QClass::IN
, DNSResourceRecord::ANSWER
);
74 BOOST_CHECK_EQUAL(pwR
.size(), 16455U);
76 string
spacket(packet
.begin(), packet
.end());
78 BOOST_CHECK_NO_THROW(MOADNSParser
mdp(false, spacket
));
81 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_mandatory
) {
82 DNSName
name("powerdns.com.");
83 vector
<uint8_t> packet
;
84 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
85 pwR
.getHeader()->qr
= 1;
87 set
<string
> keys({"alpn", "ipv6hint"});
88 set
<SvcParam
> params({SvcParam(SvcParam::mandatory
, std::move(keys
))});
90 pwR
.startRecord(name
, QType::SVCB
);
92 auto start
= pwR
.getContent().size();
94 pwR
.xfrSvcParamKeyVals(params
);
96 auto cit
= pwR
.getContent().begin();
97 for (size_t i
= 0; i
<start
; i
++)
100 vector
<uint8_t> c(cit
, pwR
.getContent().end());
101 BOOST_CHECK(c
== vector
<uint8_t>({0,0,0,4,0,1,0,6}));
104 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_alpn
) {
105 DNSName
name("powerdns.com.");
106 vector
<uint8_t> packet
;
107 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
108 pwR
.getHeader()->qr
= 1;
110 vector
<string
> alpns({"h2", "h2c", "h3"});
111 set
<SvcParam
> params({SvcParam(SvcParam::alpn
, std::move(alpns
))});
113 pwR
.startRecord(name
, QType::SVCB
);
115 auto start
= pwR
.getContent().size();
117 pwR
.xfrSvcParamKeyVals(params
);
119 auto cit
= pwR
.getContent().begin();
120 for (size_t i
= 0; i
<start
; i
++)
123 vector
<uint8_t> c(cit
, pwR
.getContent().end());
124 BOOST_CHECK(c
== vector
<uint8_t>({
131 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_no_default_alpn
) {
132 DNSName
name("powerdns.com.");
133 vector
<uint8_t> packet
;
134 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
135 pwR
.getHeader()->qr
= 1;
137 set
<SvcParam
> params({SvcParam(SvcParam::no_default_alpn
)});
139 pwR
.startRecord(name
, QType::SVCB
);
141 auto start
= pwR
.getContent().size();
143 pwR
.xfrSvcParamKeyVals(params
);
145 auto cit
= pwR
.getContent().begin();
146 for (size_t i
= 0; i
<start
; i
++)
149 vector
<uint8_t> c(cit
, pwR
.getContent().end());
150 BOOST_CHECK(c
== vector
<uint8_t>({0,2,0,0}));
153 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_port
) {
154 DNSName
name("powerdns.com.");
155 vector
<uint8_t> packet
;
156 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
157 pwR
.getHeader()->qr
= 1;
159 set
<SvcParam
> params({SvcParam(SvcParam::port
, 53)});
161 pwR
.startRecord(name
, QType::SVCB
);
163 auto start
= pwR
.getContent().size();
165 pwR
.xfrSvcParamKeyVals(params
);
167 auto cit
= pwR
.getContent().begin();
168 for (size_t i
= 0; i
<start
; i
++)
171 vector
<uint8_t> c(cit
, pwR
.getContent().end());
172 BOOST_CHECK(c
== vector
<uint8_t>({0,3,0,2,0,53}));
175 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ipv4hint
) {
176 DNSName
name("powerdns.com.");
177 vector
<uint8_t> packet
;
178 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
179 pwR
.getHeader()->qr
= 1;
181 vector
<ComboAddress
> addrs({ComboAddress("192.0.2.1"), ComboAddress("192.0.2.2")});
182 set
<SvcParam
> params({SvcParam(SvcParam::ipv4hint
, std::move(addrs
))});
184 pwR
.startRecord(name
, QType::SVCB
);
186 auto start
= pwR
.getContent().size();
188 pwR
.xfrSvcParamKeyVals(params
);
190 auto cit
= pwR
.getContent().begin();
191 for (size_t i
= 0; i
<start
; i
++)
194 vector
<uint8_t> c(cit
, pwR
.getContent().end());
195 BOOST_CHECK(c
== vector
<uint8_t>({0,4,0,8,192,0,2,1,192,0,2,2}));
198 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ech
) {
199 DNSName
name("powerdns.com.");
200 vector
<uint8_t> packet
;
201 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
202 pwR
.getHeader()->qr
= 1;
204 set
<SvcParam
> params({SvcParam(SvcParam::ech
, "a very bogus echconfig value")});
206 pwR
.startRecord(name
, QType::SVCB
);
208 auto start
= pwR
.getContent().size();
210 pwR
.xfrSvcParamKeyVals(params
);
212 auto cit
= pwR
.getContent().begin();
213 for (size_t i
= 0; i
<start
; i
++)
216 vector
<uint8_t> c(cit
, pwR
.getContent().end());
217 BOOST_CHECK(c
== vector
<uint8_t>({0,5,0,28,
218 'a',' ','v','e','r','y',' ','b','o','g','u','s',' ',
219 'e','c','h','c','o','n','f','i','g',' ','v','a','l','u','e'
223 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ipv6hint
) {
224 DNSName
name("powerdns.com.");
225 vector
<uint8_t> packet
;
226 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
227 pwR
.getHeader()->qr
= 1;
229 vector
<ComboAddress
> addrs({ComboAddress("2001:db8::1"), ComboAddress("2001:db8::2")});
230 set
<SvcParam
> params({SvcParam(SvcParam::ipv6hint
, std::move(addrs
))});
232 pwR
.startRecord(name
, QType::SVCB
);
234 auto start
= pwR
.getContent().size();
236 pwR
.xfrSvcParamKeyVals(params
);
238 auto cit
= pwR
.getContent().begin();
239 for (size_t i
= 0; i
<start
; i
++)
242 vector
<uint8_t> c(cit
, pwR
.getContent().end());
243 BOOST_CHECK(c
== vector
<uint8_t>({0,6,0,32,
244 32,1,13,184,0,0,0,0,0,0,0,0,0,0,0,1,
245 32,1,13,184,0,0,0,0,0,0,0,0,0,0,0,2}));
248 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_generic
) {
249 DNSName
name("powerdns.com.");
250 vector
<uint8_t> packet
;
251 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
252 pwR
.getHeader()->qr
= 1;
254 set
<SvcParam
> params({SvcParam(SvcParam::keyFromString("key666"), "mycoolvalue")});
256 pwR
.startRecord(name
, QType::SVCB
);
258 auto start
= pwR
.getContent().size();
260 pwR
.xfrSvcParamKeyVals(params
);
262 auto cit
= pwR
.getContent().begin();
263 for (size_t i
= 0; i
<start
; i
++)
266 vector
<uint8_t> c(cit
, pwR
.getContent().end());
267 BOOST_CHECK(c
== vector
<uint8_t>({2,154,0,11,
268 'm','y','c','o','o','l','v','a','l','u','e'
272 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_multiple
) {
273 DNSName
name("powerdns.com.");
274 vector
<uint8_t> packet
;
275 DNSPacketWriter
pwR(packet
, name
, QType::SVCB
, QClass::IN
, 0);
276 pwR
.getHeader()->qr
= 1;
278 vector
<ComboAddress
> addrs({ComboAddress("2001:db8::1"), ComboAddress("2001:db8::2")});
279 vector
<string
> alpns({"h2", "h2c", "h3"});
280 set
<SvcParam
> params({SvcParam(SvcParam::alpn
, std::move(alpns
)), SvcParam(SvcParam::ipv6hint
, std::move(addrs
)), SvcParam(SvcParam::port
, 53)});
282 pwR
.startRecord(name
, QType::SVCB
);
284 auto start
= pwR
.getContent().size();
286 pwR
.xfrSvcParamKeyVals(params
);
288 auto cit
= pwR
.getContent().begin();
289 for (size_t i
= 0; i
<start
; i
++)
292 vector
<uint8_t> c(cit
, pwR
.getContent().end());
293 BOOST_CHECK(c
== vector
<uint8_t>({
294 0,1,0,10,2,'h','2',3,'h','2','c',2,'h','3', // alpn
295 0,3,0,2,0,53, // port
297 32,1,13,184,0,0,0,0,0,0,0,0,0,0,0,1,
298 32,1,13,184,0,0,0,0,0,0,0,0,0,0,0,2}));
301 BOOST_AUTO_TEST_CASE(test_NodeOrLocatorID
) {
302 DNSName
name("powerdns.com.");
303 vector
<uint8_t> packet
;
305 NodeOrLocatorID in
= {0, 0, 0, 0, 0, 0, 0, 1};
307 DNSPacketWriter
writer(packet
, name
, QType::NID
, QClass::IN
, 0);
308 writer
.getHeader()->qr
= 1;
310 writer
.startRecord(name
, QType::NID
);
312 auto start
= writer
.getContent().size();
314 writer
.xfrNodeOrLocatorID(in
);
316 auto cit
= writer
.getContent().begin();
317 for (size_t i
= 0; i
<start
; i
++)
320 vector
<uint8_t> c(cit
, writer
.getContent().end());
321 BOOST_CHECK(c
== vector
<uint8_t>({
326 BOOST_AUTO_TEST_SUITE_END()