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 unsigned int seed = (unsigned)time(NULL); 542 unit_show_feature("ub_random"); 543 printf("ub_random seed is %u\n", seed); 544 unit_assert( (r = ub_initstate(seed, NULL)) ); 545 for(i=0; i<num; i++) { 546 a[i] = ub_random(r); 547 unit_assert(a[i] >= 0); 548 unit_assert((size_t)a[i] <= (size_t)0x7fffffff); 549 if(i > 5) 550 unit_assert(a[i] != a[i-1] || a[i] != a[i-2] || 551 a[i] != a[i-3] || a[i] != a[i-4] || 552 a[i] != a[i-5] || a[i] != a[i-6]); 553 } 554 a[0] = ub_random_max(r, 1); 555 unit_assert(a[0] >= 0 && a[0] < 1); 556 a[0] = ub_random_max(r, 10000); 557 unit_assert(a[0] >= 0 && a[0] < 10000); 558 for(i=0; i<num; i++) { 559 a[i] = ub_random_max(r, 10); 560 unit_assert(a[i] >= 0 && a[i] < 10); 561 } 562 ub_randfree(r); 563 } 564 565 #include "respip/respip.h" 566 #include "services/localzone.h" 567 #include "util/data/packed_rrset.h" 568 typedef struct addr_action {char* ip; char* sact; enum respip_action act;} 569 addr_action_t; 570 571 /** Utility function that verifies that the respip set has actions as expected */ 572 static void 573 verify_respip_set_actions(struct respip_set* set, addr_action_t actions[], 574 int actions_len) 575 { 576 int i = 0; 577 struct rbtree_type* tree = respip_set_get_tree(set); 578 for (i=0; i<actions_len; i++) { 579 struct sockaddr_storage addr; 580 int net; 581 socklen_t addrlen; 582 struct resp_addr* node; 583 netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr, 584 &addrlen, &net); 585 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 586 587 /** we have the node and the node has the correct action 588 * and has no data */ 589 unit_assert(node); 590 unit_assert(actions[i].act == 591 resp_addr_get_action(node)); 592 unit_assert(resp_addr_get_rrset(node) == NULL); 593 } 594 unit_assert(actions_len && i == actions_len); 595 unit_assert(actions_len == (int)tree->count); 596 } 597 598 /** Global respip actions test; apply raw config data and verify that 599 * all the nodes in the respip set, looked up by address, have expected 600 * actions */ 601 static void 602 respip_conf_actions_test(void) 603 { 604 addr_action_t config_response_ip[] = { 605 {"192.0.1.0/24", "deny", respip_deny}, 606 {"192.0.2.0/24", "redirect", respip_redirect}, 607 {"192.0.3.0/26", "inform", respip_inform}, 608 {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 609 {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 610 {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 611 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 612 }; 613 int i; 614 struct respip_set* set = respip_set_create(); 615 struct config_file cfg; 616 int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t)); 617 618 unit_assert(set); 619 unit_show_feature("global respip config actions apply"); 620 memset(&cfg, 0, sizeof(cfg)); 621 for(i=0; i<clen; i++) { 622 char* ip = strdup(config_response_ip[i].ip); 623 char* sact = strdup(config_response_ip[i].sact); 624 unit_assert(ip && sact); 625 if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact)) 626 unit_assert(0); 627 } 628 unit_assert(respip_global_apply_cfg(set, &cfg)); 629 verify_respip_set_actions(set, config_response_ip, clen); 630 631 respip_set_delete(set); 632 config_deldblstrlist(cfg.respip_actions); 633 } 634 635 /** Per-view respip actions test; apply raw configuration with two views 636 * and verify that actions are as expected in respip sets of both views */ 637 static void 638 respip_view_conf_actions_test(void) 639 { 640 addr_action_t config_response_ip_view1[] = { 641 {"192.0.1.0/24", "deny", respip_deny}, 642 {"192.0.2.0/24", "redirect", respip_redirect}, 643 {"192.0.3.0/26", "inform", respip_inform}, 644 {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 645 }; 646 addr_action_t config_response_ip_view2[] = { 647 {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 648 {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 649 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 650 }; 651 int i; 652 struct config_file cfg; 653 int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t)); 654 int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t)); 655 struct config_view* cv1; 656 struct config_view* cv2; 657 int have_respip_cfg = 0; 658 struct views* views = NULL; 659 struct view* v = NULL; 660 661 unit_show_feature("per-view respip config actions apply"); 662 memset(&cfg, 0, sizeof(cfg)); 663 cv1 = (struct config_view*)calloc(1, sizeof(struct config_view)); 664 cv2 = (struct config_view*)calloc(1, sizeof(struct config_view)); 665 unit_assert(cv1 && cv2); 666 cv1->name = strdup("view1"); 667 cv2->name = strdup("view2"); 668 unit_assert(cv1->name && cv2->name); 669 cv1->next = cv2; 670 cfg.views = cv1; 671 672 for(i=0; i<clen1; i++) { 673 char* ip = strdup(config_response_ip_view1[i].ip); 674 char* sact = strdup(config_response_ip_view1[i].sact); 675 unit_assert(ip && sact); 676 if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact)) 677 unit_assert(0); 678 } 679 for(i=0; i<clen2; i++) { 680 char* ip = strdup(config_response_ip_view2[i].ip); 681 char* sact = strdup(config_response_ip_view2[i].sact); 682 unit_assert(ip && sact); 683 if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact)) 684 unit_assert(0); 685 } 686 views = views_create(); 687 unit_assert(views); 688 unit_assert(views_apply_cfg(views, &cfg)); 689 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 690 691 /* now verify the respip sets in each view */ 692 v = views_find_view(views, "view1", 0); 693 unit_assert(v); 694 verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1); 695 lock_rw_unlock(&v->lock); 696 v = views_find_view(views, "view2", 0); 697 unit_assert(v); 698 verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2); 699 lock_rw_unlock(&v->lock); 700 701 views_delete(views); 702 free(cv1->name); 703 free(cv1); 704 free(cv2->name); 705 free(cv2); 706 } 707 708 typedef struct addr_data {char* ip; char* data;} addr_data_t; 709 710 /** find the respip address node in the specified tree (by address lookup) 711 * and verify type and address of the specified rdata (by index) in this 712 * node's rrset */ 713 static void 714 verify_rrset(struct respip_set* set, const char* ipstr, 715 const char* rdatastr, size_t rdi, uint16_t type) 716 { 717 struct sockaddr_storage addr; 718 int net; 719 char buf[65536]; 720 socklen_t addrlen; 721 struct rbtree_type* tree; 722 struct resp_addr* node; 723 const struct ub_packed_rrset_key* rrs; 724 725 netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net); 726 tree = respip_set_get_tree(set); 727 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 728 unit_assert(node); 729 unit_assert((rrs = resp_addr_get_rrset(node))); 730 unit_assert(ntohs(rrs->rk.type) == type); 731 packed_rr_to_string((struct ub_packed_rrset_key*)rrs, 732 rdi, 0, buf, sizeof(buf)); 733 unit_assert(strstr(buf, rdatastr)); 734 } 735 736 /** Dataset used to test redirect rrset initialization for both 737 * global and per-view respip redirect configuration */ 738 static addr_data_t config_response_ip_data[] = { 739 {"192.0.1.0/24", "A 1.2.3.4"}, 740 {"192.0.1.0/24", "A 11.12.13.14"}, 741 {"192.0.2.0/24", "CNAME www.example.com."}, 742 {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"}, 743 }; 744 745 /** Populate raw respip redirect config data, used for both global and 746 * view-based respip redirect test case */ 747 static void 748 cfg_insert_respip_data(struct config_str2list** respip_actions, 749 struct config_str2list** respip_data) 750 { 751 int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t)); 752 int i = 0; 753 754 /* insert actions (duplicate netblocks don't matter) */ 755 for(i=0; i<clen; i++) { 756 char* ip = strdup(config_response_ip_data[i].ip); 757 char* sact = strdup("redirect"); 758 unit_assert(ip && sact); 759 if(!cfg_str2list_insert(respip_actions, ip, sact)) 760 unit_assert(0); 761 } 762 /* insert data */ 763 for(i=0; i<clen; i++) { 764 char* ip = strdup(config_response_ip_data[i].ip); 765 char* data = strdup(config_response_ip_data[i].data); 766 unit_assert(ip && data); 767 if(!cfg_str2list_insert(respip_data, ip, data)) 768 unit_assert(0); 769 } 770 } 771 772 /** Test global respip redirect w/ data directives */ 773 static void 774 respip_conf_data_test(void) 775 { 776 struct respip_set* set = respip_set_create(); 777 struct config_file cfg; 778 779 unit_show_feature("global respip config data apply"); 780 memset(&cfg, 0, sizeof(cfg)); 781 782 cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data); 783 784 /* apply configuration and verify rrsets */ 785 unit_assert(respip_global_apply_cfg(set, &cfg)); 786 verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A); 787 verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A); 788 verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME); 789 verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA); 790 791 respip_set_delete(set); 792 } 793 794 /** Test per-view respip redirect w/ data directives */ 795 static void 796 respip_view_conf_data_test(void) 797 { 798 struct config_file cfg; 799 struct config_view* cv; 800 int have_respip_cfg = 0; 801 struct views* views = NULL; 802 struct view* v = NULL; 803 804 unit_show_feature("per-view respip config data apply"); 805 memset(&cfg, 0, sizeof(cfg)); 806 cv = (struct config_view*)calloc(1, sizeof(struct config_view)); 807 unit_assert(cv); 808 cv->name = strdup("view1"); 809 unit_assert(cv->name); 810 cfg.views = cv; 811 cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data); 812 views = views_create(); 813 unit_assert(views); 814 unit_assert(views_apply_cfg(views, &cfg)); 815 816 /* apply configuration and verify rrsets */ 817 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 818 v = views_find_view(views, "view1", 0); 819 unit_assert(v); 820 verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4", 821 0, LDNS_RR_TYPE_A); 822 verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14", 823 1, LDNS_RR_TYPE_A); 824 verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com", 825 0, LDNS_RR_TYPE_CNAME); 826 verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1", 827 0, LDNS_RR_TYPE_AAAA); 828 lock_rw_unlock(&v->lock); 829 830 views_delete(views); 831 free(cv->name); 832 free(cv); 833 } 834 835 /** respip unit tests */ 836 static void respip_test(void) 837 { 838 respip_view_conf_data_test(); 839 respip_conf_data_test(); 840 respip_view_conf_actions_test(); 841 respip_conf_actions_test(); 842 } 843 844 void unit_show_func(const char* file, const char* func) 845 { 846 printf("test %s:%s\n", file, func); 847 } 848 849 void unit_show_feature(const char* feature) 850 { 851 printf("test %s functions\n", feature); 852 } 853 854 #ifdef USE_ECDSA_EVP_WORKAROUND 855 void ecdsa_evp_workaround_init(void); 856 #endif 857 /** 858 * Main unit test program. Setup, teardown and report errors. 859 * @param argc: arg count. 860 * @param argv: array of commandline arguments. 861 * @return program failure if test fails. 862 */ 863 int 864 main(int argc, char* argv[]) 865 { 866 log_init(NULL, 0, NULL); 867 if(argc != 1) { 868 printf("usage: %s\n", argv[0]); 869 printf("\tperforms unit tests.\n"); 870 return 1; 871 } 872 printf("Start of %s unit test.\n", PACKAGE_STRING); 873 #ifdef HAVE_SSL 874 # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS 875 ERR_load_crypto_strings(); 876 # endif 877 # ifdef USE_GOST 878 (void)sldns_key_EVP_load_gost_id(); 879 # endif 880 # ifdef USE_ECDSA_EVP_WORKAROUND 881 ecdsa_evp_workaround_init(); 882 # endif 883 #elif defined(HAVE_NSS) 884 if(NSS_NoDB_Init(".") != SECSuccess) 885 fatal_exit("could not init NSS"); 886 #endif /* HAVE_SSL or HAVE_NSS*/ 887 checklock_start(); 888 authzone_test(); 889 neg_test(); 890 rnd_test(); 891 respip_test(); 892 verify_test(); 893 net_test(); 894 config_memsize_test(); 895 config_tag_test(); 896 dname_test(); 897 rtt_test(); 898 anchors_test(); 899 alloc_test(); 900 regional_test(); 901 lruhash_test(); 902 slabhash_test(); 903 infra_test(); 904 ldns_test(); 905 msgparse_test(); 906 #ifdef CLIENT_SUBNET 907 ecs_test(); 908 #endif /* CLIENT_SUBNET */ 909 if(log_get_lock()) { 910 lock_quick_destroy((lock_quick_type*)log_get_lock()); 911 } 912 checklock_stop(); 913 printf("%d checks ok.\n", testcount); 914 #ifdef HAVE_SSL 915 # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST) 916 sldns_key_EVP_unload_gost(); 917 # endif 918 # ifdef HAVE_OPENSSL_CONFIG 919 # ifdef HAVE_EVP_CLEANUP 920 EVP_cleanup(); 921 # endif 922 ENGINE_cleanup(); 923 CONF_modules_free(); 924 # endif 925 # ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 926 CRYPTO_cleanup_all_ex_data(); 927 # endif 928 # ifdef HAVE_ERR_FREE_STRINGS 929 ERR_free_strings(); 930 # endif 931 # ifdef HAVE_RAND_CLEANUP 932 RAND_cleanup(); 933 # endif 934 #elif defined(HAVE_NSS) 935 if(NSS_Shutdown() != SECSuccess) 936 fatal_exit("could not shutdown NSS"); 937 #endif /* HAVE_SSL or HAVE_NSS */ 938 #ifdef HAVE_PTHREAD 939 /* dlopen frees its thread specific state */ 940 pthread_exit(NULL); 941 #endif 942 return 0; 943 } 944