]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - testcode/unitmain.c
Vendor import of Unbound 1.12.0.
[FreeBSD/FreeBSD.git] / testcode / unitmain.c
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         /* Disable roundrobin for the unit tests */
871         RRSET_ROUNDROBIN = 0;
872 #ifdef USE_LIBEVENT
873         printf("Start of %s+libevent unit test.\n", PACKAGE_STRING);
874 #else
875         printf("Start of %s unit test.\n", PACKAGE_STRING);
876 #endif
877 #ifdef HAVE_SSL
878 #  ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
879         ERR_load_crypto_strings();
880 #  endif
881 #  ifdef USE_GOST
882         (void)sldns_key_EVP_load_gost_id();
883 #  endif
884 #  ifdef USE_ECDSA_EVP_WORKAROUND
885         ecdsa_evp_workaround_init();
886 #  endif
887 #elif defined(HAVE_NSS)
888         if(NSS_NoDB_Init(".") != SECSuccess)
889                 fatal_exit("could not init NSS");
890 #endif /* HAVE_SSL or HAVE_NSS*/
891         checklock_start();
892         authzone_test();
893         neg_test();
894         rnd_test();
895         respip_test();
896         verify_test();
897         net_test();
898         config_memsize_test();
899         config_tag_test();
900         dname_test();
901         rtt_test();
902         anchors_test();
903         alloc_test();
904         regional_test();
905         lruhash_test();
906         slabhash_test();
907         infra_test();
908         ldns_test();
909         msgparse_test();
910 #ifdef CLIENT_SUBNET
911         ecs_test();
912 #endif /* CLIENT_SUBNET */
913         if(log_get_lock()) {
914                 lock_basic_destroy((lock_basic_type*)log_get_lock());
915         }
916         checklock_stop();
917         printf("%d checks ok.\n", testcount);
918 #ifdef HAVE_SSL
919 #  if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
920         sldns_key_EVP_unload_gost();
921 #  endif
922 #  ifdef HAVE_OPENSSL_CONFIG
923 #  ifdef HAVE_EVP_CLEANUP
924         EVP_cleanup();
925 #  endif
926 #  if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
927         ENGINE_cleanup();
928 #  endif
929         CONF_modules_free();
930 #  endif
931 #  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
932         CRYPTO_cleanup_all_ex_data();
933 #  endif
934 #  ifdef HAVE_ERR_FREE_STRINGS
935         ERR_free_strings();
936 #  endif
937 #  ifdef HAVE_RAND_CLEANUP
938         RAND_cleanup();
939 #  endif
940 #elif defined(HAVE_NSS)
941         if(NSS_Shutdown() != SECSuccess)
942                 fatal_exit("could not shutdown NSS");
943 #endif /* HAVE_SSL or HAVE_NSS */
944 #ifdef HAVE_PTHREAD
945         /* dlopen frees its thread specific state */
946         pthread_exit(NULL);
947 #endif
948         return 0;
949 }