1 /*
2 * testcode/unitmain.c - unit test main program for unbound.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36 /**
37 * \file
38 * Unit test main program. Calls all the other unit tests.
39 * Exits with code 1 on a failure. 0 if all unit tests are successful.
40 */
41
42 #include "config.h"
43 #ifdef HAVE_OPENSSL_ERR_H
44 #include <openssl/err.h>
45 #endif
46
47 #ifdef HAVE_OPENSSL_RAND_H
48 #include <openssl/rand.h>
49 #endif
50
51 #ifdef HAVE_OPENSSL_CONF_H
52 #include <openssl/conf.h>
53 #endif
54
55 #ifdef HAVE_OPENSSL_ENGINE_H
56 #include <openssl/engine.h>
57 #endif
58
59 #ifdef HAVE_NSS
60 /* nss3 */
61 #include "nss.h"
62 #endif
63
64 #include "sldns/rrdef.h"
65 #include "sldns/keyraw.h"
66 #include "util/log.h"
67 #include "testcode/unitmain.h"
68
69 /** number of tests done */
70 int testcount = 0;
71
72 #include "util/alloc.h"
73 /** test alloc code */
74 static void
alloc_test(void)75 alloc_test(void) {
76 alloc_special_type *t1, *t2;
77 struct alloc_cache major, minor1, minor2;
78 int i;
79
80 unit_show_feature("alloc_special_obtain");
81 alloc_init(&major, NULL, 0);
82 alloc_init(&minor1, &major, 0);
83 alloc_init(&minor2, &major, 1);
84
85 t1 = alloc_special_obtain(&minor1);
86 alloc_clear(&minor1);
87
88 alloc_special_release(&minor2, t1);
89 t2 = alloc_special_obtain(&minor2);
90 unit_assert( t1 == t2 ); /* reused */
91 alloc_special_release(&minor2, t1);
92
93 for(i=0; i<100; i++) {
94 t1 = alloc_special_obtain(&minor1);
95 alloc_special_release(&minor2, t1);
96 }
97 if(0) {
98 alloc_stats(&minor1);
99 alloc_stats(&minor2);
100 alloc_stats(&major);
101 }
102 /* reuse happened */
103 unit_assert(minor1.num_quar + minor2.num_quar + major.num_quar == 11);
104
105 alloc_clear(&minor1);
106 alloc_clear(&minor2);
107 unit_assert(major.num_quar == 11);
108 alloc_clear(&major);
109 }
110
111 #include "util/net_help.h"
112 /** test net code */
113 static void
net_test(void)114 net_test(void)
115 {
116 const char* t4[] = {"\000\000\000\000",
117 "\200\000\000\000",
118 "\300\000\000\000",
119 "\340\000\000\000",
120 "\360\000\000\000",
121 "\370\000\000\000",
122 "\374\000\000\000",
123 "\376\000\000\000",
124 "\377\000\000\000",
125 "\377\200\000\000",
126 "\377\300\000\000",
127 "\377\340\000\000",
128 "\377\360\000\000",
129 "\377\370\000\000",
130 "\377\374\000\000",
131 "\377\376\000\000",
132 "\377\377\000\000",
133 "\377\377\200\000",
134 "\377\377\300\000",
135 "\377\377\340\000",
136 "\377\377\360\000",
137 "\377\377\370\000",
138 "\377\377\374\000",
139 "\377\377\376\000",
140 "\377\377\377\000",
141 "\377\377\377\200",
142 "\377\377\377\300",
143 "\377\377\377\340",
144 "\377\377\377\360",
145 "\377\377\377\370",
146 "\377\377\377\374",
147 "\377\377\377\376",
148 "\377\377\377\377",
149 "\377\377\377\377",
150 "\377\377\377\377",
151 };
152 unit_show_func("util/net_help.c", "str_is_ip6");
153 unit_assert( str_is_ip6("::") );
154 unit_assert( str_is_ip6("::1") );
155 unit_assert( str_is_ip6("2001:7b8:206:1:240:f4ff:fe37:8810") );
156 unit_assert( str_is_ip6("fe80::240:f4ff:fe37:8810") );
157 unit_assert( !str_is_ip6("0.0.0.0") );
158 unit_assert( !str_is_ip6("213.154.224.12") );
159 unit_assert( !str_is_ip6("213.154.224.255") );
160 unit_assert( !str_is_ip6("255.255.255.0") );
161 unit_show_func("util/net_help.c", "is_pow2");
162 unit_assert( is_pow2(0) );
163 unit_assert( is_pow2(1) );
164 unit_assert( is_pow2(2) );
165 unit_assert( is_pow2(4) );
166 unit_assert( is_pow2(8) );
167 unit_assert( is_pow2(16) );
168 unit_assert( is_pow2(1024) );
169 unit_assert( is_pow2(1024*1024) );
170 unit_assert( is_pow2(1024*1024*1024) );
171 unit_assert( !is_pow2(3) );
172 unit_assert( !is_pow2(5) );
173 unit_assert( !is_pow2(6) );
174 unit_assert( !is_pow2(7) );
175 unit_assert( !is_pow2(9) );
176 unit_assert( !is_pow2(10) );
177 unit_assert( !is_pow2(11) );
178 unit_assert( !is_pow2(17) );
179 unit_assert( !is_pow2(23) );
180 unit_assert( !is_pow2(257) );
181 unit_assert( !is_pow2(259) );
182
183 /* test addr_mask */
184 unit_show_func("util/net_help.c", "addr_mask");
185 if(1) {
186 struct sockaddr_in a4;
187 struct sockaddr_in6 a6;
188 socklen_t l4 = (socklen_t)sizeof(a4);
189 socklen_t l6 = (socklen_t)sizeof(a6);
190 int i;
191 a4.sin_family = AF_INET;
192 a6.sin6_family = AF_INET6;
193 for(i=0; i<35; i++) {
194 /* address 255.255.255.255 */
195 memcpy(&a4.sin_addr, "\377\377\377\377", 4);
196 addr_mask((struct sockaddr_storage*)&a4, l4, i);
197 unit_assert(memcmp(&a4.sin_addr, t4[i], 4) == 0);
198 }
199 memcpy(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16);
200 addr_mask((struct sockaddr_storage*)&a6, l6, 128);
201 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) == 0);
202 addr_mask((struct sockaddr_storage*)&a6, l6, 122);
203 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\300", 16) == 0);
204 addr_mask((struct sockaddr_storage*)&a6, l6, 120);
205 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000", 16) == 0);
206 addr_mask((struct sockaddr_storage*)&a6, l6, 64);
207 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", 16) == 0);
208 /* Check that negative value in net is not problematic. */
209 addr_mask((struct sockaddr_storage*)&a6, l6, -100);
210 addr_mask((struct sockaddr_storage*)&a6, l6, 0);
211 unit_assert(memcmp(&a6.sin6_addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16) == 0);
212 }
213
214 /* test addr_in_common */
215 unit_show_func("util/net_help.c", "addr_in_common");
216 if(1) {
217 struct sockaddr_in a4, b4;
218 struct sockaddr_in6 a6, b6;
219 socklen_t l4 = (socklen_t)sizeof(a4);
220 socklen_t l6 = (socklen_t)sizeof(a6);
221 int i;
222 a4.sin_family = AF_INET;
223 b4.sin_family = AF_INET;
224 a6.sin6_family = AF_INET6;
225 b6.sin6_family = AF_INET6;
226 memcpy(&a4.sin_addr, "abcd", 4);
227 memcpy(&b4.sin_addr, "abcd", 4);
228 unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 32,
229 (struct sockaddr_storage*)&b4, 32, l4) == 32);
230 unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 34,
231 (struct sockaddr_storage*)&b4, 32, l4) == 32);
232 for(i=0; i<=32; i++) {
233 unit_assert(addr_in_common(
234 (struct sockaddr_storage*)&a4, 32,
235 (struct sockaddr_storage*)&b4, i, l4) == i);
236 unit_assert(addr_in_common(
237 (struct sockaddr_storage*)&a4, i,
238 (struct sockaddr_storage*)&b4, 32, l4) == i);
239 unit_assert(addr_in_common(
240 (struct sockaddr_storage*)&a4, i,
241 (struct sockaddr_storage*)&b4, i, l4) == i);
242 }
243 for(i=0; i<=32; i++) {
244 memcpy(&a4.sin_addr, "\377\377\377\377", 4);
245 memcpy(&b4.sin_addr, t4[i], 4);
246 unit_assert(addr_in_common(
247 (struct sockaddr_storage*)&a4, 32,
248 (struct sockaddr_storage*)&b4, 32, l4) == i);
249 unit_assert(addr_in_common(
250 (struct sockaddr_storage*)&b4, 32,
251 (struct sockaddr_storage*)&a4, 32, l4) == i);
252 }
253 memcpy(&a6.sin6_addr, "abcdefghabcdefgh", 16);
254 memcpy(&b6.sin6_addr, "abcdefghabcdefgh", 16);
255 unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 128,
256 (struct sockaddr_storage*)&b6, 128, l6) == 128);
257 unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 129,
258 (struct sockaddr_storage*)&b6, 128, l6) == 128);
259 for(i=0; i<=128; i++) {
260 unit_assert(addr_in_common(
261 (struct sockaddr_storage*)&a6, 128,
262 (struct sockaddr_storage*)&b6, i, l6) == i);
263 unit_assert(addr_in_common(
264 (struct sockaddr_storage*)&a6, i,
265 (struct sockaddr_storage*)&b6, 128, l6) == i);
266 unit_assert(addr_in_common(
267 (struct sockaddr_storage*)&a6, i,
268 (struct sockaddr_storage*)&b6, i, l6) == i);
269 }
270 }
271 /* test netblockstrtoaddr */
272 unit_show_func("util/net_help.c", "netblockstrtoaddr");
273 if(1) {
274 struct sockaddr_storage a;
275 socklen_t alen = 0;
276 int net = 0, res;
277 char astr[128];
278 memset(&a, 0, sizeof(a));
279
280 res = netblockstrtoaddr("1.2.3.0/24", 53, &a, &alen, &net);
281 unit_assert(res!=0 && net == 24);
282 addr_to_str(&a, alen, astr, sizeof(astr));
283 unit_assert(strcmp(astr, "1.2.3.0") == 0);
284 unit_assert(ntohs(((struct sockaddr_in*)&a)->sin_port)==53);
285
286 res = netblockstrtoaddr("2001:DB8:33:44::/64", 53,
287 &a, &alen, &net);
288 unit_assert(res!=0 && net == 64);
289 addr_to_str(&a, alen, astr, sizeof(astr));
290 unit_assert(strcmp(astr, "2001:db8:33:44::") == 0);
291 unit_assert(ntohs(((struct sockaddr_in6*)&a)->sin6_port)==53);
292 }
293 /* test sockaddr_cmp_addr */
294 unit_show_func("util/net_help.c", "sockaddr_cmp_addr");
295 if(1) {
296 struct sockaddr_storage a, b;
297 socklen_t alen = (socklen_t)sizeof(a);
298 socklen_t blen = (socklen_t)sizeof(b);
299 unit_assert(ipstrtoaddr("127.0.0.0", 53, &a, &alen));
300 unit_assert(ipstrtoaddr("127.255.255.255", 53, &b, &blen));
301 unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0);
302 unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0);
303 unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0);
304 unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0);
305 unit_assert(ipstrtoaddr("192.168.121.5", 53, &a, &alen));
306 unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) > 0);
307 unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) < 0);
308 unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0);
309 unit_assert(ipstrtoaddr("2001:3578:ffeb::99", 53, &b, &blen));
310 unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0);
311 unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0);
312 unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0);
313 }
314 /* test addr_is_ip4mapped */
315 unit_show_func("util/net_help.c", "addr_is_ip4mapped");
316 if(1) {
317 struct sockaddr_storage a;
318 socklen_t l = (socklen_t)sizeof(a);
319 unit_assert(ipstrtoaddr("12.13.14.15", 53, &a, &l));
320 unit_assert(!addr_is_ip4mapped(&a, l));
321 unit_assert(ipstrtoaddr("fe80::217:31ff:fe91:df", 53, &a, &l));
322 unit_assert(!addr_is_ip4mapped(&a, l));
323 unit_assert(ipstrtoaddr("ffff::217:31ff:fe91:df", 53, &a, &l));
324 unit_assert(!addr_is_ip4mapped(&a, l));
325 unit_assert(ipstrtoaddr("::ffff:31ff:fe91:df", 53, &a, &l));
326 unit_assert(!addr_is_ip4mapped(&a, l));
327 unit_assert(ipstrtoaddr("::fffe:fe91:df", 53, &a, &l));
328 unit_assert(!addr_is_ip4mapped(&a, l));
329 unit_assert(ipstrtoaddr("::ffff:127.0.0.1", 53, &a, &l));
330 unit_assert(addr_is_ip4mapped(&a, l));
331 unit_assert(ipstrtoaddr("::ffff:127.0.0.2", 53, &a, &l));
332 unit_assert(addr_is_ip4mapped(&a, l));
333 unit_assert(ipstrtoaddr("::ffff:192.168.0.2", 53, &a, &l));
334 unit_assert(addr_is_ip4mapped(&a, l));
335 unit_assert(ipstrtoaddr("2::ffff:192.168.0.2", 53, &a, &l));
336 unit_assert(!addr_is_ip4mapped(&a, l));
337 }
338 /* test addr_is_any */
339 unit_show_func("util/net_help.c", "addr_is_any");
340 if(1) {
341 struct sockaddr_storage a;
342 socklen_t l = (socklen_t)sizeof(a);
343 unit_assert(ipstrtoaddr("0.0.0.0", 53, &a, &l));
344 unit_assert(addr_is_any(&a, l));
345 unit_assert(ipstrtoaddr("0.0.0.0", 10053, &a, &l));
346 unit_assert(addr_is_any(&a, l));
347 unit_assert(ipstrtoaddr("0.0.0.0", 0, &a, &l));
348 unit_assert(addr_is_any(&a, l));
349 unit_assert(ipstrtoaddr("::0", 0, &a, &l));
350 unit_assert(addr_is_any(&a, l));
351 unit_assert(ipstrtoaddr("::0", 53, &a, &l));
352 unit_assert(addr_is_any(&a, l));
353 unit_assert(ipstrtoaddr("::1", 53, &a, &l));
354 unit_assert(!addr_is_any(&a, l));
355 unit_assert(ipstrtoaddr("2001:1667::1", 0, &a, &l));
356 unit_assert(!addr_is_any(&a, l));
357 unit_assert(ipstrtoaddr("2001::0", 0, &a, &l));
358 unit_assert(!addr_is_any(&a, l));
359 unit_assert(ipstrtoaddr("10.0.0.0", 0, &a, &l));
360 unit_assert(!addr_is_any(&a, l));
361 unit_assert(ipstrtoaddr("0.0.0.10", 0, &a, &l));
362 unit_assert(!addr_is_any(&a, l));
363 unit_assert(ipstrtoaddr("192.0.2.1", 0, &a, &l));
364 unit_assert(!addr_is_any(&a, l));
365 }
366 }
367
368 #include "util/config_file.h"
369 /** test config_file: cfg_parse_memsize */
370 static void
config_memsize_test(void)371 config_memsize_test(void)
372 {
373 size_t v = 0;
374 unit_show_func("util/config_file.c", "cfg_parse_memsize");
375 if(0) {
376 /* these emit errors */
377 unit_assert( cfg_parse_memsize("", &v) == 0);
378 unit_assert( cfg_parse_memsize("bla", &v) == 0);
379 unit_assert( cfg_parse_memsize("nop", &v) == 0);
380 unit_assert( cfg_parse_memsize("n0b", &v) == 0);
381 unit_assert( cfg_parse_memsize("gb", &v) == 0);
382 unit_assert( cfg_parse_memsize("b", &v) == 0);
383 unit_assert( cfg_parse_memsize("kb", &v) == 0);
384 unit_assert( cfg_parse_memsize("kk kb", &v) == 0);
385 }
386 unit_assert( cfg_parse_memsize("0", &v) && v==0);
387 unit_assert( cfg_parse_memsize("1", &v) && v==1);
388 unit_assert( cfg_parse_memsize("10", &v) && v==10);
389 unit_assert( cfg_parse_memsize("10b", &v) && v==10);
390 unit_assert( cfg_parse_memsize("5b", &v) && v==5);
391 unit_assert( cfg_parse_memsize("1024", &v) && v==1024);
392 unit_assert( cfg_parse_memsize("1k", &v) && v==1024);
393 unit_assert( cfg_parse_memsize("1K", &v) && v==1024);
394 unit_assert( cfg_parse_memsize("1Kb", &v) && v==1024);
395 unit_assert( cfg_parse_memsize("1kb", &v) && v==1024);
396 unit_assert( cfg_parse_memsize("1 kb", &v) && v==1024);
397 unit_assert( cfg_parse_memsize("10 kb", &v) && v==10240);
398 unit_assert( cfg_parse_memsize("2k", &v) && v==2048);
399 unit_assert( cfg_parse_memsize("2m", &v) && v==2048*1024);
400 unit_assert( cfg_parse_memsize("3M", &v) && v==3072*1024);
401 unit_assert( cfg_parse_memsize("40m", &v) && v==40960*1024);
402 unit_assert( cfg_parse_memsize("1G", &v) && v==1024*1024*1024);
403 unit_assert( cfg_parse_memsize("1 Gb", &v) && v==1024*1024*1024);
404 unit_assert( cfg_parse_memsize("0 Gb", &v) && v==0*1024*1024);
405 }
406
407 /** test config_file: test tag code */
408 static void
config_tag_test(void)409 config_tag_test(void)
410 {
411 unit_show_func("util/config_file.c", "taglist_intersect");
412 unit_assert( taglist_intersect(
413 (uint8_t*)"\000\000\000", 3, (uint8_t*)"\001\000\001", 3
414 ) == 0);
415 unit_assert( taglist_intersect(
416 (uint8_t*)"\000\000\001", 3, (uint8_t*)"\001\000\001", 3
417 ) == 1);
418 unit_assert( taglist_intersect(
419 (uint8_t*)"\001\000\000", 3, (uint8_t*)"\001\000\001", 3
420 ) == 1);
421 unit_assert( taglist_intersect(
422 (uint8_t*)"\001", 1, (uint8_t*)"\001\000\001", 3
423 ) == 1);
424 unit_assert( taglist_intersect(
425 (uint8_t*)"\001\000\001", 3, (uint8_t*)"\001", 1
426 ) == 1);
427 }
428
429 #include "util/rtt.h"
430 #include "util/timehist.h"
431 #include "iterator/iterator.h"
432 #include "libunbound/unbound.h"
433 /** test RTT code */
434 static void
rtt_test(void)435 rtt_test(void)
436 {
437 int init = UNKNOWN_SERVER_NICENESS;
438 int i;
439 struct rtt_info r;
440 unit_show_func("util/rtt.c", "rtt_timeout");
441 rtt_init(&r);
442 /* initial value sensible */
443 unit_assert( rtt_timeout(&r) == init );
444 rtt_lost(&r, init);
445 unit_assert( rtt_timeout(&r) == init*2 );
446 rtt_lost(&r, init*2);
447 unit_assert( rtt_timeout(&r) == init*4 );
448 rtt_update(&r, 4000);
449 unit_assert( rtt_timeout(&r) >= 2000 );
450 rtt_lost(&r, rtt_timeout(&r) );
451 for(i=0; i<100; i++) {
452 rtt_lost(&r, rtt_timeout(&r) );
453 unit_assert( rtt_timeout(&r) > RTT_MIN_TIMEOUT-1);
454 unit_assert( rtt_timeout(&r) < RTT_MAX_TIMEOUT+1);
455 }
456 /* must be the same, timehist bucket is used in stats */
457 unit_assert(UB_STATS_BUCKET_NUM == NUM_BUCKETS_HIST);
458 }
459
460 #include "util/edns.h"
461 /* Complete version-invalid client cookie; needs a new one.
462 * Based on edns_cookie_rfc9018_a2 */
463 static void
edns_cookie_invalid_version(void)464 edns_cookie_invalid_version(void)
465 {
466 uint32_t timestamp = 1559734385;
467 uint8_t client_cookie[] = {
468 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57,
469 0x99, 0x00, 0x00, 0x00,
470 0x5c, 0xf7, 0x9f, 0x11,
471 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 };
472 uint8_t server_cookie[] = {
473 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57,
474 0x01, 0x00, 0x00, 0x00,
475 0x5c, 0xf7, 0xa8, 0x71,
476 0xd4, 0xa5, 0x64, 0xa1, 0x44, 0x2a, 0xca, 0x77 };
477 uint8_t server_secret[] = {
478 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f,
479 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf };
480 uint8_t buf[32];
481 /* copy client cookie|version|reserved|timestamp */
482 memcpy(buf, client_cookie, 8 + 4 + 4);
483 /* copy ip 198.51.100.100 */
484 memcpy(buf + 16, "\306\063\144\144", 4);
485 unit_assert(edns_cookie_server_validate(client_cookie,
486 sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
487 buf, timestamp) == COOKIE_STATUS_INVALID);
488 edns_cookie_server_write(buf, server_secret, 1, timestamp);
489 unit_assert(memcmp(server_cookie, buf, 24) == 0);
490 }
491
492 /* Complete hash-invalid client cookie; needs a new one. */
493 static void
edns_cookie_invalid_hash(void)494 edns_cookie_invalid_hash(void)
495 {
496 uint32_t timestamp = 0;
497 uint8_t client_cookie[] = {
498 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86,
499 0x01, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00,
501 0x32, 0xF2, 0x43, 0xB9, 0xBC, 0xFE, 0xC4, 0x06 };
502 uint8_t server_cookie[] = {
503 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86,
504 0x01, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00,
506 0xBA, 0x0D, 0x82, 0x90, 0x8F, 0xAA, 0xEB, 0xBD };
507 uint8_t server_secret[] = {
508 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f,
509 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf };
510 uint8_t buf[32];
511 /* copy client cookie|version|reserved|timestamp */
512 memcpy(buf, client_cookie, 8 + 4 + 4);
513 /* copy ip 203.0.113.203 */
514 memcpy(buf + 16, "\313\000\161\313", 4);
515 unit_assert(edns_cookie_server_validate(client_cookie,
516 sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
517 buf, timestamp) == COOKIE_STATUS_INVALID);
518 edns_cookie_server_write(buf, server_secret, 1, timestamp);
519 unit_assert(memcmp(server_cookie, buf, 24) == 0);
520 }
521
522 /* Complete hash-valid client cookie; more than 30 minutes old; needs a
523 * refreshed server cookie.
524 * A slightly better variation of edns_cookie_rfc9018_a3 for Unbound to check
525 * that RESERVED bits do not influence cookie validation. */
526 static void
edns_cookie_rfc9018_a3_better(void)527 edns_cookie_rfc9018_a3_better(void)
528 {
529 uint32_t timestamp = 1800 + 1;
530 uint8_t client_cookie[] = {
531 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86,
532 0x01, 0xab, 0xcd, 0xef,
533 0x00, 0x00, 0x00, 0x00,
534 0x32, 0xF2, 0x43, 0xB9, 0xBC, 0xFE, 0xC4, 0x06 };
535 uint8_t server_cookie[] = {
536 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86,
537 0x01, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x07, 0x09,
539 0x62, 0xD5, 0x93, 0x09, 0x14, 0x5C, 0x23, 0x9D };
540 uint8_t server_secret[] = {
541 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f,
542 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf };
543 uint8_t buf[32];
544 /* copy client cookie|version|reserved|timestamp */
545 memcpy(buf, client_cookie, 8 + 4 + 4);
546 /* copy ip 203.0.113.203 */
547 memcpy(buf + 16, "\313\000\161\313", 4);
548 unit_assert(edns_cookie_server_validate(client_cookie,
549 sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
550 buf, timestamp) == COOKIE_STATUS_VALID_RENEW);
551 edns_cookie_server_write(buf, server_secret, 1, timestamp);
552 unit_assert(memcmp(server_cookie, buf, 24) == 0);
553 }
554
555 /* Complete hash-valid client cookie; more than 60 minutes old (expired);
556 * needs a refreshed server cookie. */
557 static void
edns_cookie_rfc9018_a3(void)558 edns_cookie_rfc9018_a3(void)
559 {
560 uint32_t timestamp = 1559734700;
561 uint8_t client_cookie[] = {
562 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86,
563 0x01, 0xab, 0xcd, 0xef,
564 0x5c, 0xf7, 0x8f, 0x71,
565 0xa3, 0x14, 0x22, 0x7b, 0x66, 0x79, 0xeb, 0xf5 };
566 uint8_t server_cookie[] = {
567 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86,
568 0x01, 0x00, 0x00, 0x00,
569 0x5c, 0xf7, 0xa9, 0xac,
570 0xf7, 0x3a, 0x78, 0x10, 0xac, 0xa2, 0x38, 0x1e };
571 uint8_t server_secret[] = {
572 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f,
573 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf };
574 uint8_t buf[32];
575 /* copy client cookie|version|reserved|timestamp */
576 memcpy(buf, client_cookie, 8 + 4 + 4);
577 /* copy ip 203.0.113.203 */
578 memcpy(buf + 16, "\313\000\161\313", 4);
579 unit_assert(edns_cookie_server_validate(client_cookie,
580 sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
581 buf, timestamp) == COOKIE_STATUS_EXPIRED);
582 edns_cookie_server_write(buf, server_secret, 1, timestamp);
583 unit_assert(memcmp(server_cookie, buf, 24) == 0);
584 }
585
586 /* Complete hash-valid client cookie; more than 30 minutes old; needs a
587 * refreshed server cookie. */
588 static void
edns_cookie_rfc9018_a2(void)589 edns_cookie_rfc9018_a2(void)
590 {
591 uint32_t timestamp = 1559734385;
592 uint8_t client_cookie[] = {
593 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57,
594 0x01, 0x00, 0x00, 0x00,
595 0x5c, 0xf7, 0x9f, 0x11,
596 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 };
597 uint8_t server_cookie[] = {
598 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57,
599 0x01, 0x00, 0x00, 0x00,
600 0x5c, 0xf7, 0xa8, 0x71,
601 0xd4, 0xa5, 0x64, 0xa1, 0x44, 0x2a, 0xca, 0x77 };
602 uint8_t server_secret[] = {
603 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f,
604 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf };
605 uint8_t buf[32];
606 /* copy client cookie|version|reserved|timestamp */
607 memcpy(buf, client_cookie, 8 + 4 + 4);
608 /* copy ip 198.51.100.100 */
609 memcpy(buf + 16, "\306\063\144\144", 4);
610 unit_assert(edns_cookie_server_validate(client_cookie,
611 sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
612 buf, timestamp) == COOKIE_STATUS_VALID_RENEW);
613 edns_cookie_server_write(buf, server_secret, 1, timestamp);
614 unit_assert(memcmp(server_cookie, buf, 24) == 0);
615 }
616
617 /* Only client cookie; needs a complete server cookie. */
618 static void
edns_cookie_rfc9018_a1(void)619 edns_cookie_rfc9018_a1(void)
620 {
621 uint32_t timestamp = 1559731985;
622 uint8_t client_cookie[] = {
623 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57 };
624 uint8_t server_cookie[] = {
625 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57,
626 0x01, 0x00, 0x00, 0x00,
627 0x5c, 0xf7, 0x9f, 0x11,
628 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 };
629 uint8_t server_secret[] = {
630 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f,
631 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf };
632 uint8_t buf[32];
633 /* copy client cookie|version|reserved|timestamp */
634 memcpy(buf, server_cookie, 8 + 4 + 4);
635 /* copy ip 198.51.100.100 */
636 memcpy(buf + 16, "\306\063\144\144", 4);
637 unit_assert(edns_cookie_server_validate(client_cookie,
638 sizeof(client_cookie),
639 /* these will not be used; it will return invalid
640 * because of the size. */
641 NULL, 0, 1, NULL, 0) == COOKIE_STATUS_CLIENT_ONLY);
642 edns_cookie_server_write(buf, server_secret, 1, timestamp);
643 unit_assert(memcmp(server_cookie, buf, 24) == 0);
644 }
645
646 /** test interoperable DNS cookies (RFC9018) */
647 static void
edns_cookie_test(void)648 edns_cookie_test(void)
649 {
650 unit_show_feature("interoperable dns cookies");
651 /* Check RFC9018 appendix test vectors */
652 edns_cookie_rfc9018_a1();
653 edns_cookie_rfc9018_a2();
654 edns_cookie_rfc9018_a3();
655 /* More tests */
656 edns_cookie_rfc9018_a3_better();
657 edns_cookie_invalid_hash();
658 edns_cookie_invalid_version();
659 }
660
661 #include "util/random.h"
662 /** test randomness */
663 static void
rnd_test(void)664 rnd_test(void)
665 {
666 struct ub_randstate* r;
667 int num = 1000, i;
668 long int a[1000];
669 unit_show_feature("ub_random");
670 unit_assert( (r = ub_initstate(NULL)) );
671 for(i=0; i<num; i++) {
672 a[i] = ub_random(r);
673 unit_assert(a[i] >= 0);
674 unit_assert((size_t)a[i] <= (size_t)0x7fffffff);
675 if(i > 5)
676 unit_assert(a[i] != a[i-1] || a[i] != a[i-2] ||
677 a[i] != a[i-3] || a[i] != a[i-4] ||
678 a[i] != a[i-5] || a[i] != a[i-6]);
679 }
680 a[0] = ub_random_max(r, 1);
681 unit_assert(a[0] >= 0 && a[0] < 1);
682 a[0] = ub_random_max(r, 10000);
683 unit_assert(a[0] >= 0 && a[0] < 10000);
684 for(i=0; i<num; i++) {
685 a[i] = ub_random_max(r, 10);
686 unit_assert(a[i] >= 0 && a[i] < 10);
687 }
688 ub_randfree(r);
689 }
690
691 #include "respip/respip.h"
692 #include "services/localzone.h"
693 #include "util/data/packed_rrset.h"
694 typedef struct addr_action {char* ip; char* sact; enum respip_action act;}
695 addr_action_t;
696
697 /** Utility function that verifies that the respip set has actions as expected */
698 static void
verify_respip_set_actions(struct respip_set * set,addr_action_t actions[],int actions_len)699 verify_respip_set_actions(struct respip_set* set, addr_action_t actions[],
700 int actions_len)
701 {
702 int i = 0;
703 struct rbtree_type* tree = respip_set_get_tree(set);
704 for (i=0; i<actions_len; i++) {
705 struct sockaddr_storage addr;
706 int net;
707 socklen_t addrlen;
708 struct resp_addr* node;
709 netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr,
710 &addrlen, &net);
711 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
712
713 /** we have the node and the node has the correct action
714 * and has no data */
715 unit_assert(node);
716 unit_assert(actions[i].act ==
717 resp_addr_get_action(node));
718 unit_assert(resp_addr_get_rrset(node) == NULL);
719 }
720 unit_assert(actions_len && i == actions_len);
721 unit_assert(actions_len == (int)tree->count);
722 }
723
724 /** Global respip actions test; apply raw config data and verify that
725 * all the nodes in the respip set, looked up by address, have expected
726 * actions */
727 static void
respip_conf_actions_test(void)728 respip_conf_actions_test(void)
729 {
730 addr_action_t config_response_ip[] = {
731 {"192.0.1.0/24", "deny", respip_deny},
732 {"192.0.2.0/24", "redirect", respip_redirect},
733 {"192.0.3.0/26", "inform", respip_inform},
734 {"192.0.4.0/27", "inform_deny", respip_inform_deny},
735 {"2001:db8:1::/48", "always_transparent", respip_always_transparent},
736 {"2001:db8:2::/49", "always_refuse", respip_always_refuse},
737 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
738 };
739 int i;
740 struct respip_set* set = respip_set_create();
741 struct config_file cfg;
742 int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t));
743
744 unit_assert(set);
745 unit_show_feature("global respip config actions apply");
746 memset(&cfg, 0, sizeof(cfg));
747 for(i=0; i<clen; i++) {
748 char* ip = strdup(config_response_ip[i].ip);
749 char* sact = strdup(config_response_ip[i].sact);
750 unit_assert(ip && sact);
751 if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact))
752 unit_assert(0);
753 }
754 unit_assert(respip_global_apply_cfg(set, &cfg));
755 verify_respip_set_actions(set, config_response_ip, clen);
756
757 respip_set_delete(set);
758 config_deldblstrlist(cfg.respip_actions);
759 }
760
761 /** Per-view respip actions test; apply raw configuration with two views
762 * and verify that actions are as expected in respip sets of both views */
763 static void
respip_view_conf_actions_test(void)764 respip_view_conf_actions_test(void)
765 {
766 addr_action_t config_response_ip_view1[] = {
767 {"192.0.1.0/24", "deny", respip_deny},
768 {"192.0.2.0/24", "redirect", respip_redirect},
769 {"192.0.3.0/26", "inform", respip_inform},
770 {"192.0.4.0/27", "inform_deny", respip_inform_deny},
771 };
772 addr_action_t config_response_ip_view2[] = {
773 {"2001:db8:1::/48", "always_transparent", respip_always_transparent},
774 {"2001:db8:2::/49", "always_refuse", respip_always_refuse},
775 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
776 };
777 int i;
778 struct config_file cfg;
779 int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t));
780 int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t));
781 struct config_view* cv1;
782 struct config_view* cv2;
783 int have_respip_cfg = 0;
784 struct views* views = NULL;
785 struct view* v = NULL;
786
787 unit_show_feature("per-view respip config actions apply");
788 memset(&cfg, 0, sizeof(cfg));
789 cv1 = (struct config_view*)calloc(1, sizeof(struct config_view));
790 cv2 = (struct config_view*)calloc(1, sizeof(struct config_view));
791 unit_assert(cv1 && cv2);
792 cv1->name = strdup("view1");
793 cv2->name = strdup("view2");
794 unit_assert(cv1->name && cv2->name);
795 cv1->next = cv2;
796 cfg.views = cv1;
797
798 for(i=0; i<clen1; i++) {
799 char* ip = strdup(config_response_ip_view1[i].ip);
800 char* sact = strdup(config_response_ip_view1[i].sact);
801 unit_assert(ip && sact);
802 if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact))
803 unit_assert(0);
804 }
805 for(i=0; i<clen2; i++) {
806 char* ip = strdup(config_response_ip_view2[i].ip);
807 char* sact = strdup(config_response_ip_view2[i].sact);
808 unit_assert(ip && sact);
809 if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact))
810 unit_assert(0);
811 }
812 views = views_create();
813 unit_assert(views);
814 unit_assert(views_apply_cfg(views, &cfg));
815 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
816
817 /* now verify the respip sets in each view */
818 v = views_find_view(views, "view1", 0);
819 unit_assert(v);
820 verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1);
821 lock_rw_unlock(&v->lock);
822 v = views_find_view(views, "view2", 0);
823 unit_assert(v);
824 verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2);
825 lock_rw_unlock(&v->lock);
826
827 views_delete(views);
828 free(cv1->name);
829 free(cv1);
830 free(cv2->name);
831 free(cv2);
832 }
833
834 typedef struct addr_data {char* ip; char* data;} addr_data_t;
835
836 /** find the respip address node in the specified tree (by address lookup)
837 * and verify type and address of the specified rdata (by index) in this
838 * node's rrset */
839 static void
verify_rrset(struct respip_set * set,const char * ipstr,const char * rdatastr,size_t rdi,uint16_t type)840 verify_rrset(struct respip_set* set, const char* ipstr,
841 const char* rdatastr, size_t rdi, uint16_t type)
842 {
843 struct sockaddr_storage addr;
844 int net;
845 char buf[65536];
846 socklen_t addrlen;
847 struct rbtree_type* tree;
848 struct resp_addr* node;
849 const struct ub_packed_rrset_key* rrs;
850
851 netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net);
852 tree = respip_set_get_tree(set);
853 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
854 unit_assert(node);
855 unit_assert((rrs = resp_addr_get_rrset(node)));
856 unit_assert(ntohs(rrs->rk.type) == type);
857 packed_rr_to_string((struct ub_packed_rrset_key*)rrs,
858 rdi, 0, buf, sizeof(buf));
859 unit_assert(strstr(buf, rdatastr));
860 }
861
862 /** Dataset used to test redirect rrset initialization for both
863 * global and per-view respip redirect configuration */
864 static addr_data_t config_response_ip_data[] = {
865 {"192.0.1.0/24", "A 1.2.3.4"},
866 {"192.0.1.0/24", "A 11.12.13.14"},
867 {"192.0.2.0/24", "CNAME www.example.com."},
868 {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"},
869 };
870
871 /** Populate raw respip redirect config data, used for both global and
872 * view-based respip redirect test case */
873 static void
cfg_insert_respip_data(struct config_str2list ** respip_actions,struct config_str2list ** respip_data)874 cfg_insert_respip_data(struct config_str2list** respip_actions,
875 struct config_str2list** respip_data)
876 {
877 int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t));
878 int i = 0;
879
880 /* insert actions (duplicate netblocks don't matter) */
881 for(i=0; i<clen; i++) {
882 char* ip = strdup(config_response_ip_data[i].ip);
883 char* sact = strdup("redirect");
884 unit_assert(ip && sact);
885 if(!cfg_str2list_insert(respip_actions, ip, sact))
886 unit_assert(0);
887 }
888 /* insert data */
889 for(i=0; i<clen; i++) {
890 char* ip = strdup(config_response_ip_data[i].ip);
891 char* data = strdup(config_response_ip_data[i].data);
892 unit_assert(ip && data);
893 if(!cfg_str2list_insert(respip_data, ip, data))
894 unit_assert(0);
895 }
896 }
897
898 /** Test global respip redirect w/ data directives */
899 static void
respip_conf_data_test(void)900 respip_conf_data_test(void)
901 {
902 struct respip_set* set = respip_set_create();
903 struct config_file cfg;
904
905 unit_show_feature("global respip config data apply");
906 memset(&cfg, 0, sizeof(cfg));
907
908 cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data);
909
910 /* apply configuration and verify rrsets */
911 unit_assert(respip_global_apply_cfg(set, &cfg));
912 verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A);
913 verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A);
914 verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME);
915 verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA);
916
917 respip_set_delete(set);
918 }
919
920 /** Test per-view respip redirect w/ data directives */
921 static void
respip_view_conf_data_test(void)922 respip_view_conf_data_test(void)
923 {
924 struct config_file cfg;
925 struct config_view* cv;
926 int have_respip_cfg = 0;
927 struct views* views = NULL;
928 struct view* v = NULL;
929
930 unit_show_feature("per-view respip config data apply");
931 memset(&cfg, 0, sizeof(cfg));
932 cv = (struct config_view*)calloc(1, sizeof(struct config_view));
933 unit_assert(cv);
934 cv->name = strdup("view1");
935 unit_assert(cv->name);
936 cfg.views = cv;
937 cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data);
938 views = views_create();
939 unit_assert(views);
940 unit_assert(views_apply_cfg(views, &cfg));
941
942 /* apply configuration and verify rrsets */
943 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
944 v = views_find_view(views, "view1", 0);
945 unit_assert(v);
946 verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4",
947 0, LDNS_RR_TYPE_A);
948 verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14",
949 1, LDNS_RR_TYPE_A);
950 verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com",
951 0, LDNS_RR_TYPE_CNAME);
952 verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1",
953 0, LDNS_RR_TYPE_AAAA);
954 lock_rw_unlock(&v->lock);
955
956 views_delete(views);
957 free(cv->name);
958 free(cv);
959 }
960
961 /** respip unit tests */
respip_test(void)962 static void respip_test(void)
963 {
964 respip_view_conf_data_test();
965 respip_conf_data_test();
966 respip_view_conf_actions_test();
967 respip_conf_actions_test();
968 }
969
970 #include "util/regional.h"
971 #include "sldns/sbuffer.h"
972 #include "util/data/dname.h"
973 #include "util/data/msgreply.h"
974 #include "util/data/msgencode.h"
975 #include "sldns/str2wire.h"
976
edns_ede_encode_setup(struct edns_data * edns,struct regional * region)977 static void edns_ede_encode_setup(struct edns_data* edns,
978 struct regional* region)
979 {
980 memset(edns, 0, sizeof(*edns));
981 edns->edns_present = 1;
982 edns->edns_version = EDNS_ADVERTISED_VERSION;
983 edns->udp_size = EDNS_ADVERTISED_SIZE;
984 edns->bits &= EDNS_DO;
985 /* Fill up opt_list_out with EDEs */
986 unit_assert(
987 edns_opt_list_append_ede(&edns->opt_list_out, region,
988 LDNS_EDE_OTHER, "Too long other text"));
989 unit_assert(
990 edns_opt_list_append_ede(&edns->opt_list_out, region,
991 LDNS_EDE_OTHER, "Too long other text"));
992 unit_assert(
993 edns_opt_list_append_ede(&edns->opt_list_out, region,
994 LDNS_EDE_BLOCKED, "Too long blocked text"));
995 unit_assert(
996 edns_opt_list_append_ede(&edns->opt_list_out, region,
997 LDNS_EDE_OTHER, "Too long other text"));
998 unit_assert(
999 edns_opt_list_append_ede(&edns->opt_list_out, region,
1000 LDNS_EDE_BLOCKED, "Too long blocked text"));
1001 /* Fill up opt_list_inplace_cb_out with EDEs */
1002 unit_assert(
1003 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
1004 LDNS_EDE_OTHER, "Too long other text"));
1005 unit_assert(
1006 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
1007 LDNS_EDE_OTHER, "Too long other text"));
1008 unit_assert(
1009 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
1010 LDNS_EDE_BLOCKED, "Too long blocked text"));
1011 unit_assert(
1012 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
1013 LDNS_EDE_OTHER, "Too long other text"));
1014 unit_assert(
1015 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
1016 LDNS_EDE_BLOCKED, "Too long blocked text"));
1017 /* append another EDNS option to both lists */
1018 unit_assert(
1019 edns_opt_list_append(&edns->opt_list_out,
1020 LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region));
1021 unit_assert(
1022 edns_opt_list_append(&edns->opt_list_inplace_cb_out,
1023 LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region));
1024 /* append LDNS_EDE_OTHER at the end of both lists */
1025 unit_assert(
1026 edns_opt_list_append_ede(&edns->opt_list_out, region,
1027 LDNS_EDE_OTHER, "Too long other text"));
1028 unit_assert(
1029 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
1030 LDNS_EDE_OTHER, "Too long other text"));
1031 }
1032
edns_ede_encode_encodedecode(struct query_info * qinfo,struct reply_info * rep,struct regional * region,struct edns_data * edns,sldns_buffer * pkt)1033 static void edns_ede_encode_encodedecode(struct query_info* qinfo,
1034 struct reply_info* rep, struct regional* region,
1035 struct edns_data* edns, sldns_buffer* pkt)
1036 {
1037 /* encode */
1038 unit_assert(
1039 reply_info_answer_encode(qinfo, rep, 1, rep->flags, pkt,
1040 0, 0, region, 65535, edns, 0, 0));
1041 /* buffer ready for reading; skip after the question section */
1042 sldns_buffer_skip(pkt, LDNS_HEADER_SIZE);
1043 (void)query_dname_len(pkt);
1044 sldns_buffer_skip(pkt, 2 + 2);
1045 /* decode */
1046 unit_assert(parse_edns_from_query_pkt(pkt, edns, NULL, NULL, NULL, 0,
1047 region, NULL) == 0);
1048 }
1049
edns_ede_encode_check(struct edns_data * edns,int * found_ede,int * found_ede_other,int * found_ede_txt,int * found_other_edns)1050 static void edns_ede_encode_check(struct edns_data* edns, int* found_ede,
1051 int* found_ede_other, int* found_ede_txt, int* found_other_edns)
1052 {
1053 struct edns_option* opt;
1054 for(opt = edns->opt_list_in; opt; opt = opt->next) {
1055 if(opt->opt_code == LDNS_EDNS_EDE) {
1056 (*found_ede)++;
1057 if(opt->opt_len > 2)
1058 (*found_ede_txt)++;
1059 if(opt->opt_len >= 2 && sldns_read_uint16(
1060 opt->opt_data) == LDNS_EDE_OTHER)
1061 (*found_ede_other)++;
1062 } else {
1063 (*found_other_edns)++;
1064 }
1065 }
1066
1067 }
1068
edns_ede_encode_fit_test(struct query_info * qinfo,struct reply_info * rep,struct regional * region)1069 static void edns_ede_encode_fit_test(struct query_info* qinfo,
1070 struct reply_info* rep, struct regional* region)
1071 {
1072 struct edns_data edns;
1073 int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
1074 int found_other_edns = 0;
1075 sldns_buffer* pkt = sldns_buffer_new(65535);
1076 unit_assert(pkt);
1077 edns_ede_encode_setup(&edns, region);
1078 /* leave the pkt buffer as is; everything should fit */
1079 edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt);
1080 edns_ede_encode_check(&edns, &found_ede, &found_ede_other,
1081 &found_ede_txt, &found_other_edns);
1082 unit_assert(found_ede == 12);
1083 unit_assert(found_ede_other == 8);
1084 unit_assert(found_ede_txt == 12);
1085 unit_assert(found_other_edns == 2);
1086 /* cleanup */
1087 sldns_buffer_free(pkt);
1088 }
1089
edns_ede_encode_notxt_fit_test(struct query_info * qinfo,struct reply_info * rep,struct regional * region)1090 static void edns_ede_encode_notxt_fit_test( struct query_info* qinfo,
1091 struct reply_info* rep, struct regional* region)
1092 {
1093 struct edns_data edns;
1094 sldns_buffer* pkt;
1095 uint16_t edns_field_size, ede_txt_size;
1096 int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
1097 int found_other_edns = 0;
1098 edns_ede_encode_setup(&edns, region);
1099 /* pkt buffer should fit everything if the ede txt is cropped.
1100 * OTHER EDE should not be there since it is useless without text. */
1101 edns_field_size = calc_edns_field_size(&edns);
1102 (void)calc_ede_option_size(&edns, &ede_txt_size);
1103 pkt = sldns_buffer_new(LDNS_HEADER_SIZE
1104 + qinfo->qname_len
1105 + 2 + 2 /* qtype + qclass */
1106 + 11 /* opt record */
1107 + edns_field_size
1108 - ede_txt_size);
1109 unit_assert(pkt);
1110 edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt);
1111 edns_ede_encode_check(&edns, &found_ede, &found_ede_other,
1112 &found_ede_txt, &found_other_edns);
1113 unit_assert(found_ede == 4);
1114 unit_assert(found_ede_other == 0);
1115 unit_assert(found_ede_txt == 0);
1116 unit_assert(found_other_edns == 2);
1117 /* cleanup */
1118 sldns_buffer_free(pkt);
1119 }
1120
edns_ede_encode_no_fit_test(struct query_info * qinfo,struct reply_info * rep,struct regional * region)1121 static void edns_ede_encode_no_fit_test( struct query_info* qinfo,
1122 struct reply_info* rep, struct regional* region)
1123 {
1124 struct edns_data edns;
1125 sldns_buffer* pkt;
1126 uint16_t edns_field_size, ede_size, ede_txt_size;
1127 int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
1128 int found_other_edns = 0;
1129 edns_ede_encode_setup(&edns, region);
1130 /* pkt buffer should fit only non-EDE options. */
1131 edns_field_size = calc_edns_field_size(&edns);
1132 ede_size = calc_ede_option_size(&edns, &ede_txt_size);
1133 pkt = sldns_buffer_new(LDNS_HEADER_SIZE
1134 + qinfo->qname_len
1135 + 2 + 2 /* qtype + qclass */
1136 + 11 /* opt record */
1137 + edns_field_size
1138 - ede_size);
1139 unit_assert(pkt);
1140 edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt);
1141 edns_ede_encode_check(&edns, &found_ede, &found_ede_other,
1142 &found_ede_txt, &found_other_edns);
1143 unit_assert(found_ede == 0);
1144 unit_assert(found_ede_other == 0);
1145 unit_assert(found_ede_txt == 0);
1146 unit_assert(found_other_edns == 2);
1147 /* cleanup */
1148 sldns_buffer_free(pkt);
1149 }
1150
1151 /** test optional EDE encoding with various buffer
1152 * available sizes */
edns_ede_answer_encode_test(void)1153 static void edns_ede_answer_encode_test(void)
1154 {
1155 struct regional* region = regional_create();
1156 struct reply_info* rep;
1157 struct query_info qinfo;
1158 unit_show_feature("edns ede optional encoding");
1159 unit_assert(region);
1160 rep = construct_reply_info_base(region,
1161 LDNS_RCODE_NOERROR | BIT_QR, 1,
1162 3600, 3600, 3600, 0,
1163 0, 0, 0, 0,
1164 sec_status_unchecked, LDNS_EDE_NONE);
1165 unit_assert(rep);
1166 memset(&qinfo, 0, sizeof(qinfo));
1167 qinfo.qname = sldns_str2wire_dname("encode.ede.", &qinfo.qname_len);
1168 unit_assert(qinfo.qname);
1169 qinfo.qtype = LDNS_RR_TYPE_TXT;
1170 qinfo.qclass = LDNS_RR_CLASS_IN;
1171
1172 edns_ede_encode_fit_test(&qinfo, rep, region);
1173 edns_ede_encode_notxt_fit_test(&qinfo, rep, region);
1174 edns_ede_encode_no_fit_test(&qinfo, rep, region);
1175
1176 /* cleanup */
1177 free(qinfo.qname);
1178 regional_free_all(region);
1179 regional_destroy(region);
1180 }
1181
1182 #include "services/localzone.h"
1183 /* Utility function that compares two localzone trees */
compare_localzone_trees(struct local_zones * z1,struct local_zones * z2)1184 static void compare_localzone_trees(struct local_zones* z1,
1185 struct local_zones* z2)
1186 {
1187 struct local_zone *node1, *node2;
1188 lock_rw_rdlock(&z1->lock);
1189 lock_rw_rdlock(&z2->lock);
1190 /* size should be the same */
1191 unit_assert(z1->ztree.count == z2->ztree.count);
1192 for(node1=(struct local_zone*)rbtree_first(&z1->ztree),
1193 node2=(struct local_zone*)rbtree_first(&z2->ztree);
1194 (rbnode_type*)node1 != RBTREE_NULL &&
1195 (rbnode_type*)node2 != RBTREE_NULL;
1196 node1=(struct local_zone*)rbtree_next((rbnode_type*)node1),
1197 node2=(struct local_zone*)rbtree_next((rbnode_type*)node2)) {
1198 int labs;
1199 /* the same zone should be at the same nodes */
1200 unit_assert(!dname_lab_cmp(
1201 node1->name, node1->namelabs,
1202 node2->name, node2->namelabs,
1203 &labs));
1204 /* the zone's parent should be the same on both nodes */
1205 unit_assert(
1206 (node1->parent == NULL && node2->parent == NULL) ||
1207 (node1->parent != NULL && node2->parent != NULL));
1208 if(node1->parent) {
1209 unit_assert(!dname_lab_cmp(
1210 node1->parent->name, node1->parent->namelabs,
1211 node2->parent->name, node2->parent->namelabs,
1212 &labs));
1213 }
1214 }
1215 lock_rw_unlock(&z1->lock);
1216 lock_rw_unlock(&z2->lock);
1217 }
1218
1219 /* test that zone addition results in the same tree from both the configuration
1220 * file and the unbound-control commands */
localzone_parents_test(void)1221 static void localzone_parents_test(void)
1222 {
1223 struct local_zones *z1, *z2;
1224 size_t i;
1225 char* zone_data[] = {
1226 "one",
1227 "a.b.c.one",
1228 "b.c.one",
1229 "c.one",
1230 "two",
1231 "c.two",
1232 "b.c.two",
1233 "a.b.c.two",
1234 "a.b.c.three",
1235 "b.c.three",
1236 "c.three",
1237 "three",
1238 "c.four",
1239 "b.c.four",
1240 "a.b.c.four",
1241 "four",
1242 "."
1243 };
1244 unit_show_feature("localzones parent calculation");
1245 z1 = local_zones_create();
1246 z2 = local_zones_create();
1247 /* parse test data */
1248 for(i=0; i<sizeof(zone_data)/sizeof(zone_data[0]); i++) {
1249 uint8_t* nm;
1250 int nmlabs;
1251 size_t nmlen;
1252 struct local_zone* z;
1253
1254 /* This is the config way */
1255 z = lz_enter_zone(z1, zone_data[i], "always_nxdomain",
1256 LDNS_RR_CLASS_IN);
1257 (void)z; /* please compiler when no threading and no lock
1258 code; the following line disappears and z stays unused */
1259 lock_rw_unlock(&z->lock);
1260 lz_init_parents(z1);
1261
1262 /* This is the unbound-control way */
1263 nm = sldns_str2wire_dname(zone_data[i], &nmlen);
1264 if(!nm) unit_assert(0);
1265 nmlabs = dname_count_size_labels(nm, &nmlen);
1266 lock_rw_wrlock(&z2->lock);
1267 local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN,
1268 local_zone_always_nxdomain);
1269 lock_rw_unlock(&z2->lock);
1270 }
1271 /* The trees should be the same, iterate and check the nodes */
1272 compare_localzone_trees(z1, z2);
1273
1274 /* cleanup */
1275 local_zones_delete(z1);
1276 local_zones_delete(z2);
1277 }
1278
1279 /** localzone unit tests */
localzone_test(void)1280 static void localzone_test(void)
1281 {
1282 localzone_parents_test();
1283 }
1284
unit_show_func(const char * file,const char * func)1285 void unit_show_func(const char* file, const char* func)
1286 {
1287 printf("test %s:%s\n", file, func);
1288 }
1289
unit_show_feature(const char * feature)1290 void unit_show_feature(const char* feature)
1291 {
1292 printf("test %s functions\n", feature);
1293 }
1294
1295 #ifdef USE_ECDSA_EVP_WORKAROUND
1296 void ecdsa_evp_workaround_init(void);
1297 #endif
1298
1299 /**
1300 * Main unit test program. Setup, teardown and report errors.
1301 * @param argc: arg count.
1302 * @param argv: array of commandline arguments.
1303 * @return program failure if test fails.
1304 */
1305 int
main(int argc,char * argv[])1306 main(int argc, char* argv[])
1307 {
1308 checklock_start();
1309 log_init(NULL, 0, NULL);
1310 if(argc != 1) {
1311 printf("usage: %s\n", argv[0]);
1312 printf("\tperforms unit tests.\n");
1313 return 1;
1314 }
1315 /* Disable roundrobin for the unit tests */
1316 RRSET_ROUNDROBIN = 0;
1317 #ifdef USE_LIBEVENT
1318 printf("Start of %s+libevent unit test.\n", PACKAGE_STRING);
1319 #else
1320 printf("Start of %s unit test.\n", PACKAGE_STRING);
1321 #endif
1322 #ifdef HAVE_SSL
1323 # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
1324 ERR_load_crypto_strings();
1325 # endif
1326 # ifdef USE_GOST
1327 (void)sldns_key_EVP_load_gost_id();
1328 # endif
1329 # ifdef USE_ECDSA_EVP_WORKAROUND
1330 ecdsa_evp_workaround_init();
1331 # endif
1332 #elif defined(HAVE_NSS)
1333 if(NSS_NoDB_Init(".") != SECSuccess)
1334 fatal_exit("could not init NSS");
1335 #endif /* HAVE_SSL or HAVE_NSS*/
1336 authzone_test();
1337 neg_test();
1338 rnd_test();
1339 respip_test();
1340 verify_test();
1341 net_test();
1342 config_memsize_test();
1343 config_tag_test();
1344 dname_test();
1345 rtt_test();
1346 anchors_test();
1347 alloc_test();
1348 regional_test();
1349 lruhash_test();
1350 slabhash_test();
1351 infra_test();
1352 ldns_test();
1353 edns_cookie_test();
1354 zonemd_test();
1355 tcpreuse_test();
1356 msgparse_test();
1357 edns_ede_answer_encode_test();
1358 localzone_test();
1359 #ifdef CLIENT_SUBNET
1360 ecs_test();
1361 #endif /* CLIENT_SUBNET */
1362 #ifdef HAVE_NGTCP2
1363 doq_test();
1364 #endif /* HAVE_NGTCP2 */
1365 if(log_get_lock()) {
1366 lock_basic_destroy((lock_basic_type*)log_get_lock());
1367 }
1368 checklock_stop();
1369 printf("%d checks ok.\n", testcount);
1370 #ifdef HAVE_SSL
1371 # if defined(USE_GOST)
1372 sldns_key_EVP_unload_gost();
1373 # endif
1374 # ifdef HAVE_OPENSSL_CONFIG
1375 # ifdef HAVE_EVP_CLEANUP
1376 EVP_cleanup();
1377 # endif
1378 # if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
1379 ENGINE_cleanup();
1380 # endif
1381 CONF_modules_free();
1382 # endif
1383 # ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
1384 CRYPTO_cleanup_all_ex_data();
1385 # endif
1386 # ifdef HAVE_ERR_FREE_STRINGS
1387 ERR_free_strings();
1388 # endif
1389 # ifdef HAVE_RAND_CLEANUP
1390 RAND_cleanup();
1391 # endif
1392 #elif defined(HAVE_NSS)
1393 if(NSS_Shutdown() != SECSuccess)
1394 fatal_exit("could not shutdown NSS");
1395 #endif /* HAVE_SSL or HAVE_NSS */
1396 #ifdef HAVE_PTHREAD
1397 /* dlopen frees its thread specific state */
1398 pthread_exit(NULL);
1399 #endif
1400 return 0;
1401 }
1402