1712b2f30Ssthen /* 2712b2f30Ssthen * testcode/unitmain.c - unit test main program for unbound. 3712b2f30Ssthen * 4712b2f30Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved. 5712b2f30Ssthen * 6712b2f30Ssthen * This software is open source. 7712b2f30Ssthen * 8712b2f30Ssthen * Redistribution and use in source and binary forms, with or without 9712b2f30Ssthen * modification, are permitted provided that the following conditions 10712b2f30Ssthen * are met: 11712b2f30Ssthen * 12712b2f30Ssthen * Redistributions of source code must retain the above copyright notice, 13712b2f30Ssthen * this list of conditions and the following disclaimer. 14712b2f30Ssthen * 15712b2f30Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16712b2f30Ssthen * this list of conditions and the following disclaimer in the documentation 17712b2f30Ssthen * and/or other materials provided with the distribution. 18712b2f30Ssthen * 19712b2f30Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20712b2f30Ssthen * be used to endorse or promote products derived from this software without 21712b2f30Ssthen * specific prior written permission. 22712b2f30Ssthen * 23712b2f30Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24712b2f30Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25712b2f30Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26712b2f30Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27712b2f30Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28712b2f30Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29712b2f30Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30712b2f30Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31712b2f30Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32712b2f30Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33712b2f30Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34712b2f30Ssthen * 35712b2f30Ssthen */ 36712b2f30Ssthen /** 37712b2f30Ssthen * \file 38712b2f30Ssthen * Unit test main program. Calls all the other unit tests. 39712b2f30Ssthen * Exits with code 1 on a failure. 0 if all unit tests are successful. 40712b2f30Ssthen */ 41712b2f30Ssthen 42712b2f30Ssthen #include "config.h" 43712b2f30Ssthen #ifdef HAVE_OPENSSL_ERR_H 44712b2f30Ssthen #include <openssl/err.h> 45712b2f30Ssthen #endif 46712b2f30Ssthen 47712b2f30Ssthen #ifdef HAVE_OPENSSL_RAND_H 48712b2f30Ssthen #include <openssl/rand.h> 49712b2f30Ssthen #endif 50712b2f30Ssthen 51712b2f30Ssthen #ifdef HAVE_OPENSSL_CONF_H 52712b2f30Ssthen #include <openssl/conf.h> 53712b2f30Ssthen #endif 54712b2f30Ssthen 55712b2f30Ssthen #ifdef HAVE_OPENSSL_ENGINE_H 56712b2f30Ssthen #include <openssl/engine.h> 57712b2f30Ssthen #endif 58712b2f30Ssthen 59712b2f30Ssthen #ifdef HAVE_NSS 60712b2f30Ssthen /* nss3 */ 61712b2f30Ssthen #include "nss.h" 62712b2f30Ssthen #endif 63712b2f30Ssthen 64712b2f30Ssthen #include "sldns/rrdef.h" 65712b2f30Ssthen #include "sldns/keyraw.h" 66712b2f30Ssthen #include "util/log.h" 67712b2f30Ssthen #include "testcode/unitmain.h" 68712b2f30Ssthen 69712b2f30Ssthen /** number of tests done */ 70712b2f30Ssthen int testcount = 0; 71712b2f30Ssthen 72712b2f30Ssthen #include "util/alloc.h" 73712b2f30Ssthen /** test alloc code */ 74712b2f30Ssthen static void 75712b2f30Ssthen alloc_test(void) { 76712b2f30Ssthen alloc_special_type *t1, *t2; 77712b2f30Ssthen struct alloc_cache major, minor1, minor2; 78712b2f30Ssthen int i; 79712b2f30Ssthen 80712b2f30Ssthen unit_show_feature("alloc_special_obtain"); 81712b2f30Ssthen alloc_init(&major, NULL, 0); 82712b2f30Ssthen alloc_init(&minor1, &major, 0); 83712b2f30Ssthen alloc_init(&minor2, &major, 1); 84712b2f30Ssthen 85712b2f30Ssthen t1 = alloc_special_obtain(&minor1); 86712b2f30Ssthen alloc_clear(&minor1); 87712b2f30Ssthen 88712b2f30Ssthen alloc_special_release(&minor2, t1); 89712b2f30Ssthen t2 = alloc_special_obtain(&minor2); 90712b2f30Ssthen unit_assert( t1 == t2 ); /* reused */ 91712b2f30Ssthen alloc_special_release(&minor2, t1); 92712b2f30Ssthen 93712b2f30Ssthen for(i=0; i<100; i++) { 94712b2f30Ssthen t1 = alloc_special_obtain(&minor1); 95712b2f30Ssthen alloc_special_release(&minor2, t1); 96712b2f30Ssthen } 97712b2f30Ssthen if(0) { 98712b2f30Ssthen alloc_stats(&minor1); 99712b2f30Ssthen alloc_stats(&minor2); 100712b2f30Ssthen alloc_stats(&major); 101712b2f30Ssthen } 102712b2f30Ssthen /* reuse happened */ 103712b2f30Ssthen unit_assert(minor1.num_quar + minor2.num_quar + major.num_quar == 11); 104712b2f30Ssthen 105712b2f30Ssthen alloc_clear(&minor1); 106712b2f30Ssthen alloc_clear(&minor2); 107712b2f30Ssthen unit_assert(major.num_quar == 11); 108712b2f30Ssthen alloc_clear(&major); 109712b2f30Ssthen } 110712b2f30Ssthen 111712b2f30Ssthen #include "util/net_help.h" 112712b2f30Ssthen /** test net code */ 113712b2f30Ssthen static void 114712b2f30Ssthen net_test(void) 115712b2f30Ssthen { 116712b2f30Ssthen const char* t4[] = {"\000\000\000\000", 117712b2f30Ssthen "\200\000\000\000", 118712b2f30Ssthen "\300\000\000\000", 119712b2f30Ssthen "\340\000\000\000", 120712b2f30Ssthen "\360\000\000\000", 121712b2f30Ssthen "\370\000\000\000", 122712b2f30Ssthen "\374\000\000\000", 123712b2f30Ssthen "\376\000\000\000", 124712b2f30Ssthen "\377\000\000\000", 125712b2f30Ssthen "\377\200\000\000", 126712b2f30Ssthen "\377\300\000\000", 127712b2f30Ssthen "\377\340\000\000", 128712b2f30Ssthen "\377\360\000\000", 129712b2f30Ssthen "\377\370\000\000", 130712b2f30Ssthen "\377\374\000\000", 131712b2f30Ssthen "\377\376\000\000", 132712b2f30Ssthen "\377\377\000\000", 133712b2f30Ssthen "\377\377\200\000", 134712b2f30Ssthen "\377\377\300\000", 135712b2f30Ssthen "\377\377\340\000", 136712b2f30Ssthen "\377\377\360\000", 137712b2f30Ssthen "\377\377\370\000", 138712b2f30Ssthen "\377\377\374\000", 139712b2f30Ssthen "\377\377\376\000", 140712b2f30Ssthen "\377\377\377\000", 141712b2f30Ssthen "\377\377\377\200", 142712b2f30Ssthen "\377\377\377\300", 143712b2f30Ssthen "\377\377\377\340", 144712b2f30Ssthen "\377\377\377\360", 145712b2f30Ssthen "\377\377\377\370", 146712b2f30Ssthen "\377\377\377\374", 147712b2f30Ssthen "\377\377\377\376", 148712b2f30Ssthen "\377\377\377\377", 149712b2f30Ssthen "\377\377\377\377", 150712b2f30Ssthen "\377\377\377\377", 151712b2f30Ssthen }; 152712b2f30Ssthen unit_show_func("util/net_help.c", "str_is_ip6"); 153712b2f30Ssthen unit_assert( str_is_ip6("::") ); 154712b2f30Ssthen unit_assert( str_is_ip6("::1") ); 155712b2f30Ssthen unit_assert( str_is_ip6("2001:7b8:206:1:240:f4ff:fe37:8810") ); 156712b2f30Ssthen unit_assert( str_is_ip6("fe80::240:f4ff:fe37:8810") ); 157712b2f30Ssthen unit_assert( !str_is_ip6("0.0.0.0") ); 158712b2f30Ssthen unit_assert( !str_is_ip6("213.154.224.12") ); 159712b2f30Ssthen unit_assert( !str_is_ip6("213.154.224.255") ); 160712b2f30Ssthen unit_assert( !str_is_ip6("255.255.255.0") ); 161712b2f30Ssthen unit_show_func("util/net_help.c", "is_pow2"); 162712b2f30Ssthen unit_assert( is_pow2(0) ); 163712b2f30Ssthen unit_assert( is_pow2(1) ); 164712b2f30Ssthen unit_assert( is_pow2(2) ); 165712b2f30Ssthen unit_assert( is_pow2(4) ); 166712b2f30Ssthen unit_assert( is_pow2(8) ); 167712b2f30Ssthen unit_assert( is_pow2(16) ); 168712b2f30Ssthen unit_assert( is_pow2(1024) ); 169712b2f30Ssthen unit_assert( is_pow2(1024*1024) ); 170712b2f30Ssthen unit_assert( is_pow2(1024*1024*1024) ); 171712b2f30Ssthen unit_assert( !is_pow2(3) ); 172712b2f30Ssthen unit_assert( !is_pow2(5) ); 173712b2f30Ssthen unit_assert( !is_pow2(6) ); 174712b2f30Ssthen unit_assert( !is_pow2(7) ); 175712b2f30Ssthen unit_assert( !is_pow2(9) ); 176712b2f30Ssthen unit_assert( !is_pow2(10) ); 177712b2f30Ssthen unit_assert( !is_pow2(11) ); 178712b2f30Ssthen unit_assert( !is_pow2(17) ); 179712b2f30Ssthen unit_assert( !is_pow2(23) ); 180712b2f30Ssthen unit_assert( !is_pow2(257) ); 181712b2f30Ssthen unit_assert( !is_pow2(259) ); 182712b2f30Ssthen 183712b2f30Ssthen /* test addr_mask */ 184712b2f30Ssthen unit_show_func("util/net_help.c", "addr_mask"); 185712b2f30Ssthen if(1) { 186712b2f30Ssthen struct sockaddr_in a4; 187712b2f30Ssthen struct sockaddr_in6 a6; 188712b2f30Ssthen socklen_t l4 = (socklen_t)sizeof(a4); 189712b2f30Ssthen socklen_t l6 = (socklen_t)sizeof(a6); 190712b2f30Ssthen int i; 191712b2f30Ssthen a4.sin_family = AF_INET; 192712b2f30Ssthen a6.sin6_family = AF_INET6; 193712b2f30Ssthen for(i=0; i<35; i++) { 194712b2f30Ssthen /* address 255.255.255.255 */ 195712b2f30Ssthen memcpy(&a4.sin_addr, "\377\377\377\377", 4); 196712b2f30Ssthen addr_mask((struct sockaddr_storage*)&a4, l4, i); 197712b2f30Ssthen unit_assert(memcmp(&a4.sin_addr, t4[i], 4) == 0); 198712b2f30Ssthen } 199712b2f30Ssthen memcpy(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16); 200712b2f30Ssthen addr_mask((struct sockaddr_storage*)&a6, l6, 128); 201712b2f30Ssthen unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) == 0); 202712b2f30Ssthen addr_mask((struct sockaddr_storage*)&a6, l6, 122); 203712b2f30Ssthen unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\300", 16) == 0); 204712b2f30Ssthen addr_mask((struct sockaddr_storage*)&a6, l6, 120); 205712b2f30Ssthen unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000", 16) == 0); 206712b2f30Ssthen addr_mask((struct sockaddr_storage*)&a6, l6, 64); 207712b2f30Ssthen unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", 16) == 0); 208712b2f30Ssthen addr_mask((struct sockaddr_storage*)&a6, l6, 0); 209712b2f30Ssthen unit_assert(memcmp(&a6.sin6_addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16) == 0); 210712b2f30Ssthen } 211712b2f30Ssthen 212712b2f30Ssthen /* test addr_in_common */ 213712b2f30Ssthen unit_show_func("util/net_help.c", "addr_in_common"); 214712b2f30Ssthen if(1) { 215712b2f30Ssthen struct sockaddr_in a4, b4; 216712b2f30Ssthen struct sockaddr_in6 a6, b6; 217712b2f30Ssthen socklen_t l4 = (socklen_t)sizeof(a4); 218712b2f30Ssthen socklen_t l6 = (socklen_t)sizeof(a6); 219712b2f30Ssthen int i; 220712b2f30Ssthen a4.sin_family = AF_INET; 221712b2f30Ssthen b4.sin_family = AF_INET; 222712b2f30Ssthen a6.sin6_family = AF_INET6; 223712b2f30Ssthen b6.sin6_family = AF_INET6; 224712b2f30Ssthen memcpy(&a4.sin_addr, "abcd", 4); 225712b2f30Ssthen memcpy(&b4.sin_addr, "abcd", 4); 226712b2f30Ssthen unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 32, 227712b2f30Ssthen (struct sockaddr_storage*)&b4, 32, l4) == 32); 228712b2f30Ssthen unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 34, 229712b2f30Ssthen (struct sockaddr_storage*)&b4, 32, l4) == 32); 230712b2f30Ssthen for(i=0; i<=32; i++) { 231712b2f30Ssthen unit_assert(addr_in_common( 232712b2f30Ssthen (struct sockaddr_storage*)&a4, 32, 233712b2f30Ssthen (struct sockaddr_storage*)&b4, i, l4) == i); 234712b2f30Ssthen unit_assert(addr_in_common( 235712b2f30Ssthen (struct sockaddr_storage*)&a4, i, 236712b2f30Ssthen (struct sockaddr_storage*)&b4, 32, l4) == i); 237712b2f30Ssthen unit_assert(addr_in_common( 238712b2f30Ssthen (struct sockaddr_storage*)&a4, i, 239712b2f30Ssthen (struct sockaddr_storage*)&b4, i, l4) == i); 240712b2f30Ssthen } 241712b2f30Ssthen for(i=0; i<=32; i++) { 242712b2f30Ssthen memcpy(&a4.sin_addr, "\377\377\377\377", 4); 243712b2f30Ssthen memcpy(&b4.sin_addr, t4[i], 4); 244712b2f30Ssthen unit_assert(addr_in_common( 245712b2f30Ssthen (struct sockaddr_storage*)&a4, 32, 246712b2f30Ssthen (struct sockaddr_storage*)&b4, 32, l4) == i); 247712b2f30Ssthen unit_assert(addr_in_common( 248712b2f30Ssthen (struct sockaddr_storage*)&b4, 32, 249712b2f30Ssthen (struct sockaddr_storage*)&a4, 32, l4) == i); 250712b2f30Ssthen } 251712b2f30Ssthen memcpy(&a6.sin6_addr, "abcdefghabcdefgh", 16); 252712b2f30Ssthen memcpy(&b6.sin6_addr, "abcdefghabcdefgh", 16); 253712b2f30Ssthen unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 128, 254712b2f30Ssthen (struct sockaddr_storage*)&b6, 128, l6) == 128); 255712b2f30Ssthen unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 129, 256712b2f30Ssthen (struct sockaddr_storage*)&b6, 128, l6) == 128); 257712b2f30Ssthen for(i=0; i<=128; i++) { 258712b2f30Ssthen unit_assert(addr_in_common( 259712b2f30Ssthen (struct sockaddr_storage*)&a6, 128, 260712b2f30Ssthen (struct sockaddr_storage*)&b6, i, l6) == i); 261712b2f30Ssthen unit_assert(addr_in_common( 262712b2f30Ssthen (struct sockaddr_storage*)&a6, i, 263712b2f30Ssthen (struct sockaddr_storage*)&b6, 128, l6) == i); 264712b2f30Ssthen unit_assert(addr_in_common( 265712b2f30Ssthen (struct sockaddr_storage*)&a6, i, 266712b2f30Ssthen (struct sockaddr_storage*)&b6, i, l6) == i); 267712b2f30Ssthen } 268712b2f30Ssthen } 269712b2f30Ssthen /* test sockaddr_cmp_addr */ 270712b2f30Ssthen unit_show_func("util/net_help.c", "sockaddr_cmp_addr"); 271712b2f30Ssthen if(1) { 272712b2f30Ssthen struct sockaddr_storage a, b; 273712b2f30Ssthen socklen_t alen = (socklen_t)sizeof(a); 274712b2f30Ssthen socklen_t blen = (socklen_t)sizeof(b); 275712b2f30Ssthen unit_assert(ipstrtoaddr("127.0.0.0", 53, &a, &alen)); 276712b2f30Ssthen unit_assert(ipstrtoaddr("127.255.255.255", 53, &b, &blen)); 277712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0); 278712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0); 279712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0); 280712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0); 281712b2f30Ssthen unit_assert(ipstrtoaddr("192.168.121.5", 53, &a, &alen)); 282712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) > 0); 283712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) < 0); 284712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0); 285712b2f30Ssthen unit_assert(ipstrtoaddr("2001:3578:ffeb::99", 53, &b, &blen)); 286712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0); 287712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0); 288712b2f30Ssthen unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0); 289712b2f30Ssthen } 290712b2f30Ssthen /* test addr_is_ip4mapped */ 291712b2f30Ssthen unit_show_func("util/net_help.c", "addr_is_ip4mapped"); 292712b2f30Ssthen if(1) { 293712b2f30Ssthen struct sockaddr_storage a; 294712b2f30Ssthen socklen_t l = (socklen_t)sizeof(a); 295712b2f30Ssthen unit_assert(ipstrtoaddr("12.13.14.15", 53, &a, &l)); 296712b2f30Ssthen unit_assert(!addr_is_ip4mapped(&a, l)); 297712b2f30Ssthen unit_assert(ipstrtoaddr("fe80::217:31ff:fe91:df", 53, &a, &l)); 298712b2f30Ssthen unit_assert(!addr_is_ip4mapped(&a, l)); 299712b2f30Ssthen unit_assert(ipstrtoaddr("ffff::217:31ff:fe91:df", 53, &a, &l)); 300712b2f30Ssthen unit_assert(!addr_is_ip4mapped(&a, l)); 301712b2f30Ssthen unit_assert(ipstrtoaddr("::ffff:31ff:fe91:df", 53, &a, &l)); 302712b2f30Ssthen unit_assert(!addr_is_ip4mapped(&a, l)); 303712b2f30Ssthen unit_assert(ipstrtoaddr("::fffe:fe91:df", 53, &a, &l)); 304712b2f30Ssthen unit_assert(!addr_is_ip4mapped(&a, l)); 305712b2f30Ssthen unit_assert(ipstrtoaddr("::ffff:127.0.0.1", 53, &a, &l)); 306712b2f30Ssthen unit_assert(addr_is_ip4mapped(&a, l)); 307712b2f30Ssthen unit_assert(ipstrtoaddr("::ffff:127.0.0.2", 53, &a, &l)); 308712b2f30Ssthen unit_assert(addr_is_ip4mapped(&a, l)); 309712b2f30Ssthen unit_assert(ipstrtoaddr("::ffff:192.168.0.2", 53, &a, &l)); 310712b2f30Ssthen unit_assert(addr_is_ip4mapped(&a, l)); 311712b2f30Ssthen unit_assert(ipstrtoaddr("2::ffff:192.168.0.2", 53, &a, &l)); 312712b2f30Ssthen unit_assert(!addr_is_ip4mapped(&a, l)); 313712b2f30Ssthen } 314712b2f30Ssthen /* test addr_is_any */ 315712b2f30Ssthen unit_show_func("util/net_help.c", "addr_is_any"); 316712b2f30Ssthen if(1) { 317712b2f30Ssthen struct sockaddr_storage a; 318712b2f30Ssthen socklen_t l = (socklen_t)sizeof(a); 319712b2f30Ssthen unit_assert(ipstrtoaddr("0.0.0.0", 53, &a, &l)); 320712b2f30Ssthen unit_assert(addr_is_any(&a, l)); 321712b2f30Ssthen unit_assert(ipstrtoaddr("0.0.0.0", 10053, &a, &l)); 322712b2f30Ssthen unit_assert(addr_is_any(&a, l)); 323712b2f30Ssthen unit_assert(ipstrtoaddr("0.0.0.0", 0, &a, &l)); 324712b2f30Ssthen unit_assert(addr_is_any(&a, l)); 325712b2f30Ssthen unit_assert(ipstrtoaddr("::0", 0, &a, &l)); 326712b2f30Ssthen unit_assert(addr_is_any(&a, l)); 327712b2f30Ssthen unit_assert(ipstrtoaddr("::0", 53, &a, &l)); 328712b2f30Ssthen unit_assert(addr_is_any(&a, l)); 329712b2f30Ssthen unit_assert(ipstrtoaddr("::1", 53, &a, &l)); 330712b2f30Ssthen unit_assert(!addr_is_any(&a, l)); 331712b2f30Ssthen unit_assert(ipstrtoaddr("2001:1667::1", 0, &a, &l)); 332712b2f30Ssthen unit_assert(!addr_is_any(&a, l)); 333712b2f30Ssthen unit_assert(ipstrtoaddr("2001::0", 0, &a, &l)); 334712b2f30Ssthen unit_assert(!addr_is_any(&a, l)); 335712b2f30Ssthen unit_assert(ipstrtoaddr("10.0.0.0", 0, &a, &l)); 336712b2f30Ssthen unit_assert(!addr_is_any(&a, l)); 337712b2f30Ssthen unit_assert(ipstrtoaddr("0.0.0.10", 0, &a, &l)); 338712b2f30Ssthen unit_assert(!addr_is_any(&a, l)); 339712b2f30Ssthen unit_assert(ipstrtoaddr("192.0.2.1", 0, &a, &l)); 340712b2f30Ssthen unit_assert(!addr_is_any(&a, l)); 341712b2f30Ssthen } 342712b2f30Ssthen } 343712b2f30Ssthen 344712b2f30Ssthen #include "util/config_file.h" 345712b2f30Ssthen /** test config_file: cfg_parse_memsize */ 346712b2f30Ssthen static void 347712b2f30Ssthen config_memsize_test(void) 348712b2f30Ssthen { 349712b2f30Ssthen size_t v = 0; 350712b2f30Ssthen unit_show_func("util/config_file.c", "cfg_parse_memsize"); 351712b2f30Ssthen if(0) { 352712b2f30Ssthen /* these emit errors */ 353712b2f30Ssthen unit_assert( cfg_parse_memsize("", &v) == 0); 354712b2f30Ssthen unit_assert( cfg_parse_memsize("bla", &v) == 0); 355712b2f30Ssthen unit_assert( cfg_parse_memsize("nop", &v) == 0); 356712b2f30Ssthen unit_assert( cfg_parse_memsize("n0b", &v) == 0); 357712b2f30Ssthen unit_assert( cfg_parse_memsize("gb", &v) == 0); 358712b2f30Ssthen unit_assert( cfg_parse_memsize("b", &v) == 0); 359712b2f30Ssthen unit_assert( cfg_parse_memsize("kb", &v) == 0); 360712b2f30Ssthen unit_assert( cfg_parse_memsize("kk kb", &v) == 0); 361712b2f30Ssthen } 362712b2f30Ssthen unit_assert( cfg_parse_memsize("0", &v) && v==0); 363712b2f30Ssthen unit_assert( cfg_parse_memsize("1", &v) && v==1); 364712b2f30Ssthen unit_assert( cfg_parse_memsize("10", &v) && v==10); 365712b2f30Ssthen unit_assert( cfg_parse_memsize("10b", &v) && v==10); 366712b2f30Ssthen unit_assert( cfg_parse_memsize("5b", &v) && v==5); 367712b2f30Ssthen unit_assert( cfg_parse_memsize("1024", &v) && v==1024); 368712b2f30Ssthen unit_assert( cfg_parse_memsize("1k", &v) && v==1024); 369712b2f30Ssthen unit_assert( cfg_parse_memsize("1K", &v) && v==1024); 370712b2f30Ssthen unit_assert( cfg_parse_memsize("1Kb", &v) && v==1024); 371712b2f30Ssthen unit_assert( cfg_parse_memsize("1kb", &v) && v==1024); 372712b2f30Ssthen unit_assert( cfg_parse_memsize("1 kb", &v) && v==1024); 373712b2f30Ssthen unit_assert( cfg_parse_memsize("10 kb", &v) && v==10240); 374712b2f30Ssthen unit_assert( cfg_parse_memsize("2k", &v) && v==2048); 375712b2f30Ssthen unit_assert( cfg_parse_memsize("2m", &v) && v==2048*1024); 376712b2f30Ssthen unit_assert( cfg_parse_memsize("3M", &v) && v==3072*1024); 377712b2f30Ssthen unit_assert( cfg_parse_memsize("40m", &v) && v==40960*1024); 378712b2f30Ssthen unit_assert( cfg_parse_memsize("1G", &v) && v==1024*1024*1024); 379712b2f30Ssthen unit_assert( cfg_parse_memsize("1 Gb", &v) && v==1024*1024*1024); 380712b2f30Ssthen unit_assert( cfg_parse_memsize("0 Gb", &v) && v==0*1024*1024); 381712b2f30Ssthen } 382712b2f30Ssthen 383712b2f30Ssthen /** test config_file: test tag code */ 384712b2f30Ssthen static void 385712b2f30Ssthen config_tag_test(void) 386712b2f30Ssthen { 387712b2f30Ssthen unit_show_func("util/config_file.c", "taglist_intersect"); 388712b2f30Ssthen unit_assert( taglist_intersect( 389712b2f30Ssthen (uint8_t*)"\000\000\000", 3, (uint8_t*)"\001\000\001", 3 390712b2f30Ssthen ) == 0); 391712b2f30Ssthen unit_assert( taglist_intersect( 392712b2f30Ssthen (uint8_t*)"\000\000\001", 3, (uint8_t*)"\001\000\001", 3 393712b2f30Ssthen ) == 1); 394712b2f30Ssthen unit_assert( taglist_intersect( 395712b2f30Ssthen (uint8_t*)"\001\000\000", 3, (uint8_t*)"\001\000\001", 3 396712b2f30Ssthen ) == 1); 397712b2f30Ssthen unit_assert( taglist_intersect( 398712b2f30Ssthen (uint8_t*)"\001", 1, (uint8_t*)"\001\000\001", 3 399712b2f30Ssthen ) == 1); 400712b2f30Ssthen unit_assert( taglist_intersect( 401712b2f30Ssthen (uint8_t*)"\001\000\001", 3, (uint8_t*)"\001", 1 402712b2f30Ssthen ) == 1); 403712b2f30Ssthen } 404712b2f30Ssthen 405712b2f30Ssthen #include "util/rtt.h" 406712b2f30Ssthen #include "util/timehist.h" 4077bc20e6dSsthen #include "iterator/iterator.h" 408712b2f30Ssthen #include "libunbound/unbound.h" 409712b2f30Ssthen /** test RTT code */ 410712b2f30Ssthen static void 411712b2f30Ssthen rtt_test(void) 412712b2f30Ssthen { 4137bc20e6dSsthen int init = UNKNOWN_SERVER_NICENESS; 414712b2f30Ssthen int i; 415712b2f30Ssthen struct rtt_info r; 416712b2f30Ssthen unit_show_func("util/rtt.c", "rtt_timeout"); 417712b2f30Ssthen rtt_init(&r); 418712b2f30Ssthen /* initial value sensible */ 419712b2f30Ssthen unit_assert( rtt_timeout(&r) == init ); 420712b2f30Ssthen rtt_lost(&r, init); 421712b2f30Ssthen unit_assert( rtt_timeout(&r) == init*2 ); 422712b2f30Ssthen rtt_lost(&r, init*2); 423712b2f30Ssthen unit_assert( rtt_timeout(&r) == init*4 ); 424712b2f30Ssthen rtt_update(&r, 4000); 425712b2f30Ssthen unit_assert( rtt_timeout(&r) >= 2000 ); 426712b2f30Ssthen rtt_lost(&r, rtt_timeout(&r) ); 427712b2f30Ssthen for(i=0; i<100; i++) { 428712b2f30Ssthen rtt_lost(&r, rtt_timeout(&r) ); 429712b2f30Ssthen unit_assert( rtt_timeout(&r) > RTT_MIN_TIMEOUT-1); 430712b2f30Ssthen unit_assert( rtt_timeout(&r) < RTT_MAX_TIMEOUT+1); 431712b2f30Ssthen } 432712b2f30Ssthen /* must be the same, timehist bucket is used in stats */ 433712b2f30Ssthen unit_assert(UB_STATS_BUCKET_NUM == NUM_BUCKETS_HIST); 434712b2f30Ssthen } 435712b2f30Ssthen 436712b2f30Ssthen #include "services/cache/infra.h" 437712b2f30Ssthen 438712b2f30Ssthen /* lookup and get key and data structs easily */ 439712b2f30Ssthen static struct infra_data* infra_lookup_host(struct infra_cache* infra, 440712b2f30Ssthen struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, 441712b2f30Ssthen size_t zonelen, int wr, time_t now, struct infra_key** k) 442712b2f30Ssthen { 443712b2f30Ssthen struct infra_data* d; 444712b2f30Ssthen struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 445712b2f30Ssthen zone, zonelen, wr); 446712b2f30Ssthen if(!e) return NULL; 447712b2f30Ssthen d = (struct infra_data*)e->data; 448712b2f30Ssthen if(d->ttl < now) { 449712b2f30Ssthen lock_rw_unlock(&e->lock); 450712b2f30Ssthen return NULL; 451712b2f30Ssthen } 452712b2f30Ssthen *k = (struct infra_key*)e->key; 453712b2f30Ssthen return d; 454712b2f30Ssthen } 455712b2f30Ssthen 456712b2f30Ssthen /** test host cache */ 457712b2f30Ssthen static void 458712b2f30Ssthen infra_test(void) 459712b2f30Ssthen { 460712b2f30Ssthen struct sockaddr_storage one; 461712b2f30Ssthen socklen_t onelen; 462712b2f30Ssthen uint8_t* zone = (uint8_t*)"\007example\003com\000"; 463712b2f30Ssthen size_t zonelen = 13; 464712b2f30Ssthen struct infra_cache* slab; 465712b2f30Ssthen struct config_file* cfg = config_create(); 466712b2f30Ssthen time_t now = 0; 467712b2f30Ssthen uint8_t edns_lame; 468712b2f30Ssthen int vs, to; 469712b2f30Ssthen struct infra_key* k; 470712b2f30Ssthen struct infra_data* d; 471712b2f30Ssthen int init = 376; 472712b2f30Ssthen 473712b2f30Ssthen unit_show_feature("infra cache"); 474712b2f30Ssthen unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen)); 475712b2f30Ssthen 476712b2f30Ssthen slab = infra_create(cfg); 477712b2f30Ssthen unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, 478712b2f30Ssthen &vs, &edns_lame, &to) ); 479712b2f30Ssthen unit_assert( vs == 0 && to == init && edns_lame == 0 ); 480712b2f30Ssthen 481712b2f30Ssthen unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, LDNS_RR_TYPE_A, -1, init, now) ); 482712b2f30Ssthen unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 483712b2f30Ssthen now, &vs, &edns_lame, &to) ); 484712b2f30Ssthen unit_assert( vs == 0 && to == init*2 && edns_lame == 0 ); 485712b2f30Ssthen 486712b2f30Ssthen unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); 487712b2f30Ssthen unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 488712b2f30Ssthen now, &vs, &edns_lame, &to) ); 489712b2f30Ssthen unit_assert( vs == -1 && to == init*2 && edns_lame == 1); 490712b2f30Ssthen 491712b2f30Ssthen now += cfg->host_ttl + 10; 492712b2f30Ssthen unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 493712b2f30Ssthen now, &vs, &edns_lame, &to) ); 494712b2f30Ssthen unit_assert( vs == 0 && to == init && edns_lame == 0 ); 495712b2f30Ssthen 496712b2f30Ssthen unit_assert( infra_set_lame(slab, &one, onelen, 497712b2f30Ssthen zone, zonelen, now, 0, 0, LDNS_RR_TYPE_A) ); 498712b2f30Ssthen unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); 499712b2f30Ssthen unit_assert( d->ttl == now+cfg->host_ttl ); 500712b2f30Ssthen unit_assert( d->edns_version == 0 ); 501712b2f30Ssthen unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && 502712b2f30Ssthen !d->lame_other); 503712b2f30Ssthen lock_rw_unlock(&k->entry.lock); 504712b2f30Ssthen 505712b2f30Ssthen /* test merge of data */ 506712b2f30Ssthen unit_assert( infra_set_lame(slab, &one, onelen, 507712b2f30Ssthen zone, zonelen, now, 0, 0, LDNS_RR_TYPE_AAAA) ); 508712b2f30Ssthen unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); 509712b2f30Ssthen unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && 510712b2f30Ssthen d->lame_other); 511712b2f30Ssthen lock_rw_unlock(&k->entry.lock); 512712b2f30Ssthen 513712b2f30Ssthen /* test that noEDNS cannot overwrite known-yesEDNS */ 514712b2f30Ssthen now += cfg->host_ttl + 10; 515712b2f30Ssthen unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 516712b2f30Ssthen now, &vs, &edns_lame, &to) ); 517712b2f30Ssthen unit_assert( vs == 0 && to == init && edns_lame == 0 ); 518712b2f30Ssthen 519712b2f30Ssthen unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) ); 520712b2f30Ssthen unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 521712b2f30Ssthen now, &vs, &edns_lame, &to) ); 522712b2f30Ssthen unit_assert( vs == 0 && to == init && edns_lame == 1 ); 523712b2f30Ssthen 524712b2f30Ssthen unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); 525712b2f30Ssthen unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 526712b2f30Ssthen now, &vs, &edns_lame, &to) ); 527712b2f30Ssthen unit_assert( vs == 0 && to == init && edns_lame == 1 ); 528712b2f30Ssthen 529712b2f30Ssthen infra_delete(slab); 530712b2f30Ssthen config_delete(cfg); 531712b2f30Ssthen } 532712b2f30Ssthen 533437d2860Ssthen #include "util/edns.h" 534437d2860Ssthen /* Complete version-invalid client cookie; needs a new one. 535437d2860Ssthen * Based on edns_cookie_rfc9018_a2 */ 536437d2860Ssthen static void 537437d2860Ssthen edns_cookie_invalid_version(void) 538437d2860Ssthen { 539437d2860Ssthen uint32_t timestamp = 1559734385; 540437d2860Ssthen uint8_t client_cookie[] = { 541437d2860Ssthen 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 542437d2860Ssthen 0x99, 0x00, 0x00, 0x00, 543437d2860Ssthen 0x5c, 0xf7, 0x9f, 0x11, 544437d2860Ssthen 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 }; 545437d2860Ssthen uint8_t server_cookie[] = { 546437d2860Ssthen 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 547437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 548437d2860Ssthen 0x5c, 0xf7, 0xa8, 0x71, 549437d2860Ssthen 0xd4, 0xa5, 0x64, 0xa1, 0x44, 0x2a, 0xca, 0x77 }; 550437d2860Ssthen uint8_t server_secret[] = { 551437d2860Ssthen 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 552437d2860Ssthen 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 553437d2860Ssthen uint8_t buf[32]; 554437d2860Ssthen /* copy client cookie|version|reserved|timestamp */ 555437d2860Ssthen memcpy(buf, client_cookie, 8 + 4 + 4); 556437d2860Ssthen /* copy ip 198.51.100.100 */ 557437d2860Ssthen memcpy(buf + 16, "\306\063\144\144", 4); 558437d2860Ssthen unit_assert(edns_cookie_server_validate(client_cookie, 559437d2860Ssthen sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 560437d2860Ssthen buf, timestamp) == COOKIE_STATUS_INVALID); 561437d2860Ssthen edns_cookie_server_write(buf, server_secret, 1, timestamp); 562437d2860Ssthen unit_assert(memcmp(server_cookie, buf, 24) == 0); 563437d2860Ssthen } 564437d2860Ssthen 565437d2860Ssthen /* Complete hash-invalid client cookie; needs a new one. */ 566437d2860Ssthen static void 567437d2860Ssthen edns_cookie_invalid_hash(void) 568437d2860Ssthen { 569437d2860Ssthen uint32_t timestamp = 0; 570437d2860Ssthen uint8_t client_cookie[] = { 571437d2860Ssthen 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 572437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 573437d2860Ssthen 0x00, 0x00, 0x00, 0x00, 574437d2860Ssthen 0x32, 0xF2, 0x43, 0xB9, 0xBC, 0xFE, 0xC4, 0x06 }; 575437d2860Ssthen uint8_t server_cookie[] = { 576437d2860Ssthen 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 577437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 578437d2860Ssthen 0x00, 0x00, 0x00, 0x00, 579437d2860Ssthen 0xBA, 0x0D, 0x82, 0x90, 0x8F, 0xAA, 0xEB, 0xBD }; 580437d2860Ssthen uint8_t server_secret[] = { 581437d2860Ssthen 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 582437d2860Ssthen 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 583437d2860Ssthen uint8_t buf[32]; 584437d2860Ssthen /* copy client cookie|version|reserved|timestamp */ 585437d2860Ssthen memcpy(buf, client_cookie, 8 + 4 + 4); 586437d2860Ssthen /* copy ip 203.0.113.203 */ 587437d2860Ssthen memcpy(buf + 16, "\313\000\161\313", 4); 588437d2860Ssthen unit_assert(edns_cookie_server_validate(client_cookie, 589437d2860Ssthen sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 590437d2860Ssthen buf, timestamp) == COOKIE_STATUS_INVALID); 591437d2860Ssthen edns_cookie_server_write(buf, server_secret, 1, timestamp); 592437d2860Ssthen unit_assert(memcmp(server_cookie, buf, 24) == 0); 593437d2860Ssthen } 594437d2860Ssthen 595437d2860Ssthen /* Complete hash-valid client cookie; more than 30 minutes old; needs a 596437d2860Ssthen * refreshed server cookie. 597437d2860Ssthen * A slightly better variation of edns_cookie_rfc9018_a3 for Unbound to check 598437d2860Ssthen * that RESERVED bits do not influence cookie validation. */ 599437d2860Ssthen static void 600437d2860Ssthen edns_cookie_rfc9018_a3_better(void) 601437d2860Ssthen { 602437d2860Ssthen uint32_t timestamp = 1800 + 1; 603437d2860Ssthen uint8_t client_cookie[] = { 604437d2860Ssthen 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 605437d2860Ssthen 0x01, 0xab, 0xcd, 0xef, 606437d2860Ssthen 0x00, 0x00, 0x00, 0x00, 607437d2860Ssthen 0x32, 0xF2, 0x43, 0xB9, 0xBC, 0xFE, 0xC4, 0x06 }; 608437d2860Ssthen uint8_t server_cookie[] = { 609437d2860Ssthen 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 610437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 611437d2860Ssthen 0x00, 0x00, 0x07, 0x09, 612437d2860Ssthen 0x62, 0xD5, 0x93, 0x09, 0x14, 0x5C, 0x23, 0x9D }; 613437d2860Ssthen uint8_t server_secret[] = { 614437d2860Ssthen 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 615437d2860Ssthen 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 616437d2860Ssthen uint8_t buf[32]; 617437d2860Ssthen /* copy client cookie|version|reserved|timestamp */ 618437d2860Ssthen memcpy(buf, client_cookie, 8 + 4 + 4); 619437d2860Ssthen /* copy ip 203.0.113.203 */ 620437d2860Ssthen memcpy(buf + 16, "\313\000\161\313", 4); 621437d2860Ssthen unit_assert(edns_cookie_server_validate(client_cookie, 622437d2860Ssthen sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 623437d2860Ssthen buf, timestamp) == COOKIE_STATUS_VALID_RENEW); 624437d2860Ssthen edns_cookie_server_write(buf, server_secret, 1, timestamp); 625437d2860Ssthen unit_assert(memcmp(server_cookie, buf, 24) == 0); 626437d2860Ssthen } 627437d2860Ssthen 628437d2860Ssthen /* Complete hash-valid client cookie; more than 60 minutes old (expired); 629437d2860Ssthen * needs a refreshed server cookie. */ 630437d2860Ssthen static void 631437d2860Ssthen edns_cookie_rfc9018_a3(void) 632437d2860Ssthen { 633437d2860Ssthen uint32_t timestamp = 1559734700; 634437d2860Ssthen uint8_t client_cookie[] = { 635437d2860Ssthen 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 636437d2860Ssthen 0x01, 0xab, 0xcd, 0xef, 637437d2860Ssthen 0x5c, 0xf7, 0x8f, 0x71, 638437d2860Ssthen 0xa3, 0x14, 0x22, 0x7b, 0x66, 0x79, 0xeb, 0xf5 }; 639437d2860Ssthen uint8_t server_cookie[] = { 640437d2860Ssthen 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 641437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 642437d2860Ssthen 0x5c, 0xf7, 0xa9, 0xac, 643437d2860Ssthen 0xf7, 0x3a, 0x78, 0x10, 0xac, 0xa2, 0x38, 0x1e }; 644437d2860Ssthen uint8_t server_secret[] = { 645437d2860Ssthen 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 646437d2860Ssthen 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 647437d2860Ssthen uint8_t buf[32]; 648437d2860Ssthen /* copy client cookie|version|reserved|timestamp */ 649437d2860Ssthen memcpy(buf, client_cookie, 8 + 4 + 4); 650437d2860Ssthen /* copy ip 203.0.113.203 */ 651437d2860Ssthen memcpy(buf + 16, "\313\000\161\313", 4); 652437d2860Ssthen unit_assert(edns_cookie_server_validate(client_cookie, 653437d2860Ssthen sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 654437d2860Ssthen buf, timestamp) == COOKIE_STATUS_EXPIRED); 655437d2860Ssthen edns_cookie_server_write(buf, server_secret, 1, timestamp); 656437d2860Ssthen unit_assert(memcmp(server_cookie, buf, 24) == 0); 657437d2860Ssthen } 658437d2860Ssthen 659437d2860Ssthen /* Complete hash-valid client cookie; more than 30 minutes old; needs a 660437d2860Ssthen * refreshed server cookie. */ 661437d2860Ssthen static void 662437d2860Ssthen edns_cookie_rfc9018_a2(void) 663437d2860Ssthen { 664437d2860Ssthen uint32_t timestamp = 1559734385; 665437d2860Ssthen uint8_t client_cookie[] = { 666437d2860Ssthen 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 667437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 668437d2860Ssthen 0x5c, 0xf7, 0x9f, 0x11, 669437d2860Ssthen 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 }; 670437d2860Ssthen uint8_t server_cookie[] = { 671437d2860Ssthen 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 672437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 673437d2860Ssthen 0x5c, 0xf7, 0xa8, 0x71, 674437d2860Ssthen 0xd4, 0xa5, 0x64, 0xa1, 0x44, 0x2a, 0xca, 0x77 }; 675437d2860Ssthen uint8_t server_secret[] = { 676437d2860Ssthen 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 677437d2860Ssthen 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 678437d2860Ssthen uint8_t buf[32]; 679437d2860Ssthen /* copy client cookie|version|reserved|timestamp */ 680437d2860Ssthen memcpy(buf, client_cookie, 8 + 4 + 4); 681437d2860Ssthen /* copy ip 198.51.100.100 */ 682437d2860Ssthen memcpy(buf + 16, "\306\063\144\144", 4); 683437d2860Ssthen unit_assert(edns_cookie_server_validate(client_cookie, 684437d2860Ssthen sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 685437d2860Ssthen buf, timestamp) == COOKIE_STATUS_VALID_RENEW); 686437d2860Ssthen edns_cookie_server_write(buf, server_secret, 1, timestamp); 687437d2860Ssthen unit_assert(memcmp(server_cookie, buf, 24) == 0); 688437d2860Ssthen } 689437d2860Ssthen 690437d2860Ssthen /* Only client cookie; needs a complete server cookie. */ 691437d2860Ssthen static void 692437d2860Ssthen edns_cookie_rfc9018_a1(void) 693437d2860Ssthen { 694437d2860Ssthen uint32_t timestamp = 1559731985; 695437d2860Ssthen uint8_t client_cookie[] = { 696437d2860Ssthen 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57 }; 697437d2860Ssthen uint8_t server_cookie[] = { 698437d2860Ssthen 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 699437d2860Ssthen 0x01, 0x00, 0x00, 0x00, 700437d2860Ssthen 0x5c, 0xf7, 0x9f, 0x11, 701437d2860Ssthen 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 }; 702437d2860Ssthen uint8_t server_secret[] = { 703437d2860Ssthen 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 704437d2860Ssthen 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 705437d2860Ssthen uint8_t buf[32]; 706437d2860Ssthen /* copy client cookie|version|reserved|timestamp */ 707437d2860Ssthen memcpy(buf, server_cookie, 8 + 4 + 4); 708437d2860Ssthen /* copy ip 198.51.100.100 */ 709437d2860Ssthen memcpy(buf + 16, "\306\063\144\144", 4); 710437d2860Ssthen unit_assert(edns_cookie_server_validate(client_cookie, 711437d2860Ssthen sizeof(client_cookie), 712437d2860Ssthen /* these will not be used; it will return invalid 713437d2860Ssthen * because of the size. */ 714437d2860Ssthen NULL, 0, 1, NULL, 0) == COOKIE_STATUS_CLIENT_ONLY); 715437d2860Ssthen edns_cookie_server_write(buf, server_secret, 1, timestamp); 716437d2860Ssthen unit_assert(memcmp(server_cookie, buf, 24) == 0); 717437d2860Ssthen } 718437d2860Ssthen 719437d2860Ssthen /** test interoperable DNS cookies (RFC9018) */ 720437d2860Ssthen static void 721437d2860Ssthen edns_cookie_test(void) 722437d2860Ssthen { 723437d2860Ssthen unit_show_feature("interoperable dns cookies"); 724437d2860Ssthen /* Check RFC9018 appendix test vectors */ 725437d2860Ssthen edns_cookie_rfc9018_a1(); 726437d2860Ssthen edns_cookie_rfc9018_a2(); 727437d2860Ssthen edns_cookie_rfc9018_a3(); 728437d2860Ssthen /* More tests */ 729437d2860Ssthen edns_cookie_rfc9018_a3_better(); 730437d2860Ssthen edns_cookie_invalid_hash(); 731437d2860Ssthen edns_cookie_invalid_version(); 732437d2860Ssthen } 733437d2860Ssthen 734712b2f30Ssthen #include "util/random.h" 735712b2f30Ssthen /** test randomness */ 736712b2f30Ssthen static void 737712b2f30Ssthen rnd_test(void) 738712b2f30Ssthen { 739712b2f30Ssthen struct ub_randstate* r; 740712b2f30Ssthen int num = 1000, i; 741712b2f30Ssthen long int a[1000]; 742712b2f30Ssthen unit_show_feature("ub_random"); 743b0dfc31bSsthen unit_assert( (r = ub_initstate(NULL)) ); 744712b2f30Ssthen for(i=0; i<num; i++) { 745712b2f30Ssthen a[i] = ub_random(r); 746712b2f30Ssthen unit_assert(a[i] >= 0); 747712b2f30Ssthen unit_assert((size_t)a[i] <= (size_t)0x7fffffff); 748712b2f30Ssthen if(i > 5) 749712b2f30Ssthen unit_assert(a[i] != a[i-1] || a[i] != a[i-2] || 750712b2f30Ssthen a[i] != a[i-3] || a[i] != a[i-4] || 751712b2f30Ssthen a[i] != a[i-5] || a[i] != a[i-6]); 752712b2f30Ssthen } 753712b2f30Ssthen a[0] = ub_random_max(r, 1); 754712b2f30Ssthen unit_assert(a[0] >= 0 && a[0] < 1); 755712b2f30Ssthen a[0] = ub_random_max(r, 10000); 756712b2f30Ssthen unit_assert(a[0] >= 0 && a[0] < 10000); 757712b2f30Ssthen for(i=0; i<num; i++) { 758712b2f30Ssthen a[i] = ub_random_max(r, 10); 759712b2f30Ssthen unit_assert(a[i] >= 0 && a[i] < 10); 760712b2f30Ssthen } 761712b2f30Ssthen ub_randfree(r); 762712b2f30Ssthen } 763712b2f30Ssthen 764712b2f30Ssthen #include "respip/respip.h" 765712b2f30Ssthen #include "services/localzone.h" 766712b2f30Ssthen #include "util/data/packed_rrset.h" 767712b2f30Ssthen typedef struct addr_action {char* ip; char* sact; enum respip_action act;} 768712b2f30Ssthen addr_action_t; 769712b2f30Ssthen 770712b2f30Ssthen /** Utility function that verifies that the respip set has actions as expected */ 771712b2f30Ssthen static void 772712b2f30Ssthen verify_respip_set_actions(struct respip_set* set, addr_action_t actions[], 773712b2f30Ssthen int actions_len) 774712b2f30Ssthen { 775712b2f30Ssthen int i = 0; 776712b2f30Ssthen struct rbtree_type* tree = respip_set_get_tree(set); 777712b2f30Ssthen for (i=0; i<actions_len; i++) { 778712b2f30Ssthen struct sockaddr_storage addr; 779712b2f30Ssthen int net; 780712b2f30Ssthen socklen_t addrlen; 781712b2f30Ssthen struct resp_addr* node; 782712b2f30Ssthen netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr, 783712b2f30Ssthen &addrlen, &net); 784712b2f30Ssthen node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 785712b2f30Ssthen 786712b2f30Ssthen /** we have the node and the node has the correct action 787712b2f30Ssthen * and has no data */ 788712b2f30Ssthen unit_assert(node); 789712b2f30Ssthen unit_assert(actions[i].act == 790712b2f30Ssthen resp_addr_get_action(node)); 791712b2f30Ssthen unit_assert(resp_addr_get_rrset(node) == NULL); 792712b2f30Ssthen } 793712b2f30Ssthen unit_assert(actions_len && i == actions_len); 794712b2f30Ssthen unit_assert(actions_len == (int)tree->count); 795712b2f30Ssthen } 796712b2f30Ssthen 797712b2f30Ssthen /** Global respip actions test; apply raw config data and verify that 798712b2f30Ssthen * all the nodes in the respip set, looked up by address, have expected 799712b2f30Ssthen * actions */ 800712b2f30Ssthen static void 801712b2f30Ssthen respip_conf_actions_test(void) 802712b2f30Ssthen { 803712b2f30Ssthen addr_action_t config_response_ip[] = { 804712b2f30Ssthen {"192.0.1.0/24", "deny", respip_deny}, 805712b2f30Ssthen {"192.0.2.0/24", "redirect", respip_redirect}, 806712b2f30Ssthen {"192.0.3.0/26", "inform", respip_inform}, 807712b2f30Ssthen {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 808712b2f30Ssthen {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 809712b2f30Ssthen {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 810712b2f30Ssthen {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 811712b2f30Ssthen }; 812712b2f30Ssthen int i; 813712b2f30Ssthen struct respip_set* set = respip_set_create(); 814712b2f30Ssthen struct config_file cfg; 815712b2f30Ssthen int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t)); 816712b2f30Ssthen 817712b2f30Ssthen unit_assert(set); 818712b2f30Ssthen unit_show_feature("global respip config actions apply"); 819712b2f30Ssthen memset(&cfg, 0, sizeof(cfg)); 820712b2f30Ssthen for(i=0; i<clen; i++) { 821712b2f30Ssthen char* ip = strdup(config_response_ip[i].ip); 822712b2f30Ssthen char* sact = strdup(config_response_ip[i].sact); 823712b2f30Ssthen unit_assert(ip && sact); 824712b2f30Ssthen if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact)) 825712b2f30Ssthen unit_assert(0); 826712b2f30Ssthen } 827712b2f30Ssthen unit_assert(respip_global_apply_cfg(set, &cfg)); 828712b2f30Ssthen verify_respip_set_actions(set, config_response_ip, clen); 829712b2f30Ssthen 830712b2f30Ssthen respip_set_delete(set); 831712b2f30Ssthen config_deldblstrlist(cfg.respip_actions); 832712b2f30Ssthen } 833712b2f30Ssthen 834712b2f30Ssthen /** Per-view respip actions test; apply raw configuration with two views 835712b2f30Ssthen * and verify that actions are as expected in respip sets of both views */ 836712b2f30Ssthen static void 837712b2f30Ssthen respip_view_conf_actions_test(void) 838712b2f30Ssthen { 839712b2f30Ssthen addr_action_t config_response_ip_view1[] = { 840712b2f30Ssthen {"192.0.1.0/24", "deny", respip_deny}, 841712b2f30Ssthen {"192.0.2.0/24", "redirect", respip_redirect}, 842712b2f30Ssthen {"192.0.3.0/26", "inform", respip_inform}, 843712b2f30Ssthen {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 844712b2f30Ssthen }; 845712b2f30Ssthen addr_action_t config_response_ip_view2[] = { 846712b2f30Ssthen {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 847712b2f30Ssthen {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 848712b2f30Ssthen {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 849712b2f30Ssthen }; 850712b2f30Ssthen int i; 851712b2f30Ssthen struct config_file cfg; 852712b2f30Ssthen int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t)); 853712b2f30Ssthen int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t)); 854712b2f30Ssthen struct config_view* cv1; 855712b2f30Ssthen struct config_view* cv2; 856712b2f30Ssthen int have_respip_cfg = 0; 857712b2f30Ssthen struct views* views = NULL; 858712b2f30Ssthen struct view* v = NULL; 859712b2f30Ssthen 860712b2f30Ssthen unit_show_feature("per-view respip config actions apply"); 861712b2f30Ssthen memset(&cfg, 0, sizeof(cfg)); 862712b2f30Ssthen cv1 = (struct config_view*)calloc(1, sizeof(struct config_view)); 863712b2f30Ssthen cv2 = (struct config_view*)calloc(1, sizeof(struct config_view)); 864712b2f30Ssthen unit_assert(cv1 && cv2); 865712b2f30Ssthen cv1->name = strdup("view1"); 866712b2f30Ssthen cv2->name = strdup("view2"); 867712b2f30Ssthen unit_assert(cv1->name && cv2->name); 868712b2f30Ssthen cv1->next = cv2; 869712b2f30Ssthen cfg.views = cv1; 870712b2f30Ssthen 871712b2f30Ssthen for(i=0; i<clen1; i++) { 872712b2f30Ssthen char* ip = strdup(config_response_ip_view1[i].ip); 873712b2f30Ssthen char* sact = strdup(config_response_ip_view1[i].sact); 874712b2f30Ssthen unit_assert(ip && sact); 875712b2f30Ssthen if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact)) 876712b2f30Ssthen unit_assert(0); 877712b2f30Ssthen } 878712b2f30Ssthen for(i=0; i<clen2; i++) { 879712b2f30Ssthen char* ip = strdup(config_response_ip_view2[i].ip); 880712b2f30Ssthen char* sact = strdup(config_response_ip_view2[i].sact); 881712b2f30Ssthen unit_assert(ip && sact); 882712b2f30Ssthen if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact)) 883712b2f30Ssthen unit_assert(0); 884712b2f30Ssthen } 885712b2f30Ssthen views = views_create(); 886712b2f30Ssthen unit_assert(views); 887712b2f30Ssthen unit_assert(views_apply_cfg(views, &cfg)); 888712b2f30Ssthen unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 889712b2f30Ssthen 890712b2f30Ssthen /* now verify the respip sets in each view */ 891712b2f30Ssthen v = views_find_view(views, "view1", 0); 892712b2f30Ssthen unit_assert(v); 893712b2f30Ssthen verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1); 894712b2f30Ssthen lock_rw_unlock(&v->lock); 895712b2f30Ssthen v = views_find_view(views, "view2", 0); 896712b2f30Ssthen unit_assert(v); 897712b2f30Ssthen verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2); 898712b2f30Ssthen lock_rw_unlock(&v->lock); 899712b2f30Ssthen 900712b2f30Ssthen views_delete(views); 901712b2f30Ssthen free(cv1->name); 902712b2f30Ssthen free(cv1); 903712b2f30Ssthen free(cv2->name); 904712b2f30Ssthen free(cv2); 905712b2f30Ssthen } 906712b2f30Ssthen 907712b2f30Ssthen typedef struct addr_data {char* ip; char* data;} addr_data_t; 908712b2f30Ssthen 909712b2f30Ssthen /** find the respip address node in the specified tree (by address lookup) 910712b2f30Ssthen * and verify type and address of the specified rdata (by index) in this 911712b2f30Ssthen * node's rrset */ 912712b2f30Ssthen static void 913712b2f30Ssthen verify_rrset(struct respip_set* set, const char* ipstr, 914712b2f30Ssthen const char* rdatastr, size_t rdi, uint16_t type) 915712b2f30Ssthen { 916712b2f30Ssthen struct sockaddr_storage addr; 917712b2f30Ssthen int net; 918712b2f30Ssthen char buf[65536]; 919712b2f30Ssthen socklen_t addrlen; 920712b2f30Ssthen struct rbtree_type* tree; 921712b2f30Ssthen struct resp_addr* node; 922712b2f30Ssthen const struct ub_packed_rrset_key* rrs; 923712b2f30Ssthen 924712b2f30Ssthen netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net); 925712b2f30Ssthen tree = respip_set_get_tree(set); 926712b2f30Ssthen node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 927712b2f30Ssthen unit_assert(node); 928712b2f30Ssthen unit_assert((rrs = resp_addr_get_rrset(node))); 929712b2f30Ssthen unit_assert(ntohs(rrs->rk.type) == type); 930712b2f30Ssthen packed_rr_to_string((struct ub_packed_rrset_key*)rrs, 931712b2f30Ssthen rdi, 0, buf, sizeof(buf)); 932712b2f30Ssthen unit_assert(strstr(buf, rdatastr)); 933712b2f30Ssthen } 934712b2f30Ssthen 935712b2f30Ssthen /** Dataset used to test redirect rrset initialization for both 936712b2f30Ssthen * global and per-view respip redirect configuration */ 937712b2f30Ssthen static addr_data_t config_response_ip_data[] = { 938712b2f30Ssthen {"192.0.1.0/24", "A 1.2.3.4"}, 939712b2f30Ssthen {"192.0.1.0/24", "A 11.12.13.14"}, 940712b2f30Ssthen {"192.0.2.0/24", "CNAME www.example.com."}, 941712b2f30Ssthen {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"}, 942712b2f30Ssthen }; 943712b2f30Ssthen 944712b2f30Ssthen /** Populate raw respip redirect config data, used for both global and 945712b2f30Ssthen * view-based respip redirect test case */ 946712b2f30Ssthen static void 947712b2f30Ssthen cfg_insert_respip_data(struct config_str2list** respip_actions, 948712b2f30Ssthen struct config_str2list** respip_data) 949712b2f30Ssthen { 950712b2f30Ssthen int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t)); 951712b2f30Ssthen int i = 0; 952712b2f30Ssthen 953712b2f30Ssthen /* insert actions (duplicate netblocks don't matter) */ 954712b2f30Ssthen for(i=0; i<clen; i++) { 955712b2f30Ssthen char* ip = strdup(config_response_ip_data[i].ip); 956712b2f30Ssthen char* sact = strdup("redirect"); 957712b2f30Ssthen unit_assert(ip && sact); 958712b2f30Ssthen if(!cfg_str2list_insert(respip_actions, ip, sact)) 959712b2f30Ssthen unit_assert(0); 960712b2f30Ssthen } 961712b2f30Ssthen /* insert data */ 962712b2f30Ssthen for(i=0; i<clen; i++) { 963712b2f30Ssthen char* ip = strdup(config_response_ip_data[i].ip); 964712b2f30Ssthen char* data = strdup(config_response_ip_data[i].data); 965712b2f30Ssthen unit_assert(ip && data); 966712b2f30Ssthen if(!cfg_str2list_insert(respip_data, ip, data)) 967712b2f30Ssthen unit_assert(0); 968712b2f30Ssthen } 969712b2f30Ssthen } 970712b2f30Ssthen 971712b2f30Ssthen /** Test global respip redirect w/ data directives */ 972712b2f30Ssthen static void 973712b2f30Ssthen respip_conf_data_test(void) 974712b2f30Ssthen { 975712b2f30Ssthen struct respip_set* set = respip_set_create(); 976712b2f30Ssthen struct config_file cfg; 977712b2f30Ssthen 978712b2f30Ssthen unit_show_feature("global respip config data apply"); 979712b2f30Ssthen memset(&cfg, 0, sizeof(cfg)); 980712b2f30Ssthen 981712b2f30Ssthen cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data); 982712b2f30Ssthen 983712b2f30Ssthen /* apply configuration and verify rrsets */ 984712b2f30Ssthen unit_assert(respip_global_apply_cfg(set, &cfg)); 985712b2f30Ssthen verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A); 986712b2f30Ssthen verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A); 987712b2f30Ssthen verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME); 988712b2f30Ssthen verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA); 989712b2f30Ssthen 990712b2f30Ssthen respip_set_delete(set); 991712b2f30Ssthen } 992712b2f30Ssthen 993712b2f30Ssthen /** Test per-view respip redirect w/ data directives */ 994712b2f30Ssthen static void 995712b2f30Ssthen respip_view_conf_data_test(void) 996712b2f30Ssthen { 997712b2f30Ssthen struct config_file cfg; 998712b2f30Ssthen struct config_view* cv; 999712b2f30Ssthen int have_respip_cfg = 0; 1000712b2f30Ssthen struct views* views = NULL; 1001712b2f30Ssthen struct view* v = NULL; 1002712b2f30Ssthen 1003712b2f30Ssthen unit_show_feature("per-view respip config data apply"); 1004712b2f30Ssthen memset(&cfg, 0, sizeof(cfg)); 1005712b2f30Ssthen cv = (struct config_view*)calloc(1, sizeof(struct config_view)); 1006712b2f30Ssthen unit_assert(cv); 1007712b2f30Ssthen cv->name = strdup("view1"); 1008712b2f30Ssthen unit_assert(cv->name); 1009712b2f30Ssthen cfg.views = cv; 1010712b2f30Ssthen cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data); 1011712b2f30Ssthen views = views_create(); 1012712b2f30Ssthen unit_assert(views); 1013712b2f30Ssthen unit_assert(views_apply_cfg(views, &cfg)); 1014712b2f30Ssthen 1015712b2f30Ssthen /* apply configuration and verify rrsets */ 1016712b2f30Ssthen unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 1017712b2f30Ssthen v = views_find_view(views, "view1", 0); 1018712b2f30Ssthen unit_assert(v); 1019712b2f30Ssthen verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4", 1020712b2f30Ssthen 0, LDNS_RR_TYPE_A); 1021712b2f30Ssthen verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14", 1022712b2f30Ssthen 1, LDNS_RR_TYPE_A); 1023712b2f30Ssthen verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com", 1024712b2f30Ssthen 0, LDNS_RR_TYPE_CNAME); 1025712b2f30Ssthen verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1", 1026712b2f30Ssthen 0, LDNS_RR_TYPE_AAAA); 1027712b2f30Ssthen lock_rw_unlock(&v->lock); 1028712b2f30Ssthen 1029712b2f30Ssthen views_delete(views); 1030712b2f30Ssthen free(cv->name); 1031712b2f30Ssthen free(cv); 1032712b2f30Ssthen } 1033712b2f30Ssthen 1034712b2f30Ssthen /** respip unit tests */ 1035712b2f30Ssthen static void respip_test(void) 1036712b2f30Ssthen { 1037712b2f30Ssthen respip_view_conf_data_test(); 1038712b2f30Ssthen respip_conf_data_test(); 1039712b2f30Ssthen respip_view_conf_actions_test(); 1040712b2f30Ssthen respip_conf_actions_test(); 1041712b2f30Ssthen } 1042712b2f30Ssthen 1043437d2860Ssthen #include "util/regional.h" 1044437d2860Ssthen #include "sldns/sbuffer.h" 1045437d2860Ssthen #include "util/data/dname.h" 1046437d2860Ssthen #include "util/data/msgreply.h" 1047437d2860Ssthen #include "util/data/msgencode.h" 1048437d2860Ssthen #include "sldns/str2wire.h" 1049437d2860Ssthen 1050437d2860Ssthen static void edns_ede_encode_setup(struct edns_data* edns, 1051437d2860Ssthen struct regional* region) 1052437d2860Ssthen { 1053437d2860Ssthen memset(edns, 0, sizeof(*edns)); 1054437d2860Ssthen edns->edns_present = 1; 1055437d2860Ssthen edns->edns_version = EDNS_ADVERTISED_VERSION; 1056437d2860Ssthen edns->udp_size = EDNS_ADVERTISED_SIZE; 1057437d2860Ssthen edns->bits &= EDNS_DO; 1058437d2860Ssthen /* Fill up opt_list_out with EDEs */ 1059437d2860Ssthen unit_assert( 1060437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_out, region, 1061437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1062437d2860Ssthen unit_assert( 1063437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_out, region, 1064437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1065437d2860Ssthen unit_assert( 1066437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_out, region, 1067437d2860Ssthen LDNS_EDE_BLOCKED, "Too long blocked text")); 1068437d2860Ssthen unit_assert( 1069437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_out, region, 1070437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1071437d2860Ssthen unit_assert( 1072437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_out, region, 1073437d2860Ssthen LDNS_EDE_BLOCKED, "Too long blocked text")); 1074437d2860Ssthen /* Fill up opt_list_inplace_cb_out with EDEs */ 1075437d2860Ssthen unit_assert( 1076437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 1077437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1078437d2860Ssthen unit_assert( 1079437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 1080437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1081437d2860Ssthen unit_assert( 1082437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 1083437d2860Ssthen LDNS_EDE_BLOCKED, "Too long blocked text")); 1084437d2860Ssthen unit_assert( 1085437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 1086437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1087437d2860Ssthen unit_assert( 1088437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 1089437d2860Ssthen LDNS_EDE_BLOCKED, "Too long blocked text")); 1090437d2860Ssthen /* append another EDNS option to both lists */ 1091437d2860Ssthen unit_assert( 1092437d2860Ssthen edns_opt_list_append(&edns->opt_list_out, 1093437d2860Ssthen LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region)); 1094437d2860Ssthen unit_assert( 1095437d2860Ssthen edns_opt_list_append(&edns->opt_list_inplace_cb_out, 1096437d2860Ssthen LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region)); 1097437d2860Ssthen /* append LDNS_EDE_OTHER at the end of both lists */ 1098437d2860Ssthen unit_assert( 1099437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_out, region, 1100437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1101437d2860Ssthen unit_assert( 1102437d2860Ssthen edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 1103437d2860Ssthen LDNS_EDE_OTHER, "Too long other text")); 1104437d2860Ssthen } 1105437d2860Ssthen 1106437d2860Ssthen static void edns_ede_encode_encodedecode(struct query_info* qinfo, 1107437d2860Ssthen struct reply_info* rep, struct regional* region, 1108437d2860Ssthen struct edns_data* edns, sldns_buffer* pkt) 1109437d2860Ssthen { 1110437d2860Ssthen /* encode */ 1111437d2860Ssthen unit_assert( 1112437d2860Ssthen reply_info_answer_encode(qinfo, rep, 1, rep->flags, pkt, 1113437d2860Ssthen 0, 0, region, 65535, edns, 0, 0)); 1114437d2860Ssthen /* buffer ready for reading; skip after the question section */ 1115437d2860Ssthen sldns_buffer_skip(pkt, LDNS_HEADER_SIZE); 1116437d2860Ssthen (void)query_dname_len(pkt); 1117437d2860Ssthen sldns_buffer_skip(pkt, 2 + 2); 1118437d2860Ssthen /* decode */ 1119437d2860Ssthen unit_assert(parse_edns_from_query_pkt(pkt, edns, NULL, NULL, NULL, 0, 1120*a43524d9Ssthen region, NULL) == 0); 1121437d2860Ssthen } 1122437d2860Ssthen 1123437d2860Ssthen static void edns_ede_encode_check(struct edns_data* edns, int* found_ede, 1124437d2860Ssthen int* found_ede_other, int* found_ede_txt, int* found_other_edns) 1125437d2860Ssthen { 1126437d2860Ssthen struct edns_option* opt; 1127437d2860Ssthen for(opt = edns->opt_list_in; opt; opt = opt->next) { 1128437d2860Ssthen if(opt->opt_code == LDNS_EDNS_EDE) { 1129437d2860Ssthen (*found_ede)++; 1130437d2860Ssthen if(opt->opt_len > 2) 1131437d2860Ssthen (*found_ede_txt)++; 1132437d2860Ssthen if(opt->opt_len >= 2 && sldns_read_uint16( 1133437d2860Ssthen opt->opt_data) == LDNS_EDE_OTHER) 1134437d2860Ssthen (*found_ede_other)++; 1135437d2860Ssthen } else { 1136437d2860Ssthen (*found_other_edns)++; 1137437d2860Ssthen } 1138437d2860Ssthen } 1139437d2860Ssthen 1140437d2860Ssthen } 1141437d2860Ssthen 1142437d2860Ssthen static void edns_ede_encode_fit_test(struct query_info* qinfo, 1143437d2860Ssthen struct reply_info* rep, struct regional* region) 1144437d2860Ssthen { 1145437d2860Ssthen struct edns_data edns; 1146437d2860Ssthen int found_ede = 0, found_ede_other = 0, found_ede_txt = 0; 1147437d2860Ssthen int found_other_edns = 0; 1148437d2860Ssthen sldns_buffer* pkt = sldns_buffer_new(65535); 1149437d2860Ssthen unit_assert(pkt); 1150437d2860Ssthen edns_ede_encode_setup(&edns, region); 1151437d2860Ssthen /* leave the pkt buffer as is; everything should fit */ 1152437d2860Ssthen edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt); 1153437d2860Ssthen edns_ede_encode_check(&edns, &found_ede, &found_ede_other, 1154437d2860Ssthen &found_ede_txt, &found_other_edns); 1155437d2860Ssthen unit_assert(found_ede == 12); 1156437d2860Ssthen unit_assert(found_ede_other == 8); 1157437d2860Ssthen unit_assert(found_ede_txt == 12); 1158437d2860Ssthen unit_assert(found_other_edns == 2); 1159437d2860Ssthen /* cleanup */ 1160437d2860Ssthen sldns_buffer_free(pkt); 1161437d2860Ssthen } 1162437d2860Ssthen 1163437d2860Ssthen static void edns_ede_encode_notxt_fit_test( struct query_info* qinfo, 1164437d2860Ssthen struct reply_info* rep, struct regional* region) 1165437d2860Ssthen { 1166437d2860Ssthen struct edns_data edns; 1167437d2860Ssthen sldns_buffer* pkt; 1168437d2860Ssthen uint16_t edns_field_size, ede_txt_size; 1169437d2860Ssthen int found_ede = 0, found_ede_other = 0, found_ede_txt = 0; 1170437d2860Ssthen int found_other_edns = 0; 1171437d2860Ssthen edns_ede_encode_setup(&edns, region); 1172437d2860Ssthen /* pkt buffer should fit everything if the ede txt is cropped. 1173437d2860Ssthen * OTHER EDE should not be there since it is useless without text. */ 1174437d2860Ssthen edns_field_size = calc_edns_field_size(&edns); 1175437d2860Ssthen (void)calc_ede_option_size(&edns, &ede_txt_size); 1176437d2860Ssthen pkt = sldns_buffer_new(LDNS_HEADER_SIZE 1177437d2860Ssthen + qinfo->qname_len 1178437d2860Ssthen + 2 + 2 /* qtype + qclass */ 1179437d2860Ssthen + 11 /* opt record */ 1180437d2860Ssthen + edns_field_size 1181437d2860Ssthen - ede_txt_size); 1182437d2860Ssthen unit_assert(pkt); 1183437d2860Ssthen edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt); 1184437d2860Ssthen edns_ede_encode_check(&edns, &found_ede, &found_ede_other, 1185437d2860Ssthen &found_ede_txt, &found_other_edns); 1186437d2860Ssthen unit_assert(found_ede == 4); 1187437d2860Ssthen unit_assert(found_ede_other == 0); 1188437d2860Ssthen unit_assert(found_ede_txt == 0); 1189437d2860Ssthen unit_assert(found_other_edns == 2); 1190437d2860Ssthen /* cleanup */ 1191437d2860Ssthen sldns_buffer_free(pkt); 1192437d2860Ssthen } 1193437d2860Ssthen 1194437d2860Ssthen static void edns_ede_encode_no_fit_test( struct query_info* qinfo, 1195437d2860Ssthen struct reply_info* rep, struct regional* region) 1196437d2860Ssthen { 1197437d2860Ssthen struct edns_data edns; 1198437d2860Ssthen sldns_buffer* pkt; 1199437d2860Ssthen uint16_t edns_field_size, ede_size, ede_txt_size; 1200437d2860Ssthen int found_ede = 0, found_ede_other = 0, found_ede_txt = 0; 1201437d2860Ssthen int found_other_edns = 0; 1202437d2860Ssthen edns_ede_encode_setup(&edns, region); 1203437d2860Ssthen /* pkt buffer should fit only non-EDE options. */ 1204437d2860Ssthen edns_field_size = calc_edns_field_size(&edns); 1205437d2860Ssthen ede_size = calc_ede_option_size(&edns, &ede_txt_size); 1206437d2860Ssthen pkt = sldns_buffer_new(LDNS_HEADER_SIZE 1207437d2860Ssthen + qinfo->qname_len 1208437d2860Ssthen + 2 + 2 /* qtype + qclass */ 1209437d2860Ssthen + 11 /* opt record */ 1210437d2860Ssthen + edns_field_size 1211437d2860Ssthen - ede_size); 1212437d2860Ssthen unit_assert(pkt); 1213437d2860Ssthen edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt); 1214437d2860Ssthen edns_ede_encode_check(&edns, &found_ede, &found_ede_other, 1215437d2860Ssthen &found_ede_txt, &found_other_edns); 1216437d2860Ssthen unit_assert(found_ede == 0); 1217437d2860Ssthen unit_assert(found_ede_other == 0); 1218437d2860Ssthen unit_assert(found_ede_txt == 0); 1219437d2860Ssthen unit_assert(found_other_edns == 2); 1220437d2860Ssthen /* cleanup */ 1221437d2860Ssthen sldns_buffer_free(pkt); 1222437d2860Ssthen } 1223437d2860Ssthen 1224437d2860Ssthen /** test optional EDE encoding with various buffer 1225437d2860Ssthen * available sizes */ 1226437d2860Ssthen static void edns_ede_answer_encode_test(void) 1227437d2860Ssthen { 1228437d2860Ssthen struct regional* region = regional_create(); 1229437d2860Ssthen struct reply_info* rep; 1230437d2860Ssthen struct query_info qinfo; 1231437d2860Ssthen unit_show_feature("edns ede optional encoding"); 1232437d2860Ssthen unit_assert(region); 1233437d2860Ssthen rep = construct_reply_info_base(region, 1234437d2860Ssthen LDNS_RCODE_NOERROR | BIT_QR, 1, 1235437d2860Ssthen 3600, 3600, 3600, 1236437d2860Ssthen 0, 0, 0, 0, 1237437d2860Ssthen sec_status_unchecked, LDNS_EDE_NONE); 1238437d2860Ssthen unit_assert(rep); 1239437d2860Ssthen memset(&qinfo, 0, sizeof(qinfo)); 1240437d2860Ssthen qinfo.qname = sldns_str2wire_dname("encode.ede.", &qinfo.qname_len); 1241437d2860Ssthen unit_assert(qinfo.qname); 1242437d2860Ssthen qinfo.qtype = LDNS_RR_TYPE_TXT; 1243437d2860Ssthen qinfo.qclass = LDNS_RR_CLASS_IN; 1244437d2860Ssthen 1245437d2860Ssthen edns_ede_encode_fit_test(&qinfo, rep, region); 1246437d2860Ssthen edns_ede_encode_notxt_fit_test(&qinfo, rep, region); 1247437d2860Ssthen edns_ede_encode_no_fit_test(&qinfo, rep, region); 1248437d2860Ssthen 1249437d2860Ssthen /* cleanup */ 1250437d2860Ssthen free(qinfo.qname); 1251437d2860Ssthen regional_free_all(region); 1252437d2860Ssthen regional_destroy(region); 1253437d2860Ssthen } 1254437d2860Ssthen 1255*a43524d9Ssthen #include "services/localzone.h" 1256*a43524d9Ssthen /* Utility function that compares two localzone trees */ 1257*a43524d9Ssthen static void compare_localzone_trees(struct local_zones* z1, 1258*a43524d9Ssthen struct local_zones* z2) 1259*a43524d9Ssthen { 1260*a43524d9Ssthen struct local_zone *node1, *node2; 1261*a43524d9Ssthen lock_rw_rdlock(&z1->lock); 1262*a43524d9Ssthen lock_rw_rdlock(&z2->lock); 1263*a43524d9Ssthen /* size should be the same */ 1264*a43524d9Ssthen unit_assert(z1->ztree.count == z2->ztree.count); 1265*a43524d9Ssthen for(node1=(struct local_zone*)rbtree_first(&z1->ztree), 1266*a43524d9Ssthen node2=(struct local_zone*)rbtree_first(&z2->ztree); 1267*a43524d9Ssthen (rbnode_type*)node1 != RBTREE_NULL && 1268*a43524d9Ssthen (rbnode_type*)node2 != RBTREE_NULL; 1269*a43524d9Ssthen node1=(struct local_zone*)rbtree_next((rbnode_type*)node1), 1270*a43524d9Ssthen node2=(struct local_zone*)rbtree_next((rbnode_type*)node2)) { 1271*a43524d9Ssthen int labs; 1272*a43524d9Ssthen /* the same zone should be at the same nodes */ 1273*a43524d9Ssthen unit_assert(!dname_lab_cmp( 1274*a43524d9Ssthen node1->name, node1->namelabs, 1275*a43524d9Ssthen node2->name, node2->namelabs, 1276*a43524d9Ssthen &labs)); 1277*a43524d9Ssthen /* the zone's parent should be the same on both nodes */ 1278*a43524d9Ssthen unit_assert( 1279*a43524d9Ssthen (node1->parent == NULL && node2->parent == NULL) || 1280*a43524d9Ssthen (node1->parent != NULL && node2->parent != NULL)); 1281*a43524d9Ssthen if(node1->parent) { 1282*a43524d9Ssthen unit_assert(!dname_lab_cmp( 1283*a43524d9Ssthen node1->parent->name, node1->parent->namelabs, 1284*a43524d9Ssthen node2->parent->name, node2->parent->namelabs, 1285*a43524d9Ssthen &labs)); 1286*a43524d9Ssthen } 1287*a43524d9Ssthen } 1288*a43524d9Ssthen lock_rw_unlock(&z1->lock); 1289*a43524d9Ssthen lock_rw_unlock(&z2->lock); 1290*a43524d9Ssthen } 1291*a43524d9Ssthen 1292*a43524d9Ssthen /* test that zone addition results in the same tree from both the configuration 1293*a43524d9Ssthen * file and the unbound-control commands */ 1294*a43524d9Ssthen static void localzone_parents_test(void) 1295*a43524d9Ssthen { 1296*a43524d9Ssthen struct local_zones *z1, *z2; 1297*a43524d9Ssthen size_t i; 1298*a43524d9Ssthen char* zone_data[] = { 1299*a43524d9Ssthen "one", 1300*a43524d9Ssthen "a.b.c.one", 1301*a43524d9Ssthen "b.c.one", 1302*a43524d9Ssthen "c.one", 1303*a43524d9Ssthen "two", 1304*a43524d9Ssthen "c.two", 1305*a43524d9Ssthen "b.c.two", 1306*a43524d9Ssthen "a.b.c.two", 1307*a43524d9Ssthen "a.b.c.three", 1308*a43524d9Ssthen "b.c.three", 1309*a43524d9Ssthen "c.three", 1310*a43524d9Ssthen "three", 1311*a43524d9Ssthen "c.four", 1312*a43524d9Ssthen "b.c.four", 1313*a43524d9Ssthen "a.b.c.four", 1314*a43524d9Ssthen "four", 1315*a43524d9Ssthen "." 1316*a43524d9Ssthen }; 1317*a43524d9Ssthen unit_show_feature("localzones parent calculation"); 1318*a43524d9Ssthen z1 = local_zones_create(); 1319*a43524d9Ssthen z2 = local_zones_create(); 1320*a43524d9Ssthen /* parse test data */ 1321*a43524d9Ssthen for(i=0; i<sizeof(zone_data)/sizeof(zone_data[0]); i++) { 1322*a43524d9Ssthen uint8_t* nm; 1323*a43524d9Ssthen int nmlabs; 1324*a43524d9Ssthen size_t nmlen; 1325*a43524d9Ssthen struct local_zone* z; 1326*a43524d9Ssthen 1327*a43524d9Ssthen /* This is the config way */ 1328*a43524d9Ssthen z = lz_enter_zone(z1, zone_data[i], "always_nxdomain", 1329*a43524d9Ssthen LDNS_RR_CLASS_IN); 1330*a43524d9Ssthen (void)z; /* please compiler when no threading and no lock 1331*a43524d9Ssthen code; the following line disappears and z stays unused */ 1332*a43524d9Ssthen lock_rw_unlock(&z->lock); 1333*a43524d9Ssthen lz_init_parents(z1); 1334*a43524d9Ssthen 1335*a43524d9Ssthen /* This is the unbound-control way */ 1336*a43524d9Ssthen nm = sldns_str2wire_dname(zone_data[i], &nmlen); 1337*a43524d9Ssthen if(!nm) unit_assert(0); 1338*a43524d9Ssthen nmlabs = dname_count_size_labels(nm, &nmlen); 1339*a43524d9Ssthen lock_rw_wrlock(&z2->lock); 1340*a43524d9Ssthen local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, 1341*a43524d9Ssthen local_zone_always_nxdomain); 1342*a43524d9Ssthen lock_rw_unlock(&z2->lock); 1343*a43524d9Ssthen } 1344*a43524d9Ssthen /* The trees should be the same, iterate and check the nodes */ 1345*a43524d9Ssthen compare_localzone_trees(z1, z2); 1346*a43524d9Ssthen 1347*a43524d9Ssthen /* cleanup */ 1348*a43524d9Ssthen local_zones_delete(z1); 1349*a43524d9Ssthen local_zones_delete(z2); 1350*a43524d9Ssthen } 1351*a43524d9Ssthen 1352*a43524d9Ssthen /** localzone unit tests */ 1353*a43524d9Ssthen static void localzone_test(void) 1354*a43524d9Ssthen { 1355*a43524d9Ssthen localzone_parents_test(); 1356*a43524d9Ssthen } 1357*a43524d9Ssthen 1358712b2f30Ssthen void unit_show_func(const char* file, const char* func) 1359712b2f30Ssthen { 1360712b2f30Ssthen printf("test %s:%s\n", file, func); 1361712b2f30Ssthen } 1362712b2f30Ssthen 1363712b2f30Ssthen void unit_show_feature(const char* feature) 1364712b2f30Ssthen { 1365712b2f30Ssthen printf("test %s functions\n", feature); 1366712b2f30Ssthen } 1367712b2f30Ssthen 1368712b2f30Ssthen #ifdef USE_ECDSA_EVP_WORKAROUND 1369712b2f30Ssthen void ecdsa_evp_workaround_init(void); 1370712b2f30Ssthen #endif 1371437d2860Ssthen 1372712b2f30Ssthen /** 1373712b2f30Ssthen * Main unit test program. Setup, teardown and report errors. 1374712b2f30Ssthen * @param argc: arg count. 1375712b2f30Ssthen * @param argv: array of commandline arguments. 1376712b2f30Ssthen * @return program failure if test fails. 1377712b2f30Ssthen */ 1378712b2f30Ssthen int 1379712b2f30Ssthen main(int argc, char* argv[]) 1380712b2f30Ssthen { 138183152a15Ssthen checklock_start(); 1382712b2f30Ssthen log_init(NULL, 0, NULL); 1383712b2f30Ssthen if(argc != 1) { 1384712b2f30Ssthen printf("usage: %s\n", argv[0]); 1385712b2f30Ssthen printf("\tperforms unit tests.\n"); 1386712b2f30Ssthen return 1; 1387712b2f30Ssthen } 1388d7b4a113Ssthen /* Disable roundrobin for the unit tests */ 1389d7b4a113Ssthen RRSET_ROUNDROBIN = 0; 1390d7b4a113Ssthen #ifdef USE_LIBEVENT 1391d7b4a113Ssthen printf("Start of %s+libevent unit test.\n", PACKAGE_STRING); 1392d7b4a113Ssthen #else 1393712b2f30Ssthen printf("Start of %s unit test.\n", PACKAGE_STRING); 1394d7b4a113Ssthen #endif 1395712b2f30Ssthen #ifdef HAVE_SSL 1396712b2f30Ssthen # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS 1397712b2f30Ssthen ERR_load_crypto_strings(); 1398712b2f30Ssthen # endif 1399712b2f30Ssthen # ifdef USE_GOST 1400712b2f30Ssthen (void)sldns_key_EVP_load_gost_id(); 1401712b2f30Ssthen # endif 1402712b2f30Ssthen # ifdef USE_ECDSA_EVP_WORKAROUND 1403712b2f30Ssthen ecdsa_evp_workaround_init(); 1404712b2f30Ssthen # endif 1405712b2f30Ssthen #elif defined(HAVE_NSS) 1406712b2f30Ssthen if(NSS_NoDB_Init(".") != SECSuccess) 1407712b2f30Ssthen fatal_exit("could not init NSS"); 1408712b2f30Ssthen #endif /* HAVE_SSL or HAVE_NSS*/ 1409712b2f30Ssthen authzone_test(); 1410712b2f30Ssthen neg_test(); 1411712b2f30Ssthen rnd_test(); 1412712b2f30Ssthen respip_test(); 1413712b2f30Ssthen verify_test(); 1414712b2f30Ssthen net_test(); 1415712b2f30Ssthen config_memsize_test(); 1416712b2f30Ssthen config_tag_test(); 1417712b2f30Ssthen dname_test(); 1418712b2f30Ssthen rtt_test(); 1419712b2f30Ssthen anchors_test(); 1420712b2f30Ssthen alloc_test(); 1421712b2f30Ssthen regional_test(); 1422712b2f30Ssthen lruhash_test(); 1423712b2f30Ssthen slabhash_test(); 1424712b2f30Ssthen infra_test(); 1425712b2f30Ssthen ldns_test(); 1426437d2860Ssthen edns_cookie_test(); 1427a6cc1574Ssthen zonemd_test(); 1428a6cc1574Ssthen tcpreuse_test(); 1429712b2f30Ssthen msgparse_test(); 1430437d2860Ssthen edns_ede_answer_encode_test(); 1431*a43524d9Ssthen localzone_test(); 1432712b2f30Ssthen #ifdef CLIENT_SUBNET 1433712b2f30Ssthen ecs_test(); 1434712b2f30Ssthen #endif /* CLIENT_SUBNET */ 1435712b2f30Ssthen if(log_get_lock()) { 1436b0dfc31bSsthen lock_basic_destroy((lock_basic_type*)log_get_lock()); 1437712b2f30Ssthen } 1438712b2f30Ssthen checklock_stop(); 1439712b2f30Ssthen printf("%d checks ok.\n", testcount); 1440712b2f30Ssthen #ifdef HAVE_SSL 14411996a427Ssthen # if defined(USE_GOST) 1442712b2f30Ssthen sldns_key_EVP_unload_gost(); 1443712b2f30Ssthen # endif 1444712b2f30Ssthen # ifdef HAVE_OPENSSL_CONFIG 1445712b2f30Ssthen # ifdef HAVE_EVP_CLEANUP 1446712b2f30Ssthen EVP_cleanup(); 1447712b2f30Ssthen # endif 1448d7b4a113Ssthen # if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP) 1449712b2f30Ssthen ENGINE_cleanup(); 1450d7b4a113Ssthen # endif 1451712b2f30Ssthen CONF_modules_free(); 1452712b2f30Ssthen # endif 1453712b2f30Ssthen # ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1454712b2f30Ssthen CRYPTO_cleanup_all_ex_data(); 1455712b2f30Ssthen # endif 1456712b2f30Ssthen # ifdef HAVE_ERR_FREE_STRINGS 1457712b2f30Ssthen ERR_free_strings(); 1458712b2f30Ssthen # endif 1459712b2f30Ssthen # ifdef HAVE_RAND_CLEANUP 1460712b2f30Ssthen RAND_cleanup(); 1461712b2f30Ssthen # endif 1462712b2f30Ssthen #elif defined(HAVE_NSS) 1463712b2f30Ssthen if(NSS_Shutdown() != SECSuccess) 1464712b2f30Ssthen fatal_exit("could not shutdown NSS"); 1465712b2f30Ssthen #endif /* HAVE_SSL or HAVE_NSS */ 1466712b2f30Ssthen #ifdef HAVE_PTHREAD 1467712b2f30Ssthen /* dlopen frees its thread specific state */ 1468712b2f30Ssthen pthread_exit(NULL); 1469712b2f30Ssthen #endif 1470712b2f30Ssthen return 0; 1471712b2f30Ssthen } 1472