Home | History | Annotate | Line # | Download | only in testcode
      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 		/* 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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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 */
    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 
    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 
   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 
   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 
   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 
   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 	size_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 
   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 	size_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 */
   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 */
   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 */
   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 */
   1280 static void localzone_test(void)
   1281 {
   1282 	localzone_parents_test();
   1283 }
   1284 
   1285 #include "services/mesh.h"
   1286 /** mesh unit tests */
   1287 static void mesh_test(void)
   1288 {
   1289 	struct regional* r2, *r3;
   1290 	struct respip_client_info* c1, *c2, *c3;
   1291 	unit_show_func("services/mesh.c", "mesh_copy_client_info");
   1292 	r2 = regional_create();
   1293 	r3 = regional_create();
   1294 	if(!r2 || !r3) fatal_exit("out of memory");
   1295 
   1296 	c1 = calloc(1, sizeof(*c1));
   1297 	if(!c1) fatal_exit("out of memory");
   1298 	c1->view = calloc(1, sizeof(*c1->view));
   1299 	if(!c1->view) fatal_exit("out of memory");
   1300 	c1->view->name = strdup("view1");
   1301 	if(!c1->view->name) fatal_exit("out of memory");
   1302 
   1303 	c2 = mesh_copy_client_info(r2, c1);
   1304 	if(!c2) fatal_exit("out of memory");
   1305 	c3 = mesh_copy_client_info(r3, c2);
   1306 	if(!c3) fatal_exit("out of memory");
   1307 
   1308 	unit_assert(strcmp(c1->view->name, c2->view_name) == 0);
   1309 	unit_assert(strcmp(c1->view->name, c3->view_name) == 0);
   1310 
   1311 	/* make sure that the c3 view_name is in the r3 region. */
   1312 	unit_assert(r3->next == NULL);  /* only the first chunk present atm */
   1313 	if(strlen(c3->view_name) >= r3->large_object_size) {
   1314 		char* a = r3->large_list;
   1315 		int found = 0;
   1316 		while(a) {
   1317 			if(strcmp(c3->view_name,
   1318 				a + /* ALIGNEMENT */ sizeof(uint64_t)) == 0) {
   1319 				found = 1;
   1320 				break;
   1321 			}
   1322 			a = *(char**)a;
   1323 		}
   1324 		unit_assert(found == 1);
   1325 	} else {
   1326 		/* The allocation is expected in the r3 region first chunk */
   1327 		unit_assert((uint8_t*)c3->view_name < ((uint8_t*)r3)+r3->first_size);
   1328 	}
   1329 
   1330 	regional_destroy(r2);
   1331 	/* ASAN should complain for the freed access below */
   1332 	unit_assert(strcmp(c1->view->name, c3->view_name) == 0);
   1333 
   1334 	regional_destroy(r3);
   1335 	free(c1->view->name);
   1336 	free(c1->view);
   1337 	free(c1);
   1338 }
   1339 
   1340 void unit_show_func(const char* file, const char* func)
   1341 {
   1342 	printf("test %s:%s\n", file, func);
   1343 }
   1344 
   1345 void unit_show_feature(const char* feature)
   1346 {
   1347 	printf("test %s functions\n", feature);
   1348 }
   1349 
   1350 #ifdef USE_ECDSA_EVP_WORKAROUND
   1351 void ecdsa_evp_workaround_init(void);
   1352 #endif
   1353 
   1354 /**
   1355  * Main unit test program. Setup, teardown and report errors.
   1356  * @param argc: arg count.
   1357  * @param argv: array of commandline arguments.
   1358  * @return program failure if test fails.
   1359  */
   1360 int
   1361 main(int argc, char* argv[])
   1362 {
   1363 	checklock_start();
   1364 	log_init(NULL, 0, NULL);
   1365 	if(argc != 1) {
   1366 		printf("usage: %s\n", argv[0]);
   1367 		printf("\tperforms unit tests.\n");
   1368 		return 1;
   1369 	}
   1370 	/* Disable roundrobin for the unit tests */
   1371 	RRSET_ROUNDROBIN = 0;
   1372 #ifdef USE_LIBEVENT
   1373 	printf("Start of %s+libevent unit test.\n", PACKAGE_STRING);
   1374 #else
   1375 	printf("Start of %s unit test.\n", PACKAGE_STRING);
   1376 #endif
   1377 #ifdef HAVE_SSL
   1378 #  ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
   1379 	ERR_load_crypto_strings();
   1380 #  endif
   1381 #  ifdef USE_GOST
   1382 	(void)sldns_key_EVP_load_gost_id();
   1383 #  endif
   1384 #  ifdef USE_ECDSA_EVP_WORKAROUND
   1385 	ecdsa_evp_workaround_init();
   1386 #  endif
   1387 #elif defined(HAVE_NSS)
   1388 	if(NSS_NoDB_Init(".") != SECSuccess)
   1389 		fatal_exit("could not init NSS");
   1390 #endif /* HAVE_SSL or HAVE_NSS*/
   1391 	authzone_test();
   1392 	neg_test();
   1393 	rnd_test();
   1394 	respip_test();
   1395 	verify_test();
   1396 	net_test();
   1397 	config_memsize_test();
   1398 	config_tag_test();
   1399 	dname_test();
   1400 	rtt_test();
   1401 	anchors_test();
   1402 	alloc_test();
   1403 	regional_test();
   1404 	lruhash_test();
   1405 	slabhash_test();
   1406 	infra_test();
   1407 	ldns_test();
   1408 	edns_cookie_test();
   1409 	zonemd_test();
   1410 	tcpreuse_test();
   1411 	msgparse_test();
   1412 	edns_ede_answer_encode_test();
   1413 	localzone_test();
   1414 	mesh_test();
   1415 #ifdef CLIENT_SUBNET
   1416 	ecs_test();
   1417 #endif /* CLIENT_SUBNET */
   1418 #ifdef HAVE_NGTCP2
   1419 	doq_test();
   1420 #endif /* HAVE_NGTCP2 */
   1421 	if(log_get_lock()) {
   1422 		lock_basic_destroy((lock_basic_type*)log_get_lock());
   1423 	}
   1424 	checklock_stop();
   1425 	printf("%d checks ok.\n", testcount);
   1426 #ifdef HAVE_SSL
   1427 #  if defined(USE_GOST)
   1428 	sldns_key_EVP_unload_gost();
   1429 #  endif
   1430 #  ifdef HAVE_OPENSSL_CONFIG
   1431 #  ifdef HAVE_EVP_CLEANUP
   1432 	EVP_cleanup();
   1433 #  endif
   1434 #  if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
   1435 	ENGINE_cleanup();
   1436 #  endif
   1437 	CONF_modules_free();
   1438 #  endif
   1439 #  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
   1440 	CRYPTO_cleanup_all_ex_data();
   1441 #  endif
   1442 #  ifdef HAVE_ERR_FREE_STRINGS
   1443 	ERR_free_strings();
   1444 #  endif
   1445 #  ifdef HAVE_RAND_CLEANUP
   1446 	RAND_cleanup();
   1447 #  endif
   1448 #ifdef HAVE_OPENSSL_CLEANUP
   1449 	OPENSSL_cleanup();
   1450 #endif
   1451 #elif defined(HAVE_NSS)
   1452 	if(NSS_Shutdown() != SECSuccess)
   1453 		fatal_exit("could not shutdown NSS");
   1454 #endif /* HAVE_SSL or HAVE_NSS */
   1455 #ifdef HAVE_PTHREAD
   1456 	/* dlopen frees its thread specific state */
   1457 	pthread_exit(NULL);
   1458 #endif
   1459 	return 0;
   1460 }
   1461