1 /* 2 * testcode/unitmain.c - unit test main program for unbound. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 */ 36 /** 37 * \file 38 * Unit test main program. Calls all the other unit tests. 39 * Exits with code 1 on a failure. 0 if all unit tests are successful. 40 */ 41 42 #include "config.h" 43 #ifdef HAVE_OPENSSL_ERR_H 44 #include <openssl/err.h> 45 #endif 46 47 #ifdef HAVE_OPENSSL_RAND_H 48 #include <openssl/rand.h> 49 #endif 50 51 #ifdef HAVE_OPENSSL_CONF_H 52 #include <openssl/conf.h> 53 #endif 54 55 #ifdef HAVE_OPENSSL_ENGINE_H 56 #include <openssl/engine.h> 57 #endif 58 59 #ifdef HAVE_NSS 60 /* nss3 */ 61 #include "nss.h" 62 #endif 63 64 #include "sldns/rrdef.h" 65 #include "sldns/keyraw.h" 66 #include "util/log.h" 67 #include "testcode/unitmain.h" 68 69 /** number of tests done */ 70 int testcount = 0; 71 72 #include "util/alloc.h" 73 /** test alloc code */ 74 static void 75 alloc_test(void) { 76 alloc_special_type *t1, *t2; 77 struct alloc_cache major, minor1, minor2; 78 int i; 79 80 unit_show_feature("alloc_special_obtain"); 81 alloc_init(&major, NULL, 0); 82 alloc_init(&minor1, &major, 0); 83 alloc_init(&minor2, &major, 1); 84 85 t1 = alloc_special_obtain(&minor1); 86 alloc_clear(&minor1); 87 88 alloc_special_release(&minor2, t1); 89 t2 = alloc_special_obtain(&minor2); 90 unit_assert( t1 == t2 ); /* reused */ 91 alloc_special_release(&minor2, t1); 92 93 for(i=0; i<100; i++) { 94 t1 = alloc_special_obtain(&minor1); 95 alloc_special_release(&minor2, t1); 96 } 97 if(0) { 98 alloc_stats(&minor1); 99 alloc_stats(&minor2); 100 alloc_stats(&major); 101 } 102 /* reuse happened */ 103 unit_assert(minor1.num_quar + minor2.num_quar + major.num_quar == 11); 104 105 alloc_clear(&minor1); 106 alloc_clear(&minor2); 107 unit_assert(major.num_quar == 11); 108 alloc_clear(&major); 109 } 110 111 #include "util/net_help.h" 112 /** test net code */ 113 static void 114 net_test(void) 115 { 116 const char* t4[] = {"\000\000\000\000", 117 "\200\000\000\000", 118 "\300\000\000\000", 119 "\340\000\000\000", 120 "\360\000\000\000", 121 "\370\000\000\000", 122 "\374\000\000\000", 123 "\376\000\000\000", 124 "\377\000\000\000", 125 "\377\200\000\000", 126 "\377\300\000\000", 127 "\377\340\000\000", 128 "\377\360\000\000", 129 "\377\370\000\000", 130 "\377\374\000\000", 131 "\377\376\000\000", 132 "\377\377\000\000", 133 "\377\377\200\000", 134 "\377\377\300\000", 135 "\377\377\340\000", 136 "\377\377\360\000", 137 "\377\377\370\000", 138 "\377\377\374\000", 139 "\377\377\376\000", 140 "\377\377\377\000", 141 "\377\377\377\200", 142 "\377\377\377\300", 143 "\377\377\377\340", 144 "\377\377\377\360", 145 "\377\377\377\370", 146 "\377\377\377\374", 147 "\377\377\377\376", 148 "\377\377\377\377", 149 "\377\377\377\377", 150 "\377\377\377\377", 151 }; 152 unit_show_func("util/net_help.c", "str_is_ip6"); 153 unit_assert( str_is_ip6("::") ); 154 unit_assert( str_is_ip6("::1") ); 155 unit_assert( str_is_ip6("2001:7b8:206:1:240:f4ff:fe37:8810") ); 156 unit_assert( str_is_ip6("fe80::240:f4ff:fe37:8810") ); 157 unit_assert( !str_is_ip6("0.0.0.0") ); 158 unit_assert( !str_is_ip6("213.154.224.12") ); 159 unit_assert( !str_is_ip6("213.154.224.255") ); 160 unit_assert( !str_is_ip6("255.255.255.0") ); 161 unit_show_func("util/net_help.c", "is_pow2"); 162 unit_assert( is_pow2(0) ); 163 unit_assert( is_pow2(1) ); 164 unit_assert( is_pow2(2) ); 165 unit_assert( is_pow2(4) ); 166 unit_assert( is_pow2(8) ); 167 unit_assert( is_pow2(16) ); 168 unit_assert( is_pow2(1024) ); 169 unit_assert( is_pow2(1024*1024) ); 170 unit_assert( is_pow2(1024*1024*1024) ); 171 unit_assert( !is_pow2(3) ); 172 unit_assert( !is_pow2(5) ); 173 unit_assert( !is_pow2(6) ); 174 unit_assert( !is_pow2(7) ); 175 unit_assert( !is_pow2(9) ); 176 unit_assert( !is_pow2(10) ); 177 unit_assert( !is_pow2(11) ); 178 unit_assert( !is_pow2(17) ); 179 unit_assert( !is_pow2(23) ); 180 unit_assert( !is_pow2(257) ); 181 unit_assert( !is_pow2(259) ); 182 183 /* test addr_mask */ 184 unit_show_func("util/net_help.c", "addr_mask"); 185 if(1) { 186 struct sockaddr_in a4; 187 struct sockaddr_in6 a6; 188 socklen_t l4 = (socklen_t)sizeof(a4); 189 socklen_t l6 = (socklen_t)sizeof(a6); 190 int i; 191 a4.sin_family = AF_INET; 192 a6.sin6_family = AF_INET6; 193 for(i=0; i<35; i++) { 194 /* address 255.255.255.255 */ 195 memcpy(&a4.sin_addr, "\377\377\377\377", 4); 196 addr_mask((struct sockaddr_storage*)&a4, l4, i); 197 unit_assert(memcmp(&a4.sin_addr, t4[i], 4) == 0); 198 } 199 memcpy(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16); 200 addr_mask((struct sockaddr_storage*)&a6, l6, 128); 201 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) == 0); 202 addr_mask((struct sockaddr_storage*)&a6, l6, 122); 203 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\300", 16) == 0); 204 addr_mask((struct sockaddr_storage*)&a6, l6, 120); 205 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000", 16) == 0); 206 addr_mask((struct sockaddr_storage*)&a6, l6, 64); 207 unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", 16) == 0); 208 addr_mask((struct sockaddr_storage*)&a6, l6, 0); 209 unit_assert(memcmp(&a6.sin6_addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16) == 0); 210 } 211 212 /* test addr_in_common */ 213 unit_show_func("util/net_help.c", "addr_in_common"); 214 if(1) { 215 struct sockaddr_in a4, b4; 216 struct sockaddr_in6 a6, b6; 217 socklen_t l4 = (socklen_t)sizeof(a4); 218 socklen_t l6 = (socklen_t)sizeof(a6); 219 int i; 220 a4.sin_family = AF_INET; 221 b4.sin_family = AF_INET; 222 a6.sin6_family = AF_INET6; 223 b6.sin6_family = AF_INET6; 224 memcpy(&a4.sin_addr, "abcd", 4); 225 memcpy(&b4.sin_addr, "abcd", 4); 226 unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 32, 227 (struct sockaddr_storage*)&b4, 32, l4) == 32); 228 unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 34, 229 (struct sockaddr_storage*)&b4, 32, l4) == 32); 230 for(i=0; i<=32; i++) { 231 unit_assert(addr_in_common( 232 (struct sockaddr_storage*)&a4, 32, 233 (struct sockaddr_storage*)&b4, i, l4) == i); 234 unit_assert(addr_in_common( 235 (struct sockaddr_storage*)&a4, i, 236 (struct sockaddr_storage*)&b4, 32, l4) == i); 237 unit_assert(addr_in_common( 238 (struct sockaddr_storage*)&a4, i, 239 (struct sockaddr_storage*)&b4, i, l4) == i); 240 } 241 for(i=0; i<=32; i++) { 242 memcpy(&a4.sin_addr, "\377\377\377\377", 4); 243 memcpy(&b4.sin_addr, t4[i], 4); 244 unit_assert(addr_in_common( 245 (struct sockaddr_storage*)&a4, 32, 246 (struct sockaddr_storage*)&b4, 32, l4) == i); 247 unit_assert(addr_in_common( 248 (struct sockaddr_storage*)&b4, 32, 249 (struct sockaddr_storage*)&a4, 32, l4) == i); 250 } 251 memcpy(&a6.sin6_addr, "abcdefghabcdefgh", 16); 252 memcpy(&b6.sin6_addr, "abcdefghabcdefgh", 16); 253 unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 128, 254 (struct sockaddr_storage*)&b6, 128, l6) == 128); 255 unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 129, 256 (struct sockaddr_storage*)&b6, 128, l6) == 128); 257 for(i=0; i<=128; i++) { 258 unit_assert(addr_in_common( 259 (struct sockaddr_storage*)&a6, 128, 260 (struct sockaddr_storage*)&b6, i, l6) == i); 261 unit_assert(addr_in_common( 262 (struct sockaddr_storage*)&a6, i, 263 (struct sockaddr_storage*)&b6, 128, l6) == i); 264 unit_assert(addr_in_common( 265 (struct sockaddr_storage*)&a6, i, 266 (struct sockaddr_storage*)&b6, i, l6) == i); 267 } 268 } 269 /* test sockaddr_cmp_addr */ 270 unit_show_func("util/net_help.c", "sockaddr_cmp_addr"); 271 if(1) { 272 struct sockaddr_storage a, b; 273 socklen_t alen = (socklen_t)sizeof(a); 274 socklen_t blen = (socklen_t)sizeof(b); 275 unit_assert(ipstrtoaddr("127.0.0.0", 53, &a, &alen)); 276 unit_assert(ipstrtoaddr("127.255.255.255", 53, &b, &blen)); 277 unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0); 278 unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0); 279 unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0); 280 unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0); 281 unit_assert(ipstrtoaddr("192.168.121.5", 53, &a, &alen)); 282 unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) > 0); 283 unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) < 0); 284 unit_assert(sockaddr_cmp_addr(&a, alen, &a, alen) == 0); 285 unit_assert(ipstrtoaddr("2001:3578:ffeb::99", 53, &b, &blen)); 286 unit_assert(sockaddr_cmp_addr(&b, blen, &b, blen) == 0); 287 unit_assert(sockaddr_cmp_addr(&a, alen, &b, blen) < 0); 288 unit_assert(sockaddr_cmp_addr(&b, blen, &a, alen) > 0); 289 } 290 /* test addr_is_ip4mapped */ 291 unit_show_func("util/net_help.c", "addr_is_ip4mapped"); 292 if(1) { 293 struct sockaddr_storage a; 294 socklen_t l = (socklen_t)sizeof(a); 295 unit_assert(ipstrtoaddr("12.13.14.15", 53, &a, &l)); 296 unit_assert(!addr_is_ip4mapped(&a, l)); 297 unit_assert(ipstrtoaddr("fe80::217:31ff:fe91:df", 53, &a, &l)); 298 unit_assert(!addr_is_ip4mapped(&a, l)); 299 unit_assert(ipstrtoaddr("ffff::217:31ff:fe91:df", 53, &a, &l)); 300 unit_assert(!addr_is_ip4mapped(&a, l)); 301 unit_assert(ipstrtoaddr("::ffff:31ff:fe91:df", 53, &a, &l)); 302 unit_assert(!addr_is_ip4mapped(&a, l)); 303 unit_assert(ipstrtoaddr("::fffe:fe91:df", 53, &a, &l)); 304 unit_assert(!addr_is_ip4mapped(&a, l)); 305 unit_assert(ipstrtoaddr("::ffff:127.0.0.1", 53, &a, &l)); 306 unit_assert(addr_is_ip4mapped(&a, l)); 307 unit_assert(ipstrtoaddr("::ffff:127.0.0.2", 53, &a, &l)); 308 unit_assert(addr_is_ip4mapped(&a, l)); 309 unit_assert(ipstrtoaddr("::ffff:192.168.0.2", 53, &a, &l)); 310 unit_assert(addr_is_ip4mapped(&a, l)); 311 unit_assert(ipstrtoaddr("2::ffff:192.168.0.2", 53, &a, &l)); 312 unit_assert(!addr_is_ip4mapped(&a, l)); 313 } 314 /* test addr_is_any */ 315 unit_show_func("util/net_help.c", "addr_is_any"); 316 if(1) { 317 struct sockaddr_storage a; 318 socklen_t l = (socklen_t)sizeof(a); 319 unit_assert(ipstrtoaddr("0.0.0.0", 53, &a, &l)); 320 unit_assert(addr_is_any(&a, l)); 321 unit_assert(ipstrtoaddr("0.0.0.0", 10053, &a, &l)); 322 unit_assert(addr_is_any(&a, l)); 323 unit_assert(ipstrtoaddr("0.0.0.0", 0, &a, &l)); 324 unit_assert(addr_is_any(&a, l)); 325 unit_assert(ipstrtoaddr("::0", 0, &a, &l)); 326 unit_assert(addr_is_any(&a, l)); 327 unit_assert(ipstrtoaddr("::0", 53, &a, &l)); 328 unit_assert(addr_is_any(&a, l)); 329 unit_assert(ipstrtoaddr("::1", 53, &a, &l)); 330 unit_assert(!addr_is_any(&a, l)); 331 unit_assert(ipstrtoaddr("2001:1667::1", 0, &a, &l)); 332 unit_assert(!addr_is_any(&a, l)); 333 unit_assert(ipstrtoaddr("2001::0", 0, &a, &l)); 334 unit_assert(!addr_is_any(&a, l)); 335 unit_assert(ipstrtoaddr("10.0.0.0", 0, &a, &l)); 336 unit_assert(!addr_is_any(&a, l)); 337 unit_assert(ipstrtoaddr("0.0.0.10", 0, &a, &l)); 338 unit_assert(!addr_is_any(&a, l)); 339 unit_assert(ipstrtoaddr("192.0.2.1", 0, &a, &l)); 340 unit_assert(!addr_is_any(&a, l)); 341 } 342 } 343 344 #include "util/config_file.h" 345 /** test config_file: cfg_parse_memsize */ 346 static void 347 config_memsize_test(void) 348 { 349 size_t v = 0; 350 unit_show_func("util/config_file.c", "cfg_parse_memsize"); 351 if(0) { 352 /* these emit errors */ 353 unit_assert( cfg_parse_memsize("", &v) == 0); 354 unit_assert( cfg_parse_memsize("bla", &v) == 0); 355 unit_assert( cfg_parse_memsize("nop", &v) == 0); 356 unit_assert( cfg_parse_memsize("n0b", &v) == 0); 357 unit_assert( cfg_parse_memsize("gb", &v) == 0); 358 unit_assert( cfg_parse_memsize("b", &v) == 0); 359 unit_assert( cfg_parse_memsize("kb", &v) == 0); 360 unit_assert( cfg_parse_memsize("kk kb", &v) == 0); 361 } 362 unit_assert( cfg_parse_memsize("0", &v) && v==0); 363 unit_assert( cfg_parse_memsize("1", &v) && v==1); 364 unit_assert( cfg_parse_memsize("10", &v) && v==10); 365 unit_assert( cfg_parse_memsize("10b", &v) && v==10); 366 unit_assert( cfg_parse_memsize("5b", &v) && v==5); 367 unit_assert( cfg_parse_memsize("1024", &v) && v==1024); 368 unit_assert( cfg_parse_memsize("1k", &v) && v==1024); 369 unit_assert( cfg_parse_memsize("1K", &v) && v==1024); 370 unit_assert( cfg_parse_memsize("1Kb", &v) && v==1024); 371 unit_assert( cfg_parse_memsize("1kb", &v) && v==1024); 372 unit_assert( cfg_parse_memsize("1 kb", &v) && v==1024); 373 unit_assert( cfg_parse_memsize("10 kb", &v) && v==10240); 374 unit_assert( cfg_parse_memsize("2k", &v) && v==2048); 375 unit_assert( cfg_parse_memsize("2m", &v) && v==2048*1024); 376 unit_assert( cfg_parse_memsize("3M", &v) && v==3072*1024); 377 unit_assert( cfg_parse_memsize("40m", &v) && v==40960*1024); 378 unit_assert( cfg_parse_memsize("1G", &v) && v==1024*1024*1024); 379 unit_assert( cfg_parse_memsize("1 Gb", &v) && v==1024*1024*1024); 380 unit_assert( cfg_parse_memsize("0 Gb", &v) && v==0*1024*1024); 381 } 382 383 /** test config_file: test tag code */ 384 static void 385 config_tag_test(void) 386 { 387 unit_show_func("util/config_file.c", "taglist_intersect"); 388 unit_assert( taglist_intersect( 389 (uint8_t*)"\000\000\000", 3, (uint8_t*)"\001\000\001", 3 390 ) == 0); 391 unit_assert( taglist_intersect( 392 (uint8_t*)"\000\000\001", 3, (uint8_t*)"\001\000\001", 3 393 ) == 1); 394 unit_assert( taglist_intersect( 395 (uint8_t*)"\001\000\000", 3, (uint8_t*)"\001\000\001", 3 396 ) == 1); 397 unit_assert( taglist_intersect( 398 (uint8_t*)"\001", 1, (uint8_t*)"\001\000\001", 3 399 ) == 1); 400 unit_assert( taglist_intersect( 401 (uint8_t*)"\001\000\001", 3, (uint8_t*)"\001", 1 402 ) == 1); 403 } 404 405 #include "util/rtt.h" 406 #include "util/timehist.h" 407 #include "iterator/iterator.h" 408 #include "libunbound/unbound.h" 409 /** test RTT code */ 410 static void 411 rtt_test(void) 412 { 413 int init = UNKNOWN_SERVER_NICENESS; 414 int i; 415 struct rtt_info r; 416 unit_show_func("util/rtt.c", "rtt_timeout"); 417 rtt_init(&r); 418 /* initial value sensible */ 419 unit_assert( rtt_timeout(&r) == init ); 420 rtt_lost(&r, init); 421 unit_assert( rtt_timeout(&r) == init*2 ); 422 rtt_lost(&r, init*2); 423 unit_assert( rtt_timeout(&r) == init*4 ); 424 rtt_update(&r, 4000); 425 unit_assert( rtt_timeout(&r) >= 2000 ); 426 rtt_lost(&r, rtt_timeout(&r) ); 427 for(i=0; i<100; i++) { 428 rtt_lost(&r, rtt_timeout(&r) ); 429 unit_assert( rtt_timeout(&r) > RTT_MIN_TIMEOUT-1); 430 unit_assert( rtt_timeout(&r) < RTT_MAX_TIMEOUT+1); 431 } 432 /* must be the same, timehist bucket is used in stats */ 433 unit_assert(UB_STATS_BUCKET_NUM == NUM_BUCKETS_HIST); 434 } 435 436 #include "services/cache/infra.h" 437 438 /* lookup and get key and data structs easily */ 439 static struct infra_data* infra_lookup_host(struct infra_cache* infra, 440 struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, 441 size_t zonelen, int wr, time_t now, struct infra_key** k) 442 { 443 struct infra_data* d; 444 struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 445 zone, zonelen, wr); 446 if(!e) return NULL; 447 d = (struct infra_data*)e->data; 448 if(d->ttl < now) { 449 lock_rw_unlock(&e->lock); 450 return NULL; 451 } 452 *k = (struct infra_key*)e->key; 453 return d; 454 } 455 456 /** test host cache */ 457 static void 458 infra_test(void) 459 { 460 struct sockaddr_storage one; 461 socklen_t onelen; 462 uint8_t* zone = (uint8_t*)"\007example\003com\000"; 463 size_t zonelen = 13; 464 struct infra_cache* slab; 465 struct config_file* cfg = config_create(); 466 time_t now = 0; 467 uint8_t edns_lame; 468 int vs, to; 469 struct infra_key* k; 470 struct infra_data* d; 471 int init = 376; 472 473 unit_show_feature("infra cache"); 474 unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen)); 475 476 slab = infra_create(cfg); 477 unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, 478 &vs, &edns_lame, &to) ); 479 unit_assert( vs == 0 && to == init && edns_lame == 0 ); 480 481 unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, LDNS_RR_TYPE_A, -1, init, now) ); 482 unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 483 now, &vs, &edns_lame, &to) ); 484 unit_assert( vs == 0 && to == init*2 && edns_lame == 0 ); 485 486 unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); 487 unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 488 now, &vs, &edns_lame, &to) ); 489 unit_assert( vs == -1 && to == init*2 && edns_lame == 1); 490 491 now += cfg->host_ttl + 10; 492 unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 493 now, &vs, &edns_lame, &to) ); 494 unit_assert( vs == 0 && to == init && edns_lame == 0 ); 495 496 unit_assert( infra_set_lame(slab, &one, onelen, 497 zone, zonelen, now, 0, 0, LDNS_RR_TYPE_A) ); 498 unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); 499 unit_assert( d->ttl == now+cfg->host_ttl ); 500 unit_assert( d->edns_version == 0 ); 501 unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && 502 !d->lame_other); 503 lock_rw_unlock(&k->entry.lock); 504 505 /* test merge of data */ 506 unit_assert( infra_set_lame(slab, &one, onelen, 507 zone, zonelen, now, 0, 0, LDNS_RR_TYPE_AAAA) ); 508 unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); 509 unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && 510 d->lame_other); 511 lock_rw_unlock(&k->entry.lock); 512 513 /* test that noEDNS cannot overwrite known-yesEDNS */ 514 now += cfg->host_ttl + 10; 515 unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 516 now, &vs, &edns_lame, &to) ); 517 unit_assert( vs == 0 && to == init && edns_lame == 0 ); 518 519 unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) ); 520 unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 521 now, &vs, &edns_lame, &to) ); 522 unit_assert( vs == 0 && to == init && edns_lame == 1 ); 523 524 unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); 525 unit_assert( infra_host(slab, &one, onelen, zone, zonelen, 526 now, &vs, &edns_lame, &to) ); 527 unit_assert( vs == 0 && to == init && edns_lame == 1 ); 528 529 infra_delete(slab); 530 config_delete(cfg); 531 } 532 533 #include "util/random.h" 534 /** test randomness */ 535 static void 536 rnd_test(void) 537 { 538 struct ub_randstate* r; 539 int num = 1000, i; 540 long int a[1000]; 541 unit_show_feature("ub_random"); 542 unit_assert( (r = ub_initstate(NULL)) ); 543 for(i=0; i<num; i++) { 544 a[i] = ub_random(r); 545 unit_assert(a[i] >= 0); 546 unit_assert((size_t)a[i] <= (size_t)0x7fffffff); 547 if(i > 5) 548 unit_assert(a[i] != a[i-1] || a[i] != a[i-2] || 549 a[i] != a[i-3] || a[i] != a[i-4] || 550 a[i] != a[i-5] || a[i] != a[i-6]); 551 } 552 a[0] = ub_random_max(r, 1); 553 unit_assert(a[0] >= 0 && a[0] < 1); 554 a[0] = ub_random_max(r, 10000); 555 unit_assert(a[0] >= 0 && a[0] < 10000); 556 for(i=0; i<num; i++) { 557 a[i] = ub_random_max(r, 10); 558 unit_assert(a[i] >= 0 && a[i] < 10); 559 } 560 ub_randfree(r); 561 } 562 563 #include "respip/respip.h" 564 #include "services/localzone.h" 565 #include "util/data/packed_rrset.h" 566 typedef struct addr_action {char* ip; char* sact; enum respip_action act;} 567 addr_action_t; 568 569 /** Utility function that verifies that the respip set has actions as expected */ 570 static void 571 verify_respip_set_actions(struct respip_set* set, addr_action_t actions[], 572 int actions_len) 573 { 574 int i = 0; 575 struct rbtree_type* tree = respip_set_get_tree(set); 576 for (i=0; i<actions_len; i++) { 577 struct sockaddr_storage addr; 578 int net; 579 socklen_t addrlen; 580 struct resp_addr* node; 581 netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr, 582 &addrlen, &net); 583 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 584 585 /** we have the node and the node has the correct action 586 * and has no data */ 587 unit_assert(node); 588 unit_assert(actions[i].act == 589 resp_addr_get_action(node)); 590 unit_assert(resp_addr_get_rrset(node) == NULL); 591 } 592 unit_assert(actions_len && i == actions_len); 593 unit_assert(actions_len == (int)tree->count); 594 } 595 596 /** Global respip actions test; apply raw config data and verify that 597 * all the nodes in the respip set, looked up by address, have expected 598 * actions */ 599 static void 600 respip_conf_actions_test(void) 601 { 602 addr_action_t config_response_ip[] = { 603 {"192.0.1.0/24", "deny", respip_deny}, 604 {"192.0.2.0/24", "redirect", respip_redirect}, 605 {"192.0.3.0/26", "inform", respip_inform}, 606 {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 607 {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 608 {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 609 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 610 }; 611 int i; 612 struct respip_set* set = respip_set_create(); 613 struct config_file cfg; 614 int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t)); 615 616 unit_assert(set); 617 unit_show_feature("global respip config actions apply"); 618 memset(&cfg, 0, sizeof(cfg)); 619 for(i=0; i<clen; i++) { 620 char* ip = strdup(config_response_ip[i].ip); 621 char* sact = strdup(config_response_ip[i].sact); 622 unit_assert(ip && sact); 623 if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact)) 624 unit_assert(0); 625 } 626 unit_assert(respip_global_apply_cfg(set, &cfg)); 627 verify_respip_set_actions(set, config_response_ip, clen); 628 629 respip_set_delete(set); 630 config_deldblstrlist(cfg.respip_actions); 631 } 632 633 /** Per-view respip actions test; apply raw configuration with two views 634 * and verify that actions are as expected in respip sets of both views */ 635 static void 636 respip_view_conf_actions_test(void) 637 { 638 addr_action_t config_response_ip_view1[] = { 639 {"192.0.1.0/24", "deny", respip_deny}, 640 {"192.0.2.0/24", "redirect", respip_redirect}, 641 {"192.0.3.0/26", "inform", respip_inform}, 642 {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 643 }; 644 addr_action_t config_response_ip_view2[] = { 645 {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 646 {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 647 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 648 }; 649 int i; 650 struct config_file cfg; 651 int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t)); 652 int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t)); 653 struct config_view* cv1; 654 struct config_view* cv2; 655 int have_respip_cfg = 0; 656 struct views* views = NULL; 657 struct view* v = NULL; 658 659 unit_show_feature("per-view respip config actions apply"); 660 memset(&cfg, 0, sizeof(cfg)); 661 cv1 = (struct config_view*)calloc(1, sizeof(struct config_view)); 662 cv2 = (struct config_view*)calloc(1, sizeof(struct config_view)); 663 unit_assert(cv1 && cv2); 664 cv1->name = strdup("view1"); 665 cv2->name = strdup("view2"); 666 unit_assert(cv1->name && cv2->name); 667 cv1->next = cv2; 668 cfg.views = cv1; 669 670 for(i=0; i<clen1; i++) { 671 char* ip = strdup(config_response_ip_view1[i].ip); 672 char* sact = strdup(config_response_ip_view1[i].sact); 673 unit_assert(ip && sact); 674 if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact)) 675 unit_assert(0); 676 } 677 for(i=0; i<clen2; i++) { 678 char* ip = strdup(config_response_ip_view2[i].ip); 679 char* sact = strdup(config_response_ip_view2[i].sact); 680 unit_assert(ip && sact); 681 if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact)) 682 unit_assert(0); 683 } 684 views = views_create(); 685 unit_assert(views); 686 unit_assert(views_apply_cfg(views, &cfg)); 687 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 688 689 /* now verify the respip sets in each view */ 690 v = views_find_view(views, "view1", 0); 691 unit_assert(v); 692 verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1); 693 lock_rw_unlock(&v->lock); 694 v = views_find_view(views, "view2", 0); 695 unit_assert(v); 696 verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2); 697 lock_rw_unlock(&v->lock); 698 699 views_delete(views); 700 free(cv1->name); 701 free(cv1); 702 free(cv2->name); 703 free(cv2); 704 } 705 706 typedef struct addr_data {char* ip; char* data;} addr_data_t; 707 708 /** find the respip address node in the specified tree (by address lookup) 709 * and verify type and address of the specified rdata (by index) in this 710 * node's rrset */ 711 static void 712 verify_rrset(struct respip_set* set, const char* ipstr, 713 const char* rdatastr, size_t rdi, uint16_t type) 714 { 715 struct sockaddr_storage addr; 716 int net; 717 char buf[65536]; 718 socklen_t addrlen; 719 struct rbtree_type* tree; 720 struct resp_addr* node; 721 const struct ub_packed_rrset_key* rrs; 722 723 netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net); 724 tree = respip_set_get_tree(set); 725 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 726 unit_assert(node); 727 unit_assert((rrs = resp_addr_get_rrset(node))); 728 unit_assert(ntohs(rrs->rk.type) == type); 729 packed_rr_to_string((struct ub_packed_rrset_key*)rrs, 730 rdi, 0, buf, sizeof(buf)); 731 unit_assert(strstr(buf, rdatastr)); 732 } 733 734 /** Dataset used to test redirect rrset initialization for both 735 * global and per-view respip redirect configuration */ 736 static addr_data_t config_response_ip_data[] = { 737 {"192.0.1.0/24", "A 1.2.3.4"}, 738 {"192.0.1.0/24", "A 11.12.13.14"}, 739 {"192.0.2.0/24", "CNAME www.example.com."}, 740 {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"}, 741 }; 742 743 /** Populate raw respip redirect config data, used for both global and 744 * view-based respip redirect test case */ 745 static void 746 cfg_insert_respip_data(struct config_str2list** respip_actions, 747 struct config_str2list** respip_data) 748 { 749 int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t)); 750 int i = 0; 751 752 /* insert actions (duplicate netblocks don't matter) */ 753 for(i=0; i<clen; i++) { 754 char* ip = strdup(config_response_ip_data[i].ip); 755 char* sact = strdup("redirect"); 756 unit_assert(ip && sact); 757 if(!cfg_str2list_insert(respip_actions, ip, sact)) 758 unit_assert(0); 759 } 760 /* insert data */ 761 for(i=0; i<clen; i++) { 762 char* ip = strdup(config_response_ip_data[i].ip); 763 char* data = strdup(config_response_ip_data[i].data); 764 unit_assert(ip && data); 765 if(!cfg_str2list_insert(respip_data, ip, data)) 766 unit_assert(0); 767 } 768 } 769 770 /** Test global respip redirect w/ data directives */ 771 static void 772 respip_conf_data_test(void) 773 { 774 struct respip_set* set = respip_set_create(); 775 struct config_file cfg; 776 777 unit_show_feature("global respip config data apply"); 778 memset(&cfg, 0, sizeof(cfg)); 779 780 cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data); 781 782 /* apply configuration and verify rrsets */ 783 unit_assert(respip_global_apply_cfg(set, &cfg)); 784 verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A); 785 verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A); 786 verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME); 787 verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA); 788 789 respip_set_delete(set); 790 } 791 792 /** Test per-view respip redirect w/ data directives */ 793 static void 794 respip_view_conf_data_test(void) 795 { 796 struct config_file cfg; 797 struct config_view* cv; 798 int have_respip_cfg = 0; 799 struct views* views = NULL; 800 struct view* v = NULL; 801 802 unit_show_feature("per-view respip config data apply"); 803 memset(&cfg, 0, sizeof(cfg)); 804 cv = (struct config_view*)calloc(1, sizeof(struct config_view)); 805 unit_assert(cv); 806 cv->name = strdup("view1"); 807 unit_assert(cv->name); 808 cfg.views = cv; 809 cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data); 810 views = views_create(); 811 unit_assert(views); 812 unit_assert(views_apply_cfg(views, &cfg)); 813 814 /* apply configuration and verify rrsets */ 815 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 816 v = views_find_view(views, "view1", 0); 817 unit_assert(v); 818 verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4", 819 0, LDNS_RR_TYPE_A); 820 verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14", 821 1, LDNS_RR_TYPE_A); 822 verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com", 823 0, LDNS_RR_TYPE_CNAME); 824 verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1", 825 0, LDNS_RR_TYPE_AAAA); 826 lock_rw_unlock(&v->lock); 827 828 views_delete(views); 829 free(cv->name); 830 free(cv); 831 } 832 833 /** respip unit tests */ 834 static void respip_test(void) 835 { 836 respip_view_conf_data_test(); 837 respip_conf_data_test(); 838 respip_view_conf_actions_test(); 839 respip_conf_actions_test(); 840 } 841 842 void unit_show_func(const char* file, const char* func) 843 { 844 printf("test %s:%s\n", file, func); 845 } 846 847 void unit_show_feature(const char* feature) 848 { 849 printf("test %s functions\n", feature); 850 } 851 852 #ifdef USE_ECDSA_EVP_WORKAROUND 853 void ecdsa_evp_workaround_init(void); 854 #endif 855 /** 856 * Main unit test program. Setup, teardown and report errors. 857 * @param argc: arg count. 858 * @param argv: array of commandline arguments. 859 * @return program failure if test fails. 860 */ 861 int 862 main(int argc, char* argv[]) 863 { 864 log_init(NULL, 0, NULL); 865 if(argc != 1) { 866 printf("usage: %s\n", argv[0]); 867 printf("\tperforms unit tests.\n"); 868 return 1; 869 } 870 printf("Start of %s unit test.\n", PACKAGE_STRING); 871 #ifdef HAVE_SSL 872 # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS 873 ERR_load_crypto_strings(); 874 # endif 875 # ifdef USE_GOST 876 (void)sldns_key_EVP_load_gost_id(); 877 # endif 878 # ifdef USE_ECDSA_EVP_WORKAROUND 879 ecdsa_evp_workaround_init(); 880 # endif 881 #elif defined(HAVE_NSS) 882 if(NSS_NoDB_Init(".") != SECSuccess) 883 fatal_exit("could not init NSS"); 884 #endif /* HAVE_SSL or HAVE_NSS*/ 885 checklock_start(); 886 authzone_test(); 887 neg_test(); 888 rnd_test(); 889 respip_test(); 890 verify_test(); 891 net_test(); 892 config_memsize_test(); 893 config_tag_test(); 894 dname_test(); 895 rtt_test(); 896 anchors_test(); 897 alloc_test(); 898 regional_test(); 899 lruhash_test(); 900 slabhash_test(); 901 infra_test(); 902 ldns_test(); 903 msgparse_test(); 904 #ifdef CLIENT_SUBNET 905 ecs_test(); 906 #endif /* CLIENT_SUBNET */ 907 if(log_get_lock()) { 908 lock_basic_destroy((lock_basic_type*)log_get_lock()); 909 } 910 checklock_stop(); 911 printf("%d checks ok.\n", testcount); 912 #ifdef HAVE_SSL 913 # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST) 914 sldns_key_EVP_unload_gost(); 915 # endif 916 # ifdef HAVE_OPENSSL_CONFIG 917 # ifdef HAVE_EVP_CLEANUP 918 EVP_cleanup(); 919 # endif 920 ENGINE_cleanup(); 921 CONF_modules_free(); 922 # endif 923 # ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 924 CRYPTO_cleanup_all_ex_data(); 925 # endif 926 # ifdef HAVE_ERR_FREE_STRINGS 927 ERR_free_strings(); 928 # endif 929 # ifdef HAVE_RAND_CLEANUP 930 RAND_cleanup(); 931 # endif 932 #elif defined(HAVE_NSS) 933 if(NSS_Shutdown() != SECSuccess) 934 fatal_exit("could not shutdown NSS"); 935 #endif /* HAVE_SSL or HAVE_NSS */ 936 #ifdef HAVE_PTHREAD 937 /* dlopen frees its thread specific state */ 938 pthread_exit(NULL); 939 #endif 940 return 0; 941 } 942