1/* $NetBSD$ */ 2 3/* 4 * Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1998-2001, 2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20/* Id: t_rbt.c,v 1.35 2011/03/12 04:59:46 tbox Exp */ 21 22#include <config.h> 23 24#include <ctype.h> 25#include <stdlib.h> 26 27#include <isc/entropy.h> 28#include <isc/mem.h> 29#include <isc/util.h> 30#include <isc/hash.h> 31#include <isc/string.h> 32 33#include <dns/fixedname.h> 34#include <dns/rbt.h> 35#include <dns/result.h> 36 37#include <tests/t_api.h> 38 39#define BUFLEN 1024 40#define DNSNAMELEN 255 41 42char *progname; 43char *Tokens[T_MAXTOKS]; 44 45static int 46t_dns_rbtnodechain_init(char *dbfile, char *findname, 47 char *firstname, char *firstorigin, 48 char *nextname, char *nextorigin, 49 char *prevname, char *prevorigin, 50 char *lastname, char *lastorigin); 51static char * 52fixedname_totext(dns_fixedname_t *name); 53 54static int 55fixedname_cmp(dns_fixedname_t *dns_name, char *txtname); 56 57static char * 58dnsname_totext(dns_name_t *name); 59 60static int 61t_namechk(isc_result_t dns_result, dns_fixedname_t *dns_name, char *exp_name, 62 dns_fixedname_t *dns_origin, char *exp_origin, 63 isc_result_t exp_result); 64 65/* 66 * Parts adapted from the original rbt_test.c. 67 */ 68static int 69fixedname_cmp(dns_fixedname_t *dns_name, char *txtname) { 70 char *name; 71 72 name = dnsname_totext(dns_fixedname_name(dns_name)); 73 if (strcmp(txtname, "NULL") == 0) { 74 if ((name == NULL) || (*name == '\0')) 75 return(0); 76 return(1); 77 } else { 78 return(strcmp(name, txtname)); 79 } 80} 81 82static char * 83dnsname_totext(dns_name_t *name) { 84 static char buf[BUFLEN]; 85 isc_buffer_t target; 86 87 isc_buffer_init(&target, buf, BUFLEN); 88 dns_name_totext(name, ISC_FALSE, &target); 89 *((char *)(target.base) + target.used) = '\0'; 90 return(target.base); 91} 92 93static char * 94fixedname_totext(dns_fixedname_t *name) { 95 static char buf[BUFLEN]; 96 isc_buffer_t target; 97 98 memset(buf, 0, BUFLEN); 99 isc_buffer_init(&target, buf, BUFLEN); 100 dns_name_totext(dns_fixedname_name(name), ISC_FALSE, &target); 101 *((char *)(target.base) + target.used) = '\0'; 102 return(target.base); 103} 104 105#ifdef NEED_PRINT_DATA 106 107static isc_result_t 108print_data(void *data) { 109 isc_result_t dns_result; 110 isc_buffer_t target; 111 char *buffer[DNSNAMELEN]; 112 113 isc_buffer_init(&target, buffer, sizeof(buffer)); 114 115 dns_result = dns_name_totext(data, ISC_FALSE, &target); 116 if (dns_result != ISC_R_SUCCESS) { 117 t_info("dns_name_totext failed %s\n", 118 dns_result_totext(dns_result)); 119 } 120 return(dns_result); 121} 122 123#endif /* NEED_PRINT_DATA */ 124 125static int 126create_name(char *s, isc_mem_t *mctx, dns_name_t **dns_name) { 127 int nfails; 128 int length; 129 isc_result_t result; 130 isc_buffer_t source; 131 isc_buffer_t target; 132 dns_name_t *name; 133 134 nfails = 0; 135 136 if (s && *s) { 137 138 length = strlen(s); 139 140 isc_buffer_init(&source, s, length); 141 isc_buffer_add(&source, length); 142 143 /* 144 * The buffer for the actual name will immediately follow the 145 * name structure. 146 */ 147 name = isc_mem_get(mctx, sizeof(*name) + DNSNAMELEN); 148 if (name == NULL) { 149 t_info("isc_mem_get failed\n"); 150 ++nfails; 151 } else { 152 153 dns_name_init(name, NULL); 154 isc_buffer_init(&target, name + 1, DNSNAMELEN); 155 156 result = dns_name_fromtext(name, &source, dns_rootname, 157 0, &target); 158 159 if (result != ISC_R_SUCCESS) { 160 ++nfails; 161 t_info("dns_name_fromtext(%s) failed %s\n", 162 s, dns_result_totext(result)); 163 isc_mem_put(mctx, name, 164 sizeof(*name) + DNSNAMELEN); 165 } else 166 *dns_name = name; 167 } 168 } else { 169 ++nfails; 170 t_info("create_name: empty name\n"); 171 } 172 173 return(nfails); 174} 175 176static void 177delete_name(void *data, void *arg) { 178 isc_mem_put((isc_mem_t *)arg, data, sizeof(dns_name_t) + DNSNAMELEN); 179} 180 181 182/* 183 * Adapted from the original rbt_test.c. 184 */ 185static int 186t1_add(char *name, dns_rbt_t *rbt, isc_mem_t *mctx, isc_result_t *dns_result) { 187 int nprobs; 188 dns_name_t *dns_name; 189 190 nprobs = 0; 191 if (name && dns_result) { 192 if (create_name(name, mctx, &dns_name) == 0) { 193 if (T_debug) 194 t_info("dns_rbt_addname succeeded\n"); 195 *dns_result = dns_rbt_addname(rbt, dns_name, dns_name); 196 if (*dns_result != ISC_R_SUCCESS) { 197 delete_name(dns_name, mctx); 198 t_info("dns_rbt_addname failed %s\n", 199 dns_result_totext(*dns_result)); 200 ++nprobs; 201 } 202 } else { 203 ++nprobs; 204 } 205 } else { 206 ++nprobs; 207 } 208 return(nprobs); 209} 210 211static int 212t1_delete(char *name, dns_rbt_t *rbt, isc_mem_t *mctx, 213 isc_result_t *dns_result) 214{ 215 int nprobs; 216 dns_name_t *dns_name; 217 218 nprobs = 0; 219 if (name && dns_result) { 220 if (create_name(name, mctx, &dns_name) == 0) { 221 *dns_result = dns_rbt_deletename(rbt, dns_name, 222 ISC_FALSE); 223 delete_name(dns_name, mctx); 224 } else { 225 ++nprobs; 226 } 227 } else { 228 ++nprobs; 229 } 230 return(nprobs); 231} 232 233static int 234t1_search(char *name, dns_rbt_t *rbt, isc_mem_t *mctx, 235 isc_result_t *dns_result) 236{ 237 int nprobs; 238 dns_name_t *dns_searchname; 239 dns_name_t *dns_foundname; 240 dns_fixedname_t dns_fixedname; 241 void *data; 242 243 nprobs = 0; 244 if (name && dns_result) { 245 if (create_name(name, mctx, &dns_searchname) == 0) { 246 dns_fixedname_init(&dns_fixedname); 247 dns_foundname = dns_fixedname_name(&dns_fixedname); 248 data = NULL; 249 *dns_result = dns_rbt_findname(rbt, dns_searchname, 0, 250 dns_foundname, &data); 251 delete_name(dns_searchname, mctx); 252 } else { 253 ++nprobs; 254 } 255 } else { 256 ++nprobs; 257 } 258 return(nprobs); 259} 260 261/* 262 * Initialize a database from filename. 263 */ 264static int 265rbt_init(char *filename, dns_rbt_t **rbt, isc_mem_t *mctx) { 266 int rval; 267 isc_result_t dns_result; 268 char *p; 269 FILE *fp; 270 271 fp = fopen(filename, "r"); 272 if (fp == NULL) { 273 t_info("No such file %s\n", filename); 274 return(1); 275 } 276 277 dns_result = dns_rbt_create(mctx, delete_name, mctx, rbt); 278 if (dns_result != ISC_R_SUCCESS) { 279 t_info("dns_rbt_create failed %s\n", 280 dns_result_totext(dns_result)); 281 fclose(fp); 282 return(1); 283 } 284 285 while ((p = t_fgetbs(fp)) != NULL) { 286 287 /* 288 * Skip any comment lines. 289 */ 290 if ((*p == '#') || (*p == '\0') || (*p == ' ')) { 291 (void)free(p); 292 continue; 293 } 294 295 if (T_debug) 296 t_info("adding name %s to the rbt\n", p); 297 298 rval = t1_add(p, *rbt, mctx, &dns_result); 299 if ((rval != 0) || (dns_result != ISC_R_SUCCESS)) { 300 t_info("add of %s failed\n", p); 301 dns_rbt_destroy(rbt); 302 fclose(fp); 303 return(1); 304 } 305 (void) free(p); 306 } 307 fclose(fp); 308 return(0); 309} 310 311static int 312test_rbt_gen(char *filename, char *command, char *testname, 313 isc_result_t exp_result) 314{ 315 int rval; 316 int result; 317 dns_rbt_t *rbt; 318 isc_result_t isc_result; 319 isc_result_t dns_result; 320 isc_mem_t *mctx; 321 isc_entropy_t *ectx; 322 dns_name_t *dns_name; 323 324 result = T_UNRESOLVED; 325 326 if (strcmp(command, "create") != 0) 327 t_info("testing using name %s\n", testname); 328 329 mctx = NULL; 330 ectx = NULL; 331 332 isc_result = isc_mem_create(0, 0, &mctx); 333 if (isc_result != ISC_R_SUCCESS) { 334 t_info("isc_mem_create: %s: exiting\n", 335 dns_result_totext(isc_result)); 336 return(T_UNRESOLVED); 337 } 338 339 isc_result = isc_entropy_create(mctx, &ectx); 340 if (isc_result != ISC_R_SUCCESS) { 341 t_info("isc_entropy_create: %s: exiting\n", 342 dns_result_totext(isc_result)); 343 isc_mem_destroy(&mctx); 344 return(T_UNRESOLVED); 345 } 346 347 isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); 348 if (isc_result != ISC_R_SUCCESS) { 349 t_info("isc_hash_create: %s: exiting\n", 350 dns_result_totext(isc_result)); 351 isc_entropy_detach(&ectx); 352 isc_mem_destroy(&mctx); 353 return(T_UNRESOLVED); 354 } 355 356 rbt = NULL; 357 if (rbt_init(filename, &rbt, mctx) != 0) { 358 if (strcmp(command, "create") == 0) 359 result = T_FAIL; 360 isc_hash_destroy(); 361 isc_entropy_detach(&ectx); 362 isc_mem_destroy(&mctx); 363 return(result); 364 } 365 366 /* 367 * Now try the database command. 368 */ 369 if (strcmp(command, "create") == 0) { 370 result = T_PASS; 371 } else if (strcmp(command, "add") == 0) { 372 if (create_name(testname, mctx, &dns_name) == 0) { 373 dns_result = dns_rbt_addname(rbt, dns_name, dns_name); 374 375 if (dns_result != ISC_R_SUCCESS) 376 delete_name(dns_name, mctx); 377 378 if (dns_result == exp_result) { 379 if (dns_result == ISC_R_SUCCESS) { 380 rval = t1_search(testname, rbt, mctx, 381 &dns_result); 382 if (rval == 0) { 383 if (dns_result == ISC_R_SUCCESS) { 384 result = T_PASS; 385 } else { 386 result = T_FAIL; 387 } 388 } else { 389 t_info("t1_search failed\n"); 390 result = T_UNRESOLVED; 391 } 392 } else { 393 result = T_PASS; 394 } 395 } else { 396 t_info("dns_rbt_addname returned %s, " 397 "expected %s\n", 398 dns_result_totext(dns_result), 399 dns_result_totext(exp_result)); 400 result = T_FAIL; 401 } 402 } else { 403 t_info("create_name failed\n"); 404 result = T_UNRESOLVED; 405 } 406 } else if ((strcmp(command, "delete") == 0) || 407 (strcmp(command, "nuke") == 0)) { 408 rval = t1_delete(testname, rbt, mctx, &dns_result); 409 if (rval == 0) { 410 if (dns_result == exp_result) { 411 rval = t1_search(testname, rbt, mctx, 412 &dns_result); 413 if (rval == 0) { 414 if (dns_result == ISC_R_SUCCESS) { 415 t_info("dns_rbt_deletename " 416 "didn't delete " 417 "the name"); 418 result = T_FAIL; 419 } else { 420 result = T_PASS; 421 } 422 } 423 } else { 424 t_info("delete returned %s, expected %s\n", 425 dns_result_totext(dns_result), 426 dns_result_totext(exp_result)); 427 result = T_FAIL; 428 } 429 } 430 } else if (strcmp(command, "search") == 0) { 431 rval = t1_search(testname, rbt, mctx, &dns_result); 432 if (rval == 0) { 433 if (dns_result == exp_result) { 434 result = T_PASS; 435 } else { 436 t_info("find returned %s, expected %s\n", 437 dns_result_totext(dns_result), 438 dns_result_totext(exp_result)); 439 result = T_FAIL; 440 } 441 } 442 } 443 444 dns_rbt_destroy(&rbt); 445 isc_hash_destroy(); 446 isc_entropy_detach(&ectx); 447 isc_mem_destroy(&mctx); 448 return(result); 449} 450 451static int 452test_dns_rbt_x(const char *filename) { 453 FILE *fp; 454 char *p; 455 int line; 456 int cnt; 457 int result; 458 int nfails; 459 int nprobs; 460 461 nfails = 0; 462 nprobs = 0; 463 464 fp = fopen(filename, "r"); 465 if (fp != NULL) { 466 line = 0; 467 while ((p = t_fgetbs(fp)) != NULL) { 468 469 ++line; 470 471 /* 472 * Skip comment lines. 473 */ 474 if ((isspace((unsigned char)*p)) || (*p == '#')) { 475 (void)free(p); 476 continue; 477 } 478 479 /* 480 * Name of db file, command, testname, 481 * expected result. 482 */ 483 cnt = t_bustline(p, Tokens); 484 if (cnt == 4) { 485 result = test_rbt_gen(Tokens[0], Tokens[1], 486 Tokens[2], 487 t_dns_result_fromtext(Tokens[3])); 488 if (result != T_PASS) 489 ++nfails; 490 } else { 491 t_info("bad format in %s at line %d\n", 492 filename, line); 493 ++nprobs; 494 } 495 496 (void)free(p); 497 } 498 (void)fclose(fp); 499 } else { 500 t_info("Missing datafile %s\n", filename); 501 ++nprobs; 502 } 503 504 result = T_UNRESOLVED; 505 if ((nfails == 0) && (nprobs == 0)) 506 result = T_PASS; 507 else if (nfails) 508 result = T_FAIL; 509 510 return(result); 511} 512 513 514static const char *a1 = "dns_rbt_create creates a rbt and returns " 515 "ISC_R_SUCCESS on success"; 516 517static void 518t1() { 519 int result; 520 521 t_assert("dns_rbt_create", 1, T_REQUIRED, "%s", a1); 522 result = test_dns_rbt_x("dns_rbt_create_1_data"); 523 t_result(result); 524} 525 526static const char *a2 = "dns_rbt_addname adds a name to a database and " 527 "returns ISC_R_SUCCESS on success"; 528 529static void 530t2() { 531 int result; 532 533 t_assert("dns_rbt_addname", 2, T_REQUIRED, "%s", a2); 534 result = test_dns_rbt_x("dns_rbt_addname_1_data"); 535 t_result(result); 536} 537 538static const char *a3 = "when name already exists, dns_rbt_addname() " 539 "returns ISC_R_EXISTS"; 540 541static void 542t3() { 543 int result; 544 545 t_assert("dns_rbt_addname", 3, T_REQUIRED, "%s", a3); 546 result = test_dns_rbt_x("dns_rbt_addname_2_data"); 547 t_result(result); 548} 549 550static const char *a4 = "when name exists, dns_rbt_deletename() returns " 551 "ISC_R_SUCCESS"; 552 553static void 554t4() { 555 int result; 556 557 t_assert("dns_rbt_deletename", 4, T_REQUIRED, "%s", a4); 558 result = test_dns_rbt_x("dns_rbt_deletename_1_data"); 559 t_result(result); 560} 561 562static const char *a5 = "when name does not exist, dns_rbt_deletename() " 563 "returns ISC_R_NOTFOUND"; 564static void 565t5() { 566 int result; 567 568 t_assert("dns_rbt_deletename", 5, T_REQUIRED, "%s", a5); 569 result = test_dns_rbt_x("dns_rbt_deletename_2_data"); 570 t_result(result); 571} 572 573static const char *a6 = "when name exists and exactly matches the " 574 "search name dns_rbt_findname() returns ISC_R_SUCCESS"; 575 576static void 577t6() { 578 int result; 579 580 t_assert("dns_rbt_findname", 6, T_REQUIRED, "%s", a6); 581 result = test_dns_rbt_x("dns_rbt_findname_1_data"); 582 t_result(result); 583} 584 585static const char *a7 = "when a name does not exist, " 586 "dns_rbt_findname returns ISC_R_NOTFOUND"; 587 588static void 589t7() { 590 int result; 591 592 t_assert("dns_rbt_findname", 7, T_REQUIRED, "%s", a7); 593 result = test_dns_rbt_x("dns_rbt_findname_2_data"); 594 t_result(result); 595} 596 597static const char *a8 = "when a superdomain is found with data matching name, " 598 "dns_rbt_findname returns DNS_R_PARTIALMATCH"; 599 600static void 601t8() { 602 int result; 603 604 t_assert("dns_rbt_findname", 8, T_REQUIRED, "%s", a8); 605 result = test_dns_rbt_x("dns_rbt_findname_3_data"); 606 t_result(result); 607} 608 609 610static const char *a9 = "a call to dns_rbtnodechain_init(chain, mctx) " 611 "initializes chain"; 612 613static int 614t9_walkchain(dns_rbtnodechain_t *chain, dns_rbt_t *rbt) { 615 int cnt; 616 int order; 617 unsigned int nlabels; 618 int nprobs; 619 isc_result_t dns_result; 620 621 dns_fixedname_t name; 622 dns_fixedname_t origin; 623 dns_fixedname_t fullname1; 624 dns_fixedname_t fullname2; 625 626 cnt = 0; 627 nprobs = 0; 628 629 do { 630 631 if (cnt == 0) { 632 dns_fixedname_init(&name); 633 dns_fixedname_init(&origin); 634 dns_result = dns_rbtnodechain_first(chain, rbt, 635 dns_fixedname_name(&name), 636 dns_fixedname_name(&origin)); 637 if (dns_result != DNS_R_NEWORIGIN) { 638 t_info("dns_rbtnodechain_first returned %s, " 639 "expecting DNS_R_NEWORIGIN\n", 640 dns_result_totext(dns_result)); 641 ++nprobs; 642 break; 643 } 644 t_info("first name:\t<%s>\n", fixedname_totext(&name)); 645 t_info("first origin:\t<%s>\n", 646 fixedname_totext(&origin)); 647 } else { 648 dns_fixedname_init(&fullname1); 649 dns_result = dns_name_concatenate( 650 dns_fixedname_name(&name), 651 dns_name_isabsolute(dns_fixedname_name(&name)) ? 652 NULL : dns_fixedname_name(&origin), 653 dns_fixedname_name(&fullname1), NULL); 654 if (dns_result != ISC_R_SUCCESS) { 655 t_info("dns_name_concatenate failed %s\n", 656 dns_result_totext(dns_result)); 657 ++nprobs; 658 break; 659 } 660 661 /* 662 * Expecting origin not to get touched if next 663 * doesn't return NEWORIGIN. 664 */ 665 dns_fixedname_init(&name); 666 dns_result = dns_rbtnodechain_next(chain, 667 dns_fixedname_name(&name), 668 dns_fixedname_name(&origin)); 669 if ((dns_result != ISC_R_SUCCESS) && 670 (dns_result != DNS_R_NEWORIGIN)) { 671 if (dns_result != ISC_R_NOMORE) { 672 t_info("dns_rbtnodechain_next " 673 "failed %s\n", 674 dns_result_totext(dns_result)); 675 ++nprobs; 676 } 677 break; 678 } 679 680 t_info("next name:\t<%s>\n", fixedname_totext(&name)); 681 t_info("next origin:\t<%s>\n", 682 fixedname_totext(&origin)); 683 684 dns_fixedname_init(&fullname2); 685 dns_result = dns_name_concatenate( 686 dns_fixedname_name(&name), 687 dns_name_isabsolute(dns_fixedname_name(&name)) ? 688 NULL : dns_fixedname_name(&origin), 689 dns_fixedname_name(&fullname2), NULL); 690 if (dns_result != ISC_R_SUCCESS) { 691 t_info("dns_name_concatenate failed %s\n", 692 dns_result_totext(dns_result)); 693 ++nprobs; 694 break; 695 } 696 697 t_info("comparing\t<%s>\n", 698 fixedname_totext(&fullname1)); 699 t_info("\twith\t<%s>\n", fixedname_totext(&fullname2)); 700 701 (void)dns_name_fullcompare( 702 dns_fixedname_name(&fullname1), 703 dns_fixedname_name(&fullname2), 704 &order, &nlabels); 705 706 if (order >= 0) { 707 t_info("unexpected order %s %s %s\n", 708 dnsname_totext(dns_fixedname_name(&fullname1)), 709 order == -1 ? "<" : (order == 0 ? "==" : ">"), 710 dnsname_totext(dns_fixedname_name(&fullname2))); 711 ++nprobs; 712 } 713 } 714 715 ++cnt; 716 } while (1); 717 718 return (nprobs); 719} 720 721/* 722 * Test by exercising the first|last|next|prev funcs in useful ways. 723 */ 724 725static int 726t_namechk(isc_result_t dns_result, dns_fixedname_t *dns_name, char *exp_name, 727 dns_fixedname_t *dns_origin, char *exp_origin, 728 isc_result_t exp_result) 729{ 730 int nfails; 731 732 nfails = 0; 733 734 if (fixedname_cmp(dns_name, exp_name)) { 735 t_info("\texpected name of %s, got %s\n", 736 exp_name, fixedname_totext(dns_name)); 737 ++nfails; 738 } 739 if (exp_origin != NULL) { 740 t_info("checking for DNS_R_NEWORIGIN\n"); 741 if (dns_result == exp_result) { 742 if (fixedname_cmp(dns_origin, exp_origin)) { 743 t_info("\torigin %s, expected %s\n", 744 fixedname_totext(dns_origin), 745 exp_origin); 746 ++nfails; 747 } 748 } else { 749 t_info("\tgot %s\n", dns_result_totext(dns_result)); 750 ++nfails; 751 } 752 } 753 return(nfails); 754} 755 756static int 757t_dns_rbtnodechain_init(char *dbfile, char *findname, 758 char *nextname, char *nextorigin, 759 char *prevname, char *prevorigin, 760 char *firstname, char *firstorigin, 761 char *lastname, char *lastorigin) 762{ 763 int result; 764 int len; 765 int nfails; 766 dns_rbt_t *rbt; 767 dns_rbtnode_t *node; 768 dns_rbtnodechain_t chain; 769 isc_mem_t *mctx; 770 isc_entropy_t *ectx; 771 isc_result_t isc_result; 772 isc_result_t dns_result; 773 dns_fixedname_t dns_findname; 774 dns_fixedname_t dns_foundname; 775 dns_fixedname_t dns_firstname; 776 dns_fixedname_t dns_lastname; 777 dns_fixedname_t dns_prevname; 778 dns_fixedname_t dns_nextname; 779 dns_fixedname_t dns_origin; 780 isc_buffer_t isc_buffer; 781 782 result = T_UNRESOLVED; 783 784 nfails = 0; 785 mctx = NULL; 786 ectx = NULL; 787 788 isc_result = isc_mem_create(0, 0, &mctx); 789 if (isc_result != ISC_R_SUCCESS) { 790 t_info("isc_mem_create failed %s\n", 791 isc_result_totext(isc_result)); 792 return(result); 793 } 794 795 isc_result = isc_entropy_create(mctx, &ectx); 796 if (isc_result != ISC_R_SUCCESS) { 797 t_info("isc_entropy_create: %s: exiting\n", 798 dns_result_totext(isc_result)); 799 isc_mem_destroy(&mctx); 800 return(T_UNRESOLVED); 801 } 802 803 isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); 804 if (isc_result != ISC_R_SUCCESS) { 805 t_info("isc_hash_create: %s: exiting\n", 806 dns_result_totext(isc_result)); 807 isc_entropy_detach(&ectx); 808 isc_mem_destroy(&mctx); 809 return(T_UNRESOLVED); 810 } 811 812 dns_rbtnodechain_init(&chain, mctx); 813 814 rbt = NULL; 815 if (rbt_init(dbfile, &rbt, mctx)) { 816 t_info("rbt_init %s failed\n", dbfile); 817 isc_hash_destroy(); 818 isc_entropy_detach(&ectx); 819 isc_mem_destroy(&mctx); 820 return(result); 821 } 822 823 len = strlen(findname); 824 isc_buffer_init(&isc_buffer, findname, len); 825 isc_buffer_add(&isc_buffer, len); 826 827 dns_fixedname_init(&dns_foundname); 828 dns_fixedname_init(&dns_findname); 829 dns_fixedname_init(&dns_firstname); 830 dns_fixedname_init(&dns_origin); 831 dns_fixedname_init(&dns_lastname); 832 dns_fixedname_init(&dns_prevname); 833 dns_fixedname_init(&dns_nextname); 834 835 dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname), 836 &isc_buffer, NULL, 0, NULL); 837 838 if (dns_result != ISC_R_SUCCESS) { 839 t_info("dns_name_fromtext failed %s\n", 840 dns_result_totext(dns_result)); 841 return(result); 842 } 843 844 /* 845 * Set the starting node. 846 */ 847 node = NULL; 848 dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname), 849 dns_fixedname_name(&dns_foundname), 850 &node, &chain, DNS_RBTFIND_EMPTYDATA, 851 NULL, NULL); 852 853 if (dns_result != ISC_R_SUCCESS) { 854 t_info("dns_rbt_findnode failed %s\n", 855 dns_result_totext(dns_result)); 856 return(result); 857 } 858 859 /* 860 * Check next. 861 */ 862 t_info("checking for next name of %s and new origin of %s\n", 863 nextname, nextorigin); 864 dns_result = dns_rbtnodechain_next(&chain, 865 dns_fixedname_name(&dns_nextname), 866 dns_fixedname_name(&dns_origin)); 867 868 if ((dns_result != ISC_R_SUCCESS) && 869 (dns_result != DNS_R_NEWORIGIN)) { 870 t_info("dns_rbtnodechain_next unexpectedly returned %s\n", 871 dns_result_totext(dns_result)); 872 } 873 874 nfails += t_namechk(dns_result, &dns_nextname, nextname, &dns_origin, 875 nextorigin, DNS_R_NEWORIGIN); 876 877 /* 878 * Set the starting node again. 879 */ 880 node = NULL; 881 dns_fixedname_init(&dns_foundname); 882 dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname), 883 dns_fixedname_name(&dns_foundname), 884 &node, &chain, DNS_RBTFIND_EMPTYDATA, 885 NULL, NULL); 886 887 if (dns_result != ISC_R_SUCCESS) { 888 t_info("\tdns_rbt_findnode failed %s\n", 889 dns_result_totext(dns_result)); 890 return(result); 891 } 892 893 /* 894 * Check previous. 895 */ 896 t_info("checking for previous name of %s and new origin of %s\n", 897 prevname, prevorigin); 898 dns_fixedname_init(&dns_origin); 899 dns_result = dns_rbtnodechain_prev(&chain, 900 dns_fixedname_name(&dns_prevname), 901 dns_fixedname_name(&dns_origin)); 902 903 if ((dns_result != ISC_R_SUCCESS) && 904 (dns_result != DNS_R_NEWORIGIN)) { 905 t_info("dns_rbtnodechain_prev unexpectedly returned %s\n", 906 dns_result_totext(dns_result)); 907 } 908 nfails += t_namechk(dns_result, &dns_prevname, prevname, &dns_origin, 909 prevorigin, DNS_R_NEWORIGIN); 910 911 /* 912 * Check first. 913 */ 914 t_info("checking for first name of %s and new origin of %s\n", 915 firstname, firstorigin); 916 dns_result = dns_rbtnodechain_first(&chain, rbt, 917 dns_fixedname_name(&dns_firstname), 918 dns_fixedname_name(&dns_origin)); 919 920 if (dns_result != DNS_R_NEWORIGIN) { 921 t_info("dns_rbtnodechain_first unexpectedly returned %s\n", 922 dns_result_totext(dns_result)); 923 } 924 nfails += t_namechk(dns_result, &dns_firstname, firstname, 925 &dns_origin, firstorigin, DNS_R_NEWORIGIN); 926 927 /* 928 * Check last. 929 */ 930 t_info("checking for last name of %s\n", lastname); 931 dns_result = dns_rbtnodechain_last(&chain, rbt, 932 dns_fixedname_name(&dns_lastname), 933 dns_fixedname_name(&dns_origin)); 934 935 if (dns_result != DNS_R_NEWORIGIN) { 936 t_info("dns_rbtnodechain_last unexpectedly returned %s\n", 937 dns_result_totext(dns_result)); 938 } 939 nfails += t_namechk(dns_result, &dns_lastname, lastname, &dns_origin, 940 lastorigin, DNS_R_NEWORIGIN); 941 942 /* 943 * Check node ordering. 944 */ 945 t_info("checking node ordering\n"); 946 nfails += t9_walkchain(&chain, rbt); 947 948 if (nfails) 949 result = T_FAIL; 950 else 951 result = T_PASS; 952 953 dns_rbtnodechain_invalidate(&chain); 954 dns_rbt_destroy(&rbt); 955 956 isc_hash_destroy(); 957 isc_entropy_detach(&ectx); 958 isc_mem_destroy(&mctx); 959 960 return(result); 961} 962 963static int 964test_dns_rbtnodechain_init(const char *filename) { 965 FILE *fp; 966 char *p; 967 int line; 968 int cnt; 969 int result; 970 int nfails; 971 int nprobs; 972 973 nfails = 0; 974 nprobs = 0; 975 976 fp = fopen(filename, "r"); 977 if (fp != NULL) { 978 line = 0; 979 while ((p = t_fgetbs(fp)) != NULL) { 980 981 ++line; 982 983 /* 984 * Skip comment lines. 985 */ 986 if ((isspace((unsigned char)*p)) || (*p == '#')) { 987 (void)free(p); 988 continue; 989 } 990 991 cnt = t_bustline(p, Tokens); 992 if (cnt == 10) { 993 result = t_dns_rbtnodechain_init( 994 Tokens[0], /* dbfile */ 995 Tokens[1], /* startname */ 996 Tokens[2], /* nextname */ 997 Tokens[3], /* nextorigin */ 998 Tokens[4], /* prevname */ 999 Tokens[5], /* prevorigin */ 1000 Tokens[6], /* firstname */ 1001 Tokens[7], /* firstorigin */ 1002 Tokens[8], /* lastname */ 1003 Tokens[9]); /* lastorigin */ 1004 if (result != T_PASS) { 1005 if (result == T_FAIL) 1006 ++nfails; 1007 else 1008 ++nprobs; 1009 } 1010 } else { 1011 t_info("bad format in %s at line %d\n", 1012 filename, line); 1013 ++nprobs; 1014 } 1015 1016 (void)free(p); 1017 } 1018 (void)fclose(fp); 1019 } else { 1020 t_info("Missing datafile %s\n", filename); 1021 ++nprobs; 1022 } 1023 1024 result = T_UNRESOLVED; 1025 1026 if ((nfails == 0) && (nprobs == 0)) 1027 result = T_PASS; 1028 else if (nfails) 1029 result = T_FAIL; 1030 1031 return(result); 1032} 1033 1034static void 1035t9() { 1036 int result; 1037 1038 t_assert("dns_rbtnodechain_init", 9, T_REQUIRED, "%s", a9); 1039 result = test_dns_rbtnodechain_init("dns_rbtnodechain_init_data"); 1040 t_result(result); 1041} 1042 1043static int 1044t_dns_rbtnodechain_first(char *dbfile, char *expected_firstname, 1045 char *expected_firstorigin, 1046 char *expected_nextname, 1047 char *expected_nextorigin) 1048{ 1049 int result; 1050 int nfails; 1051 dns_rbt_t *rbt; 1052 dns_rbtnodechain_t chain; 1053 isc_mem_t *mctx; 1054 isc_entropy_t *ectx; 1055 isc_result_t isc_result; 1056 isc_result_t dns_result; 1057 dns_fixedname_t dns_name; 1058 dns_fixedname_t dns_origin; 1059 isc_result_t expected_result; 1060 1061 result = T_UNRESOLVED; 1062 1063 nfails = 0; 1064 mctx = NULL; 1065 ectx = NULL; 1066 1067 dns_fixedname_init(&dns_name); 1068 dns_fixedname_init(&dns_origin); 1069 1070 isc_result = isc_mem_create(0, 0, &mctx); 1071 if (isc_result != ISC_R_SUCCESS) { 1072 t_info("isc_mem_create failed %s\n", 1073 isc_result_totext(isc_result)); 1074 return(result); 1075 } 1076 1077 isc_result = isc_entropy_create(mctx, &ectx); 1078 if (isc_result != ISC_R_SUCCESS) { 1079 t_info("isc_entropy_create: %s: exiting\n", 1080 dns_result_totext(isc_result)); 1081 isc_mem_destroy(&mctx); 1082 return(T_UNRESOLVED); 1083 } 1084 1085 isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); 1086 if (isc_result != ISC_R_SUCCESS) { 1087 t_info("isc_hash_create: %s: exiting\n", 1088 dns_result_totext(isc_result)); 1089 isc_entropy_detach(&ectx); 1090 isc_mem_destroy(&mctx); 1091 return(T_UNRESOLVED); 1092 } 1093 1094 dns_rbtnodechain_init(&chain, mctx); 1095 1096 rbt = NULL; 1097 if (rbt_init(dbfile, &rbt, mctx)) { 1098 t_info("rbt_init %s failed\n", dbfile); 1099 isc_hash_destroy(); 1100 isc_entropy_detach(&ectx); 1101 isc_mem_destroy(&mctx); 1102 return(result); 1103 } 1104 1105 t_info("testing for first name of %s, origin of %s\n", 1106 expected_firstname, expected_firstorigin); 1107 1108 dns_result = dns_rbtnodechain_first(&chain, rbt, 1109 dns_fixedname_name(&dns_name), 1110 dns_fixedname_name(&dns_origin)); 1111 1112 if (dns_result != DNS_R_NEWORIGIN) 1113 t_info("dns_rbtnodechain_first unexpectedly returned %s\n", 1114 dns_result_totext(dns_result)); 1115 1116 nfails += t_namechk(dns_result, &dns_name, expected_firstname, 1117 &dns_origin, expected_firstorigin, DNS_R_NEWORIGIN); 1118 1119 dns_fixedname_init(&dns_name); 1120 dns_result = dns_rbtnodechain_next(&chain, 1121 dns_fixedname_name(&dns_name), 1122 dns_fixedname_name(&dns_origin)); 1123 1124 t_info("testing for next name of %s, origin of %s\n", 1125 expected_nextname, expected_nextorigin); 1126 1127 if ((dns_result != ISC_R_SUCCESS) && (dns_result != DNS_R_NEWORIGIN)) 1128 t_info("dns_rbtnodechain_next unexpectedly returned %s\n", 1129 dns_result_totext(dns_result)); 1130 1131 if (strcasecmp(expected_firstorigin, expected_nextorigin) == 0) 1132 expected_result = ISC_R_SUCCESS; 1133 else 1134 expected_result = DNS_R_NEWORIGIN; 1135 nfails += t_namechk(dns_result, &dns_name, expected_nextname, 1136 &dns_origin, expected_nextorigin, expected_result); 1137 1138 if (nfails) 1139 result = T_FAIL; 1140 else 1141 result = T_PASS; 1142 1143 dns_rbtnodechain_invalidate(&chain); 1144 1145 dns_rbt_destroy(&rbt); 1146 isc_hash_destroy(); 1147 isc_entropy_detach(&ectx); 1148 isc_mem_destroy(&mctx); 1149 return(result); 1150} 1151 1152static int 1153test_dns_rbtnodechain_first(const char *filename) { 1154 FILE *fp; 1155 char *p; 1156 int line; 1157 int cnt; 1158 int result; 1159 int nfails; 1160 int nprobs; 1161 1162 nfails = 0; 1163 nprobs = 0; 1164 1165 fp = fopen(filename, "r"); 1166 if (fp != NULL) { 1167 line = 0; 1168 while ((p = t_fgetbs(fp)) != NULL) { 1169 1170 ++line; 1171 1172 /* 1173 * Skip comment lines. 1174 */ 1175 if ((isspace((unsigned char)*p)) || (*p == '#')) { 1176 (void)free(p); 1177 continue; 1178 } 1179 1180 cnt = t_bustline(p, Tokens); 1181 if (cnt == 5) { 1182 result = t_dns_rbtnodechain_first( 1183 Tokens[0], /* dbfile */ 1184 Tokens[1], /* firstname */ 1185 Tokens[2], /* firstorigin */ 1186 Tokens[3], /* nextname */ 1187 Tokens[4]); /* nextorigin */ 1188 if (result != T_PASS) { 1189 if (result == T_FAIL) 1190 ++nfails; 1191 else 1192 ++nprobs; 1193 } 1194 } else { 1195 t_info("bad format in %s at line %d\n", 1196 filename, line); 1197 ++nprobs; 1198 } 1199 1200 (void)free(p); 1201 } 1202 (void)fclose(fp); 1203 } else { 1204 t_info("Missing datafile %s\n", filename); 1205 ++nprobs; 1206 } 1207 1208 result = T_UNRESOLVED; 1209 1210 if ((nfails == 0) && (nprobs == 0)) 1211 result = T_PASS; 1212 else if (nfails) 1213 result = T_FAIL; 1214 1215 return(result); 1216} 1217 1218static const char *a10 = "a call to " 1219 "dns_rbtnodechain_first(chain, rbt, name, origin) " 1220 "sets name to point to the root of the tree, " 1221 "origin to point to the origin, " 1222 "and returns DNS_R_NEWORIGIN"; 1223 1224static void 1225t10() { 1226 int result; 1227 1228 t_assert("dns_rbtnodechain_first", 10, T_REQUIRED, "%s", a10); 1229 result = test_dns_rbtnodechain_first("dns_rbtnodechain_first_data"); 1230 t_result(result); 1231} 1232 1233static int 1234t_dns_rbtnodechain_last(char *dbfile, char *expected_lastname, 1235 char *expected_lastorigin, 1236 char *expected_prevname, 1237 char *expected_prevorigin) 1238{ 1239 1240 int result; 1241 int nfails; 1242 dns_rbt_t *rbt; 1243 dns_rbtnodechain_t chain; 1244 isc_mem_t *mctx; 1245 isc_entropy_t *ectx; 1246 isc_result_t isc_result; 1247 isc_result_t dns_result; 1248 dns_fixedname_t dns_name; 1249 dns_fixedname_t dns_origin; 1250 isc_result_t expected_result; 1251 1252 result = T_UNRESOLVED; 1253 1254 nfails = 0; 1255 mctx = NULL; 1256 ectx = NULL; 1257 1258 dns_fixedname_init(&dns_name); 1259 dns_fixedname_init(&dns_origin); 1260 1261 isc_result = isc_mem_create(0, 0, &mctx); 1262 if (isc_result != ISC_R_SUCCESS) { 1263 t_info("isc_mem_create failed %s\n", 1264 isc_result_totext(isc_result)); 1265 return(result); 1266 } 1267 1268 isc_result = isc_entropy_create(mctx, &ectx); 1269 if (isc_result != ISC_R_SUCCESS) { 1270 t_info("isc_entropy_create: %s: exiting\n", 1271 dns_result_totext(isc_result)); 1272 isc_mem_destroy(&mctx); 1273 return(T_UNRESOLVED); 1274 } 1275 1276 isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); 1277 if (isc_result != ISC_R_SUCCESS) { 1278 t_info("isc_hash_create: %s: exiting\n", 1279 dns_result_totext(isc_result)); 1280 isc_entropy_detach(&ectx); 1281 isc_mem_destroy(&mctx); 1282 return(T_UNRESOLVED); 1283 } 1284 1285 dns_rbtnodechain_init(&chain, mctx); 1286 1287 rbt = NULL; 1288 if (rbt_init(dbfile, &rbt, mctx)) { 1289 t_info("rbt_init %s failed\n", dbfile); 1290 isc_hash_destroy(); 1291 isc_entropy_detach(&ectx); 1292 isc_mem_destroy(&mctx); 1293 return(result); 1294 } 1295 1296 t_info("testing for last name of %s, origin of %s\n", 1297 expected_lastname, expected_lastorigin); 1298 1299 dns_result = dns_rbtnodechain_last(&chain, rbt, 1300 dns_fixedname_name(&dns_name), 1301 dns_fixedname_name(&dns_origin)); 1302 1303 if (dns_result != DNS_R_NEWORIGIN) { 1304 t_info("dns_rbtnodechain_last unexpectedly returned %s\n", 1305 dns_result_totext(dns_result)); 1306 } 1307 nfails += t_namechk(dns_result, &dns_name, expected_lastname, 1308 &dns_origin, expected_lastorigin, DNS_R_NEWORIGIN); 1309 1310 t_info("testing for previous name of %s, origin of %s\n", 1311 expected_prevname, expected_prevorigin); 1312 1313 dns_fixedname_init(&dns_name); 1314 dns_result = dns_rbtnodechain_prev(&chain, 1315 dns_fixedname_name(&dns_name), 1316 dns_fixedname_name(&dns_origin)); 1317 1318 if ((dns_result != ISC_R_SUCCESS) && 1319 (dns_result != DNS_R_NEWORIGIN)) { 1320 t_info("dns_rbtnodechain_prev unexpectedly returned %s\n", 1321 dns_result_totext(dns_result)); 1322 } 1323 if (strcasecmp(expected_lastorigin, expected_prevorigin) == 0) 1324 expected_result = ISC_R_SUCCESS; 1325 else 1326 expected_result = DNS_R_NEWORIGIN; 1327 nfails += t_namechk(dns_result, &dns_name, expected_prevname, 1328 &dns_origin, expected_prevorigin, expected_result); 1329 1330 if (nfails) 1331 result = T_FAIL; 1332 else 1333 result = T_PASS; 1334 1335 dns_rbtnodechain_invalidate(&chain); 1336 dns_rbt_destroy(&rbt); 1337 1338 isc_hash_destroy(); 1339 isc_entropy_detach(&ectx); 1340 isc_mem_destroy(&mctx); 1341 1342 return(result); 1343} 1344 1345static int 1346test_dns_rbtnodechain_last(const char *filename) { 1347 FILE *fp; 1348 char *p; 1349 int line; 1350 int cnt; 1351 int result; 1352 int nfails; 1353 int nprobs; 1354 1355 nfails = 0; 1356 nprobs = 0; 1357 1358 fp = fopen(filename, "r"); 1359 if (fp != NULL) { 1360 line = 0; 1361 while ((p = t_fgetbs(fp)) != NULL) { 1362 1363 ++line; 1364 1365 /* 1366 * Skip comment lines. 1367 */ 1368 if ((isspace((unsigned char)*p)) || (*p == '#')) { 1369 (void)free(p); 1370 continue; 1371 } 1372 1373 cnt = t_bustline(p, Tokens); 1374 if (cnt == 5) { 1375 result = t_dns_rbtnodechain_last( 1376 Tokens[0], /* dbfile */ 1377 Tokens[1], /* lastname */ 1378 Tokens[2], /* lastorigin */ 1379 Tokens[3], /* prevname */ 1380 Tokens[4]); /* prevorigin */ 1381 if (result != T_PASS) { 1382 if (result == T_FAIL) 1383 ++nfails; 1384 else 1385 ++nprobs; 1386 } 1387 } else { 1388 t_info("bad format in %s at line %d\n", 1389 filename, line); 1390 ++nprobs; 1391 } 1392 1393 (void)free(p); 1394 } 1395 (void)fclose(fp); 1396 } else { 1397 t_info("Missing datafile %s\n", filename); 1398 ++nprobs; 1399 } 1400 1401 result = T_UNRESOLVED; 1402 1403 if ((nfails == 0) && (nprobs == 0)) 1404 result = T_PASS; 1405 else if (nfails) 1406 result = T_FAIL; 1407 1408 return(result); 1409} 1410 1411static const char *a11 = "a call to " 1412 "dns_rbtnodechain_last(chain, rbt, name, origin) " 1413 "sets name to point to the last node of the megatree, " 1414 "origin to the name of the level above it, " 1415 "and returns DNS_R_NEWORIGIN"; 1416 1417static void 1418t11() { 1419 int result; 1420 1421 t_assert("dns_rbtnodechain_last", 11, T_REQUIRED, "%s", a11); 1422 result = test_dns_rbtnodechain_last("dns_rbtnodechain_last_data"); 1423 t_result(result); 1424} 1425 1426static int 1427t_dns_rbtnodechain_next(char *dbfile, char *findname, 1428 char *nextname, char *nextorigin) 1429{ 1430 1431 int result; 1432 int len; 1433 int nfails; 1434 dns_rbt_t *rbt; 1435 dns_rbtnode_t *node; 1436 dns_rbtnodechain_t chain; 1437 isc_mem_t *mctx; 1438 isc_entropy_t *ectx; 1439 isc_result_t isc_result; 1440 isc_result_t dns_result; 1441 dns_fixedname_t dns_findname; 1442 dns_fixedname_t dns_foundname; 1443 dns_fixedname_t dns_nextname; 1444 dns_fixedname_t dns_origin; 1445 isc_buffer_t isc_buffer; 1446 1447 result = T_UNRESOLVED; 1448 1449 nfails = 0; 1450 mctx = NULL; 1451 ectx = NULL; 1452 1453 isc_result = isc_mem_create(0, 0, &mctx); 1454 if (isc_result != ISC_R_SUCCESS) { 1455 t_info("isc_mem_create failed %s\n", 1456 isc_result_totext(isc_result)); 1457 return(result); 1458 } 1459 1460 isc_result = isc_entropy_create(mctx, &ectx); 1461 if (isc_result != ISC_R_SUCCESS) { 1462 t_info("isc_entropy_create: %s: exiting\n", 1463 dns_result_totext(isc_result)); 1464 isc_mem_destroy(&mctx); 1465 return(T_UNRESOLVED); 1466 } 1467 1468 isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); 1469 if (isc_result != ISC_R_SUCCESS) { 1470 t_info("isc_hash_create: %s: exiting\n", 1471 dns_result_totext(isc_result)); 1472 isc_entropy_detach(&ectx); 1473 isc_mem_destroy(&mctx); 1474 return(T_UNRESOLVED); 1475 } 1476 1477 dns_rbtnodechain_init(&chain, mctx); 1478 1479 rbt = NULL; 1480 if (rbt_init(dbfile, &rbt, mctx)) { 1481 t_info("rbt_init %s failed\n", dbfile); 1482 isc_hash_destroy(); 1483 isc_entropy_detach(&ectx); 1484 isc_mem_destroy(&mctx); 1485 return(result); 1486 } 1487 1488 len = strlen(findname); 1489 isc_buffer_init(&isc_buffer, findname, len); 1490 isc_buffer_add(&isc_buffer, len); 1491 1492 dns_fixedname_init(&dns_foundname); 1493 dns_fixedname_init(&dns_findname); 1494 dns_fixedname_init(&dns_nextname); 1495 dns_fixedname_init(&dns_origin); 1496 1497 dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname), 1498 &isc_buffer, NULL, 0, NULL); 1499 1500 if (dns_result != ISC_R_SUCCESS) { 1501 t_info("dns_name_fromtext failed %s\n", 1502 dns_result_totext(dns_result)); 1503 return(result); 1504 } 1505 1506 /* 1507 * Set the starting node. 1508 */ 1509 node = NULL; 1510 dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname), 1511 dns_fixedname_name(&dns_foundname), 1512 &node, &chain, DNS_RBTFIND_EMPTYDATA, 1513 NULL, NULL); 1514 1515 if (dns_result != ISC_R_SUCCESS) { 1516 t_info("dns_rbt_findnode failed %s\n", 1517 dns_result_totext(dns_result)); 1518 return(result); 1519 } 1520 1521 /* 1522 * Check next. 1523 */ 1524 t_info("checking for next name of %s and new origin of %s\n", 1525 nextname, nextorigin); 1526 dns_result = dns_rbtnodechain_next(&chain, 1527 dns_fixedname_name(&dns_nextname), 1528 dns_fixedname_name(&dns_origin)); 1529 1530 if ((dns_result != ISC_R_SUCCESS) && (dns_result != DNS_R_NEWORIGIN)) { 1531 t_info("dns_rbtnodechain_next unexpectedly returned %s\n", 1532 dns_result_totext(dns_result)); 1533 } 1534 1535 nfails += t_namechk(dns_result, &dns_nextname, nextname, &dns_origin, 1536 nextorigin, DNS_R_NEWORIGIN); 1537 1538 if (nfails) 1539 result = T_FAIL; 1540 else 1541 result = T_PASS; 1542 1543 dns_rbtnodechain_invalidate(&chain); 1544 dns_rbt_destroy(&rbt); 1545 1546 isc_hash_destroy(); 1547 isc_entropy_detach(&ectx); 1548 isc_mem_destroy(&mctx); 1549 1550 return(result); 1551} 1552 1553static int 1554test_dns_rbtnodechain_next(const char *filename) { 1555 FILE *fp; 1556 char *p; 1557 int line; 1558 int cnt; 1559 int result; 1560 int nfails; 1561 int nprobs; 1562 1563 nfails = 0; 1564 nprobs = 0; 1565 1566 fp = fopen(filename, "r"); 1567 if (fp != NULL) { 1568 line = 0; 1569 while ((p = t_fgetbs(fp)) != NULL) { 1570 1571 ++line; 1572 1573 /* 1574 * Skip comment lines. 1575 */ 1576 if ((isspace((unsigned char)*p)) || (*p == '#')) { 1577 (void)free(p); 1578 continue; 1579 } 1580 1581 cnt = t_bustline(p, Tokens); 1582 if (cnt == 4) { 1583 result = t_dns_rbtnodechain_next( 1584 Tokens[0], /* dbfile */ 1585 Tokens[1], /* findname */ 1586 Tokens[2], /* nextname */ 1587 Tokens[3]); /* nextorigin */ 1588 if (result != T_PASS) { 1589 if (result == T_FAIL) 1590 ++nfails; 1591 else 1592 ++nprobs; 1593 } 1594 } else { 1595 t_info("bad format in %s at line %d\n", 1596 filename, line); 1597 ++nprobs; 1598 } 1599 1600 (void)free(p); 1601 } 1602 (void)fclose(fp); 1603 } else { 1604 t_info("Missing datafile %s\n", filename); 1605 ++nprobs; 1606 } 1607 1608 result = T_UNRESOLVED; 1609 1610 if ((nfails == 0) && (nprobs == 0)) 1611 result = T_PASS; 1612 else if (nfails) 1613 result = T_FAIL; 1614 1615 return(result); 1616} 1617 1618static const char *a12 = "a call to " 1619 "dns_rbtnodechain_next(chain, name, origin) " 1620 "sets name to point to the next node of the tree " 1621 "and returns ISC_R_SUCCESS or " 1622 "DNS_R_NEWORIGIN on success"; 1623 1624 1625static void 1626t12() { 1627 int result; 1628 1629 t_assert("dns_rbtnodechain_next", 12, T_REQUIRED, "%s", a12); 1630 result = test_dns_rbtnodechain_next("dns_rbtnodechain_next_data"); 1631 t_result(result); 1632} 1633 1634static int 1635t_dns_rbtnodechain_prev(char *dbfile, char *findname, char *prevname, 1636 char *prevorigin) 1637{ 1638 int result; 1639 int len; 1640 int nfails; 1641 dns_rbt_t *rbt; 1642 dns_rbtnode_t *node; 1643 dns_rbtnodechain_t chain; 1644 isc_mem_t *mctx; 1645 isc_entropy_t *ectx = NULL; 1646 isc_result_t isc_result; 1647 isc_result_t dns_result; 1648 dns_fixedname_t dns_findname; 1649 dns_fixedname_t dns_foundname; 1650 dns_fixedname_t dns_prevname; 1651 dns_fixedname_t dns_origin; 1652 isc_buffer_t isc_buffer; 1653 1654 result = T_UNRESOLVED; 1655 1656 nfails = 0; 1657 mctx = NULL; 1658 ectx = NULL; 1659 1660 isc_result = isc_mem_create(0, 0, &mctx); 1661 if (isc_result != ISC_R_SUCCESS) { 1662 t_info("isc_mem_create failed %s\n", 1663 isc_result_totext(isc_result)); 1664 return(result); 1665 } 1666 1667 isc_result = isc_entropy_create(mctx, &ectx); 1668 if (isc_result != ISC_R_SUCCESS) { 1669 t_info("isc_entropy_create: %s: exiting\n", 1670 dns_result_totext(isc_result)); 1671 isc_mem_destroy(&mctx); 1672 return(T_UNRESOLVED); 1673 } 1674 1675 isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); 1676 if (isc_result != ISC_R_SUCCESS) { 1677 t_info("isc_hash_create: %s: exiting\n", 1678 dns_result_totext(isc_result)); 1679 isc_entropy_detach(&ectx); 1680 isc_mem_destroy(&mctx); 1681 return(T_UNRESOLVED); 1682 } 1683 1684 dns_rbtnodechain_init(&chain, mctx); 1685 1686 rbt = NULL; 1687 if (rbt_init(dbfile, &rbt, mctx)) { 1688 t_info("rbt_init %s failed\n", dbfile); 1689 isc_hash_destroy(); 1690 isc_entropy_detach(&ectx); 1691 isc_mem_destroy(&mctx); 1692 return(result); 1693 } 1694 1695 len = strlen(findname); 1696 isc_buffer_init(&isc_buffer, findname, len); 1697 isc_buffer_add(&isc_buffer, len); 1698 1699 dns_fixedname_init(&dns_foundname); 1700 dns_fixedname_init(&dns_findname); 1701 dns_fixedname_init(&dns_prevname); 1702 dns_fixedname_init(&dns_origin); 1703 1704 dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname), 1705 &isc_buffer, NULL, 0, NULL); 1706 1707 if (dns_result != ISC_R_SUCCESS) { 1708 t_info("dns_name_fromtext failed %s\n", 1709 dns_result_totext(dns_result)); 1710 return(result); 1711 } 1712 1713 /* 1714 * Set the starting node. 1715 */ 1716 node = NULL; 1717 dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname), 1718 dns_fixedname_name(&dns_foundname), 1719 &node, &chain, DNS_RBTFIND_EMPTYDATA, 1720 NULL, NULL); 1721 1722 if (dns_result != ISC_R_SUCCESS) { 1723 t_info("dns_rbt_findnode failed %s\n", 1724 dns_result_totext(dns_result)); 1725 return(result); 1726 } 1727 1728 /* 1729 * Check next. 1730 */ 1731 t_info("checking for next name of %s and new origin of %s\n", 1732 prevname, prevorigin); 1733 dns_result = dns_rbtnodechain_prev(&chain, 1734 dns_fixedname_name(&dns_prevname), 1735 dns_fixedname_name(&dns_origin)); 1736 1737 if ((dns_result != ISC_R_SUCCESS) && (dns_result != DNS_R_NEWORIGIN)) { 1738 t_info("dns_rbtnodechain_prev unexpectedly returned %s\n", 1739 dns_result_totext(dns_result)); 1740 } 1741 1742 nfails += t_namechk(dns_result, &dns_prevname, prevname, &dns_origin, 1743 prevorigin, DNS_R_NEWORIGIN); 1744 1745 if (nfails) 1746 result = T_FAIL; 1747 else 1748 result = T_PASS; 1749 1750 dns_rbtnodechain_invalidate(&chain); 1751 dns_rbt_destroy(&rbt); 1752 1753 isc_hash_destroy(); 1754 isc_entropy_detach(&ectx); 1755 isc_mem_destroy(&mctx); 1756 1757 return(result); 1758} 1759 1760static int 1761test_dns_rbtnodechain_prev(const char *filename) { 1762 FILE *fp; 1763 char *p; 1764 int line; 1765 int cnt; 1766 int result; 1767 int nfails; 1768 int nprobs; 1769 1770 nfails = 0; 1771 nprobs = 0; 1772 1773 fp = fopen(filename, "r"); 1774 if (fp != NULL) { 1775 line = 0; 1776 while ((p = t_fgetbs(fp)) != NULL) { 1777 1778 ++line; 1779 1780 /* 1781 * Skip comment lines. 1782 */ 1783 if ((isspace((unsigned char)*p)) || (*p == '#')) { 1784 (void)free(p); 1785 continue; 1786 } 1787 1788 cnt = t_bustline(p, Tokens); 1789 if (cnt == 4) { 1790 result = t_dns_rbtnodechain_prev( 1791 Tokens[0], /* dbfile */ 1792 Tokens[1], /* findname */ 1793 Tokens[2], /* prevname */ 1794 Tokens[3]); /* prevorigin */ 1795 if (result != T_PASS) { 1796 if (result == T_FAIL) 1797 ++nfails; 1798 else 1799 ++nprobs; 1800 } 1801 } else { 1802 t_info("bad format in %s at line %d\n", 1803 filename, line); 1804 ++nprobs; 1805 } 1806 1807 (void)free(p); 1808 } 1809 (void)fclose(fp); 1810 } else { 1811 t_info("Missing datafile %s\n", filename); 1812 ++nprobs; 1813 } 1814 1815 result = T_UNRESOLVED; 1816 1817 if ((nfails == 0) && (nprobs == 0)) 1818 result = T_PASS; 1819 else if (nfails) 1820 result = T_FAIL; 1821 1822 return(result); 1823} 1824 1825static const char *a13 = "a call to " 1826 "dns_rbtnodechain_prev(chain, name, origin) " 1827 "sets name to point to the previous node of the tree " 1828 "and returns ISC_R_SUCCESS or " 1829 "DNS_R_NEWORIGIN on success"; 1830 1831static void 1832t13() { 1833 int result; 1834 1835 t_assert("dns_rbtnodechain_prev", 13, T_REQUIRED, "%s", a13); 1836 result = test_dns_rbtnodechain_prev("dns_rbtnodechain_prev_data"); 1837 t_result(result); 1838} 1839 1840 1841 1842testspec_t T_testlist[] = { 1843 { t1, "dns_rbt_create" }, 1844 { t2, "dns_rbt_addname 1" }, 1845 { t3, "dns_rbt_addname 2" }, 1846 { t4, "dns_rbt_deletename 1" }, 1847 { t5, "dns_rbt_deletename 2" }, 1848 { t6, "dns_rbt_findname 1" }, 1849 { t7, "dns_rbt_findname 2" }, 1850 { t8, "dns_rbt_findname 3" }, 1851 { t9, "dns_rbtnodechain_init" }, 1852 { t10, "dns_rbtnodechain_first" }, 1853 { t11, "dns_rbtnodechain_last" }, 1854 { t12, "dns_rbtnodechain_next" }, 1855 { t13, "dns_rbtnodechain_prev" }, 1856 { NULL, NULL } 1857}; 1858 1859