xref: /openbsd-src/usr.sbin/unbound/testcode/unitmain.c (revision 9f11ffb7133c203312a01e4b986886bc88c7d74b)
1 /*
2  * testcode/unitmain.c - unit test main program for unbound.
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 /**
37  * \file
38  * Unit test main program. Calls all the other unit tests.
39  * Exits with code 1 on a failure. 0 if all unit tests are successful.
40  */
41 
42 #include "config.h"
43 #ifdef HAVE_OPENSSL_ERR_H
44 #include <openssl/err.h>
45 #endif
46 
47 #ifdef HAVE_OPENSSL_RAND_H
48 #include <openssl/rand.h>
49 #endif
50 
51 #ifdef HAVE_OPENSSL_CONF_H
52 #include <openssl/conf.h>
53 #endif
54 
55 #ifdef HAVE_OPENSSL_ENGINE_H
56 #include <openssl/engine.h>
57 #endif
58 
59 #ifdef HAVE_NSS
60 /* nss3 */
61 #include "nss.h"
62 #endif
63 
64 #include "sldns/rrdef.h"
65 #include "sldns/keyraw.h"
66 #include "util/log.h"
67 #include "testcode/unitmain.h"
68 
69 /** number of tests done */
70 int testcount = 0;
71 
72 #include "util/alloc.h"
73 /** test alloc code */
74 static void
75 alloc_test(void) {
76 	alloc_special_type *t1, *t2;
77 	struct alloc_cache major, minor1, minor2;
78 	int i;
79 
80 	unit_show_feature("alloc_special_obtain");
81 	alloc_init(&major, NULL, 0);
82 	alloc_init(&minor1, &major, 0);
83 	alloc_init(&minor2, &major, 1);
84 
85 	t1 = alloc_special_obtain(&minor1);
86 	alloc_clear(&minor1);
87 
88 	alloc_special_release(&minor2, t1);
89 	t2 = alloc_special_obtain(&minor2);
90 	unit_assert( t1 == t2 ); /* reused */
91 	alloc_special_release(&minor2, t1);
92 
93 	for(i=0; i<100; i++) {
94 		t1 = alloc_special_obtain(&minor1);
95 		alloc_special_release(&minor2, t1);
96 	}
97 	if(0) {
98 		alloc_stats(&minor1);
99 		alloc_stats(&minor2);
100 		alloc_stats(&major);
101 	}
102 	/* reuse happened */
103 	unit_assert(minor1.num_quar + minor2.num_quar + major.num_quar == 11);
104 
105 	alloc_clear(&minor1);
106 	alloc_clear(&minor2);
107 	unit_assert(major.num_quar == 11);
108 	alloc_clear(&major);
109 }
110 
111 #include "util/net_help.h"
112 /** test net code */
113 static void
114 net_test(void)
115 {
116 	const char* t4[] = {"\000\000\000\000",
117 		"\200\000\000\000",
118 		"\300\000\000\000",
119 		"\340\000\000\000",
120 		"\360\000\000\000",
121 		"\370\000\000\000",
122 		"\374\000\000\000",
123 		"\376\000\000\000",
124 		"\377\000\000\000",
125 		"\377\200\000\000",
126 		"\377\300\000\000",
127 		"\377\340\000\000",
128 		"\377\360\000\000",
129 		"\377\370\000\000",
130 		"\377\374\000\000",
131 		"\377\376\000\000",
132 		"\377\377\000\000",
133 		"\377\377\200\000",
134 		"\377\377\300\000",
135 		"\377\377\340\000",
136 		"\377\377\360\000",
137 		"\377\377\370\000",
138 		"\377\377\374\000",
139 		"\377\377\376\000",
140 		"\377\377\377\000",
141 		"\377\377\377\200",
142 		"\377\377\377\300",
143 		"\377\377\377\340",
144 		"\377\377\377\360",
145 		"\377\377\377\370",
146 		"\377\377\377\374",
147 		"\377\377\377\376",
148 		"\377\377\377\377",
149 		"\377\377\377\377",
150 		"\377\377\377\377",
151 	};
152 	unit_show_func("util/net_help.c", "str_is_ip6");
153 	unit_assert( str_is_ip6("::") );
154 	unit_assert( str_is_ip6("::1") );
155 	unit_assert( str_is_ip6("2001:7b8:206:1:240:f4ff:fe37:8810") );
156 	unit_assert( str_is_ip6("fe80::240:f4ff:fe37:8810") );
157 	unit_assert( !str_is_ip6("0.0.0.0") );
158 	unit_assert( !str_is_ip6("213.154.224.12") );
159 	unit_assert( !str_is_ip6("213.154.224.255") );
160 	unit_assert( !str_is_ip6("255.255.255.0") );
161 	unit_show_func("util/net_help.c", "is_pow2");
162 	unit_assert( is_pow2(0) );
163 	unit_assert( is_pow2(1) );
164 	unit_assert( is_pow2(2) );
165 	unit_assert( is_pow2(4) );
166 	unit_assert( is_pow2(8) );
167 	unit_assert( is_pow2(16) );
168 	unit_assert( is_pow2(1024) );
169 	unit_assert( is_pow2(1024*1024) );
170 	unit_assert( is_pow2(1024*1024*1024) );
171 	unit_assert( !is_pow2(3) );
172 	unit_assert( !is_pow2(5) );
173 	unit_assert( !is_pow2(6) );
174 	unit_assert( !is_pow2(7) );
175 	unit_assert( !is_pow2(9) );
176 	unit_assert( !is_pow2(10) );
177 	unit_assert( !is_pow2(11) );
178 	unit_assert( !is_pow2(17) );
179 	unit_assert( !is_pow2(23) );
180 	unit_assert( !is_pow2(257) );
181 	unit_assert( !is_pow2(259) );
182 
183 	/* test addr_mask */
184 	unit_show_func("util/net_help.c", "addr_mask");
185 	if(1) {
186 		struct sockaddr_in a4;
187 		struct sockaddr_in6 a6;
188 		socklen_t l4 = (socklen_t)sizeof(a4);
189 		socklen_t l6 = (socklen_t)sizeof(a6);
190 		int i;
191 		a4.sin_family = AF_INET;
192 		a6.sin6_family = AF_INET6;
193 		for(i=0; i<35; i++) {
194 			/* address 255.255.255.255 */
195 			memcpy(&a4.sin_addr, "\377\377\377\377", 4);
196 			addr_mask((struct sockaddr_storage*)&a4, l4, i);
197 			unit_assert(memcmp(&a4.sin_addr, t4[i], 4) == 0);
198 		}
199 		memcpy(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16);
200 		addr_mask((struct sockaddr_storage*)&a6, l6, 128);
201 		unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) == 0);
202 		addr_mask((struct sockaddr_storage*)&a6, l6, 122);
203 		unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\300", 16) == 0);
204 		addr_mask((struct sockaddr_storage*)&a6, l6, 120);
205 		unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000", 16) == 0);
206 		addr_mask((struct sockaddr_storage*)&a6, l6, 64);
207 		unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", 16) == 0);
208 		addr_mask((struct sockaddr_storage*)&a6, l6, 0);
209 		unit_assert(memcmp(&a6.sin6_addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16) == 0);
210 	}
211 
212 	/* test addr_in_common */
213 	unit_show_func("util/net_help.c", "addr_in_common");
214 	if(1) {
215 		struct sockaddr_in a4, b4;
216 		struct sockaddr_in6 a6, b6;
217 		socklen_t l4 = (socklen_t)sizeof(a4);
218 		socklen_t l6 = (socklen_t)sizeof(a6);
219 		int i;
220 		a4.sin_family = AF_INET;
221 		b4.sin_family = AF_INET;
222 		a6.sin6_family = AF_INET6;
223 		b6.sin6_family = AF_INET6;
224 		memcpy(&a4.sin_addr, "abcd", 4);
225 		memcpy(&b4.sin_addr, "abcd", 4);
226 		unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 32,
227 			(struct sockaddr_storage*)&b4, 32, l4) == 32);
228 		unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 34,
229 			(struct sockaddr_storage*)&b4, 32, l4) == 32);
230 		for(i=0; i<=32; i++) {
231 			unit_assert(addr_in_common(
232 				(struct sockaddr_storage*)&a4, 32,
233 				(struct sockaddr_storage*)&b4, i, l4) == i);
234 			unit_assert(addr_in_common(
235 				(struct sockaddr_storage*)&a4, i,
236 				(struct sockaddr_storage*)&b4, 32, l4) == i);
237 			unit_assert(addr_in_common(
238 				(struct sockaddr_storage*)&a4, i,
239 				(struct sockaddr_storage*)&b4, i, l4) == i);
240 		}
241 		for(i=0; i<=32; i++) {
242 			memcpy(&a4.sin_addr, "\377\377\377\377", 4);
243 			memcpy(&b4.sin_addr, t4[i], 4);
244 			unit_assert(addr_in_common(
245 				(struct sockaddr_storage*)&a4, 32,
246 				(struct sockaddr_storage*)&b4, 32, l4) == i);
247 			unit_assert(addr_in_common(
248 				(struct sockaddr_storage*)&b4, 32,
249 				(struct sockaddr_storage*)&a4, 32, l4) == i);
250 		}
251 		memcpy(&a6.sin6_addr, "abcdefghabcdefgh", 16);
252 		memcpy(&b6.sin6_addr, "abcdefghabcdefgh", 16);
253 		unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 128,
254 			(struct sockaddr_storage*)&b6, 128, l6) == 128);
255 		unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 129,
256 			(struct sockaddr_storage*)&b6, 128, l6) == 128);
257 		for(i=0; i<=128; i++) {
258 			unit_assert(addr_in_common(
259 				(struct sockaddr_storage*)&a6, 128,
260 				(struct sockaddr_storage*)&b6, i, l6) == i);
261 			unit_assert(addr_in_common(
262 				(struct sockaddr_storage*)&a6, i,
263 				(struct sockaddr_storage*)&b6, 128, l6) == i);
264 			unit_assert(addr_in_common(
265 				(struct sockaddr_storage*)&a6, i,
266 				(struct sockaddr_storage*)&b6, i, l6) == i);
267 		}
268 	}
269 	/* test sockaddr_cmp_addr */
270 	unit_show_func("util/net_help.c", "sockaddr_cmp_addr");
271 	if(1) {
272 		struct sockaddr_storage a, b;
273 		socklen_t alen = (socklen_t)sizeof(a);
274 		socklen_t blen = (socklen_t)sizeof(b);
275 		unit_assert(ipstrtoaddr("127.0.0.0", 53, &a, &alen));
276 		unit_assert(ipstrtoaddr("127.255.255.255", 53, &b, &blen));
277 		unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0);
278 		unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0);
279 		unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0);
280 		unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0);
281 		unit_assert(ipstrtoaddr("192.168.121.5", 53, &a, &alen));
282 		unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) > 0);
283 		unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) < 0);
284 		unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0);
285 		unit_assert(ipstrtoaddr("2001:3578:ffeb::99", 53, &b, &blen));
286 		unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0);
287 		unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0);
288 		unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0);
289 	}
290 	/* test addr_is_ip4mapped */
291 	unit_show_func("util/net_help.c", "addr_is_ip4mapped");
292 	if(1) {
293 		struct sockaddr_storage a;
294 		socklen_t l = (socklen_t)sizeof(a);
295 		unit_assert(ipstrtoaddr("12.13.14.15", 53, &a, &l));
296 		unit_assert(!addr_is_ip4mapped(&a, l));
297 		unit_assert(ipstrtoaddr("fe80::217:31ff:fe91:df", 53, &a, &l));
298 		unit_assert(!addr_is_ip4mapped(&a, l));
299 		unit_assert(ipstrtoaddr("ffff::217:31ff:fe91:df", 53, &a, &l));
300 		unit_assert(!addr_is_ip4mapped(&a, l));
301 		unit_assert(ipstrtoaddr("::ffff:31ff:fe91:df", 53, &a, &l));
302 		unit_assert(!addr_is_ip4mapped(&a, l));
303 		unit_assert(ipstrtoaddr("::fffe:fe91:df", 53, &a, &l));
304 		unit_assert(!addr_is_ip4mapped(&a, l));
305 		unit_assert(ipstrtoaddr("::ffff:127.0.0.1", 53, &a, &l));
306 		unit_assert(addr_is_ip4mapped(&a, l));
307 		unit_assert(ipstrtoaddr("::ffff:127.0.0.2", 53, &a, &l));
308 		unit_assert(addr_is_ip4mapped(&a, l));
309 		unit_assert(ipstrtoaddr("::ffff:192.168.0.2", 53, &a, &l));
310 		unit_assert(addr_is_ip4mapped(&a, l));
311 		unit_assert(ipstrtoaddr("2::ffff:192.168.0.2", 53, &a, &l));
312 		unit_assert(!addr_is_ip4mapped(&a, l));
313 	}
314 	/* test addr_is_any */
315 	unit_show_func("util/net_help.c", "addr_is_any");
316 	if(1) {
317 		struct sockaddr_storage a;
318 		socklen_t l = (socklen_t)sizeof(a);
319 		unit_assert(ipstrtoaddr("0.0.0.0", 53, &a, &l));
320 		unit_assert(addr_is_any(&a, l));
321 		unit_assert(ipstrtoaddr("0.0.0.0", 10053, &a, &l));
322 		unit_assert(addr_is_any(&a, l));
323 		unit_assert(ipstrtoaddr("0.0.0.0", 0, &a, &l));
324 		unit_assert(addr_is_any(&a, l));
325 		unit_assert(ipstrtoaddr("::0", 0, &a, &l));
326 		unit_assert(addr_is_any(&a, l));
327 		unit_assert(ipstrtoaddr("::0", 53, &a, &l));
328 		unit_assert(addr_is_any(&a, l));
329 		unit_assert(ipstrtoaddr("::1", 53, &a, &l));
330 		unit_assert(!addr_is_any(&a, l));
331 		unit_assert(ipstrtoaddr("2001:1667::1", 0, &a, &l));
332 		unit_assert(!addr_is_any(&a, l));
333 		unit_assert(ipstrtoaddr("2001::0", 0, &a, &l));
334 		unit_assert(!addr_is_any(&a, l));
335 		unit_assert(ipstrtoaddr("10.0.0.0", 0, &a, &l));
336 		unit_assert(!addr_is_any(&a, l));
337 		unit_assert(ipstrtoaddr("0.0.0.10", 0, &a, &l));
338 		unit_assert(!addr_is_any(&a, l));
339 		unit_assert(ipstrtoaddr("192.0.2.1", 0, &a, &l));
340 		unit_assert(!addr_is_any(&a, l));
341 	}
342 }
343 
344 #include "util/config_file.h"
345 /** test config_file: cfg_parse_memsize */
346 static void
347 config_memsize_test(void)
348 {
349 	size_t v = 0;
350 	unit_show_func("util/config_file.c", "cfg_parse_memsize");
351 	if(0) {
352 		/* these emit errors */
353 		unit_assert( cfg_parse_memsize("", &v) == 0);
354 		unit_assert( cfg_parse_memsize("bla", &v) == 0);
355 		unit_assert( cfg_parse_memsize("nop", &v) == 0);
356 		unit_assert( cfg_parse_memsize("n0b", &v) == 0);
357 		unit_assert( cfg_parse_memsize("gb", &v) == 0);
358 		unit_assert( cfg_parse_memsize("b", &v) == 0);
359 		unit_assert( cfg_parse_memsize("kb", &v) == 0);
360 		unit_assert( cfg_parse_memsize("kk kb", &v) == 0);
361 	}
362 	unit_assert( cfg_parse_memsize("0", &v) && v==0);
363 	unit_assert( cfg_parse_memsize("1", &v) && v==1);
364 	unit_assert( cfg_parse_memsize("10", &v) && v==10);
365 	unit_assert( cfg_parse_memsize("10b", &v) && v==10);
366 	unit_assert( cfg_parse_memsize("5b", &v) && v==5);
367 	unit_assert( cfg_parse_memsize("1024", &v) && v==1024);
368 	unit_assert( cfg_parse_memsize("1k", &v) && v==1024);
369 	unit_assert( cfg_parse_memsize("1K", &v) && v==1024);
370 	unit_assert( cfg_parse_memsize("1Kb", &v) && v==1024);
371 	unit_assert( cfg_parse_memsize("1kb", &v) && v==1024);
372 	unit_assert( cfg_parse_memsize("1 kb", &v) && v==1024);
373 	unit_assert( cfg_parse_memsize("10 kb", &v) && v==10240);
374 	unit_assert( cfg_parse_memsize("2k", &v) && v==2048);
375 	unit_assert( cfg_parse_memsize("2m", &v) && v==2048*1024);
376 	unit_assert( cfg_parse_memsize("3M", &v) && v==3072*1024);
377 	unit_assert( cfg_parse_memsize("40m", &v) && v==40960*1024);
378 	unit_assert( cfg_parse_memsize("1G", &v) && v==1024*1024*1024);
379 	unit_assert( cfg_parse_memsize("1 Gb", &v) && v==1024*1024*1024);
380 	unit_assert( cfg_parse_memsize("0 Gb", &v) && v==0*1024*1024);
381 }
382 
383 /** test config_file: test tag code */
384 static void
385 config_tag_test(void)
386 {
387 	unit_show_func("util/config_file.c", "taglist_intersect");
388 	unit_assert( taglist_intersect(
389 		(uint8_t*)"\000\000\000", 3, (uint8_t*)"\001\000\001", 3
390 		) == 0);
391 	unit_assert( taglist_intersect(
392 		(uint8_t*)"\000\000\001", 3, (uint8_t*)"\001\000\001", 3
393 		) == 1);
394 	unit_assert( taglist_intersect(
395 		(uint8_t*)"\001\000\000", 3, (uint8_t*)"\001\000\001", 3
396 		) == 1);
397 	unit_assert( taglist_intersect(
398 		(uint8_t*)"\001", 1, (uint8_t*)"\001\000\001", 3
399 		) == 1);
400 	unit_assert( taglist_intersect(
401 		(uint8_t*)"\001\000\001", 3, (uint8_t*)"\001", 1
402 		) == 1);
403 }
404 
405 #include "util/rtt.h"
406 #include "util/timehist.h"
407 #include "iterator/iterator.h"
408 #include "libunbound/unbound.h"
409 /** test RTT code */
410 static void
411 rtt_test(void)
412 {
413 	int init = UNKNOWN_SERVER_NICENESS;
414 	int i;
415 	struct rtt_info r;
416 	unit_show_func("util/rtt.c", "rtt_timeout");
417 	rtt_init(&r);
418 	/* initial value sensible */
419 	unit_assert( rtt_timeout(&r) == init );
420 	rtt_lost(&r, init);
421 	unit_assert( rtt_timeout(&r) == init*2 );
422 	rtt_lost(&r, init*2);
423 	unit_assert( rtt_timeout(&r) == init*4 );
424 	rtt_update(&r, 4000);
425 	unit_assert( rtt_timeout(&r) >= 2000 );
426 	rtt_lost(&r, rtt_timeout(&r) );
427 	for(i=0; i<100; i++) {
428 		rtt_lost(&r, rtt_timeout(&r) );
429 		unit_assert( rtt_timeout(&r) > RTT_MIN_TIMEOUT-1);
430 		unit_assert( rtt_timeout(&r) < RTT_MAX_TIMEOUT+1);
431 	}
432 	/* must be the same, timehist bucket is used in stats */
433 	unit_assert(UB_STATS_BUCKET_NUM == NUM_BUCKETS_HIST);
434 }
435 
436 #include "services/cache/infra.h"
437 
438 /* lookup and get key and data structs easily */
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
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/random.h"
534 /** test randomness */
535 static void
536 rnd_test(void)
537 {
538 	struct ub_randstate* r;
539 	int num = 1000, i;
540 	long int a[1000];
541 	unsigned int seed = (unsigned)time(NULL);
542 	unit_show_feature("ub_random");
543 	printf("ub_random seed is %u\n", seed);
544 	unit_assert( (r = ub_initstate(seed, NULL)) );
545 	for(i=0; i<num; i++) {
546 		a[i] = ub_random(r);
547 		unit_assert(a[i] >= 0);
548 		unit_assert((size_t)a[i] <= (size_t)0x7fffffff);
549 		if(i > 5)
550 			unit_assert(a[i] != a[i-1] || a[i] != a[i-2] ||
551 				a[i] != a[i-3] || a[i] != a[i-4] ||
552 				a[i] != a[i-5] || a[i] != a[i-6]);
553 	}
554 	a[0] = ub_random_max(r, 1);
555 	unit_assert(a[0] >= 0 && a[0] < 1);
556 	a[0] = ub_random_max(r, 10000);
557 	unit_assert(a[0] >= 0 && a[0] < 10000);
558 	for(i=0; i<num; i++) {
559 		a[i] = ub_random_max(r, 10);
560 		unit_assert(a[i] >= 0 && a[i] < 10);
561 	}
562 	ub_randfree(r);
563 }
564 
565 #include "respip/respip.h"
566 #include "services/localzone.h"
567 #include "util/data/packed_rrset.h"
568 typedef struct addr_action {char* ip; char* sact; enum respip_action act;}
569 	addr_action_t;
570 
571 /** Utility function that verifies that the respip set has actions as expected */
572 static void
573 verify_respip_set_actions(struct respip_set* set, addr_action_t actions[],
574 	int actions_len)
575 {
576 	int i = 0;
577 	struct rbtree_type* tree = respip_set_get_tree(set);
578 	for (i=0; i<actions_len; i++) {
579 		struct sockaddr_storage addr;
580 		int net;
581 		socklen_t addrlen;
582 		struct resp_addr* node;
583 		netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr,
584 			&addrlen, &net);
585 		node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
586 
587 		/** we have the node and the node has the correct action
588 		  * and has no data */
589 		unit_assert(node);
590 		unit_assert(actions[i].act ==
591 			resp_addr_get_action(node));
592 		unit_assert(resp_addr_get_rrset(node) == NULL);
593 	}
594 	unit_assert(actions_len && i == actions_len);
595 	unit_assert(actions_len == (int)tree->count);
596 }
597 
598 /** Global respip actions test; apply raw config data and verify that
599   * all the nodes in the respip set, looked up by address, have expected
600   * actions */
601 static void
602 respip_conf_actions_test(void)
603 {
604 	addr_action_t config_response_ip[] = {
605 		{"192.0.1.0/24", "deny", respip_deny},
606 		{"192.0.2.0/24", "redirect", respip_redirect},
607 		{"192.0.3.0/26", "inform", respip_inform},
608 		{"192.0.4.0/27", "inform_deny", respip_inform_deny},
609 		{"2001:db8:1::/48", "always_transparent", respip_always_transparent},
610 		{"2001:db8:2::/49", "always_refuse", respip_always_refuse},
611 		{"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
612 	};
613 	int i;
614 	struct respip_set* set = respip_set_create();
615 	struct config_file cfg;
616 	int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t));
617 
618 	unit_assert(set);
619 	unit_show_feature("global respip config actions apply");
620 	memset(&cfg, 0, sizeof(cfg));
621 	for(i=0; i<clen; i++) {
622 		char* ip = strdup(config_response_ip[i].ip);
623 		char* sact = strdup(config_response_ip[i].sact);
624 		unit_assert(ip && sact);
625 		if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact))
626 			unit_assert(0);
627 	}
628 	unit_assert(respip_global_apply_cfg(set, &cfg));
629 	verify_respip_set_actions(set, config_response_ip, clen);
630 
631 	respip_set_delete(set);
632 	config_deldblstrlist(cfg.respip_actions);
633 }
634 
635 /** Per-view respip actions test; apply raw configuration with two views
636   * and verify that actions are as expected in respip sets of both views */
637 static void
638 respip_view_conf_actions_test(void)
639 {
640 	addr_action_t config_response_ip_view1[] = {
641 		{"192.0.1.0/24", "deny", respip_deny},
642 		{"192.0.2.0/24", "redirect", respip_redirect},
643 		{"192.0.3.0/26", "inform", respip_inform},
644 		{"192.0.4.0/27", "inform_deny", respip_inform_deny},
645 	};
646 	addr_action_t config_response_ip_view2[] = {
647 		{"2001:db8:1::/48", "always_transparent", respip_always_transparent},
648 		{"2001:db8:2::/49", "always_refuse", respip_always_refuse},
649 		{"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
650 	};
651 	int i;
652 	struct config_file cfg;
653 	int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t));
654 	int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t));
655 	struct config_view* cv1;
656 	struct config_view* cv2;
657 	int have_respip_cfg = 0;
658 	struct views* views = NULL;
659 	struct view* v = NULL;
660 
661 	unit_show_feature("per-view respip config actions apply");
662 	memset(&cfg, 0, sizeof(cfg));
663 	cv1 = (struct config_view*)calloc(1, sizeof(struct config_view));
664 	cv2 = (struct config_view*)calloc(1, sizeof(struct config_view));
665 	unit_assert(cv1 && cv2);
666 	cv1->name = strdup("view1");
667 	cv2->name = strdup("view2");
668 	unit_assert(cv1->name && cv2->name);
669 	cv1->next = cv2;
670 	cfg.views = cv1;
671 
672 	for(i=0; i<clen1; i++) {
673 		char* ip = strdup(config_response_ip_view1[i].ip);
674 		char* sact = strdup(config_response_ip_view1[i].sact);
675 		unit_assert(ip && sact);
676 		if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact))
677 			unit_assert(0);
678 	}
679 	for(i=0; i<clen2; i++) {
680 		char* ip = strdup(config_response_ip_view2[i].ip);
681 		char* sact = strdup(config_response_ip_view2[i].sact);
682 		unit_assert(ip && sact);
683 		if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact))
684 			unit_assert(0);
685 	}
686 	views = views_create();
687 	unit_assert(views);
688 	unit_assert(views_apply_cfg(views, &cfg));
689 	unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
690 
691 	/* now verify the respip sets in each view */
692 	v = views_find_view(views, "view1", 0);
693 	unit_assert(v);
694 	verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1);
695 	lock_rw_unlock(&v->lock);
696 	v = views_find_view(views, "view2", 0);
697 	unit_assert(v);
698 	verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2);
699 	lock_rw_unlock(&v->lock);
700 
701 	views_delete(views);
702 	free(cv1->name);
703 	free(cv1);
704 	free(cv2->name);
705 	free(cv2);
706 }
707 
708 typedef struct addr_data {char* ip; char* data;} addr_data_t;
709 
710 /** find the respip address node in the specified tree (by address lookup)
711   * and verify type and address of the specified rdata (by index) in this
712   * node's rrset */
713 static void
714 verify_rrset(struct respip_set* set, const char* ipstr,
715 	const char* rdatastr, size_t rdi, uint16_t type)
716 {
717 	struct sockaddr_storage addr;
718 	int net;
719 	char buf[65536];
720 	socklen_t addrlen;
721 	struct rbtree_type* tree;
722 	struct resp_addr* node;
723 	const struct ub_packed_rrset_key* rrs;
724 
725 	netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net);
726 	tree = respip_set_get_tree(set);
727 	node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
728 	unit_assert(node);
729 	unit_assert((rrs = resp_addr_get_rrset(node)));
730 	unit_assert(ntohs(rrs->rk.type) == type);
731 	packed_rr_to_string((struct ub_packed_rrset_key*)rrs,
732 		rdi, 0, buf, sizeof(buf));
733 	unit_assert(strstr(buf, rdatastr));
734 }
735 
736 /** Dataset used to test redirect rrset initialization for both
737   * global and per-view respip redirect configuration */
738 static addr_data_t config_response_ip_data[] = {
739 	{"192.0.1.0/24", "A 1.2.3.4"},
740 	{"192.0.1.0/24", "A 11.12.13.14"},
741 	{"192.0.2.0/24", "CNAME www.example.com."},
742 	{"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"},
743 };
744 
745 /** Populate raw respip redirect config data, used for both global and
746   * view-based respip redirect test case */
747 static void
748 cfg_insert_respip_data(struct config_str2list** respip_actions,
749 	struct config_str2list** respip_data)
750 {
751 	int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t));
752 	int i = 0;
753 
754 	/* insert actions (duplicate netblocks don't matter) */
755 	for(i=0; i<clen; i++) {
756 		char* ip = strdup(config_response_ip_data[i].ip);
757 		char* sact = strdup("redirect");
758 		unit_assert(ip && sact);
759 		if(!cfg_str2list_insert(respip_actions, ip, sact))
760 			unit_assert(0);
761 	}
762 	/* insert data */
763 	for(i=0; i<clen; i++) {
764 		char* ip = strdup(config_response_ip_data[i].ip);
765 		char* data = strdup(config_response_ip_data[i].data);
766 		unit_assert(ip && data);
767 		if(!cfg_str2list_insert(respip_data, ip, data))
768 			unit_assert(0);
769 	}
770 }
771 
772 /** Test global respip redirect w/ data directives */
773 static void
774 respip_conf_data_test(void)
775 {
776 	struct respip_set* set = respip_set_create();
777 	struct config_file cfg;
778 
779 	unit_show_feature("global respip config data apply");
780 	memset(&cfg, 0, sizeof(cfg));
781 
782 	cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data);
783 
784 	/* apply configuration and verify rrsets */
785 	unit_assert(respip_global_apply_cfg(set, &cfg));
786 	verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A);
787 	verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A);
788 	verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME);
789 	verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA);
790 
791 	respip_set_delete(set);
792 }
793 
794 /** Test per-view respip redirect w/ data directives */
795 static void
796 respip_view_conf_data_test(void)
797 {
798 	struct config_file cfg;
799 	struct config_view* cv;
800 	int have_respip_cfg = 0;
801 	struct views* views = NULL;
802 	struct view* v = NULL;
803 
804 	unit_show_feature("per-view respip config data apply");
805 	memset(&cfg, 0, sizeof(cfg));
806 	cv = (struct config_view*)calloc(1, sizeof(struct config_view));
807 	unit_assert(cv);
808 	cv->name = strdup("view1");
809 	unit_assert(cv->name);
810 	cfg.views = cv;
811 	cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data);
812 	views = views_create();
813 	unit_assert(views);
814 	unit_assert(views_apply_cfg(views, &cfg));
815 
816 	/* apply configuration and verify rrsets */
817 	unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
818 	v = views_find_view(views, "view1", 0);
819 	unit_assert(v);
820 	verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4",
821 		0, LDNS_RR_TYPE_A);
822 	verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14",
823 		1, LDNS_RR_TYPE_A);
824 	verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com",
825 		0, LDNS_RR_TYPE_CNAME);
826 	verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1",
827 		0, LDNS_RR_TYPE_AAAA);
828 	lock_rw_unlock(&v->lock);
829 
830 	views_delete(views);
831 	free(cv->name);
832 	free(cv);
833 }
834 
835 /** respip unit tests */
836 static void respip_test(void)
837 {
838 	respip_view_conf_data_test();
839 	respip_conf_data_test();
840 	respip_view_conf_actions_test();
841 	respip_conf_actions_test();
842 }
843 
844 void unit_show_func(const char* file, const char* func)
845 {
846 	printf("test %s:%s\n", file, func);
847 }
848 
849 void unit_show_feature(const char* feature)
850 {
851 	printf("test %s functions\n", feature);
852 }
853 
854 #ifdef USE_ECDSA_EVP_WORKAROUND
855 void ecdsa_evp_workaround_init(void);
856 #endif
857 /**
858  * Main unit test program. Setup, teardown and report errors.
859  * @param argc: arg count.
860  * @param argv: array of commandline arguments.
861  * @return program failure if test fails.
862  */
863 int
864 main(int argc, char* argv[])
865 {
866 	log_init(NULL, 0, NULL);
867 	if(argc != 1) {
868 		printf("usage: %s\n", argv[0]);
869 		printf("\tperforms unit tests.\n");
870 		return 1;
871 	}
872 	printf("Start of %s unit test.\n", PACKAGE_STRING);
873 #ifdef HAVE_SSL
874 #  ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
875 	ERR_load_crypto_strings();
876 #  endif
877 #  ifdef USE_GOST
878 	(void)sldns_key_EVP_load_gost_id();
879 #  endif
880 #  ifdef USE_ECDSA_EVP_WORKAROUND
881 	ecdsa_evp_workaround_init();
882 #  endif
883 #elif defined(HAVE_NSS)
884 	if(NSS_NoDB_Init(".") != SECSuccess)
885 		fatal_exit("could not init NSS");
886 #endif /* HAVE_SSL or HAVE_NSS*/
887 	checklock_start();
888 	authzone_test();
889 	neg_test();
890 	rnd_test();
891 	respip_test();
892 	verify_test();
893 	net_test();
894 	config_memsize_test();
895 	config_tag_test();
896 	dname_test();
897 	rtt_test();
898 	anchors_test();
899 	alloc_test();
900 	regional_test();
901 	lruhash_test();
902 	slabhash_test();
903 	infra_test();
904 	ldns_test();
905 	msgparse_test();
906 #ifdef CLIENT_SUBNET
907 	ecs_test();
908 #endif /* CLIENT_SUBNET */
909 	if(log_get_lock()) {
910 		lock_quick_destroy((lock_quick_type*)log_get_lock());
911 	}
912 	checklock_stop();
913 	printf("%d checks ok.\n", testcount);
914 #ifdef HAVE_SSL
915 #  if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
916 	sldns_key_EVP_unload_gost();
917 #  endif
918 #  ifdef HAVE_OPENSSL_CONFIG
919 #  ifdef HAVE_EVP_CLEANUP
920 	EVP_cleanup();
921 #  endif
922 	ENGINE_cleanup();
923 	CONF_modules_free();
924 #  endif
925 #  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
926 	CRYPTO_cleanup_all_ex_data();
927 #  endif
928 #  ifdef HAVE_ERR_FREE_STRINGS
929 	ERR_free_strings();
930 #  endif
931 #  ifdef HAVE_RAND_CLEANUP
932 	RAND_cleanup();
933 #  endif
934 #elif defined(HAVE_NSS)
935 	if(NSS_Shutdown() != SECSuccess)
936 		fatal_exit("could not shutdown NSS");
937 #endif /* HAVE_SSL or HAVE_NSS */
938 #ifdef HAVE_PTHREAD
939 	/* dlopen frees its thread specific state */
940 	pthread_exit(NULL);
941 #endif
942 	return 0;
943 }
944