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