]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - testcode/unitmain.c
Vendor import of Unbound 1.6.2.
[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 /** test RTT code */
407 static void
408 rtt_test(void)
409 {
410         int init = 376;
411         int i;
412         struct rtt_info r;
413         unit_show_func("util/rtt.c", "rtt_timeout");
414         rtt_init(&r);
415         /* initial value sensible */
416         unit_assert( rtt_timeout(&r) == init );
417         rtt_lost(&r, init);
418         unit_assert( rtt_timeout(&r) == init*2 );
419         rtt_lost(&r, init*2);
420         unit_assert( rtt_timeout(&r) == init*4 );
421         rtt_update(&r, 4000);
422         unit_assert( rtt_timeout(&r) >= 2000 );
423         rtt_lost(&r, rtt_timeout(&r) );
424         for(i=0; i<100; i++) {
425                 rtt_lost(&r, rtt_timeout(&r) ); 
426                 unit_assert( rtt_timeout(&r) > RTT_MIN_TIMEOUT-1);
427                 unit_assert( rtt_timeout(&r) < RTT_MAX_TIMEOUT+1);
428         }
429 }
430
431 #include "services/cache/infra.h"
432 #include "util/config_file.h"
433
434 /* lookup and get key and data structs easily */
435 static struct infra_data* infra_lookup_host(struct infra_cache* infra,
436         struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
437         size_t zonelen, int wr, time_t now, struct infra_key** k)
438 {
439         struct infra_data* d;
440         struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
441                 zone, zonelen, wr);
442         if(!e) return NULL;
443         d = (struct infra_data*)e->data;
444         if(d->ttl < now) {
445                 lock_rw_unlock(&e->lock);
446                 return NULL;
447         }
448         *k = (struct infra_key*)e->key;
449         return d;
450 }
451
452 /** test host cache */
453 static void
454 infra_test(void)
455 {
456         struct sockaddr_storage one;
457         socklen_t onelen;
458         uint8_t* zone = (uint8_t*)"\007example\003com\000";
459         size_t zonelen = 13;
460         struct infra_cache* slab;
461         struct config_file* cfg = config_create();
462         time_t now = 0;
463         uint8_t edns_lame;
464         int vs, to;
465         struct infra_key* k;
466         struct infra_data* d;
467         int init = 376;
468
469         unit_show_feature("infra cache");
470         unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen));
471
472         slab = infra_create(cfg);
473         unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now,
474                 &vs, &edns_lame, &to) );
475         unit_assert( vs == 0 && to == init && edns_lame == 0 );
476
477         unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, LDNS_RR_TYPE_A, -1, init, now) );
478         unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 
479                         now, &vs, &edns_lame, &to) );
480         unit_assert( vs == 0 && to == init*2 && edns_lame == 0 );
481
482         unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) );
483         unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 
484                         now, &vs, &edns_lame, &to) );
485         unit_assert( vs == -1 && to == init*2  && edns_lame == 1);
486
487         now += cfg->host_ttl + 10;
488         unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 
489                         now, &vs, &edns_lame, &to) );
490         unit_assert( vs == 0 && to == init && edns_lame == 0 );
491         
492         unit_assert( infra_set_lame(slab, &one, onelen,
493                 zone, zonelen,  now, 0, 0, LDNS_RR_TYPE_A) );
494         unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) );
495         unit_assert( d->ttl == now+cfg->host_ttl );
496         unit_assert( d->edns_version == 0 );
497         unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A &&
498                 !d->lame_other);
499         lock_rw_unlock(&k->entry.lock);
500
501         /* test merge of data */
502         unit_assert( infra_set_lame(slab, &one, onelen,
503                 zone, zonelen,  now, 0, 0, LDNS_RR_TYPE_AAAA) );
504         unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) );
505         unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A &&
506                 d->lame_other);
507         lock_rw_unlock(&k->entry.lock);
508
509         /* test that noEDNS cannot overwrite known-yesEDNS */
510         now += cfg->host_ttl + 10;
511         unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 
512                         now, &vs, &edns_lame, &to) );
513         unit_assert( vs == 0 && to == init && edns_lame == 0 );
514
515         unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) );
516         unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 
517                         now, &vs, &edns_lame, &to) );
518         unit_assert( vs == 0 && to == init && edns_lame == 1 );
519
520         unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) );
521         unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 
522                         now, &vs, &edns_lame, &to) );
523         unit_assert( vs == 0 && to == init && edns_lame == 1 );
524
525         infra_delete(slab);
526         config_delete(cfg);
527 }
528
529 #include "util/random.h"
530 /** test randomness */
531 static void
532 rnd_test(void)
533 {
534         struct ub_randstate* r;
535         int num = 1000, i;
536         long int a[1000];
537         unsigned int seed = (unsigned)time(NULL);
538         unit_show_feature("ub_random");
539         printf("ub_random seed is %u\n", seed);
540         unit_assert( (r = ub_initstate(seed, NULL)) );
541         for(i=0; i<num; i++) {
542                 a[i] = ub_random(r);
543                 unit_assert(a[i] >= 0);
544                 unit_assert((size_t)a[i] <= (size_t)0x7fffffff);
545                 if(i > 5)
546                         unit_assert(a[i] != a[i-1] || a[i] != a[i-2] ||
547                                 a[i] != a[i-3] || a[i] != a[i-4] ||
548                                 a[i] != a[i-5] || a[i] != a[i-6]);
549         }
550         a[0] = ub_random_max(r, 1);
551         unit_assert(a[0] >= 0 && a[0] < 1);
552         a[0] = ub_random_max(r, 10000);
553         unit_assert(a[0] >= 0 && a[0] < 10000);
554         for(i=0; i<num; i++) {
555                 a[i] = ub_random_max(r, 10);
556                 unit_assert(a[i] >= 0 && a[i] < 10);
557         }
558         ub_randfree(r);
559 }
560
561 #include "respip/respip.h"
562 #include "services/localzone.h"
563 #include "util/data/packed_rrset.h"
564 typedef struct addr_action {char* ip; char* sact; enum respip_action act;}
565         addr_action_t;
566
567 /** Utility function that verifies that the respip set has actions as expected */
568 static void
569 verify_respip_set_actions(struct respip_set* set, addr_action_t actions[],
570         int actions_len)
571 {
572         int i = 0;
573         struct rbtree_type* tree = respip_set_get_tree(set);
574         for (i=0; i<actions_len; i++) {
575                 struct sockaddr_storage addr;
576                 int net;
577                 socklen_t addrlen;
578                 struct resp_addr* node;
579                 netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr,
580                         &addrlen, &net);
581                 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
582
583                 /** we have the node and the node has the correct action
584                   * and has no data */
585                 unit_assert(node);
586                 unit_assert(actions[i].act ==
587                         resp_addr_get_action(node));
588                 unit_assert(resp_addr_get_rrset(node) == NULL);
589         }
590         unit_assert(actions_len && i == actions_len);
591         unit_assert(actions_len == (int)tree->count);
592 }
593
594 /** Global respip actions test; apply raw config data and verify that
595   * all the nodes in the respip set, looked up by address, have expected
596   * actions */
597 static void
598 respip_conf_actions_test(void)
599 {
600         addr_action_t config_response_ip[] = {
601                 {"192.0.1.0/24", "deny", respip_deny},
602                 {"192.0.2.0/24", "redirect", respip_redirect},
603                 {"192.0.3.0/26", "inform", respip_inform},
604                 {"192.0.4.0/27", "inform_deny", respip_inform_deny},
605                 {"2001:db8:1::/48", "always_transparent", respip_always_transparent},
606                 {"2001:db8:2::/49", "always_refuse", respip_always_refuse},
607                 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
608         };
609         int i;
610         struct respip_set* set = respip_set_create();
611         struct config_file cfg;
612         int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t));
613
614         unit_assert(set);
615         unit_show_feature("global respip config actions apply");
616         memset(&cfg, 0, sizeof(cfg));
617         for(i=0; i<clen; i++) {
618                 char* ip = strdup(config_response_ip[i].ip);
619                 char* sact = strdup(config_response_ip[i].sact);
620                 unit_assert(ip && sact);
621                 if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact))
622                         unit_assert(0);
623         }
624         unit_assert(respip_global_apply_cfg(set, &cfg));
625         verify_respip_set_actions(set, config_response_ip, clen);
626 }
627
628 /** Per-view respip actions test; apply raw configuration with two views
629   * and verify that actions are as expected in respip sets of both views */
630 static void
631 respip_view_conf_actions_test(void)
632 {
633         addr_action_t config_response_ip_view1[] = {
634                 {"192.0.1.0/24", "deny", respip_deny},
635                 {"192.0.2.0/24", "redirect", respip_redirect},
636                 {"192.0.3.0/26", "inform", respip_inform},
637                 {"192.0.4.0/27", "inform_deny", respip_inform_deny},
638         };
639         addr_action_t config_response_ip_view2[] = {
640                 {"2001:db8:1::/48", "always_transparent", respip_always_transparent},
641                 {"2001:db8:2::/49", "always_refuse", respip_always_refuse},
642                 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
643         };
644         int i;
645         struct config_file cfg;
646         int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t));
647         int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t));
648         struct config_view* cv1;
649         struct config_view* cv2;
650         int have_respip_cfg = 0;
651         struct views* views = NULL;
652         struct view* v = NULL;
653
654         unit_show_feature("per-view respip config actions apply");
655         memset(&cfg, 0, sizeof(cfg));
656         cv1 = (struct config_view*)calloc(1, sizeof(struct config_view));
657         cv2 = (struct config_view*)calloc(1, sizeof(struct config_view));
658         unit_assert(cv1 && cv2);
659         cv1->name = strdup("view1");
660         cv2->name = strdup("view2");
661         unit_assert(cv1->name && cv2->name);
662         cv1->next = cv2;
663         cfg.views = cv1;
664
665         for(i=0; i<clen1; i++) {
666                 char* ip = strdup(config_response_ip_view1[i].ip);
667                 char* sact = strdup(config_response_ip_view1[i].sact);
668                 unit_assert(ip && sact);
669                 if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact))
670                         unit_assert(0);
671         }
672         for(i=0; i<clen2; i++) {
673                 char* ip = strdup(config_response_ip_view2[i].ip);
674                 char* sact = strdup(config_response_ip_view2[i].sact);
675                 unit_assert(ip && sact);
676                 if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact))
677                         unit_assert(0);
678         }
679         views = views_create();
680         unit_assert(views);
681         unit_assert(views_apply_cfg(views, &cfg));
682         unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
683
684         /* now verify the respip sets in each view */
685         v = views_find_view(views, "view1", 0);
686         unit_assert(v);
687         verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1);
688         lock_rw_unlock(&v->lock);
689         v = views_find_view(views, "view2", 0);
690         unit_assert(v);
691         verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2);
692         lock_rw_unlock(&v->lock);
693 }
694
695 typedef struct addr_data {char* ip; char* data;} addr_data_t;
696
697 /** find the respip address node in the specified tree (by address lookup)
698   * and verify type and address of the specified rdata (by index) in this
699   * node's rrset */
700 static void
701 verify_rrset(struct respip_set* set, const char* ipstr,
702         const char* rdatastr, size_t rdi, uint16_t type)
703 {
704         struct sockaddr_storage addr;
705         int net;
706         char buf[65536];
707         socklen_t addrlen;
708         struct rbtree_type* tree;
709         struct resp_addr* node;
710         const struct ub_packed_rrset_key* rrs;
711
712         netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net);
713         tree = respip_set_get_tree(set);
714         node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
715         unit_assert(node);
716         unit_assert((rrs = resp_addr_get_rrset(node)));
717         unit_assert(ntohs(rrs->rk.type) == type);
718         packed_rr_to_string((struct ub_packed_rrset_key*)rrs,
719                 rdi, 0, buf, sizeof(buf));
720         unit_assert(strstr(buf, rdatastr));
721 }
722
723 /** Dataset used to test redirect rrset initialization for both
724   * global and per-view respip redirect configuration */
725 static addr_data_t config_response_ip_data[] = {
726         {"192.0.1.0/24", "A 1.2.3.4"},
727         {"192.0.1.0/24", "A 11.12.13.14"},
728         {"192.0.2.0/24", "CNAME www.example.com."},
729         {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"},
730 };
731
732 /** Populate raw respip redirect config data, used for both global and
733   * view-based respip redirect test case */
734 static void
735 cfg_insert_respip_data(struct config_str2list** respip_actions,
736         struct config_str2list** respip_data)
737 {
738         int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t));
739         int i = 0;
740
741         /* insert actions (duplicate netblocks don't matter) */
742         for(i=0; i<clen; i++) {
743                 char* ip = strdup(config_response_ip_data[i].ip);
744                 char* sact = strdup("redirect");
745                 unit_assert(ip && sact);
746                 if(!cfg_str2list_insert(respip_actions, ip, sact))
747                         unit_assert(0);
748         }
749         /* insert data */
750         for(i=0; i<clen; i++) {
751                 char* ip = strdup(config_response_ip_data[i].ip);
752                 char* data = strdup(config_response_ip_data[i].data);
753                 unit_assert(ip && data);
754                 if(!cfg_str2list_insert(respip_data, ip, data))
755                         unit_assert(0);
756         }
757 }
758
759 /** Test global respip redirect w/ data directives */
760 static void
761 respip_conf_data_test(void)
762 {
763         struct respip_set* set = respip_set_create();
764         struct config_file cfg;
765
766         unit_show_feature("global respip config data apply");
767         memset(&cfg, 0, sizeof(cfg));
768
769         cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data);
770
771         /* apply configuration and verify rrsets */
772         unit_assert(respip_global_apply_cfg(set, &cfg));
773         verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A);
774         verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A);
775         verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME);
776         verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA);
777 }
778
779 /** Test per-view respip redirect w/ data directives */
780 static void
781 respip_view_conf_data_test(void)
782 {
783         struct config_file cfg;
784         struct config_view* cv;
785         int have_respip_cfg = 0;
786         struct views* views = NULL;
787         struct view* v = NULL;
788
789         unit_show_feature("per-view respip config data apply");
790         memset(&cfg, 0, sizeof(cfg));
791         cv = (struct config_view*)calloc(1, sizeof(struct config_view));
792         unit_assert(cv);
793         cv->name = strdup("view1");
794         unit_assert(cv->name);
795         cfg.views = cv;
796         cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data);
797         views = views_create();
798         unit_assert(views);
799         unit_assert(views_apply_cfg(views, &cfg));
800
801         /* apply configuration and verify rrsets */
802         unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
803         v = views_find_view(views, "view1", 0);
804         unit_assert(v);
805         verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4",
806                 0, LDNS_RR_TYPE_A);
807         verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14",
808                 1, LDNS_RR_TYPE_A);
809         verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com",
810                 0, LDNS_RR_TYPE_CNAME);
811         verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1",
812                 0, LDNS_RR_TYPE_AAAA);
813 }
814
815 /** respip unit tests */
816 static void respip_test(void)
817 {
818         respip_view_conf_data_test();
819         respip_conf_data_test();
820         respip_view_conf_actions_test();
821         respip_conf_actions_test();
822 }
823
824 void unit_show_func(const char* file, const char* func)
825 {
826         printf("test %s:%s\n", file, func);
827 }
828
829 void unit_show_feature(const char* feature)
830 {
831         printf("test %s functions\n", feature);
832 }
833
834 #ifdef USE_ECDSA_EVP_WORKAROUND
835 void ecdsa_evp_workaround_init(void);
836 #endif
837 /**
838  * Main unit test program. Setup, teardown and report errors.
839  * @param argc: arg count.
840  * @param argv: array of commandline arguments.
841  * @return program failure if test fails.
842  */
843 int 
844 main(int argc, char* argv[])
845 {
846         log_init(NULL, 0, NULL);
847         if(argc != 1) {
848                 printf("usage: %s\n", argv[0]);
849                 printf("\tperforms unit tests.\n");
850                 return 1;
851         }
852         printf("Start of %s unit test.\n", PACKAGE_STRING);
853 #ifdef HAVE_SSL
854 #  ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
855         ERR_load_crypto_strings();
856 #  endif
857 #  ifdef USE_GOST
858         (void)sldns_key_EVP_load_gost_id();
859 #  endif
860 #  ifdef USE_ECDSA_EVP_WORKAROUND
861         ecdsa_evp_workaround_init();
862 #  endif
863 #elif defined(HAVE_NSS)
864         if(NSS_NoDB_Init(".") != SECSuccess)
865                 fatal_exit("could not init NSS");
866 #endif /* HAVE_SSL or HAVE_NSS*/
867         checklock_start();
868         neg_test();
869         rnd_test();
870         respip_test();
871         verify_test();
872         net_test();
873         config_memsize_test();
874         config_tag_test();
875         dname_test();
876         rtt_test();
877         anchors_test();
878         alloc_test();
879         regional_test();
880         lruhash_test();
881         slabhash_test();
882         infra_test();
883         ldns_test();
884         msgparse_test();
885 #ifdef CLIENT_SUBNET
886         ecs_test();
887 #endif /* CLIENT_SUBNET */
888         checklock_stop();
889         printf("%d checks ok.\n", testcount);
890 #ifdef HAVE_SSL
891 #  if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
892         sldns_key_EVP_unload_gost();
893 #  endif
894 #  ifdef HAVE_OPENSSL_CONFIG
895 #  ifdef HAVE_EVP_CLEANUP
896         EVP_cleanup();
897 #  endif
898         ENGINE_cleanup();
899         CONF_modules_free();
900 #  endif
901 #  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
902         CRYPTO_cleanup_all_ex_data();
903 #  endif
904 #  ifdef HAVE_ERR_FREE_STRINGS
905         ERR_free_strings();
906 #  endif
907 #  ifdef HAVE_RAND_CLEANUP
908         RAND_cleanup();
909 #  endif
910 #elif defined(HAVE_NSS)
911         if(NSS_Shutdown() != SECSuccess)
912                 fatal_exit("could not shutdown NSS");
913 #endif /* HAVE_SSL or HAVE_NSS */
914 #ifdef HAVE_PTHREAD
915         /* dlopen frees its thread specific state */
916         pthread_exit(NULL);
917 #endif
918         return 0;
919 }