1 /* $NetBSD: name_test.c,v 1.3 2024/09/22 00:14:11 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #include <inttypes.h> 17 #include <sched.h> /* IWYU pragma: keep */ 18 #include <setjmp.h> 19 #include <stdarg.h> 20 #include <stdbool.h> 21 #include <stddef.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <unistd.h> 25 26 #define UNIT_TESTING 27 #include <cmocka.h> 28 29 #include <isc/buffer.h> 30 #include <isc/commandline.h> 31 #include <isc/mem.h> 32 #include <isc/os.h> 33 #include <isc/print.h> 34 #include <isc/thread.h> 35 #include <isc/util.h> 36 37 #include <dns/compress.h> 38 #include <dns/fixedname.h> 39 #include <dns/name.h> 40 41 #include <tests/dns.h> 42 43 /* Set to true (or use -v option) for verbose output */ 44 static bool verbose = false; 45 46 /* dns_name_fullcompare test */ 47 ISC_RUN_TEST_IMPL(fullcompare) { 48 dns_fixedname_t fixed1; 49 dns_fixedname_t fixed2; 50 dns_name_t *name1; 51 dns_name_t *name2; 52 dns_namereln_t relation; 53 int i; 54 isc_result_t result; 55 struct { 56 const char *name1; 57 const char *name2; 58 dns_namereln_t relation; 59 int order; 60 unsigned int nlabels; 61 } data[] = { 62 /* relative */ 63 { "", "", dns_namereln_equal, 0, 0 }, 64 { "foo", "", dns_namereln_subdomain, 1, 0 }, 65 { "", "foo", dns_namereln_contains, -1, 0 }, 66 { "foo", "bar", dns_namereln_none, 4, 0 }, 67 { "bar", "foo", dns_namereln_none, -4, 0 }, 68 { "bar.foo", "foo", dns_namereln_subdomain, 1, 1 }, 69 { "foo", "bar.foo", dns_namereln_contains, -1, 1 }, 70 { "baz.bar.foo", "bar.foo", dns_namereln_subdomain, 1, 2 }, 71 { "bar.foo", "baz.bar.foo", dns_namereln_contains, -1, 2 }, 72 { "foo.example", "bar.example", dns_namereln_commonancestor, 4, 73 1 }, 74 75 /* absolute */ 76 { ".", ".", dns_namereln_equal, 0, 1 }, 77 { "foo.", "bar.", dns_namereln_commonancestor, 4, 1 }, 78 { "bar.", "foo.", dns_namereln_commonancestor, -4, 1 }, 79 { "foo.example.", "bar.example.", dns_namereln_commonancestor, 80 4, 2 }, 81 { "bar.foo.", "foo.", dns_namereln_subdomain, 1, 2 }, 82 { "foo.", "bar.foo.", dns_namereln_contains, -1, 2 }, 83 { "baz.bar.foo.", "bar.foo.", dns_namereln_subdomain, 1, 3 }, 84 { "bar.foo.", "baz.bar.foo.", dns_namereln_contains, -1, 3 }, 85 { NULL, NULL, dns_namereln_none, 0, 0 } 86 }; 87 88 UNUSED(state); 89 90 name1 = dns_fixedname_initname(&fixed1); 91 name2 = dns_fixedname_initname(&fixed2); 92 for (i = 0; data[i].name1 != NULL; i++) { 93 int order = 3000; 94 unsigned int nlabels = 3000; 95 96 if (data[i].name1[0] == 0) { 97 dns_fixedname_init(&fixed1); 98 } else { 99 result = dns_name_fromstring2(name1, data[i].name1, 100 NULL, 0, NULL); 101 assert_int_equal(result, ISC_R_SUCCESS); 102 } 103 if (data[i].name2[0] == 0) { 104 dns_fixedname_init(&fixed2); 105 } else { 106 result = dns_name_fromstring2(name2, data[i].name2, 107 NULL, 0, NULL); 108 assert_int_equal(result, ISC_R_SUCCESS); 109 } 110 relation = dns_name_fullcompare(name1, name1, &order, &nlabels); 111 assert_int_equal(relation, dns_namereln_equal); 112 assert_int_equal(order, 0); 113 assert_int_equal(nlabels, name1->labels); 114 115 /* Some random initializer */ 116 order = 3001; 117 nlabels = 3001; 118 119 relation = dns_name_fullcompare(name1, name2, &order, &nlabels); 120 assert_int_equal(relation, data[i].relation); 121 assert_int_equal(order, data[i].order); 122 assert_int_equal(nlabels, data[i].nlabels); 123 } 124 } 125 126 static void 127 compress_test(dns_name_t *name1, dns_name_t *name2, dns_name_t *name3, 128 unsigned char *expected, unsigned int length, 129 dns_compress_t *cctx, dns_decompress_t *dctx) { 130 isc_buffer_t source; 131 isc_buffer_t target; 132 dns_name_t name; 133 unsigned char buf1[1024]; 134 unsigned char buf2[1024]; 135 136 isc_buffer_init(&source, buf1, sizeof(buf1)); 137 isc_buffer_init(&target, buf2, sizeof(buf2)); 138 139 assert_int_equal(dns_name_towire(name1, cctx, &source), ISC_R_SUCCESS); 140 141 assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS); 142 assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS); 143 assert_int_equal(dns_name_towire(name3, cctx, &source), ISC_R_SUCCESS); 144 145 isc_buffer_setactive(&source, source.used); 146 147 dns_name_init(&name, NULL); 148 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) == 149 ISC_R_SUCCESS); 150 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) == 151 ISC_R_SUCCESS); 152 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) == 153 ISC_R_SUCCESS); 154 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) == 155 ISC_R_SUCCESS); 156 dns_decompress_invalidate(dctx); 157 158 assert_int_equal(target.used, length); 159 assert_true(memcmp(target.base, expected, target.used) == 0); 160 } 161 162 /* name compression test */ 163 ISC_RUN_TEST_IMPL(compression) { 164 unsigned int allowed; 165 dns_compress_t cctx; 166 dns_decompress_t dctx; 167 dns_name_t name1; 168 dns_name_t name2; 169 dns_name_t name3; 170 isc_region_t r; 171 unsigned char plain1[] = "\003yyy\003foo"; 172 unsigned char plain2[] = "\003bar\003yyy\003foo"; 173 unsigned char plain3[] = "\003xxx\003bar\003foo"; 174 unsigned char plain[] = "\003yyy\003foo\0\003bar\003yyy\003foo\0\003" 175 "bar\003yyy\003foo\0\003xxx\003bar\003foo"; 176 177 UNUSED(state); 178 179 dns_name_init(&name1, NULL); 180 r.base = plain1; 181 r.length = sizeof(plain1); 182 dns_name_fromregion(&name1, &r); 183 184 dns_name_init(&name2, NULL); 185 r.base = plain2; 186 r.length = sizeof(plain2); 187 dns_name_fromregion(&name2, &r); 188 189 dns_name_init(&name3, NULL); 190 r.base = plain3; 191 r.length = sizeof(plain3); 192 dns_name_fromregion(&name3, &r); 193 194 /* Test 1: NONE */ 195 allowed = DNS_COMPRESS_NONE; 196 assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); 197 dns_compress_setmethods(&cctx, allowed); 198 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); 199 dns_decompress_setmethods(&dctx, allowed); 200 201 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx, 202 &dctx); 203 204 dns_compress_rollback(&cctx, 0); 205 dns_compress_invalidate(&cctx); 206 207 /* Test2: GLOBAL14 */ 208 allowed = DNS_COMPRESS_GLOBAL14; 209 assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); 210 dns_compress_setmethods(&cctx, allowed); 211 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); 212 dns_decompress_setmethods(&dctx, allowed); 213 214 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx, 215 &dctx); 216 217 dns_compress_rollback(&cctx, 0); 218 dns_compress_invalidate(&cctx); 219 220 /* Test3: ALL */ 221 allowed = DNS_COMPRESS_ALL; 222 assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); 223 dns_compress_setmethods(&cctx, allowed); 224 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); 225 dns_decompress_setmethods(&dctx, allowed); 226 227 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx, 228 &dctx); 229 230 dns_compress_rollback(&cctx, 0); 231 dns_compress_invalidate(&cctx); 232 233 /* Test4: NONE disabled */ 234 allowed = DNS_COMPRESS_NONE; 235 assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); 236 dns_compress_setmethods(&cctx, allowed); 237 dns_compress_disable(&cctx); 238 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); 239 dns_decompress_setmethods(&dctx, allowed); 240 241 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx, 242 &dctx); 243 244 dns_compress_rollback(&cctx, 0); 245 dns_compress_invalidate(&cctx); 246 247 /* Test5: GLOBAL14 disabled */ 248 allowed = DNS_COMPRESS_GLOBAL14; 249 assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); 250 dns_compress_setmethods(&cctx, allowed); 251 dns_compress_disable(&cctx); 252 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); 253 dns_decompress_setmethods(&dctx, allowed); 254 255 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx, 256 &dctx); 257 258 dns_compress_rollback(&cctx, 0); 259 dns_compress_invalidate(&cctx); 260 261 /* Test6: ALL disabled */ 262 allowed = DNS_COMPRESS_ALL; 263 assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); 264 dns_compress_setmethods(&cctx, allowed); 265 dns_compress_disable(&cctx); 266 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); 267 dns_decompress_setmethods(&dctx, allowed); 268 269 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx, 270 &dctx); 271 272 dns_compress_rollback(&cctx, 0); 273 dns_compress_invalidate(&cctx); 274 } 275 276 ISC_RUN_TEST_IMPL(fromregion) { 277 dns_name_t name; 278 isc_buffer_t b; 279 isc_region_t r; 280 /* 281 * target and source need to be bigger than DNS_NAME_MAXWIRE to 282 * exercise 'len > DNS_NAME_MAXWIRE' test in dns_name_fromwire 283 */ 284 unsigned char target[DNS_NAME_MAXWIRE + 10]; 285 unsigned char source[DNS_NAME_MAXWIRE + 10] = { '\007', 'e', 'x', 'a', 286 'm', 'p', 'l', 'e' }; 287 /* 288 * Extract the fully qualified name at the beginning of 'source' 289 * into 'name' where 'name.ndata' points to the buffer 'target'. 290 */ 291 isc_buffer_init(&b, target, sizeof(target)); 292 dns_name_init(&name, NULL); 293 dns_name_setbuffer(&name, &b); 294 r.base = source; 295 r.length = sizeof(source); 296 dns_name_fromregion(&name, &r); 297 assert_int_equal(9, name.length); 298 assert_ptr_equal(target, name.ndata); 299 assert_true(dns_name_isabsolute(&name)); 300 301 /* 302 * Extract the fully qualified name at the beginning of 'source' 303 * into 'name' where 'name.ndata' points to the source. 304 */ 305 isc_buffer_init(&b, target, sizeof(target)); 306 dns_name_init(&name, NULL); 307 r.base = source; 308 r.length = sizeof(source); 309 dns_name_fromregion(&name, &r); 310 assert_int_equal(9, name.length); 311 assert_ptr_equal(source, name.ndata); 312 assert_true(dns_name_isabsolute(&name)); 313 314 /* 315 * Extract the partially qualified name in 'source' into 'name' 316 * where 'name.ndata' points to the source. 317 */ 318 isc_buffer_init(&b, target, sizeof(target)); 319 dns_name_init(&name, NULL); 320 r.base = source; 321 r.length = 8; 322 dns_name_fromregion(&name, &r); 323 assert_int_equal(8, name.length); 324 assert_ptr_equal(source, name.ndata); 325 assert_false(dns_name_isabsolute(&name)); 326 327 /* 328 * Extract empty name in 'source' into 'name'. 329 */ 330 isc_buffer_init(&b, target, sizeof(target)); 331 dns_name_init(&name, NULL); 332 r.base = source; 333 r.length = 0; 334 dns_name_fromregion(&name, &r); 335 assert_int_equal(0, name.length); 336 assert_ptr_equal(source, name.ndata); 337 assert_false(dns_name_isabsolute(&name)); 338 } 339 340 /* is trust-anchor-telemetry test */ 341 ISC_RUN_TEST_IMPL(istat) { 342 dns_fixedname_t fixed; 343 dns_name_t *name; 344 isc_result_t result; 345 size_t i; 346 struct { 347 const char *name; 348 bool istat; 349 } data[] = { { ".", false }, 350 { "_ta-", false }, 351 { "_ta-1234", true }, 352 { "_TA-1234", true }, 353 { "+TA-1234", false }, 354 { "_fa-1234", false }, 355 { "_td-1234", false }, 356 { "_ta_1234", false }, 357 { "_ta-g234", false }, 358 { "_ta-1h34", false }, 359 { "_ta-12i4", false }, 360 { "_ta-123j", false }, 361 { "_ta-1234-abcf", true }, 362 { "_ta-1234-abcf-ED89", true }, 363 { "_ta-12345-abcf-ED89", false }, 364 { "_ta-.example", false }, 365 { "_ta-1234.example", true }, 366 { "_ta-1234-abcf.example", true }, 367 { "_ta-1234-abcf-ED89.example", true }, 368 { "_ta-12345-abcf-ED89.example", false }, 369 { "_ta-1234-abcfe-ED89.example", false }, 370 { "_ta-1234-abcf-EcD89.example", false } }; 371 372 UNUSED(state); 373 374 name = dns_fixedname_initname(&fixed); 375 376 for (i = 0; i < (sizeof(data) / sizeof(data[0])); i++) { 377 result = dns_name_fromstring(name, data[i].name, 0, NULL); 378 assert_int_equal(result, ISC_R_SUCCESS); 379 assert_int_equal(dns_name_istat(name), data[i].istat); 380 } 381 } 382 383 /* dns_nane_init */ 384 ISC_RUN_TEST_IMPL(init) { 385 dns_name_t name; 386 unsigned char offsets[1]; 387 388 UNUSED(state); 389 390 dns_name_init(&name, offsets); 391 392 assert_null(name.ndata); 393 assert_int_equal(name.length, 0); 394 assert_int_equal(name.labels, 0); 395 assert_int_equal(name.attributes, 0); 396 assert_ptr_equal(name.offsets, offsets); 397 assert_null(name.buffer); 398 } 399 400 /* dns_nane_invalidate */ 401 ISC_RUN_TEST_IMPL(invalidate) { 402 dns_name_t name; 403 unsigned char offsets[1]; 404 405 UNUSED(state); 406 407 dns_name_init(&name, offsets); 408 dns_name_invalidate(&name); 409 410 assert_null(name.ndata); 411 assert_int_equal(name.length, 0); 412 assert_int_equal(name.labels, 0); 413 assert_int_equal(name.attributes, 0); 414 assert_null(name.offsets); 415 assert_null(name.buffer); 416 } 417 418 /* dns_nane_setbuffer/hasbuffer */ 419 ISC_RUN_TEST_IMPL(buffer) { 420 dns_name_t name; 421 unsigned char buf[BUFSIZ]; 422 isc_buffer_t b; 423 424 UNUSED(state); 425 426 isc_buffer_init(&b, buf, BUFSIZ); 427 dns_name_init(&name, NULL); 428 dns_name_setbuffer(&name, &b); 429 assert_ptr_equal(name.buffer, &b); 430 assert_true(dns_name_hasbuffer(&name)); 431 } 432 433 /* dns_nane_isabsolute */ 434 ISC_RUN_TEST_IMPL(isabsolute) { 435 struct { 436 const char *namestr; 437 bool expect; 438 } testcases[] = { { "x", false }, 439 { "a.b.c.d.", true }, 440 { "x.z", false } }; 441 unsigned int i; 442 443 UNUSED(state); 444 445 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { 446 isc_result_t result; 447 dns_name_t name; 448 unsigned char data[BUFSIZ]; 449 isc_buffer_t b, nb; 450 size_t len; 451 452 len = strlen(testcases[i].namestr); 453 isc_buffer_constinit(&b, testcases[i].namestr, len); 454 isc_buffer_add(&b, len); 455 456 dns_name_init(&name, NULL); 457 isc_buffer_init(&nb, data, BUFSIZ); 458 dns_name_setbuffer(&name, &nb); 459 result = dns_name_fromtext(&name, &b, NULL, 0, NULL); 460 assert_int_equal(result, ISC_R_SUCCESS); 461 462 assert_int_equal(dns_name_isabsolute(&name), 463 testcases[i].expect); 464 } 465 } 466 467 /* dns_nane_hash */ 468 ISC_RUN_TEST_IMPL(hash) { 469 struct { 470 const char *name1; 471 const char *name2; 472 bool expect; 473 bool expecti; 474 } testcases[] = { 475 { "a.b.c.d", "A.B.C.D", true, false }, 476 { "a.b.c.d.", "A.B.C.D.", true, false }, 477 { "a.b.c.d", "a.b.c.d", true, true }, 478 { "A.B.C.D.", "A.B.C.D.", true, false }, 479 { "x.y.z.w", "a.b.c.d", false, false }, 480 { "x.y.z.w.", "a.b.c.d.", false, false }, 481 }; 482 unsigned int i; 483 484 UNUSED(state); 485 486 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { 487 isc_result_t result; 488 dns_fixedname_t f1, f2; 489 dns_name_t *n1, *n2; 490 unsigned int h1, h2; 491 492 n1 = dns_fixedname_initname(&f1); 493 n2 = dns_fixedname_initname(&f2); 494 495 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0, 496 NULL); 497 assert_int_equal(result, ISC_R_SUCCESS); 498 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0, 499 NULL); 500 assert_int_equal(result, ISC_R_SUCCESS); 501 502 /* Check case-insensitive hashing first */ 503 h1 = dns_name_hash(n1, false); 504 h2 = dns_name_hash(n2, false); 505 506 if (verbose) { 507 print_message("# %s hashes to %u, " 508 "%s to %u, case insensitive\n", 509 testcases[i].name1, h1, 510 testcases[i].name2, h2); 511 } 512 513 assert_int_equal((h1 == h2), testcases[i].expect); 514 515 /* Now case-sensitive */ 516 h1 = dns_name_hash(n1, false); 517 h2 = dns_name_hash(n2, false); 518 519 if (verbose) { 520 print_message("# %s hashes to %u, " 521 "%s to %u, case sensitive\n", 522 testcases[i].name1, h1, 523 testcases[i].name2, h2); 524 } 525 526 assert_int_equal((h1 == h2), testcases[i].expect); 527 } 528 } 529 530 /* dns_nane_issubdomain */ 531 ISC_RUN_TEST_IMPL(issubdomain) { 532 struct { 533 const char *name1; 534 const char *name2; 535 bool expect; 536 } testcases[] = { 537 { "c.d", "a.b.c.d", false }, { "c.d.", "a.b.c.d.", false }, 538 { "b.c.d", "c.d", true }, { "a.b.c.d.", "c.d.", true }, 539 { "a.b.c", "a.b.c", true }, { "a.b.c.", "a.b.c.", true }, 540 { "x.y.z", "a.b.c", false } 541 }; 542 unsigned int i; 543 544 UNUSED(state); 545 546 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { 547 isc_result_t result; 548 dns_fixedname_t f1, f2; 549 dns_name_t *n1, *n2; 550 551 n1 = dns_fixedname_initname(&f1); 552 n2 = dns_fixedname_initname(&f2); 553 554 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0, 555 NULL); 556 assert_int_equal(result, ISC_R_SUCCESS); 557 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0, 558 NULL); 559 assert_int_equal(result, ISC_R_SUCCESS); 560 561 if (verbose) { 562 print_message("# check: %s %s a subdomain of %s\n", 563 testcases[i].name1, 564 testcases[i].expect ? "is" : "is not", 565 testcases[i].name2); 566 } 567 568 assert_int_equal(dns_name_issubdomain(n1, n2), 569 testcases[i].expect); 570 } 571 } 572 573 /* dns_nane_countlabels */ 574 ISC_RUN_TEST_IMPL(countlabels) { 575 struct { 576 const char *namestr; 577 unsigned int expect; 578 } testcases[] = { 579 { "c.d", 2 }, { "c.d.", 3 }, { "a.b.c.d.", 5 }, 580 { "a.b.c.d", 4 }, { "a.b.c", 3 }, { ".", 1 }, 581 }; 582 unsigned int i; 583 584 UNUSED(state); 585 586 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { 587 isc_result_t result; 588 dns_fixedname_t fname; 589 dns_name_t *name; 590 591 name = dns_fixedname_initname(&fname); 592 593 result = dns_name_fromstring2(name, testcases[i].namestr, NULL, 594 0, NULL); 595 assert_int_equal(result, ISC_R_SUCCESS); 596 597 if (verbose) { 598 print_message("# %s: expect %u labels\n", 599 testcases[i].namestr, 600 testcases[i].expect); 601 } 602 603 assert_int_equal(dns_name_countlabels(name), 604 testcases[i].expect); 605 } 606 } 607 608 /* dns_nane_getlabel */ 609 ISC_RUN_TEST_IMPL(getlabel) { 610 struct { 611 const char *name1; 612 unsigned int pos1; 613 const char *name2; 614 unsigned int pos2; 615 } testcases[] = { 616 { "c.d", 1, "a.b.c.d", 3 }, 617 { "a.b.c.d", 3, "c.d", 1 }, 618 { "a.b.c.", 3, "A.B.C.", 3 }, 619 }; 620 unsigned int i; 621 622 UNUSED(state); 623 624 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { 625 isc_result_t result; 626 dns_fixedname_t f1, f2; 627 dns_name_t *n1, *n2; 628 dns_label_t l1, l2; 629 unsigned int j; 630 631 n1 = dns_fixedname_initname(&f1); 632 n2 = dns_fixedname_initname(&f2); 633 634 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0, 635 NULL); 636 assert_int_equal(result, ISC_R_SUCCESS); 637 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0, 638 NULL); 639 assert_int_equal(result, ISC_R_SUCCESS); 640 641 dns_name_getlabel(n1, testcases[i].pos1, &l1); 642 dns_name_getlabel(n2, testcases[i].pos2, &l2); 643 assert_int_equal(l1.length, l2.length); 644 645 for (j = 0; j < l1.length; j++) { 646 assert_int_equal(l1.base[j], l2.base[j]); 647 } 648 } 649 } 650 651 /* dns_nane_getlabelsequence */ 652 ISC_RUN_TEST_IMPL(getlabelsequence) { 653 struct { 654 const char *name1; 655 unsigned int pos1; 656 const char *name2; 657 unsigned int pos2; 658 unsigned int range; 659 } testcases[] = { 660 { "c.d", 1, "a.b.c.d", 3, 1 }, 661 { "a.b.c.d.e", 2, "c.d", 0, 2 }, 662 { "a.b.c", 0, "a.b.c", 0, 3 }, 663 }; 664 unsigned int i; 665 666 UNUSED(state); 667 668 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { 669 isc_result_t result; 670 dns_name_t t1, t2; 671 dns_fixedname_t f1, f2; 672 dns_name_t *n1, *n2; 673 674 /* target names */ 675 dns_name_init(&t1, NULL); 676 dns_name_init(&t2, NULL); 677 678 /* source names */ 679 n1 = dns_fixedname_initname(&f1); 680 n2 = dns_fixedname_initname(&f2); 681 682 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0, 683 NULL); 684 assert_int_equal(result, ISC_R_SUCCESS); 685 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0, 686 NULL); 687 assert_int_equal(result, ISC_R_SUCCESS); 688 689 dns_name_getlabelsequence(n1, testcases[i].pos1, 690 testcases[i].range, &t1); 691 dns_name_getlabelsequence(n2, testcases[i].pos2, 692 testcases[i].range, &t2); 693 694 assert_true(dns_name_equal(&t1, &t2)); 695 } 696 } 697 698 #ifdef DNS_BENCHMARK_TESTS 699 700 /* 701 * XXXMUKS: Don't delete this code. It is useful in benchmarking the 702 * name parser, but we don't require it as part of the unit test runs. 703 */ 704 705 /* Benchmark dns_name_fromwire() implementation */ 706 707 ISC_RUN_TEST_IMPL(fromwire_thread(void *arg) { 708 unsigned int maxval = 32000000; 709 uint8_t data[] = { 3, 'w', 'w', 'w', 7, 'e', 'x', 710 'a', 'm', 'p', 'l', 'e', 7, 'i', 711 'n', 'v', 'a', 'l', 'i', 'd', 0 }; 712 unsigned char output_data[DNS_NAME_MAXWIRE]; 713 isc_buffer_t source, target; 714 unsigned int i; 715 dns_decompress_t dctx; 716 717 UNUSED(arg); 718 719 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); 720 dns_decompress_setmethods(&dctx, DNS_COMPRESS_NONE); 721 722 isc_buffer_init(&source, data, sizeof(data)); 723 isc_buffer_add(&source, sizeof(data)); 724 isc_buffer_init(&target, output_data, sizeof(output_data)); 725 726 /* Parse 32 million names in each thread */ 727 for (i = 0; i < maxval; i++) { 728 dns_name_t name; 729 730 isc_buffer_clear(&source); 731 isc_buffer_clear(&target); 732 isc_buffer_add(&source, sizeof(data)); 733 isc_buffer_setactive(&source, sizeof(data)); 734 735 dns_name_init(&name, NULL); 736 (void)dns_name_fromwire(&name, &source, &dctx, 0, &target); 737 } 738 739 return (NULL); 740 } 741 742 ISC_RUN_TEST_IMPL(benchmark) { 743 isc_result_t result; 744 unsigned int i; 745 isc_time_t ts1, ts2; 746 double t; 747 unsigned int nthreads; 748 isc_thread_t threads[32]; 749 750 UNUSED(state); 751 752 debug_mem_record = false; 753 754 result = isc_time_now(&ts1); 755 assert_int_equal(result, ISC_R_SUCCESS); 756 757 nthreads = ISC_MIN(isc_os_ncpus(), 32); 758 nthreads = ISC_MAX(nthreads, 1); 759 for (i = 0; i < nthreads; i++) { 760 isc_thread_create(fromwire_thread, NULL, &threads[i]); 761 } 762 763 for (i = 0; i < nthreads; i++) { 764 isc_thread_join(threads[i], NULL); 765 } 766 767 result = isc_time_now(&ts2); 768 assert_int_equal(result, ISC_R_SUCCESS); 769 770 t = isc_time_microdiff(&ts2, &ts1); 771 772 printf("%u dns_name_fromwire() calls, %f seconds, %f calls/second\n", 773 nthreads * 32000000, t / 1000000.0, 774 (nthreads * 32000000) / (t / 1000000.0)); 775 } 776 777 #endif /* DNS_BENCHMARK_TESTS */ 778 779 ISC_TEST_LIST_START 780 ISC_TEST_ENTRY(fullcompare) 781 ISC_TEST_ENTRY(compression) 782 ISC_TEST_ENTRY(fromregion) 783 ISC_TEST_ENTRY(istat) 784 ISC_TEST_ENTRY(init) 785 ISC_TEST_ENTRY(invalidate) 786 ISC_TEST_ENTRY(buffer) 787 ISC_TEST_ENTRY(isabsolute) 788 ISC_TEST_ENTRY(hash) 789 ISC_TEST_ENTRY(issubdomain) 790 ISC_TEST_ENTRY(countlabels) 791 ISC_TEST_ENTRY(getlabel) 792 ISC_TEST_ENTRY(getlabelsequence) 793 #ifdef DNS_BENCHMARK_TESTS 794 ISC_TEST_ENTRY(benchmark) 795 #endif /* DNS_BENCHMARK_TESTS */ 796 ISC_TEST_LIST_END 797 798 ISC_TEST_MAIN 799