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