xref: /freebsd/contrib/unbound/testcode/unitmain.c (revision b2efd602aea8b3cbc3fb215b9611946d04fceb10)
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