]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/test-dnswriter_cc.cc
Merge pull request #10396 from omoerbeek/rec-log-levels
[thirdparty/pdns.git] / pdns / test-dnswriter_cc.cc
1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
3
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7
8 #include <boost/test/unit_test.hpp>
9 #include <fstream>
10
11 #include "dnswriter.hh"
12 #include "dnsparser.hh"
13
14 BOOST_AUTO_TEST_SUITE(test_dnswriter_cc)
15
16 BOOST_AUTO_TEST_CASE(test_compressionBool) {
17 auto testCompressionBool = [](bool compress, size_t size1, size_t size2) {
18 DNSName name("powerdns.com.");
19
20 vector<uint8_t> packet;
21 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
22 pwR.getHeader()->qr = 1;
23
24 pwR.startRecord(DNSName("mediumsizedlabel.example.net"), QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, compress);
25 pwR.xfrIP('P'<<24 |
26 'Q'<<16 |
27 'R'<<8 |
28 'S');
29 pwR.commit();
30 BOOST_CHECK_EQUAL(pwR.size(), size1);
31
32 pwR.startRecord(DNSName("adifferentlabel.example.net"), QType::NS, 3600, QClass::IN, DNSResourceRecord::ANSWER, compress);
33 pwR.xfrName(DNSName("target.example.net"), true);
34 pwR.commit();
35 BOOST_CHECK_EQUAL(pwR.size(), size2);
36
37 string spacket(packet.begin(), packet.end());
38
39 BOOST_CHECK_NO_THROW(MOADNSParser mdp(false, spacket));
40 };
41
42 testCompressionBool(true, 74, 111);
43 testCompressionBool(false, 74, 133);
44 }
45
46 BOOST_AUTO_TEST_CASE(test_compressionBoundary) {
47 DNSName name("powerdns.com.");
48
49 vector<uint8_t> packet;
50 DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
51 pwR.getHeader()->qr = 1;
52
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("\"");
56 pwR.xfrText(txt);
57 pwR.commit();
58 BOOST_CHECK_EQUAL(pwR.size(), 16368U);
59
60 pwR.startRecord(DNSName("mediumsizedlabel.example.net"), QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER);
61 pwR.xfrIP('P'<<24 |
62 'Q'<<16 |
63 'R'<<8 |
64 'S');
65 pwR.commit();
66 BOOST_CHECK_EQUAL(pwR.size(), 16412U); // 16412 (0x401c) puts '7example3net' at 0x4001
67
68 pwR.startRecord(DNSName("adifferentlabel.example.net"), QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER);
69 pwR.xfrIP('D'<<24 |
70 'E'<<16 |
71 'F'<<8 |
72 'G');
73 pwR.commit();
74 BOOST_CHECK_EQUAL(pwR.size(), 16455U);
75
76 string spacket(packet.begin(), packet.end());
77
78 BOOST_CHECK_NO_THROW(MOADNSParser mdp(false, spacket));
79 }
80
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;
86
87 set<string> keys({"alpn", "ipv6hint"});
88 set<SvcParam> params({SvcParam(SvcParam::mandatory, std::move(keys))});
89
90 pwR.startRecord(name, QType::SVCB);
91 pwR.commit();
92 auto start = pwR.getContent().size();
93
94 pwR.xfrSvcParamKeyVals(params);
95 pwR.commit();
96 auto cit = pwR.getContent().begin();
97 for (size_t i = 0; i<start; i++)
98 cit++;
99
100 vector<uint8_t> c(cit, pwR.getContent().end());
101 BOOST_CHECK(c == vector<uint8_t>({0,0,0,4,0,1,0,6}));
102 }
103
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;
109
110 vector<string> alpns({"h2", "h2c", "h3"});
111 set<SvcParam> params({SvcParam(SvcParam::alpn, std::move(alpns))});
112
113 pwR.startRecord(name, QType::SVCB);
114 pwR.commit();
115 auto start = pwR.getContent().size();
116
117 pwR.xfrSvcParamKeyVals(params);
118 pwR.commit();
119 auto cit = pwR.getContent().begin();
120 for (size_t i = 0; i<start; i++)
121 cit++;
122
123 vector<uint8_t> c(cit, pwR.getContent().end());
124 BOOST_CHECK(c == vector<uint8_t>({
125 0,1,0,10,
126 2,'h','2',
127 3,'h','2','c',
128 2,'h','3'}));
129 }
130
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;
136
137 set<SvcParam> params({SvcParam(SvcParam::no_default_alpn)});
138
139 pwR.startRecord(name, QType::SVCB);
140 pwR.commit();
141 auto start = pwR.getContent().size();
142
143 pwR.xfrSvcParamKeyVals(params);
144 pwR.commit();
145 auto cit = pwR.getContent().begin();
146 for (size_t i = 0; i<start; i++)
147 cit++;
148
149 vector<uint8_t> c(cit, pwR.getContent().end());
150 BOOST_CHECK(c == vector<uint8_t>({0,2,0,0}));
151 }
152
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;
158
159 set<SvcParam> params({SvcParam(SvcParam::port, 53)});
160
161 pwR.startRecord(name, QType::SVCB);
162 pwR.commit();
163 auto start = pwR.getContent().size();
164
165 pwR.xfrSvcParamKeyVals(params);
166 pwR.commit();
167 auto cit = pwR.getContent().begin();
168 for (size_t i = 0; i<start; i++)
169 cit++;
170
171 vector<uint8_t> c(cit, pwR.getContent().end());
172 BOOST_CHECK(c == vector<uint8_t>({0,3,0,2,0,53}));
173 }
174
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;
180
181 vector<ComboAddress> addrs({ComboAddress("192.0.2.1"), ComboAddress("192.0.2.2")});
182 set<SvcParam> params({SvcParam(SvcParam::ipv4hint, std::move(addrs))});
183
184 pwR.startRecord(name, QType::SVCB);
185 pwR.commit();
186 auto start = pwR.getContent().size();
187
188 pwR.xfrSvcParamKeyVals(params);
189 pwR.commit();
190 auto cit = pwR.getContent().begin();
191 for (size_t i = 0; i<start; i++)
192 cit++;
193
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}));
196 }
197
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;
203
204 set<SvcParam> params({SvcParam(SvcParam::ech, "a very bogus echconfig value")});
205
206 pwR.startRecord(name, QType::SVCB);
207 pwR.commit();
208 auto start = pwR.getContent().size();
209
210 pwR.xfrSvcParamKeyVals(params);
211 pwR.commit();
212 auto cit = pwR.getContent().begin();
213 for (size_t i = 0; i<start; i++)
214 cit++;
215
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'
220 }));
221 }
222
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;
228
229 vector<ComboAddress> addrs({ComboAddress("2001:db8::1"), ComboAddress("2001:db8::2")});
230 set<SvcParam> params({SvcParam(SvcParam::ipv6hint, std::move(addrs))});
231
232 pwR.startRecord(name, QType::SVCB);
233 pwR.commit();
234 auto start = pwR.getContent().size();
235
236 pwR.xfrSvcParamKeyVals(params);
237 pwR.commit();
238 auto cit = pwR.getContent().begin();
239 for (size_t i = 0; i<start; i++)
240 cit++;
241
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}));
246 }
247
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;
253
254 set<SvcParam> params({SvcParam(SvcParam::keyFromString("key666"), "mycoolvalue")});
255
256 pwR.startRecord(name, QType::SVCB);
257 pwR.commit();
258 auto start = pwR.getContent().size();
259
260 pwR.xfrSvcParamKeyVals(params);
261 pwR.commit();
262 auto cit = pwR.getContent().begin();
263 for (size_t i = 0; i<start; i++)
264 cit++;
265
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'
269 }));
270 }
271
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;
277
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)});
281
282 pwR.startRecord(name, QType::SVCB);
283 pwR.commit();
284 auto start = pwR.getContent().size();
285
286 pwR.xfrSvcParamKeyVals(params);
287 pwR.commit();
288 auto cit = pwR.getContent().begin();
289 for (size_t i = 0; i<start; i++)
290 cit++;
291
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
296 0,6,0,32, // ipv6
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}));
299 }
300
301 BOOST_AUTO_TEST_CASE(test_NodeOrLocatorID) {
302 DNSName name("powerdns.com.");
303 vector<uint8_t> packet;
304
305 NodeOrLocatorID in = {0, 0, 0, 0, 0, 0, 0, 1};
306
307 DNSPacketWriter writer(packet, name, QType::NID, QClass::IN, 0);
308 writer.getHeader()->qr = 1;
309
310 writer.startRecord(name, QType::NID);
311 writer.commit();
312 auto start = writer.getContent().size();
313
314 writer.xfrNodeOrLocatorID(in);
315 writer.commit();
316 auto cit = writer.getContent().begin();
317 for (size_t i = 0; i<start; i++)
318 cit++;
319
320 vector<uint8_t> c(cit, writer.getContent().end());
321 BOOST_CHECK(c == vector<uint8_t>({
322 0, 0, 0, 0,
323 0, 0, 0, 1}));
324 }
325
326 BOOST_AUTO_TEST_SUITE_END()