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 	unit_show_feature("ub_random");
542 	unit_assert( (r = ub_initstate(NULL)) );
543 	for(i=0; i<num; i++) {
544 		a[i] = ub_random(r);
545 		unit_assert(a[i] >= 0);
546 		unit_assert((size_t)a[i] <= (size_t)0x7fffffff);
547 		if(i > 5)
548 			unit_assert(a[i] != a[i-1] || a[i] != a[i-2] ||
549 				a[i] != a[i-3] || a[i] != a[i-4] ||
550 				a[i] != a[i-5] || a[i] != a[i-6]);
551 	}
552 	a[0] = ub_random_max(r, 1);
553 	unit_assert(a[0] >= 0 && a[0] < 1);
554 	a[0] = ub_random_max(r, 10000);
555 	unit_assert(a[0] >= 0 && a[0] < 10000);
556 	for(i=0; i<num; i++) {
557 		a[i] = ub_random_max(r, 10);
558 		unit_assert(a[i] >= 0 && a[i] < 10);
559 	}
560 	ub_randfree(r);
561 }
562 
563 #include "respip/respip.h"
564 #include "services/localzone.h"
565 #include "util/data/packed_rrset.h"
566 typedef struct addr_action {char* ip; char* sact; enum respip_action act;}
567 	addr_action_t;
568 
569 /** Utility function that verifies that the respip set has actions as expected */
570 static void
571 verify_respip_set_actions(struct respip_set* set, addr_action_t actions[],
572 	int actions_len)
573 {
574 	int i = 0;
575 	struct rbtree_type* tree = respip_set_get_tree(set);
576 	for (i=0; i<actions_len; i++) {
577 		struct sockaddr_storage addr;
578 		int net;
579 		socklen_t addrlen;
580 		struct resp_addr* node;
581 		netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr,
582 			&addrlen, &net);
583 		node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
584 
585 		/** we have the node and the node has the correct action
586 		  * and has no data */
587 		unit_assert(node);
588 		unit_assert(actions[i].act ==
589 			resp_addr_get_action(node));
590 		unit_assert(resp_addr_get_rrset(node) == NULL);
591 	}
592 	unit_assert(actions_len && i == actions_len);
593 	unit_assert(actions_len == (int)tree->count);
594 }
595 
596 /** Global respip actions test; apply raw config data and verify that
597   * all the nodes in the respip set, looked up by address, have expected
598   * actions */
599 static void
600 respip_conf_actions_test(void)
601 {
602 	addr_action_t config_response_ip[] = {
603 		{"192.0.1.0/24", "deny", respip_deny},
604 		{"192.0.2.0/24", "redirect", respip_redirect},
605 		{"192.0.3.0/26", "inform", respip_inform},
606 		{"192.0.4.0/27", "inform_deny", respip_inform_deny},
607 		{"2001:db8:1::/48", "always_transparent", respip_always_transparent},
608 		{"2001:db8:2::/49", "always_refuse", respip_always_refuse},
609 		{"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
610 	};
611 	int i;
612 	struct respip_set* set = respip_set_create();
613 	struct config_file cfg;
614 	int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t));
615 
616 	unit_assert(set);
617 	unit_show_feature("global respip config actions apply");
618 	memset(&cfg, 0, sizeof(cfg));
619 	for(i=0; i<clen; i++) {
620 		char* ip = strdup(config_response_ip[i].ip);
621 		char* sact = strdup(config_response_ip[i].sact);
622 		unit_assert(ip && sact);
623 		if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact))
624 			unit_assert(0);
625 	}
626 	unit_assert(respip_global_apply_cfg(set, &cfg));
627 	verify_respip_set_actions(set, config_response_ip, clen);
628 
629 	respip_set_delete(set);
630 	config_deldblstrlist(cfg.respip_actions);
631 }
632 
633 /** Per-view respip actions test; apply raw configuration with two views
634   * and verify that actions are as expected in respip sets of both views */
635 static void
636 respip_view_conf_actions_test(void)
637 {
638 	addr_action_t config_response_ip_view1[] = {
639 		{"192.0.1.0/24", "deny", respip_deny},
640 		{"192.0.2.0/24", "redirect", respip_redirect},
641 		{"192.0.3.0/26", "inform", respip_inform},
642 		{"192.0.4.0/27", "inform_deny", respip_inform_deny},
643 	};
644 	addr_action_t config_response_ip_view2[] = {
645 		{"2001:db8:1::/48", "always_transparent", respip_always_transparent},
646 		{"2001:db8:2::/49", "always_refuse", respip_always_refuse},
647 		{"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
648 	};
649 	int i;
650 	struct config_file cfg;
651 	int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t));
652 	int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t));
653 	struct config_view* cv1;
654 	struct config_view* cv2;
655 	int have_respip_cfg = 0;
656 	struct views* views = NULL;
657 	struct view* v = NULL;
658 
659 	unit_show_feature("per-view respip config actions apply");
660 	memset(&cfg, 0, sizeof(cfg));
661 	cv1 = (struct config_view*)calloc(1, sizeof(struct config_view));
662 	cv2 = (struct config_view*)calloc(1, sizeof(struct config_view));
663 	unit_assert(cv1 && cv2);
664 	cv1->name = strdup("view1");
665 	cv2->name = strdup("view2");
666 	unit_assert(cv1->name && cv2->name);
667 	cv1->next = cv2;
668 	cfg.views = cv1;
669 
670 	for(i=0; i<clen1; i++) {
671 		char* ip = strdup(config_response_ip_view1[i].ip);
672 		char* sact = strdup(config_response_ip_view1[i].sact);
673 		unit_assert(ip && sact);
674 		if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact))
675 			unit_assert(0);
676 	}
677 	for(i=0; i<clen2; i++) {
678 		char* ip = strdup(config_response_ip_view2[i].ip);
679 		char* sact = strdup(config_response_ip_view2[i].sact);
680 		unit_assert(ip && sact);
681 		if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact))
682 			unit_assert(0);
683 	}
684 	views = views_create();
685 	unit_assert(views);
686 	unit_assert(views_apply_cfg(views, &cfg));
687 	unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
688 
689 	/* now verify the respip sets in each view */
690 	v = views_find_view(views, "view1", 0);
691 	unit_assert(v);
692 	verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1);
693 	lock_rw_unlock(&v->lock);
694 	v = views_find_view(views, "view2", 0);
695 	unit_assert(v);
696 	verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2);
697 	lock_rw_unlock(&v->lock);
698 
699 	views_delete(views);
700 	free(cv1->name);
701 	free(cv1);
702 	free(cv2->name);
703 	free(cv2);
704 }
705 
706 typedef struct addr_data {char* ip; char* data;} addr_data_t;
707 
708 /** find the respip address node in the specified tree (by address lookup)
709   * and verify type and address of the specified rdata (by index) in this
710   * node's rrset */
711 static void
712 verify_rrset(struct respip_set* set, const char* ipstr,
713 	const char* rdatastr, size_t rdi, uint16_t type)
714 {
715 	struct sockaddr_storage addr;
716 	int net;
717 	char buf[65536];
718 	socklen_t addrlen;
719 	struct rbtree_type* tree;
720 	struct resp_addr* node;
721 	const struct ub_packed_rrset_key* rrs;
722 
723 	netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net);
724 	tree = respip_set_get_tree(set);
725 	node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
726 	unit_assert(node);
727 	unit_assert((rrs = resp_addr_get_rrset(node)));
728 	unit_assert(ntohs(rrs->rk.type) == type);
729 	packed_rr_to_string((struct ub_packed_rrset_key*)rrs,
730 		rdi, 0, buf, sizeof(buf));
731 	unit_assert(strstr(buf, rdatastr));
732 }
733 
734 /** Dataset used to test redirect rrset initialization for both
735   * global and per-view respip redirect configuration */
736 static addr_data_t config_response_ip_data[] = {
737 	{"192.0.1.0/24", "A 1.2.3.4"},
738 	{"192.0.1.0/24", "A 11.12.13.14"},
739 	{"192.0.2.0/24", "CNAME www.example.com."},
740 	{"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"},
741 };
742 
743 /** Populate raw respip redirect config data, used for both global and
744   * view-based respip redirect test case */
745 static void
746 cfg_insert_respip_data(struct config_str2list** respip_actions,
747 	struct config_str2list** respip_data)
748 {
749 	int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t));
750 	int i = 0;
751 
752 	/* insert actions (duplicate netblocks don't matter) */
753 	for(i=0; i<clen; i++) {
754 		char* ip = strdup(config_response_ip_data[i].ip);
755 		char* sact = strdup("redirect");
756 		unit_assert(ip && sact);
757 		if(!cfg_str2list_insert(respip_actions, ip, sact))
758 			unit_assert(0);
759 	}
760 	/* insert data */
761 	for(i=0; i<clen; i++) {
762 		char* ip = strdup(config_response_ip_data[i].ip);
763 		char* data = strdup(config_response_ip_data[i].data);
764 		unit_assert(ip && data);
765 		if(!cfg_str2list_insert(respip_data, ip, data))
766 			unit_assert(0);
767 	}
768 }
769 
770 /** Test global respip redirect w/ data directives */
771 static void
772 respip_conf_data_test(void)
773 {
774 	struct respip_set* set = respip_set_create();
775 	struct config_file cfg;
776 
777 	unit_show_feature("global respip config data apply");
778 	memset(&cfg, 0, sizeof(cfg));
779 
780 	cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data);
781 
782 	/* apply configuration and verify rrsets */
783 	unit_assert(respip_global_apply_cfg(set, &cfg));
784 	verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A);
785 	verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A);
786 	verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME);
787 	verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA);
788 
789 	respip_set_delete(set);
790 }
791 
792 /** Test per-view respip redirect w/ data directives */
793 static void
794 respip_view_conf_data_test(void)
795 {
796 	struct config_file cfg;
797 	struct config_view* cv;
798 	int have_respip_cfg = 0;
799 	struct views* views = NULL;
800 	struct view* v = NULL;
801 
802 	unit_show_feature("per-view respip config data apply");
803 	memset(&cfg, 0, sizeof(cfg));
804 	cv = (struct config_view*)calloc(1, sizeof(struct config_view));
805 	unit_assert(cv);
806 	cv->name = strdup("view1");
807 	unit_assert(cv->name);
808 	cfg.views = cv;
809 	cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data);
810 	views = views_create();
811 	unit_assert(views);
812 	unit_assert(views_apply_cfg(views, &cfg));
813 
814 	/* apply configuration and verify rrsets */
815 	unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
816 	v = views_find_view(views, "view1", 0);
817 	unit_assert(v);
818 	verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4",
819 		0, LDNS_RR_TYPE_A);
820 	verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14",
821 		1, LDNS_RR_TYPE_A);
822 	verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com",
823 		0, LDNS_RR_TYPE_CNAME);
824 	verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1",
825 		0, LDNS_RR_TYPE_AAAA);
826 	lock_rw_unlock(&v->lock);
827 
828 	views_delete(views);
829 	free(cv->name);
830 	free(cv);
831 }
832 
833 /** respip unit tests */
834 static void respip_test(void)
835 {
836 	respip_view_conf_data_test();
837 	respip_conf_data_test();
838 	respip_view_conf_actions_test();
839 	respip_conf_actions_test();
840 }
841 
842 void unit_show_func(const char* file, const char* func)
843 {
844 	printf("test %s:%s\n", file, func);
845 }
846 
847 void unit_show_feature(const char* feature)
848 {
849 	printf("test %s functions\n", feature);
850 }
851 
852 #ifdef USE_ECDSA_EVP_WORKAROUND
853 void ecdsa_evp_workaround_init(void);
854 #endif
855 /**
856  * Main unit test program. Setup, teardown and report errors.
857  * @param argc: arg count.
858  * @param argv: array of commandline arguments.
859  * @return program failure if test fails.
860  */
861 int
862 main(int argc, char* argv[])
863 {
864 	log_init(NULL, 0, NULL);
865 	if(argc != 1) {
866 		printf("usage: %s\n", argv[0]);
867 		printf("\tperforms unit tests.\n");
868 		return 1;
869 	}
870 	printf("Start of %s unit test.\n", PACKAGE_STRING);
871 #ifdef HAVE_SSL
872 #  ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
873 	ERR_load_crypto_strings();
874 #  endif
875 #  ifdef USE_GOST
876 	(void)sldns_key_EVP_load_gost_id();
877 #  endif
878 #  ifdef USE_ECDSA_EVP_WORKAROUND
879 	ecdsa_evp_workaround_init();
880 #  endif
881 #elif defined(HAVE_NSS)
882 	if(NSS_NoDB_Init(".") != SECSuccess)
883 		fatal_exit("could not init NSS");
884 #endif /* HAVE_SSL or HAVE_NSS*/
885 	checklock_start();
886 	authzone_test();
887 	neg_test();
888 	rnd_test();
889 	respip_test();
890 	verify_test();
891 	net_test();
892 	config_memsize_test();
893 	config_tag_test();
894 	dname_test();
895 	rtt_test();
896 	anchors_test();
897 	alloc_test();
898 	regional_test();
899 	lruhash_test();
900 	slabhash_test();
901 	infra_test();
902 	ldns_test();
903 	msgparse_test();
904 #ifdef CLIENT_SUBNET
905 	ecs_test();
906 #endif /* CLIENT_SUBNET */
907 	if(log_get_lock()) {
908 		lock_basic_destroy((lock_basic_type*)log_get_lock());
909 	}
910 	checklock_stop();
911 	printf("%d checks ok.\n", testcount);
912 #ifdef HAVE_SSL
913 #  if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
914 	sldns_key_EVP_unload_gost();
915 #  endif
916 #  ifdef HAVE_OPENSSL_CONFIG
917 #  ifdef HAVE_EVP_CLEANUP
918 	EVP_cleanup();
919 #  endif
920 	ENGINE_cleanup();
921 	CONF_modules_free();
922 #  endif
923 #  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
924 	CRYPTO_cleanup_all_ex_data();
925 #  endif
926 #  ifdef HAVE_ERR_FREE_STRINGS
927 	ERR_free_strings();
928 #  endif
929 #  ifdef HAVE_RAND_CLEANUP
930 	RAND_cleanup();
931 #  endif
932 #elif defined(HAVE_NSS)
933 	if(NSS_Shutdown() != SECSuccess)
934 		fatal_exit("could not shutdown NSS");
935 #endif /* HAVE_SSL or HAVE_NSS */
936 #ifdef HAVE_PTHREAD
937 	/* dlopen frees its thread specific state */
938 	pthread_exit(NULL);
939 #endif
940 	return 0;
941 }
942