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 "util/edns.h" 437 /* Complete version-invalid client cookie; needs a new one. 438 * Based on edns_cookie_rfc9018_a2 */ 439 static void 440 edns_cookie_invalid_version(void) 441 { 442 uint32_t timestamp = 1559734385; 443 uint8_t client_cookie[] = { 444 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 445 0x99, 0x00, 0x00, 0x00, 446 0x5c, 0xf7, 0x9f, 0x11, 447 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 }; 448 uint8_t server_cookie[] = { 449 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 450 0x01, 0x00, 0x00, 0x00, 451 0x5c, 0xf7, 0xa8, 0x71, 452 0xd4, 0xa5, 0x64, 0xa1, 0x44, 0x2a, 0xca, 0x77 }; 453 uint8_t server_secret[] = { 454 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 455 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 456 uint8_t buf[32]; 457 /* copy client cookie|version|reserved|timestamp */ 458 memcpy(buf, client_cookie, 8 + 4 + 4); 459 /* copy ip 198.51.100.100 */ 460 memcpy(buf + 16, "\306\063\144\144", 4); 461 unit_assert(edns_cookie_server_validate(client_cookie, 462 sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 463 buf, timestamp) == COOKIE_STATUS_INVALID); 464 edns_cookie_server_write(buf, server_secret, 1, timestamp); 465 unit_assert(memcmp(server_cookie, buf, 24) == 0); 466 } 467 468 /* Complete hash-invalid client cookie; needs a new one. */ 469 static void 470 edns_cookie_invalid_hash(void) 471 { 472 uint32_t timestamp = 0; 473 uint8_t client_cookie[] = { 474 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 475 0x01, 0x00, 0x00, 0x00, 476 0x00, 0x00, 0x00, 0x00, 477 0x32, 0xF2, 0x43, 0xB9, 0xBC, 0xFE, 0xC4, 0x06 }; 478 uint8_t server_cookie[] = { 479 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 480 0x01, 0x00, 0x00, 0x00, 481 0x00, 0x00, 0x00, 0x00, 482 0xBA, 0x0D, 0x82, 0x90, 0x8F, 0xAA, 0xEB, 0xBD }; 483 uint8_t server_secret[] = { 484 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 485 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 486 uint8_t buf[32]; 487 /* copy client cookie|version|reserved|timestamp */ 488 memcpy(buf, client_cookie, 8 + 4 + 4); 489 /* copy ip 203.0.113.203 */ 490 memcpy(buf + 16, "\313\000\161\313", 4); 491 unit_assert(edns_cookie_server_validate(client_cookie, 492 sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 493 buf, timestamp) == COOKIE_STATUS_INVALID); 494 edns_cookie_server_write(buf, server_secret, 1, timestamp); 495 unit_assert(memcmp(server_cookie, buf, 24) == 0); 496 } 497 498 /* Complete hash-valid client cookie; more than 30 minutes old; needs a 499 * refreshed server cookie. 500 * A slightly better variation of edns_cookie_rfc9018_a3 for Unbound to check 501 * that RESERVED bits do not influence cookie validation. */ 502 static void 503 edns_cookie_rfc9018_a3_better(void) 504 { 505 uint32_t timestamp = 1800 + 1; 506 uint8_t client_cookie[] = { 507 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 508 0x01, 0xab, 0xcd, 0xef, 509 0x00, 0x00, 0x00, 0x00, 510 0x32, 0xF2, 0x43, 0xB9, 0xBC, 0xFE, 0xC4, 0x06 }; 511 uint8_t server_cookie[] = { 512 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 513 0x01, 0x00, 0x00, 0x00, 514 0x00, 0x00, 0x07, 0x09, 515 0x62, 0xD5, 0x93, 0x09, 0x14, 0x5C, 0x23, 0x9D }; 516 uint8_t server_secret[] = { 517 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 518 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 519 uint8_t buf[32]; 520 /* copy client cookie|version|reserved|timestamp */ 521 memcpy(buf, client_cookie, 8 + 4 + 4); 522 /* copy ip 203.0.113.203 */ 523 memcpy(buf + 16, "\313\000\161\313", 4); 524 unit_assert(edns_cookie_server_validate(client_cookie, 525 sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 526 buf, timestamp) == COOKIE_STATUS_VALID_RENEW); 527 edns_cookie_server_write(buf, server_secret, 1, timestamp); 528 unit_assert(memcmp(server_cookie, buf, 24) == 0); 529 } 530 531 /* Complete hash-valid client cookie; more than 60 minutes old (expired); 532 * needs a refreshed server cookie. */ 533 static void 534 edns_cookie_rfc9018_a3(void) 535 { 536 uint32_t timestamp = 1559734700; 537 uint8_t client_cookie[] = { 538 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 539 0x01, 0xab, 0xcd, 0xef, 540 0x5c, 0xf7, 0x8f, 0x71, 541 0xa3, 0x14, 0x22, 0x7b, 0x66, 0x79, 0xeb, 0xf5 }; 542 uint8_t server_cookie[] = { 543 0xfc, 0x93, 0xfc, 0x62, 0x80, 0x7d, 0xdb, 0x86, 544 0x01, 0x00, 0x00, 0x00, 545 0x5c, 0xf7, 0xa9, 0xac, 546 0xf7, 0x3a, 0x78, 0x10, 0xac, 0xa2, 0x38, 0x1e }; 547 uint8_t server_secret[] = { 548 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 549 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 550 uint8_t buf[32]; 551 /* copy client cookie|version|reserved|timestamp */ 552 memcpy(buf, client_cookie, 8 + 4 + 4); 553 /* copy ip 203.0.113.203 */ 554 memcpy(buf + 16, "\313\000\161\313", 4); 555 unit_assert(edns_cookie_server_validate(client_cookie, 556 sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 557 buf, timestamp) == COOKIE_STATUS_EXPIRED); 558 edns_cookie_server_write(buf, server_secret, 1, timestamp); 559 unit_assert(memcmp(server_cookie, buf, 24) == 0); 560 } 561 562 /* Complete hash-valid client cookie; more than 30 minutes old; needs a 563 * refreshed server cookie. */ 564 static void 565 edns_cookie_rfc9018_a2(void) 566 { 567 uint32_t timestamp = 1559734385; 568 uint8_t client_cookie[] = { 569 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 570 0x01, 0x00, 0x00, 0x00, 571 0x5c, 0xf7, 0x9f, 0x11, 572 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 }; 573 uint8_t server_cookie[] = { 574 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 575 0x01, 0x00, 0x00, 0x00, 576 0x5c, 0xf7, 0xa8, 0x71, 577 0xd4, 0xa5, 0x64, 0xa1, 0x44, 0x2a, 0xca, 0x77 }; 578 uint8_t server_secret[] = { 579 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 580 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 581 uint8_t buf[32]; 582 /* copy client cookie|version|reserved|timestamp */ 583 memcpy(buf, client_cookie, 8 + 4 + 4); 584 /* copy ip 198.51.100.100 */ 585 memcpy(buf + 16, "\306\063\144\144", 4); 586 unit_assert(edns_cookie_server_validate(client_cookie, 587 sizeof(client_cookie), server_secret, sizeof(server_secret), 1, 588 buf, timestamp) == COOKIE_STATUS_VALID_RENEW); 589 edns_cookie_server_write(buf, server_secret, 1, timestamp); 590 unit_assert(memcmp(server_cookie, buf, 24) == 0); 591 } 592 593 /* Only client cookie; needs a complete server cookie. */ 594 static void 595 edns_cookie_rfc9018_a1(void) 596 { 597 uint32_t timestamp = 1559731985; 598 uint8_t client_cookie[] = { 599 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57 }; 600 uint8_t server_cookie[] = { 601 0x24, 0x64, 0xc4, 0xab, 0xcf, 0x10, 0xc9, 0x57, 602 0x01, 0x00, 0x00, 0x00, 603 0x5c, 0xf7, 0x9f, 0x11, 604 0x1f, 0x81, 0x30, 0xc3, 0xee, 0xe2, 0x94, 0x80 }; 605 uint8_t server_secret[] = { 606 0xe5, 0xe9, 0x73, 0xe5, 0xa6, 0xb2, 0xa4, 0x3f, 607 0x48, 0xe7, 0xdc, 0x84, 0x9e, 0x37, 0xbf, 0xcf }; 608 uint8_t buf[32]; 609 /* copy client cookie|version|reserved|timestamp */ 610 memcpy(buf, server_cookie, 8 + 4 + 4); 611 /* copy ip 198.51.100.100 */ 612 memcpy(buf + 16, "\306\063\144\144", 4); 613 unit_assert(edns_cookie_server_validate(client_cookie, 614 sizeof(client_cookie), 615 /* these will not be used; it will return invalid 616 * because of the size. */ 617 NULL, 0, 1, NULL, 0) == COOKIE_STATUS_CLIENT_ONLY); 618 edns_cookie_server_write(buf, server_secret, 1, timestamp); 619 unit_assert(memcmp(server_cookie, buf, 24) == 0); 620 } 621 622 /** test interoperable DNS cookies (RFC9018) */ 623 static void 624 edns_cookie_test(void) 625 { 626 unit_show_feature("interoperable dns cookies"); 627 /* Check RFC9018 appendix test vectors */ 628 edns_cookie_rfc9018_a1(); 629 edns_cookie_rfc9018_a2(); 630 edns_cookie_rfc9018_a3(); 631 /* More tests */ 632 edns_cookie_rfc9018_a3_better(); 633 edns_cookie_invalid_hash(); 634 edns_cookie_invalid_version(); 635 } 636 637 #include "util/random.h" 638 /** test randomness */ 639 static void 640 rnd_test(void) 641 { 642 struct ub_randstate* r; 643 int num = 1000, i; 644 long int a[1000]; 645 unit_show_feature("ub_random"); 646 unit_assert( (r = ub_initstate(NULL)) ); 647 for(i=0; i<num; i++) { 648 a[i] = ub_random(r); 649 unit_assert(a[i] >= 0); 650 unit_assert((size_t)a[i] <= (size_t)0x7fffffff); 651 if(i > 5) 652 unit_assert(a[i] != a[i-1] || a[i] != a[i-2] || 653 a[i] != a[i-3] || a[i] != a[i-4] || 654 a[i] != a[i-5] || a[i] != a[i-6]); 655 } 656 a[0] = ub_random_max(r, 1); 657 unit_assert(a[0] >= 0 && a[0] < 1); 658 a[0] = ub_random_max(r, 10000); 659 unit_assert(a[0] >= 0 && a[0] < 10000); 660 for(i=0; i<num; i++) { 661 a[i] = ub_random_max(r, 10); 662 unit_assert(a[i] >= 0 && a[i] < 10); 663 } 664 ub_randfree(r); 665 } 666 667 #include "respip/respip.h" 668 #include "services/localzone.h" 669 #include "util/data/packed_rrset.h" 670 typedef struct addr_action {char* ip; char* sact; enum respip_action act;} 671 addr_action_t; 672 673 /** Utility function that verifies that the respip set has actions as expected */ 674 static void 675 verify_respip_set_actions(struct respip_set* set, addr_action_t actions[], 676 int actions_len) 677 { 678 int i = 0; 679 struct rbtree_type* tree = respip_set_get_tree(set); 680 for (i=0; i<actions_len; i++) { 681 struct sockaddr_storage addr; 682 int net; 683 socklen_t addrlen; 684 struct resp_addr* node; 685 netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr, 686 &addrlen, &net); 687 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 688 689 /** we have the node and the node has the correct action 690 * and has no data */ 691 unit_assert(node); 692 unit_assert(actions[i].act == 693 resp_addr_get_action(node)); 694 unit_assert(resp_addr_get_rrset(node) == NULL); 695 } 696 unit_assert(actions_len && i == actions_len); 697 unit_assert(actions_len == (int)tree->count); 698 } 699 700 /** Global respip actions test; apply raw config data and verify that 701 * all the nodes in the respip set, looked up by address, have expected 702 * actions */ 703 static void 704 respip_conf_actions_test(void) 705 { 706 addr_action_t config_response_ip[] = { 707 {"192.0.1.0/24", "deny", respip_deny}, 708 {"192.0.2.0/24", "redirect", respip_redirect}, 709 {"192.0.3.0/26", "inform", respip_inform}, 710 {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 711 {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 712 {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 713 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 714 }; 715 int i; 716 struct respip_set* set = respip_set_create(); 717 struct config_file cfg; 718 int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t)); 719 720 unit_assert(set); 721 unit_show_feature("global respip config actions apply"); 722 memset(&cfg, 0, sizeof(cfg)); 723 for(i=0; i<clen; i++) { 724 char* ip = strdup(config_response_ip[i].ip); 725 char* sact = strdup(config_response_ip[i].sact); 726 unit_assert(ip && sact); 727 if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact)) 728 unit_assert(0); 729 } 730 unit_assert(respip_global_apply_cfg(set, &cfg)); 731 verify_respip_set_actions(set, config_response_ip, clen); 732 733 respip_set_delete(set); 734 config_deldblstrlist(cfg.respip_actions); 735 } 736 737 /** Per-view respip actions test; apply raw configuration with two views 738 * and verify that actions are as expected in respip sets of both views */ 739 static void 740 respip_view_conf_actions_test(void) 741 { 742 addr_action_t config_response_ip_view1[] = { 743 {"192.0.1.0/24", "deny", respip_deny}, 744 {"192.0.2.0/24", "redirect", respip_redirect}, 745 {"192.0.3.0/26", "inform", respip_inform}, 746 {"192.0.4.0/27", "inform_deny", respip_inform_deny}, 747 }; 748 addr_action_t config_response_ip_view2[] = { 749 {"2001:db8:1::/48", "always_transparent", respip_always_transparent}, 750 {"2001:db8:2::/49", "always_refuse", respip_always_refuse}, 751 {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain}, 752 }; 753 int i; 754 struct config_file cfg; 755 int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t)); 756 int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t)); 757 struct config_view* cv1; 758 struct config_view* cv2; 759 int have_respip_cfg = 0; 760 struct views* views = NULL; 761 struct view* v = NULL; 762 763 unit_show_feature("per-view respip config actions apply"); 764 memset(&cfg, 0, sizeof(cfg)); 765 cv1 = (struct config_view*)calloc(1, sizeof(struct config_view)); 766 cv2 = (struct config_view*)calloc(1, sizeof(struct config_view)); 767 unit_assert(cv1 && cv2); 768 cv1->name = strdup("view1"); 769 cv2->name = strdup("view2"); 770 unit_assert(cv1->name && cv2->name); 771 cv1->next = cv2; 772 cfg.views = cv1; 773 774 for(i=0; i<clen1; i++) { 775 char* ip = strdup(config_response_ip_view1[i].ip); 776 char* sact = strdup(config_response_ip_view1[i].sact); 777 unit_assert(ip && sact); 778 if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact)) 779 unit_assert(0); 780 } 781 for(i=0; i<clen2; i++) { 782 char* ip = strdup(config_response_ip_view2[i].ip); 783 char* sact = strdup(config_response_ip_view2[i].sact); 784 unit_assert(ip && sact); 785 if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact)) 786 unit_assert(0); 787 } 788 views = views_create(); 789 unit_assert(views); 790 unit_assert(views_apply_cfg(views, &cfg)); 791 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 792 793 /* now verify the respip sets in each view */ 794 v = views_find_view(views, "view1", 0); 795 unit_assert(v); 796 verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1); 797 lock_rw_unlock(&v->lock); 798 v = views_find_view(views, "view2", 0); 799 unit_assert(v); 800 verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2); 801 lock_rw_unlock(&v->lock); 802 803 views_delete(views); 804 free(cv1->name); 805 free(cv1); 806 free(cv2->name); 807 free(cv2); 808 } 809 810 typedef struct addr_data {char* ip; char* data;} addr_data_t; 811 812 /** find the respip address node in the specified tree (by address lookup) 813 * and verify type and address of the specified rdata (by index) in this 814 * node's rrset */ 815 static void 816 verify_rrset(struct respip_set* set, const char* ipstr, 817 const char* rdatastr, size_t rdi, uint16_t type) 818 { 819 struct sockaddr_storage addr; 820 int net; 821 char buf[65536]; 822 socklen_t addrlen; 823 struct rbtree_type* tree; 824 struct resp_addr* node; 825 const struct ub_packed_rrset_key* rrs; 826 827 netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net); 828 tree = respip_set_get_tree(set); 829 node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net); 830 unit_assert(node); 831 unit_assert((rrs = resp_addr_get_rrset(node))); 832 unit_assert(ntohs(rrs->rk.type) == type); 833 packed_rr_to_string((struct ub_packed_rrset_key*)rrs, 834 rdi, 0, buf, sizeof(buf)); 835 unit_assert(strstr(buf, rdatastr)); 836 } 837 838 /** Dataset used to test redirect rrset initialization for both 839 * global and per-view respip redirect configuration */ 840 static addr_data_t config_response_ip_data[] = { 841 {"192.0.1.0/24", "A 1.2.3.4"}, 842 {"192.0.1.0/24", "A 11.12.13.14"}, 843 {"192.0.2.0/24", "CNAME www.example.com."}, 844 {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"}, 845 }; 846 847 /** Populate raw respip redirect config data, used for both global and 848 * view-based respip redirect test case */ 849 static void 850 cfg_insert_respip_data(struct config_str2list** respip_actions, 851 struct config_str2list** respip_data) 852 { 853 int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t)); 854 int i = 0; 855 856 /* insert actions (duplicate netblocks don't matter) */ 857 for(i=0; i<clen; i++) { 858 char* ip = strdup(config_response_ip_data[i].ip); 859 char* sact = strdup("redirect"); 860 unit_assert(ip && sact); 861 if(!cfg_str2list_insert(respip_actions, ip, sact)) 862 unit_assert(0); 863 } 864 /* insert data */ 865 for(i=0; i<clen; i++) { 866 char* ip = strdup(config_response_ip_data[i].ip); 867 char* data = strdup(config_response_ip_data[i].data); 868 unit_assert(ip && data); 869 if(!cfg_str2list_insert(respip_data, ip, data)) 870 unit_assert(0); 871 } 872 } 873 874 /** Test global respip redirect w/ data directives */ 875 static void 876 respip_conf_data_test(void) 877 { 878 struct respip_set* set = respip_set_create(); 879 struct config_file cfg; 880 881 unit_show_feature("global respip config data apply"); 882 memset(&cfg, 0, sizeof(cfg)); 883 884 cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data); 885 886 /* apply configuration and verify rrsets */ 887 unit_assert(respip_global_apply_cfg(set, &cfg)); 888 verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A); 889 verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A); 890 verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME); 891 verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA); 892 893 respip_set_delete(set); 894 } 895 896 /** Test per-view respip redirect w/ data directives */ 897 static void 898 respip_view_conf_data_test(void) 899 { 900 struct config_file cfg; 901 struct config_view* cv; 902 int have_respip_cfg = 0; 903 struct views* views = NULL; 904 struct view* v = NULL; 905 906 unit_show_feature("per-view respip config data apply"); 907 memset(&cfg, 0, sizeof(cfg)); 908 cv = (struct config_view*)calloc(1, sizeof(struct config_view)); 909 unit_assert(cv); 910 cv->name = strdup("view1"); 911 unit_assert(cv->name); 912 cfg.views = cv; 913 cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data); 914 views = views_create(); 915 unit_assert(views); 916 unit_assert(views_apply_cfg(views, &cfg)); 917 918 /* apply configuration and verify rrsets */ 919 unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg)); 920 v = views_find_view(views, "view1", 0); 921 unit_assert(v); 922 verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4", 923 0, LDNS_RR_TYPE_A); 924 verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14", 925 1, LDNS_RR_TYPE_A); 926 verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com", 927 0, LDNS_RR_TYPE_CNAME); 928 verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1", 929 0, LDNS_RR_TYPE_AAAA); 930 lock_rw_unlock(&v->lock); 931 932 views_delete(views); 933 free(cv->name); 934 free(cv); 935 } 936 937 /** respip unit tests */ 938 static void respip_test(void) 939 { 940 respip_view_conf_data_test(); 941 respip_conf_data_test(); 942 respip_view_conf_actions_test(); 943 respip_conf_actions_test(); 944 } 945 946 #include "util/regional.h" 947 #include "sldns/sbuffer.h" 948 #include "util/data/dname.h" 949 #include "util/data/msgreply.h" 950 #include "util/data/msgencode.h" 951 #include "sldns/str2wire.h" 952 953 static void edns_ede_encode_setup(struct edns_data* edns, 954 struct regional* region) 955 { 956 memset(edns, 0, sizeof(*edns)); 957 edns->edns_present = 1; 958 edns->edns_version = EDNS_ADVERTISED_VERSION; 959 edns->udp_size = EDNS_ADVERTISED_SIZE; 960 edns->bits &= EDNS_DO; 961 /* Fill up opt_list_out with EDEs */ 962 unit_assert( 963 edns_opt_list_append_ede(&edns->opt_list_out, region, 964 LDNS_EDE_OTHER, "Too long other text")); 965 unit_assert( 966 edns_opt_list_append_ede(&edns->opt_list_out, region, 967 LDNS_EDE_OTHER, "Too long other text")); 968 unit_assert( 969 edns_opt_list_append_ede(&edns->opt_list_out, region, 970 LDNS_EDE_BLOCKED, "Too long blocked text")); 971 unit_assert( 972 edns_opt_list_append_ede(&edns->opt_list_out, region, 973 LDNS_EDE_OTHER, "Too long other text")); 974 unit_assert( 975 edns_opt_list_append_ede(&edns->opt_list_out, region, 976 LDNS_EDE_BLOCKED, "Too long blocked text")); 977 /* Fill up opt_list_inplace_cb_out with EDEs */ 978 unit_assert( 979 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 980 LDNS_EDE_OTHER, "Too long other text")); 981 unit_assert( 982 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 983 LDNS_EDE_OTHER, "Too long other text")); 984 unit_assert( 985 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 986 LDNS_EDE_BLOCKED, "Too long blocked text")); 987 unit_assert( 988 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 989 LDNS_EDE_OTHER, "Too long other text")); 990 unit_assert( 991 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 992 LDNS_EDE_BLOCKED, "Too long blocked text")); 993 /* append another EDNS option to both lists */ 994 unit_assert( 995 edns_opt_list_append(&edns->opt_list_out, 996 LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region)); 997 unit_assert( 998 edns_opt_list_append(&edns->opt_list_inplace_cb_out, 999 LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region)); 1000 /* append LDNS_EDE_OTHER at the end of both lists */ 1001 unit_assert( 1002 edns_opt_list_append_ede(&edns->opt_list_out, region, 1003 LDNS_EDE_OTHER, "Too long other text")); 1004 unit_assert( 1005 edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region, 1006 LDNS_EDE_OTHER, "Too long other text")); 1007 } 1008 1009 static void edns_ede_encode_encodedecode(struct query_info* qinfo, 1010 struct reply_info* rep, struct regional* region, 1011 struct edns_data* edns, sldns_buffer* pkt) 1012 { 1013 /* encode */ 1014 unit_assert( 1015 reply_info_answer_encode(qinfo, rep, 1, rep->flags, pkt, 1016 0, 0, region, 65535, edns, 0, 0)); 1017 /* buffer ready for reading; skip after the question section */ 1018 sldns_buffer_skip(pkt, LDNS_HEADER_SIZE); 1019 (void)query_dname_len(pkt); 1020 sldns_buffer_skip(pkt, 2 + 2); 1021 /* decode */ 1022 unit_assert(parse_edns_from_query_pkt(pkt, edns, NULL, NULL, NULL, 0, 1023 region, NULL) == 0); 1024 } 1025 1026 static void edns_ede_encode_check(struct edns_data* edns, int* found_ede, 1027 int* found_ede_other, int* found_ede_txt, int* found_other_edns) 1028 { 1029 struct edns_option* opt; 1030 for(opt = edns->opt_list_in; opt; opt = opt->next) { 1031 if(opt->opt_code == LDNS_EDNS_EDE) { 1032 (*found_ede)++; 1033 if(opt->opt_len > 2) 1034 (*found_ede_txt)++; 1035 if(opt->opt_len >= 2 && sldns_read_uint16( 1036 opt->opt_data) == LDNS_EDE_OTHER) 1037 (*found_ede_other)++; 1038 } else { 1039 (*found_other_edns)++; 1040 } 1041 } 1042 1043 } 1044 1045 static void edns_ede_encode_fit_test(struct query_info* qinfo, 1046 struct reply_info* rep, struct regional* region) 1047 { 1048 struct edns_data edns; 1049 int found_ede = 0, found_ede_other = 0, found_ede_txt = 0; 1050 int found_other_edns = 0; 1051 sldns_buffer* pkt = sldns_buffer_new(65535); 1052 unit_assert(pkt); 1053 edns_ede_encode_setup(&edns, region); 1054 /* leave the pkt buffer as is; everything should fit */ 1055 edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt); 1056 edns_ede_encode_check(&edns, &found_ede, &found_ede_other, 1057 &found_ede_txt, &found_other_edns); 1058 unit_assert(found_ede == 12); 1059 unit_assert(found_ede_other == 8); 1060 unit_assert(found_ede_txt == 12); 1061 unit_assert(found_other_edns == 2); 1062 /* cleanup */ 1063 sldns_buffer_free(pkt); 1064 } 1065 1066 static void edns_ede_encode_notxt_fit_test( struct query_info* qinfo, 1067 struct reply_info* rep, struct regional* region) 1068 { 1069 struct edns_data edns; 1070 sldns_buffer* pkt; 1071 uint16_t edns_field_size, ede_txt_size; 1072 int found_ede = 0, found_ede_other = 0, found_ede_txt = 0; 1073 int found_other_edns = 0; 1074 edns_ede_encode_setup(&edns, region); 1075 /* pkt buffer should fit everything if the ede txt is cropped. 1076 * OTHER EDE should not be there since it is useless without text. */ 1077 edns_field_size = calc_edns_field_size(&edns); 1078 (void)calc_ede_option_size(&edns, &ede_txt_size); 1079 pkt = sldns_buffer_new(LDNS_HEADER_SIZE 1080 + qinfo->qname_len 1081 + 2 + 2 /* qtype + qclass */ 1082 + 11 /* opt record */ 1083 + edns_field_size 1084 - ede_txt_size); 1085 unit_assert(pkt); 1086 edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt); 1087 edns_ede_encode_check(&edns, &found_ede, &found_ede_other, 1088 &found_ede_txt, &found_other_edns); 1089 unit_assert(found_ede == 4); 1090 unit_assert(found_ede_other == 0); 1091 unit_assert(found_ede_txt == 0); 1092 unit_assert(found_other_edns == 2); 1093 /* cleanup */ 1094 sldns_buffer_free(pkt); 1095 } 1096 1097 static void edns_ede_encode_no_fit_test( struct query_info* qinfo, 1098 struct reply_info* rep, struct regional* region) 1099 { 1100 struct edns_data edns; 1101 sldns_buffer* pkt; 1102 uint16_t edns_field_size, ede_size, ede_txt_size; 1103 int found_ede = 0, found_ede_other = 0, found_ede_txt = 0; 1104 int found_other_edns = 0; 1105 edns_ede_encode_setup(&edns, region); 1106 /* pkt buffer should fit only non-EDE options. */ 1107 edns_field_size = calc_edns_field_size(&edns); 1108 ede_size = calc_ede_option_size(&edns, &ede_txt_size); 1109 pkt = sldns_buffer_new(LDNS_HEADER_SIZE 1110 + qinfo->qname_len 1111 + 2 + 2 /* qtype + qclass */ 1112 + 11 /* opt record */ 1113 + edns_field_size 1114 - ede_size); 1115 unit_assert(pkt); 1116 edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt); 1117 edns_ede_encode_check(&edns, &found_ede, &found_ede_other, 1118 &found_ede_txt, &found_other_edns); 1119 unit_assert(found_ede == 0); 1120 unit_assert(found_ede_other == 0); 1121 unit_assert(found_ede_txt == 0); 1122 unit_assert(found_other_edns == 2); 1123 /* cleanup */ 1124 sldns_buffer_free(pkt); 1125 } 1126 1127 /** test optional EDE encoding with various buffer 1128 * available sizes */ 1129 static void edns_ede_answer_encode_test(void) 1130 { 1131 struct regional* region = regional_create(); 1132 struct reply_info* rep; 1133 struct query_info qinfo; 1134 unit_show_feature("edns ede optional encoding"); 1135 unit_assert(region); 1136 rep = construct_reply_info_base(region, 1137 LDNS_RCODE_NOERROR | BIT_QR, 1, 1138 3600, 3600, 3600, 0, 1139 0, 0, 0, 0, 1140 sec_status_unchecked, LDNS_EDE_NONE); 1141 unit_assert(rep); 1142 memset(&qinfo, 0, sizeof(qinfo)); 1143 qinfo.qname = sldns_str2wire_dname("encode.ede.", &qinfo.qname_len); 1144 unit_assert(qinfo.qname); 1145 qinfo.qtype = LDNS_RR_TYPE_TXT; 1146 qinfo.qclass = LDNS_RR_CLASS_IN; 1147 1148 edns_ede_encode_fit_test(&qinfo, rep, region); 1149 edns_ede_encode_notxt_fit_test(&qinfo, rep, region); 1150 edns_ede_encode_no_fit_test(&qinfo, rep, region); 1151 1152 /* cleanup */ 1153 free(qinfo.qname); 1154 regional_free_all(region); 1155 regional_destroy(region); 1156 } 1157 1158 #include "services/localzone.h" 1159 /* Utility function that compares two localzone trees */ 1160 static void compare_localzone_trees(struct local_zones* z1, 1161 struct local_zones* z2) 1162 { 1163 struct local_zone *node1, *node2; 1164 lock_rw_rdlock(&z1->lock); 1165 lock_rw_rdlock(&z2->lock); 1166 /* size should be the same */ 1167 unit_assert(z1->ztree.count == z2->ztree.count); 1168 for(node1=(struct local_zone*)rbtree_first(&z1->ztree), 1169 node2=(struct local_zone*)rbtree_first(&z2->ztree); 1170 (rbnode_type*)node1 != RBTREE_NULL && 1171 (rbnode_type*)node2 != RBTREE_NULL; 1172 node1=(struct local_zone*)rbtree_next((rbnode_type*)node1), 1173 node2=(struct local_zone*)rbtree_next((rbnode_type*)node2)) { 1174 int labs; 1175 /* the same zone should be at the same nodes */ 1176 unit_assert(!dname_lab_cmp( 1177 node1->name, node1->namelabs, 1178 node2->name, node2->namelabs, 1179 &labs)); 1180 /* the zone's parent should be the same on both nodes */ 1181 unit_assert( 1182 (node1->parent == NULL && node2->parent == NULL) || 1183 (node1->parent != NULL && node2->parent != NULL)); 1184 if(node1->parent) { 1185 unit_assert(!dname_lab_cmp( 1186 node1->parent->name, node1->parent->namelabs, 1187 node2->parent->name, node2->parent->namelabs, 1188 &labs)); 1189 } 1190 } 1191 lock_rw_unlock(&z1->lock); 1192 lock_rw_unlock(&z2->lock); 1193 } 1194 1195 /* test that zone addition results in the same tree from both the configuration 1196 * file and the unbound-control commands */ 1197 static void localzone_parents_test(void) 1198 { 1199 struct local_zones *z1, *z2; 1200 size_t i; 1201 char* zone_data[] = { 1202 "one", 1203 "a.b.c.one", 1204 "b.c.one", 1205 "c.one", 1206 "two", 1207 "c.two", 1208 "b.c.two", 1209 "a.b.c.two", 1210 "a.b.c.three", 1211 "b.c.three", 1212 "c.three", 1213 "three", 1214 "c.four", 1215 "b.c.four", 1216 "a.b.c.four", 1217 "four", 1218 "." 1219 }; 1220 unit_show_feature("localzones parent calculation"); 1221 z1 = local_zones_create(); 1222 z2 = local_zones_create(); 1223 /* parse test data */ 1224 for(i=0; i<sizeof(zone_data)/sizeof(zone_data[0]); i++) { 1225 uint8_t* nm; 1226 int nmlabs; 1227 size_t nmlen; 1228 struct local_zone* z; 1229 1230 /* This is the config way */ 1231 z = lz_enter_zone(z1, zone_data[i], "always_nxdomain", 1232 LDNS_RR_CLASS_IN); 1233 (void)z; /* please compiler when no threading and no lock 1234 code; the following line disappears and z stays unused */ 1235 lock_rw_unlock(&z->lock); 1236 lz_init_parents(z1); 1237 1238 /* This is the unbound-control way */ 1239 nm = sldns_str2wire_dname(zone_data[i], &nmlen); 1240 if(!nm) unit_assert(0); 1241 nmlabs = dname_count_size_labels(nm, &nmlen); 1242 lock_rw_wrlock(&z2->lock); 1243 local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, 1244 local_zone_always_nxdomain); 1245 lock_rw_unlock(&z2->lock); 1246 } 1247 /* The trees should be the same, iterate and check the nodes */ 1248 compare_localzone_trees(z1, z2); 1249 1250 /* cleanup */ 1251 local_zones_delete(z1); 1252 local_zones_delete(z2); 1253 } 1254 1255 /** localzone unit tests */ 1256 static void localzone_test(void) 1257 { 1258 localzone_parents_test(); 1259 } 1260 1261 void unit_show_func(const char* file, const char* func) 1262 { 1263 printf("test %s:%s\n", file, func); 1264 } 1265 1266 void unit_show_feature(const char* feature) 1267 { 1268 printf("test %s functions\n", feature); 1269 } 1270 1271 #ifdef USE_ECDSA_EVP_WORKAROUND 1272 void ecdsa_evp_workaround_init(void); 1273 #endif 1274 1275 /** 1276 * Main unit test program. Setup, teardown and report errors. 1277 * @param argc: arg count. 1278 * @param argv: array of commandline arguments. 1279 * @return program failure if test fails. 1280 */ 1281 int 1282 main(int argc, char* argv[]) 1283 { 1284 checklock_start(); 1285 log_init(NULL, 0, NULL); 1286 if(argc != 1) { 1287 printf("usage: %s\n", argv[0]); 1288 printf("\tperforms unit tests.\n"); 1289 return 1; 1290 } 1291 /* Disable roundrobin for the unit tests */ 1292 RRSET_ROUNDROBIN = 0; 1293 #ifdef USE_LIBEVENT 1294 printf("Start of %s+libevent unit test.\n", PACKAGE_STRING); 1295 #else 1296 printf("Start of %s unit test.\n", PACKAGE_STRING); 1297 #endif 1298 #ifdef HAVE_SSL 1299 # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS 1300 ERR_load_crypto_strings(); 1301 # endif 1302 # ifdef USE_GOST 1303 (void)sldns_key_EVP_load_gost_id(); 1304 # endif 1305 # ifdef USE_ECDSA_EVP_WORKAROUND 1306 ecdsa_evp_workaround_init(); 1307 # endif 1308 #elif defined(HAVE_NSS) 1309 if(NSS_NoDB_Init(".") != SECSuccess) 1310 fatal_exit("could not init NSS"); 1311 #endif /* HAVE_SSL or HAVE_NSS*/ 1312 authzone_test(); 1313 neg_test(); 1314 rnd_test(); 1315 respip_test(); 1316 verify_test(); 1317 net_test(); 1318 config_memsize_test(); 1319 config_tag_test(); 1320 dname_test(); 1321 rtt_test(); 1322 anchors_test(); 1323 alloc_test(); 1324 regional_test(); 1325 lruhash_test(); 1326 slabhash_test(); 1327 infra_test(); 1328 ldns_test(); 1329 edns_cookie_test(); 1330 zonemd_test(); 1331 tcpreuse_test(); 1332 msgparse_test(); 1333 edns_ede_answer_encode_test(); 1334 localzone_test(); 1335 #ifdef CLIENT_SUBNET 1336 ecs_test(); 1337 #endif /* CLIENT_SUBNET */ 1338 #ifdef HAVE_NGTCP2 1339 doq_test(); 1340 #endif /* HAVE_NGTCP2 */ 1341 if(log_get_lock()) { 1342 lock_basic_destroy((lock_basic_type*)log_get_lock()); 1343 } 1344 checklock_stop(); 1345 printf("%d checks ok.\n", testcount); 1346 #ifdef HAVE_SSL 1347 # if defined(USE_GOST) 1348 sldns_key_EVP_unload_gost(); 1349 # endif 1350 # ifdef HAVE_OPENSSL_CONFIG 1351 # ifdef HAVE_EVP_CLEANUP 1352 EVP_cleanup(); 1353 # endif 1354 # if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP) 1355 ENGINE_cleanup(); 1356 # endif 1357 CONF_modules_free(); 1358 # endif 1359 # ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1360 CRYPTO_cleanup_all_ex_data(); 1361 # endif 1362 # ifdef HAVE_ERR_FREE_STRINGS 1363 ERR_free_strings(); 1364 # endif 1365 # ifdef HAVE_RAND_CLEANUP 1366 RAND_cleanup(); 1367 # endif 1368 #elif defined(HAVE_NSS) 1369 if(NSS_Shutdown() != SECSuccess) 1370 fatal_exit("could not shutdown NSS"); 1371 #endif /* HAVE_SSL or HAVE_NSS */ 1372 #ifdef HAVE_PTHREAD 1373 /* dlopen frees its thread specific state */ 1374 pthread_exit(NULL); 1375 #endif 1376 return 0; 1377 } 1378