]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/test-iputils_hh.cc
Merge pull request #7007 from Line-Rate-Development/prometheus_active_servers
[thirdparty/pdns.git] / pdns / test-iputils_hh.cc
1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 #include <boost/test/unit_test.hpp>
7 #include <bitset>
8 #include "iputils.hh"
9
10 using namespace boost;
11
12 BOOST_AUTO_TEST_SUITE(test_iputils_hh)
13
14 BOOST_AUTO_TEST_CASE(test_ComboAddress) {
15 ComboAddress local("127.0.0.1", 53);
16 BOOST_CHECK(local==local);
17 BOOST_CHECK_EQUAL(local.sin4.sin_family, AF_INET);
18 BOOST_CHECK_EQUAL(local.sin4.sin_port, htons(53));
19 BOOST_CHECK_EQUAL(local.sin4.sin_addr.s_addr, htonl(0x7f000001UL));
20
21 ComboAddress remote("130.161.33.15", 53);
22 BOOST_CHECK(!(local == remote));
23 BOOST_CHECK_EQUAL(remote.sin4.sin_port, htons(53));
24
25 ComboAddress withport("213.244.168.210:53");
26 BOOST_CHECK_EQUAL(withport.sin4.sin_port, htons(53));
27
28 ComboAddress withportO("213.244.168.210:53", 5300);
29 BOOST_CHECK_EQUAL(withportO.sin4.sin_port, htons(53));
30
31 withport = ComboAddress("[::]:53");
32 BOOST_CHECK_EQUAL(withport.sin4.sin_port, htons(53));
33
34 withport = ComboAddress("[::]:5300", 53);
35 BOOST_CHECK_EQUAL(withport.sin4.sin_port, htons(5300));
36
37 ComboAddress defaultport("213.244.168.210");
38 BOOST_CHECK_EQUAL(defaultport.sin4.sin_port, htons(0));
39
40 defaultport = ComboAddress("[::1]");
41 BOOST_CHECK_EQUAL(defaultport.sin4.sin_port, htons(0));
42
43 defaultport = ComboAddress("::1");
44 BOOST_CHECK_EQUAL(defaultport.sin4.sin_port, htons(0));
45
46 // Verify that 2 'empty' ComboAddresses are equal, used in syncres.hh to
47 // signal auth-zones
48 ComboAddress a = ComboAddress();
49 ComboAddress b = ComboAddress();
50 BOOST_CHECK(a == b);
51
52 // Verify that 2 ComboAddresses are not the same
53 ComboAddress c = ComboAddress("127.0.0.1:53");
54 ComboAddress d = ComboAddress("127.0.0.1:52");
55 ComboAddress e = ComboAddress("127.0.0.2:53");
56
57 BOOST_CHECK(a != c);
58 BOOST_CHECK(c != d);
59 BOOST_CHECK(c != e);
60 BOOST_CHECK(d != e);
61 BOOST_CHECK(!(a != b));
62
63 // Verify that we don't allow invalid port numbers
64 BOOST_CHECK_THROW(ComboAddress("127.0.0.1:70000"), PDNSException); // Port no. too high
65 BOOST_CHECK_THROW(ComboAddress("127.0.0.1:-6"), PDNSException); // Port no. too low
66 BOOST_CHECK_THROW(ComboAddress("[::1]:70000"), PDNSException); // Port no. too high
67 BOOST_CHECK_THROW(ComboAddress("[::1]:-6"), PDNSException); // Port no. too low
68 }
69
70 BOOST_AUTO_TEST_CASE(test_ComboAddressCompare) {
71 ComboAddress a, b;
72 a.reset();
73 b.reset();
74 BOOST_CHECK(!(a<b));
75 BOOST_CHECK(!(a>b));
76 }
77
78 BOOST_AUTO_TEST_CASE(test_ComboAddressTruncate) {
79 ComboAddress ca4("130.161.252.29");
80 ca4.truncate(24);
81 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.252.0");
82 ca4.truncate(16);
83 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.0.0");
84
85
86
87 ca4 = ComboAddress("130.161.252.29");
88 ComboAddress orig(ca4);
89 for(int n=32; n; --n) {
90 ca4.truncate(n);
91
92 uint32_t p;
93 memcpy(&p, (char*)&ca4.sin4.sin_addr.s_addr, 4);
94 std::bitset<32> result(htonl(p));
95
96 memcpy(&p, (char*)&orig.sin4.sin_addr.s_addr, 4);
97 std::bitset<32> manual(htonl(p));
98
99 auto tokill=32-n;
100 for(int i =0; i< tokill; ++i)
101 manual.set(i, 0);
102
103 BOOST_CHECK_EQUAL(result, manual);
104 }
105
106 ca4 = ComboAddress("130.161.252.29");
107 ca4.truncate(31);
108 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.252.28");
109
110 ca4.truncate(30);
111 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.252.28");
112
113 ca4.truncate(29);
114 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.252.24");
115
116 ca4.truncate(23);
117 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.252.0");
118
119 ca4.truncate(22);
120 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.252.0");
121
122 ca4.truncate(21);
123 BOOST_CHECK_EQUAL(ca4.toString(), "130.161.248.0");
124
125 ComboAddress ca6("2001:888:2000:1d::2");
126 ca6.truncate(120);
127 BOOST_CHECK_EQUAL(ca6.toString(), "2001:888:2000:1d::");
128 ca6.truncate(64);
129 BOOST_CHECK_EQUAL(ca6.toString(), "2001:888:2000:1d::");
130 ca6.truncate(72); // 0102 304 0506 78
131 BOOST_CHECK_EQUAL(ca6.toString(), "2001:888:2000:1d::");
132 ca6.truncate(56);
133 BOOST_CHECK_EQUAL(ca6.toString(), "2001:888:2000::");
134 ca6.truncate(48);
135 BOOST_CHECK_EQUAL(ca6.toString(), "2001:888:2000::");
136 ca6.truncate(32);
137 BOOST_CHECK_EQUAL(ca6.toString(), "2001:888::");
138 ca6.truncate(16);
139 BOOST_CHECK_EQUAL(ca6.toString(), "2001::");
140 ca6.truncate(8);
141 BOOST_CHECK_EQUAL(ca6.toString(), "2000::");
142
143
144 orig=ca6=ComboAddress("2001:888:2000:1d::2");
145 for(int n=128; n; --n) {
146 ca6.truncate(n);
147
148 std::bitset<128> result, manual;
149 for(int i=0; i < 16; ++i) {
150 result<<=8;
151 result|= std::bitset<128>(*((unsigned char*)&ca6.sin6.sin6_addr.s6_addr + i));
152
153 manual<<=8;
154 manual|= std::bitset<128>(*((unsigned char*)&orig.sin6.sin6_addr.s6_addr + i));
155 }
156
157 auto tokill=128-n;
158 for(int i =0; i< tokill; ++i)
159 manual.set(i, 0);
160
161 BOOST_CHECK_EQUAL(result, manual);
162 }
163 }
164
165
166 BOOST_AUTO_TEST_CASE(test_Mapping)
167 {
168 ComboAddress lh("::1");
169 BOOST_CHECK_EQUAL(lh.toString(), "::1");
170 }
171
172 BOOST_AUTO_TEST_CASE(test_Netmask) {
173 ComboAddress local("127.0.0.1", 53);
174 ComboAddress remote("130.161.252.29", 53);
175
176 Netmask nm("127.0.0.1/24");
177 BOOST_CHECK(nm.getBits() == 24);
178 BOOST_CHECK(nm.match(local));
179 BOOST_CHECK(!nm.match(remote));
180 BOOST_CHECK(nm.isIpv4());
181 BOOST_CHECK(!nm.isIpv6());
182
183 Netmask nm6("fe80::92fb:a6ff:fe4a:51da/64");
184 BOOST_CHECK(nm6.getBits() == 64);
185 BOOST_CHECK(nm6.match("fe80::92fb:a6ff:fe4a:51db"));
186 BOOST_CHECK(!nm6.match("fe81::92fb:a6ff:fe4a:51db"));
187 BOOST_CHECK(!nm6.isIpv4());
188 BOOST_CHECK(nm6.isIpv6());
189
190 Netmask nmp("130.161.252.29/32");
191 BOOST_CHECK(nmp.match(remote));
192
193 Netmask nmp6("fe80::92fb:a6ff:fe4a:51da/128");
194 BOOST_CHECK(nmp6.match("fe80::92fb:a6ff:fe4a:51da"));
195 BOOST_CHECK(!nmp6.match("fe81::92fb:a6ff:fe4a:51db"));
196
197 Netmask all("0.0.0.0/0");
198 BOOST_CHECK(all.match(local) && all.match(remote));
199
200 Netmask all6("::/0");
201 BOOST_CHECK(all6.match("::1") && all6.match("fe80::92fb:a6ff:fe4a:51da"));
202
203
204 Netmask fromCombo1(ComboAddress("192.0.2.1:53"), 32);
205 Netmask fromCombo2(ComboAddress("192.0.2.1:54"), 32);
206 BOOST_CHECK(fromCombo1 == fromCombo2);
207 BOOST_CHECK(fromCombo1.match("192.0.2.1"));
208 BOOST_CHECK(fromCombo1.match(ComboAddress("192.0.2.1:80")));
209 BOOST_CHECK(fromCombo1.getNetwork() == ComboAddress("192.0.2.1"));
210 BOOST_CHECK(fromCombo1.getMaskedNetwork() == ComboAddress("192.0.2.1"));
211
212 Netmask nm25("192.0.2.255/25");
213 BOOST_CHECK(nm25.getBits() == 25);
214 BOOST_CHECK(nm25.getNetwork() == ComboAddress("192.0.2.255"));
215 BOOST_CHECK(nm25.getMaskedNetwork() == ComboAddress("192.0.2.128"));
216
217 /* Make sure that more specific Netmasks are lesser than less specific ones,
218 as this is very useful when matching. */
219 Netmask specific32("192.0.0.0/32");
220 Netmask specific24("192.0.0.0/24");
221 Netmask specific16("192.0.0.0/16");
222 BOOST_CHECK(specific32 < specific24);
223 BOOST_CHECK(specific24 > specific32);
224 BOOST_CHECK(specific24 < specific16);
225 BOOST_CHECK(specific16 > specific24);
226
227 Netmask sameMask1("192.0.0.0/16");
228 Netmask sameMask2("192.0.0.1/16");
229 BOOST_CHECK(sameMask1 < sameMask2);
230 BOOST_CHECK(sameMask2 > sameMask1);
231
232 /* An empty Netmask should be larger than
233 every others. */
234 Netmask empty = Netmask();
235 Netmask full("255.255.255.255/32");
236 BOOST_CHECK(empty > all);
237 BOOST_CHECK(all < empty);
238 BOOST_CHECK(empty > full);
239 BOOST_CHECK(full < empty);
240 }
241
242 BOOST_AUTO_TEST_CASE(test_NetmaskGroup) {
243
244 {
245 NetmaskGroup ng;
246 ng.addMask("10.0.1.0");
247 BOOST_CHECK(ng.match(ComboAddress("10.0.1.0")));
248 ng.toMasks("127.0.0.0/8, 10.0.0.0/24");
249 BOOST_CHECK(ng.match(ComboAddress("127.0.0.1")));
250 BOOST_CHECK(ng.match(ComboAddress("10.0.0.3")));
251 BOOST_CHECK(ng.match(ComboAddress("10.0.1.0")));
252 BOOST_CHECK(!ng.match(ComboAddress("128.1.2.3")));
253 BOOST_CHECK(!ng.match(ComboAddress("10.0.1.1")));
254 BOOST_CHECK(!ng.match(ComboAddress("::1")));
255 ng.addMask("::1");
256 BOOST_CHECK(ng.match(ComboAddress("::1")));
257 BOOST_CHECK(!ng.match(ComboAddress("::2")));
258 ng.addMask("fe80::/16");
259 BOOST_CHECK(ng.match(ComboAddress("fe80::1")));
260 BOOST_CHECK(!ng.match(ComboAddress("fe81::1")));
261 BOOST_CHECK_EQUAL(ng.toString(), "10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16");
262
263 /* negative entries using the explicit flag */
264 ng.addMask("172.16.0.0/16", true);
265 BOOST_CHECK(ng.match(ComboAddress("172.16.1.1")));
266 BOOST_CHECK(ng.match(ComboAddress("172.16.4.50")));
267 ng.addMask("172.16.4.0/24", false);
268 BOOST_CHECK(ng.match(ComboAddress("172.16.1.1")));
269 BOOST_CHECK(!ng.match(ComboAddress("172.16.4.50")));
270 ng.addMask("fe80::/24", false);
271 BOOST_CHECK(!ng.match(ComboAddress("fe80::1")));
272 BOOST_CHECK(!ng.match(ComboAddress("fe81::1")));
273 /* not in fe80::/24 but in fe80::/16, should match */
274 BOOST_CHECK(ng.match(ComboAddress("fe80:0100::1")));
275
276 /* negative entries using '!' */
277 BOOST_CHECK(ng.match(ComboAddress("172.16.10.80")));
278 ng.addMask("!172.16.10.0/24");
279 BOOST_CHECK(!ng.match(ComboAddress("172.16.10.80")));
280 ng.addMask("2001:db8::/32");
281 ng.addMask("!2001:db8::/64");
282 BOOST_CHECK(!ng.match(ComboAddress("2001:db8::1")));
283 /* not in 2001:db8::/64 but in 2001:db8::/32, should match */
284 BOOST_CHECK(ng.match(ComboAddress("2001:db8:1::1")));
285
286 BOOST_CHECK_EQUAL(ng.toString(), "10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16, 172.16.0.0/16, !172.16.4.0/24, !fe80::/24, !172.16.10.0/24, 2001:db8::/32, !2001:db8::/64");
287 }
288
289 {
290 /* this time using Netmask objects instead of strings */
291 NetmaskGroup ng;
292 ng.addMask(Netmask("10.0.1.0"));
293 BOOST_CHECK(ng.match(ComboAddress("10.0.1.0")));
294 ng.addMask(Netmask("127.0.0.0/8"));
295 ng.addMask(Netmask("10.0.0.0/24"));
296 BOOST_CHECK(ng.match(ComboAddress("127.0.0.1")));
297 BOOST_CHECK(ng.match(ComboAddress("10.0.0.3")));
298 BOOST_CHECK(ng.match(ComboAddress("10.0.1.0")));
299 BOOST_CHECK(!ng.match(ComboAddress("128.1.2.3")));
300 BOOST_CHECK(!ng.match(ComboAddress("10.0.1.1")));
301 BOOST_CHECK(!ng.match(ComboAddress("::1")));
302 ng.addMask(Netmask("::1"));
303 BOOST_CHECK(ng.match(ComboAddress("::1")));
304 BOOST_CHECK(!ng.match(ComboAddress("::2")));
305 ng.addMask(Netmask("fe80::/16"));
306 BOOST_CHECK(ng.match(ComboAddress("fe80::1")));
307 BOOST_CHECK(!ng.match(ComboAddress("fe81::1")));
308 BOOST_CHECK_EQUAL(ng.toString(), "10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16");
309
310 /* negative entries using the explicit flag */
311 ng.addMask(Netmask("172.16.0.0/16"), true);
312 BOOST_CHECK(ng.match(ComboAddress("172.16.1.1")));
313 BOOST_CHECK(ng.match(ComboAddress("172.16.4.50")));
314 ng.addMask(Netmask("172.16.4.0/24"), false);
315 BOOST_CHECK(ng.match(ComboAddress("172.16.1.1")));
316 BOOST_CHECK(!ng.match(ComboAddress("172.16.4.50")));
317 ng.addMask("fe80::/24", false);
318 BOOST_CHECK(!ng.match(ComboAddress("fe80::1")));
319 BOOST_CHECK(!ng.match(ComboAddress("fe81::1")));
320 /* not in fe80::/24 but in fe80::/16, should match */
321 BOOST_CHECK(ng.match(ComboAddress("fe80:0100::1")));
322
323 BOOST_CHECK_EQUAL(ng.toString(), "10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16, 172.16.0.0/16, !172.16.4.0/24, !fe80::/24");
324 }
325 }
326
327
328 BOOST_AUTO_TEST_CASE(test_NetmaskTree) {
329 NetmaskTree<int> nmt;
330 nmt.insert(Netmask("130.161.252.0/24")).second=0;
331 nmt.insert(Netmask("130.161.0.0/16")).second=1;
332 nmt.insert(Netmask("130.0.0.0/8")).second=2;
333
334 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("213.244.168.210")), (void*)0);
335 auto found=nmt.lookup(ComboAddress("130.161.252.29"));
336 BOOST_CHECK(found);
337 BOOST_CHECK_EQUAL(found->second, 0);
338 found=nmt.lookup(ComboAddress("130.161.180.1"));
339 BOOST_CHECK(found);
340 BOOST_CHECK_EQUAL(found->second, 1);
341
342 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("130.255.255.255"))->second, 2);
343 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("130.161.252.255"))->second, 0);
344 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("130.161.253.255"))->second, 1);
345
346 found=nmt.lookup(ComboAddress("130.145.180.1"));
347 BOOST_CHECK(found);
348 BOOST_CHECK_EQUAL(found->second, 2);
349
350 nmt.clear();
351 BOOST_CHECK(!nmt.lookup(ComboAddress("130.161.180.1")));
352
353 nmt.insert(Netmask("::1")).second=1;
354 nmt.insert(Netmask("::/0")).second=0;
355 nmt.insert(Netmask("fe80::/16")).second=2;
356 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("130.161.253.255")), (void*)0);
357 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("::2"))->second, 0);
358 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("::ffff"))->second, 0);
359 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("::1"))->second, 1);
360 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("fe80::1"))->second, 2);
361 }
362
363 BOOST_AUTO_TEST_CASE(test_single) {
364 NetmaskTree<bool> nmt;
365 nmt.insert(Netmask("127.0.0.0/8")).second=1;
366 BOOST_CHECK_EQUAL(nmt.lookup(ComboAddress("127.0.0.1"))->second, 1);
367 }
368
369 BOOST_AUTO_TEST_CASE(test_scale) {
370 string start="192.168.";
371 NetmaskTree<int> works;
372 for(int i=0; i < 256; ++i) {
373 for(int j=0; j < 256; ++j) {
374 works.insert(Netmask(start+std::to_string(i)+"."+std::to_string(j))).second=i*j;
375 }
376 }
377
378 for(int i=0; i < 256; ++i) {
379 for(int j=0; j < 256; ++j) {
380 BOOST_CHECK_EQUAL(works.lookup(ComboAddress(start+std::to_string(i)+"."+std::to_string(j)))->second, i*j);
381 }
382 }
383
384 start="130.161.";
385 for(int i=0; i < 256; ++i) {
386 for(int j=0; j < 256; ++j) {
387 BOOST_CHECK_EQUAL(works.lookup(ComboAddress(start+std::to_string(i)+"."+std::to_string(j))), (void*)0);
388 }
389 }
390
391 start="2000:123:";
392 for(int i=0; i < 256; ++i) {
393 for(int j=0; j < 256; ++j) {
394 works.insert(Netmask(start+std::to_string(i)+":"+std::to_string(j)+"::/64")).second=i*j;
395 }
396 }
397
398 for(int i=0; i < 256; ++i) {
399 for(int j=0; j < 256; ++j) {
400 BOOST_CHECK_EQUAL(works.lookup(ComboAddress(start+std::to_string(i)+":"+std::to_string(j)+"::"+std::to_string(i)+":"+std::to_string(j)))->second, i*j);
401 }
402 }
403
404 start="2001:123:";
405 for(int i=0; i < 256; ++i) {
406 for(int j=0; j < 256; ++j) {
407 BOOST_CHECK_EQUAL(works.lookup(ComboAddress(start+std::to_string(i)+":"+std::to_string(j)+"::"+std::to_string(i)+":"+std::to_string(j))), (void*)0);
408 }
409 }
410 }
411
412 BOOST_AUTO_TEST_CASE(test_removal) {
413 std::string prefix = "192.";
414 NetmaskTree<int> nmt(true);
415
416 size_t count = 0;
417 for(unsigned int i = 0; i < 256; ++i) {
418 for(unsigned int j = 16; j <= 32; ++j) {
419 nmt.insert(Netmask(prefix + std::to_string(i) +".127.255/"+std::to_string(j))).second = j;
420 count++;
421 }
422 }
423
424 BOOST_CHECK_EQUAL(nmt.size(), count);
425
426 for(unsigned int i = 0; i < 256; ++i) {
427 ComboAddress key(prefix + std::to_string(i) + ".127.255");
428 const auto result = nmt.lookup(key);
429 BOOST_CHECK_EQUAL(result->first.getBits(), 32);
430 BOOST_CHECK_EQUAL(result->first.getMaskedNetwork().toString(), key.toString());
431 BOOST_CHECK_EQUAL(result->second, 32);
432 }
433
434 for(unsigned int i = 0; i < 256; ++i) {
435 for(unsigned int j = 32; j >= 16; --j) {
436 ComboAddress key(prefix + std::to_string(i) + ".127.255");
437 nmt.erase(Netmask(key, j));
438 const auto result = nmt.lookup(key);
439
440 if (j > 16) {
441 BOOST_REQUIRE(result != nullptr);
442 BOOST_CHECK_EQUAL(result->first.getBits(), j-1);
443 BOOST_CHECK_EQUAL(result->first.getMaskedNetwork().toString(), Netmask(key, j-1).getMaskedNetwork().toString());
444 BOOST_CHECK_EQUAL(result->second, j - 1);
445 }
446 else {
447 BOOST_CHECK(result == nullptr);
448 }
449 }
450 }
451
452 BOOST_CHECK_EQUAL(nmt.size(), 0);
453 BOOST_CHECK(nmt.empty());
454 }
455
456 BOOST_AUTO_TEST_SUITE_END()