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 */
70int testcount = 0;
71
72#include "util/alloc.h"
73/** test alloc code */
74static void
75alloc_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 */
113static void
114net_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 */
346static void
347config_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 */
384static void
385config_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 */
410static void
411rtt_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 */
439static 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 */
457static void
458infra_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 */
536static void
537edns_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. */
566static void
567edns_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. */
599static void
600edns_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. */
630static void
631edns_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. */
661static void
662edns_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. */
691static void
692edns_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) */
720static void
721edns_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 */
736static void
737rnd_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"
767typedef 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 */
771static void
772verify_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 */
800static void
801respip_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 */
836static void
837respip_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
907typedef 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 */
912static void
913verify_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 */
937static 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 */
946static void
947cfg_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 */
972static void
973respip_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 */
994static void
995respip_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 */
1035static 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
1050static 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
1106static 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) == 0);
1121}
1122
1123static 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
1142static 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
1163static 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
1194static 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 */
1226static 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
1255void unit_show_func(const char* file, const char* func)
1256{
1257	printf("test %s:%s\n", file, func);
1258}
1259
1260void unit_show_feature(const char* feature)
1261{
1262	printf("test %s functions\n", feature);
1263}
1264
1265#ifdef USE_ECDSA_EVP_WORKAROUND
1266void ecdsa_evp_workaround_init(void);
1267#endif
1268
1269/**
1270 * Main unit test program. Setup, teardown and report errors.
1271 * @param argc: arg count.
1272 * @param argv: array of commandline arguments.
1273 * @return program failure if test fails.
1274 */
1275int
1276main(int argc, char* argv[])
1277{
1278	checklock_start();
1279	log_init(NULL, 0, NULL);
1280	if(argc != 1) {
1281		printf("usage: %s\n", argv[0]);
1282		printf("\tperforms unit tests.\n");
1283		return 1;
1284	}
1285	/* Disable roundrobin for the unit tests */
1286	RRSET_ROUNDROBIN = 0;
1287#ifdef USE_LIBEVENT
1288	printf("Start of %s+libevent unit test.\n", PACKAGE_STRING);
1289#else
1290	printf("Start of %s unit test.\n", PACKAGE_STRING);
1291#endif
1292#ifdef HAVE_SSL
1293#  ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
1294	ERR_load_crypto_strings();
1295#  endif
1296#  ifdef USE_GOST
1297	(void)sldns_key_EVP_load_gost_id();
1298#  endif
1299#  ifdef USE_ECDSA_EVP_WORKAROUND
1300	ecdsa_evp_workaround_init();
1301#  endif
1302#elif defined(HAVE_NSS)
1303	if(NSS_NoDB_Init(".") != SECSuccess)
1304		fatal_exit("could not init NSS");
1305#endif /* HAVE_SSL or HAVE_NSS*/
1306	authzone_test();
1307	neg_test();
1308	rnd_test();
1309	respip_test();
1310	verify_test();
1311	net_test();
1312	config_memsize_test();
1313	config_tag_test();
1314	dname_test();
1315	rtt_test();
1316	anchors_test();
1317	alloc_test();
1318	regional_test();
1319	lruhash_test();
1320	slabhash_test();
1321	infra_test();
1322	ldns_test();
1323	edns_cookie_test();
1324	zonemd_test();
1325	tcpreuse_test();
1326	msgparse_test();
1327	edns_ede_answer_encode_test();
1328#ifdef CLIENT_SUBNET
1329	ecs_test();
1330#endif /* CLIENT_SUBNET */
1331	if(log_get_lock()) {
1332		lock_basic_destroy((lock_basic_type*)log_get_lock());
1333	}
1334	checklock_stop();
1335	printf("%d checks ok.\n", testcount);
1336#ifdef HAVE_SSL
1337#  if defined(USE_GOST)
1338	sldns_key_EVP_unload_gost();
1339#  endif
1340#  ifdef HAVE_OPENSSL_CONFIG
1341#  ifdef HAVE_EVP_CLEANUP
1342	EVP_cleanup();
1343#  endif
1344#  if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
1345	ENGINE_cleanup();
1346#  endif
1347	CONF_modules_free();
1348#  endif
1349#  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
1350	CRYPTO_cleanup_all_ex_data();
1351#  endif
1352#  ifdef HAVE_ERR_FREE_STRINGS
1353	ERR_free_strings();
1354#  endif
1355#  ifdef HAVE_RAND_CLEANUP
1356	RAND_cleanup();
1357#  endif
1358#elif defined(HAVE_NSS)
1359	if(NSS_Shutdown() != SECSuccess)
1360		fatal_exit("could not shutdown NSS");
1361#endif /* HAVE_SSL or HAVE_NSS */
1362#ifdef HAVE_PTHREAD
1363	/* dlopen frees its thread specific state */
1364	pthread_exit(NULL);
1365#endif
1366	return 0;
1367}
1368