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