1 /* $NetBSD: view.c,v 1.10 2014/12/10 04:37:58 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-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 */ 21 22 /*! \file */ 23 24 #include <config.h> 25 26 #include <isc/file.h> 27 #include <isc/hash.h> 28 #include <isc/print.h> 29 #include <isc/sha2.h> 30 #include <isc/stats.h> 31 #include <isc/string.h> /* Required for HP/UX (and others?) */ 32 #include <isc/task.h> 33 #include <isc/util.h> 34 35 #include <dns/acache.h> 36 #include <dns/acl.h> 37 #include <dns/adb.h> 38 #include <dns/cache.h> 39 #include <dns/db.h> 40 #include <dns/dispatch.h> 41 #include <dns/dlz.h> 42 #include <dns/dns64.h> 43 #include <dns/dnssec.h> 44 #include <dns/events.h> 45 #include <dns/forward.h> 46 #include <dns/keytable.h> 47 #include <dns/keyvalues.h> 48 #include <dns/master.h> 49 #include <dns/masterdump.h> 50 #include <dns/order.h> 51 #include <dns/peer.h> 52 #include <dns/rrl.h> 53 #include <dns/rbt.h> 54 #include <dns/rdataset.h> 55 #include <dns/request.h> 56 #include <dns/resolver.h> 57 #include <dns/result.h> 58 #include <dns/rpz.h> 59 #include <dns/stats.h> 60 #include <dns/tsig.h> 61 #include <dns/zone.h> 62 #include <dns/zt.h> 63 64 #define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0) 65 #define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0) 66 #define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0) 67 68 #define DNS_VIEW_DELONLYHASH 111 69 70 static void resolver_shutdown(isc_task_t *task, isc_event_t *event); 71 static void adb_shutdown(isc_task_t *task, isc_event_t *event); 72 static void req_shutdown(isc_task_t *task, isc_event_t *event); 73 74 isc_result_t 75 dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, 76 const char *name, dns_view_t **viewp) 77 { 78 dns_view_t *view; 79 isc_result_t result; 80 81 /* 82 * Create a view. 83 */ 84 85 REQUIRE(name != NULL); 86 REQUIRE(viewp != NULL && *viewp == NULL); 87 88 view = isc_mem_get(mctx, sizeof(*view)); 89 if (view == NULL) 90 return (ISC_R_NOMEMORY); 91 92 view->mctx = NULL; 93 isc_mem_attach(mctx, &view->mctx); 94 view->name = isc_mem_strdup(mctx, name); 95 if (view->name == NULL) { 96 result = ISC_R_NOMEMORY; 97 goto cleanup_view; 98 } 99 result = isc_mutex_init(&view->lock); 100 if (result != ISC_R_SUCCESS) 101 goto cleanup_name; 102 103 view->zonetable = NULL; 104 if (isc_bind9) { 105 result = dns_zt_create(mctx, rdclass, &view->zonetable); 106 if (result != ISC_R_SUCCESS) { 107 UNEXPECTED_ERROR(__FILE__, __LINE__, 108 "dns_zt_create() failed: %s", 109 isc_result_totext(result)); 110 result = ISC_R_UNEXPECTED; 111 goto cleanup_mutex; 112 } 113 } 114 view->secroots_priv = NULL; 115 view->fwdtable = NULL; 116 result = dns_fwdtable_create(mctx, &view->fwdtable); 117 if (result != ISC_R_SUCCESS) { 118 UNEXPECTED_ERROR(__FILE__, __LINE__, 119 "dns_fwdtable_create() failed: %s", 120 isc_result_totext(result)); 121 result = ISC_R_UNEXPECTED; 122 goto cleanup_zt; 123 } 124 125 view->acache = NULL; 126 view->cache = NULL; 127 view->cachedb = NULL; 128 ISC_LIST_INIT(view->dlz_searched); 129 ISC_LIST_INIT(view->dlz_unsearched); 130 view->hints = NULL; 131 view->resolver = NULL; 132 view->adb = NULL; 133 view->requestmgr = NULL; 134 view->rdclass = rdclass; 135 view->frozen = ISC_FALSE; 136 view->task = NULL; 137 result = isc_refcount_init(&view->references, 1); 138 if (result != ISC_R_SUCCESS) 139 goto cleanup_fwdtable; 140 view->weakrefs = 0; 141 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| 142 DNS_VIEWATTR_REQSHUTDOWN); 143 view->statickeys = NULL; 144 view->dynamickeys = NULL; 145 view->matchclients = NULL; 146 view->matchdestinations = NULL; 147 view->matchrecursiveonly = ISC_FALSE; 148 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); 149 if (result != ISC_R_SUCCESS) 150 goto cleanup_references; 151 view->peers = NULL; 152 view->order = NULL; 153 view->delonly = NULL; 154 view->rootdelonly = ISC_FALSE; 155 view->rootexclude = NULL; 156 view->adbstats = NULL; 157 view->resstats = NULL; 158 view->resquerystats = NULL; 159 view->cacheshared = ISC_FALSE; 160 ISC_LIST_INIT(view->dns64); 161 view->dns64cnt = 0; 162 163 /* 164 * Initialize configuration data with default values. 165 */ 166 view->recursion = ISC_TRUE; 167 view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */ 168 view->additionalfromcache = ISC_TRUE; 169 view->additionalfromauth = ISC_TRUE; 170 view->enablednssec = ISC_TRUE; 171 view->enablevalidation = ISC_TRUE; 172 view->acceptexpired = ISC_FALSE; 173 view->minimalresponses = ISC_FALSE; 174 view->transfer_format = dns_one_answer; 175 view->cacheacl = NULL; 176 view->cacheonacl = NULL; 177 view->queryacl = NULL; 178 view->queryonacl = NULL; 179 view->recursionacl = NULL; 180 view->recursiononacl = NULL; 181 view->sortlist = NULL; 182 view->transferacl = NULL; 183 view->notifyacl = NULL; 184 view->updateacl = NULL; 185 view->upfwdacl = NULL; 186 view->denyansweracl = NULL; 187 view->nocasecompress = NULL; 188 view->answeracl_exclude = NULL; 189 view->denyanswernames = NULL; 190 view->answernames_exclude = NULL; 191 view->rrl = NULL; 192 view->provideixfr = ISC_TRUE; 193 view->maxcachettl = 7 * 24 * 3600; 194 view->maxncachettl = 3 * 3600; 195 view->prefetch_eligible = 0; 196 view->prefetch_trigger = 0; 197 view->dstport = 53; 198 view->preferred_glue = 0; 199 view->flush = ISC_FALSE; 200 view->dlv = NULL; 201 view->maxudp = 0; 202 view->situdp = 0; 203 view->maxbits = 0; 204 view->v4_aaaa = dns_aaaa_ok; 205 view->v6_aaaa = dns_aaaa_ok; 206 view->aaaa_acl = NULL; 207 view->rpzs = NULL; 208 dns_fixedname_init(&view->dlv_fixed); 209 view->managed_keys = NULL; 210 view->redirect = NULL; 211 view->requestnsid = ISC_FALSE; 212 view->requestsit = ISC_TRUE; 213 view->new_zone_file = NULL; 214 view->new_zone_config = NULL; 215 view->cfg_destroy = NULL; 216 217 if (isc_bind9) { 218 result = dns_order_create(view->mctx, &view->order); 219 if (result != ISC_R_SUCCESS) 220 goto cleanup_dynkeys; 221 } 222 223 result = dns_peerlist_new(view->mctx, &view->peers); 224 if (result != ISC_R_SUCCESS) 225 goto cleanup_order; 226 227 result = dns_aclenv_init(view->mctx, &view->aclenv); 228 if (result != ISC_R_SUCCESS) 229 goto cleanup_peerlist; 230 231 ISC_LINK_INIT(view, link); 232 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL, 233 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown, 234 view, NULL, NULL, NULL); 235 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL, 236 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown, 237 view, NULL, NULL, NULL); 238 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL, 239 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, 240 view, NULL, NULL, NULL); 241 view->viewlist = NULL; 242 view->magic = DNS_VIEW_MAGIC; 243 244 *viewp = view; 245 246 return (ISC_R_SUCCESS); 247 248 cleanup_peerlist: 249 if (view->peers != NULL) 250 dns_peerlist_detach(&view->peers); 251 252 cleanup_order: 253 if (view->order != NULL) 254 dns_order_detach(&view->order); 255 256 cleanup_dynkeys: 257 if (view->dynamickeys != NULL) 258 dns_tsigkeyring_detach(&view->dynamickeys); 259 260 cleanup_references: 261 isc_refcount_destroy(&view->references); 262 263 cleanup_fwdtable: 264 if (view->fwdtable != NULL) 265 dns_fwdtable_destroy(&view->fwdtable); 266 267 cleanup_zt: 268 if (view->zonetable != NULL) 269 dns_zt_detach(&view->zonetable); 270 271 cleanup_mutex: 272 DESTROYLOCK(&view->lock); 273 274 cleanup_name: 275 isc_mem_free(mctx, view->name); 276 277 cleanup_view: 278 isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); 279 280 return (result); 281 } 282 283 static inline void 284 destroy(dns_view_t *view) { 285 dns_dns64_t *dns64; 286 dns_dlzdb_t *dlzdb; 287 288 REQUIRE(!ISC_LINK_LINKED(view, link)); 289 REQUIRE(isc_refcount_current(&view->references) == 0); 290 REQUIRE(view->weakrefs == 0); 291 REQUIRE(RESSHUTDOWN(view)); 292 REQUIRE(ADBSHUTDOWN(view)); 293 REQUIRE(REQSHUTDOWN(view)); 294 295 if (view->order != NULL) 296 dns_order_detach(&view->order); 297 if (view->peers != NULL) 298 dns_peerlist_detach(&view->peers); 299 300 if (view->dynamickeys != NULL) { 301 isc_result_t result; 302 char template[20]; 303 char keyfile[20]; 304 FILE *fp = NULL; 305 int n; 306 307 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", 308 view->name); 309 if (n > 0 && (size_t)n < sizeof(keyfile)) { 310 result = isc_file_mktemplate(keyfile, template, 311 sizeof(template)); 312 if (result == ISC_R_SUCCESS) 313 (void)isc_file_openuniqueprivate(template, &fp); 314 } 315 if (fp == NULL) 316 dns_tsigkeyring_detach(&view->dynamickeys); 317 else { 318 result = dns_tsigkeyring_dumpanddetach( 319 &view->dynamickeys, fp); 320 if (result == ISC_R_SUCCESS) { 321 if (fclose(fp) == 0) 322 result = isc_file_rename(template, 323 keyfile); 324 if (result != ISC_R_SUCCESS) 325 (void)remove(template); 326 } else { 327 (void)fclose(fp); 328 (void)remove(template); 329 } 330 } 331 } 332 if (view->statickeys != NULL) 333 dns_tsigkeyring_detach(&view->statickeys); 334 if (view->adb != NULL) 335 dns_adb_detach(&view->adb); 336 if (view->resolver != NULL) 337 dns_resolver_detach(&view->resolver); 338 if (view->acache != NULL) { 339 if (view->cachedb != NULL) 340 dns_acache_putdb(view->acache, view->cachedb); 341 dns_acache_detach(&view->acache); 342 } 343 dns_rrl_view_destroy(view); 344 if (view->rpzs != NULL) 345 dns_rpz_detach_rpzs(&view->rpzs); 346 for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); 347 dlzdb != NULL; 348 dlzdb = ISC_LIST_HEAD(view->dlz_searched)) { 349 ISC_LIST_UNLINK(view->dlz_searched, dlzdb, link); 350 dns_dlzdestroy(&dlzdb); 351 } 352 for (dlzdb = ISC_LIST_HEAD(view->dlz_unsearched); 353 dlzdb != NULL; 354 dlzdb = ISC_LIST_HEAD(view->dlz_unsearched)) { 355 ISC_LIST_UNLINK(view->dlz_unsearched, dlzdb, link); 356 dns_dlzdestroy(&dlzdb); 357 } 358 if (view->requestmgr != NULL) 359 dns_requestmgr_detach(&view->requestmgr); 360 if (view->task != NULL) 361 isc_task_detach(&view->task); 362 if (view->hints != NULL) 363 dns_db_detach(&view->hints); 364 if (view->cachedb != NULL) 365 dns_db_detach(&view->cachedb); 366 if (view->cache != NULL) 367 dns_cache_detach(&view->cache); 368 if (view->nocasecompress != NULL) 369 dns_acl_detach(&view->nocasecompress); 370 if (view->matchclients != NULL) 371 dns_acl_detach(&view->matchclients); 372 if (view->matchdestinations != NULL) 373 dns_acl_detach(&view->matchdestinations); 374 if (view->cacheacl != NULL) 375 dns_acl_detach(&view->cacheacl); 376 if (view->cacheonacl != NULL) 377 dns_acl_detach(&view->cacheonacl); 378 if (view->queryacl != NULL) 379 dns_acl_detach(&view->queryacl); 380 if (view->queryonacl != NULL) 381 dns_acl_detach(&view->queryonacl); 382 if (view->recursionacl != NULL) 383 dns_acl_detach(&view->recursionacl); 384 if (view->recursiononacl != NULL) 385 dns_acl_detach(&view->recursiononacl); 386 if (view->sortlist != NULL) 387 dns_acl_detach(&view->sortlist); 388 if (view->transferacl != NULL) 389 dns_acl_detach(&view->transferacl); 390 if (view->notifyacl != NULL) 391 dns_acl_detach(&view->notifyacl); 392 if (view->updateacl != NULL) 393 dns_acl_detach(&view->updateacl); 394 if (view->upfwdacl != NULL) 395 dns_acl_detach(&view->upfwdacl); 396 if (view->denyansweracl != NULL) 397 dns_acl_detach(&view->denyansweracl); 398 if (view->aaaa_acl != NULL) 399 dns_acl_detach(&view->aaaa_acl); 400 if (view->answeracl_exclude != NULL) 401 dns_rbt_destroy(&view->answeracl_exclude); 402 if (view->denyanswernames != NULL) 403 dns_rbt_destroy(&view->denyanswernames); 404 if (view->answernames_exclude != NULL) 405 dns_rbt_destroy(&view->answernames_exclude); 406 if (view->delonly != NULL) { 407 dns_name_t *name; 408 int i; 409 410 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 411 name = ISC_LIST_HEAD(view->delonly[i]); 412 while (name != NULL) { 413 ISC_LIST_UNLINK(view->delonly[i], name, link); 414 dns_name_free(name, view->mctx); 415 isc_mem_put(view->mctx, name, sizeof(*name)); 416 name = ISC_LIST_HEAD(view->delonly[i]); 417 } 418 } 419 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) * 420 DNS_VIEW_DELONLYHASH); 421 view->delonly = NULL; 422 } 423 if (view->rootexclude != NULL) { 424 dns_name_t *name; 425 int i; 426 427 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 428 name = ISC_LIST_HEAD(view->rootexclude[i]); 429 while (name != NULL) { 430 ISC_LIST_UNLINK(view->rootexclude[i], 431 name, link); 432 dns_name_free(name, view->mctx); 433 isc_mem_put(view->mctx, name, sizeof(*name)); 434 name = ISC_LIST_HEAD(view->rootexclude[i]); 435 } 436 } 437 isc_mem_put(view->mctx, view->rootexclude, 438 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); 439 view->rootexclude = NULL; 440 } 441 if (view->adbstats != NULL) 442 isc_stats_detach(&view->adbstats); 443 if (view->resstats != NULL) 444 isc_stats_detach(&view->resstats); 445 if (view->resquerystats != NULL) 446 dns_stats_detach(&view->resquerystats); 447 if (view->secroots_priv != NULL) 448 dns_keytable_detach(&view->secroots_priv); 449 for (dns64 = ISC_LIST_HEAD(view->dns64); 450 dns64 != NULL; 451 dns64 = ISC_LIST_HEAD(view->dns64)) { 452 dns_dns64_unlink(&view->dns64, dns64); 453 dns_dns64_destroy(&dns64); 454 } 455 if (view->managed_keys != NULL) 456 dns_zone_detach(&view->managed_keys); 457 if (view->redirect != NULL) 458 dns_zone_detach(&view->redirect); 459 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); 460 dns_fwdtable_destroy(&view->fwdtable); 461 dns_aclenv_destroy(&view->aclenv); 462 DESTROYLOCK(&view->lock); 463 isc_refcount_destroy(&view->references); 464 isc_mem_free(view->mctx, view->name); 465 isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); 466 } 467 468 /* 469 * Return true iff 'view' may be freed. 470 * The caller must be holding the view lock. 471 */ 472 static isc_boolean_t 473 all_done(dns_view_t *view) { 474 475 if (isc_refcount_current(&view->references) == 0 && 476 view->weakrefs == 0 && 477 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) 478 return (ISC_TRUE); 479 480 return (ISC_FALSE); 481 } 482 483 void 484 dns_view_attach(dns_view_t *source, dns_view_t **targetp) { 485 486 REQUIRE(DNS_VIEW_VALID(source)); 487 REQUIRE(targetp != NULL && *targetp == NULL); 488 489 isc_refcount_increment(&source->references, NULL); 490 491 *targetp = source; 492 } 493 494 static void 495 view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { 496 dns_view_t *view; 497 unsigned int refs; 498 isc_boolean_t done = ISC_FALSE; 499 500 REQUIRE(viewp != NULL); 501 view = *viewp; 502 REQUIRE(DNS_VIEW_VALID(view)); 503 504 if (flush) 505 view->flush = ISC_TRUE; 506 isc_refcount_decrement(&view->references, &refs); 507 if (refs == 0) { 508 dns_zone_t *mkzone = NULL, *rdzone = NULL; 509 510 LOCK(&view->lock); 511 if (!RESSHUTDOWN(view)) 512 dns_resolver_shutdown(view->resolver); 513 if (!ADBSHUTDOWN(view)) 514 dns_adb_shutdown(view->adb); 515 if (!REQSHUTDOWN(view)) 516 dns_requestmgr_shutdown(view->requestmgr); 517 if (view->acache != NULL) 518 dns_acache_shutdown(view->acache); 519 if (view->zonetable != NULL) { 520 if (view->flush) 521 dns_zt_flushanddetach(&view->zonetable); 522 else 523 dns_zt_detach(&view->zonetable); 524 } 525 if (view->managed_keys != NULL) { 526 mkzone = view->managed_keys; 527 view->managed_keys = NULL; 528 if (view->flush) 529 dns_zone_flush(mkzone); 530 } 531 if (view->redirect != NULL) { 532 rdzone = view->redirect; 533 view->redirect = NULL; 534 if (view->flush) 535 dns_zone_flush(rdzone); 536 } 537 done = all_done(view); 538 UNLOCK(&view->lock); 539 540 /* Need to detach zones outside view lock */ 541 if (mkzone != NULL) 542 dns_zone_detach(&mkzone); 543 544 if (rdzone != NULL) 545 dns_zone_detach(&rdzone); 546 } 547 548 *viewp = NULL; 549 550 if (done) 551 destroy(view); 552 } 553 554 void 555 dns_view_flushanddetach(dns_view_t **viewp) { 556 view_flushanddetach(viewp, ISC_TRUE); 557 } 558 559 void 560 dns_view_detach(dns_view_t **viewp) { 561 view_flushanddetach(viewp, ISC_FALSE); 562 } 563 564 static isc_result_t 565 dialup(dns_zone_t *zone, void *dummy) { 566 UNUSED(dummy); 567 dns_zone_dialup(zone); 568 return (ISC_R_SUCCESS); 569 } 570 571 void 572 dns_view_dialup(dns_view_t *view) { 573 REQUIRE(DNS_VIEW_VALID(view)); 574 REQUIRE(view->zonetable != NULL); 575 576 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL); 577 } 578 579 void 580 dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { 581 582 REQUIRE(DNS_VIEW_VALID(source)); 583 REQUIRE(targetp != NULL && *targetp == NULL); 584 585 LOCK(&source->lock); 586 source->weakrefs++; 587 UNLOCK(&source->lock); 588 589 *targetp = source; 590 } 591 592 void 593 dns_view_weakdetach(dns_view_t **viewp) { 594 dns_view_t *view; 595 isc_boolean_t done = ISC_FALSE; 596 597 REQUIRE(viewp != NULL); 598 view = *viewp; 599 REQUIRE(DNS_VIEW_VALID(view)); 600 601 LOCK(&view->lock); 602 603 INSIST(view->weakrefs > 0); 604 view->weakrefs--; 605 done = all_done(view); 606 607 UNLOCK(&view->lock); 608 609 *viewp = NULL; 610 611 if (done) 612 destroy(view); 613 } 614 615 static void 616 resolver_shutdown(isc_task_t *task, isc_event_t *event) { 617 dns_view_t *view = event->ev_arg; 618 isc_boolean_t done; 619 620 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); 621 REQUIRE(DNS_VIEW_VALID(view)); 622 REQUIRE(view->task == task); 623 624 UNUSED(task); 625 626 isc_event_free(&event); 627 628 LOCK(&view->lock); 629 630 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; 631 done = all_done(view); 632 633 UNLOCK(&view->lock); 634 635 if (done) 636 destroy(view); 637 } 638 639 static void 640 adb_shutdown(isc_task_t *task, isc_event_t *event) { 641 dns_view_t *view = event->ev_arg; 642 isc_boolean_t done; 643 644 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); 645 REQUIRE(DNS_VIEW_VALID(view)); 646 REQUIRE(view->task == task); 647 648 UNUSED(task); 649 650 isc_event_free(&event); 651 652 LOCK(&view->lock); 653 654 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; 655 done = all_done(view); 656 657 UNLOCK(&view->lock); 658 659 if (done) 660 destroy(view); 661 } 662 663 static void 664 req_shutdown(isc_task_t *task, isc_event_t *event) { 665 dns_view_t *view = event->ev_arg; 666 isc_boolean_t done; 667 668 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); 669 REQUIRE(DNS_VIEW_VALID(view)); 670 REQUIRE(view->task == task); 671 672 UNUSED(task); 673 674 isc_event_free(&event); 675 676 LOCK(&view->lock); 677 678 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; 679 done = all_done(view); 680 681 UNLOCK(&view->lock); 682 683 if (done) 684 destroy(view); 685 } 686 687 isc_result_t 688 dns_view_createzonetable(dns_view_t *view) { 689 690 REQUIRE(DNS_VIEW_VALID(view)); 691 REQUIRE(!view->frozen); 692 REQUIRE(view->zonetable == NULL); 693 694 return (dns_zt_create(view->mctx, view->rdclass, &view->zonetable)); 695 } 696 697 isc_result_t 698 dns_view_createresolver(dns_view_t *view, 699 isc_taskmgr_t *taskmgr, 700 unsigned int ntasks, unsigned int ndisp, 701 isc_socketmgr_t *socketmgr, 702 isc_timermgr_t *timermgr, 703 unsigned int options, 704 dns_dispatchmgr_t *dispatchmgr, 705 dns_dispatch_t *dispatchv4, 706 dns_dispatch_t *dispatchv6) 707 { 708 isc_result_t result; 709 isc_event_t *event; 710 isc_mem_t *mctx = NULL; 711 712 REQUIRE(DNS_VIEW_VALID(view)); 713 REQUIRE(!view->frozen); 714 REQUIRE(view->resolver == NULL); 715 716 result = isc_task_create(taskmgr, 0, &view->task); 717 if (result != ISC_R_SUCCESS) 718 return (result); 719 isc_task_setname(view->task, "view", view); 720 721 result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr, 722 timermgr, options, dispatchmgr, 723 dispatchv4, dispatchv6, 724 &view->resolver); 725 if (result != ISC_R_SUCCESS) { 726 isc_task_detach(&view->task); 727 return (result); 728 } 729 event = &view->resevent; 730 dns_resolver_whenshutdown(view->resolver, view->task, &event); 731 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; 732 733 result = isc_mem_create(0, 0, &mctx); 734 if (result != ISC_R_SUCCESS) { 735 dns_resolver_shutdown(view->resolver); 736 return (result); 737 } 738 739 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb); 740 isc_mem_setname(mctx, "ADB", NULL); 741 isc_mem_detach(&mctx); 742 if (result != ISC_R_SUCCESS) { 743 dns_resolver_shutdown(view->resolver); 744 return (result); 745 } 746 event = &view->adbevent; 747 dns_adb_whenshutdown(view->adb, view->task, &event); 748 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; 749 750 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, 751 dns_resolver_taskmgr(view->resolver), 752 dns_resolver_dispatchmgr(view->resolver), 753 dispatchv4, dispatchv6, 754 &view->requestmgr); 755 if (result != ISC_R_SUCCESS) { 756 dns_adb_shutdown(view->adb); 757 dns_resolver_shutdown(view->resolver); 758 return (result); 759 } 760 event = &view->reqevent; 761 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); 762 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; 763 764 return (ISC_R_SUCCESS); 765 } 766 767 void 768 dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { 769 dns_view_setcache2(view, cache, ISC_FALSE); 770 } 771 772 void 773 dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) { 774 REQUIRE(DNS_VIEW_VALID(view)); 775 REQUIRE(!view->frozen); 776 777 view->cacheshared = shared; 778 if (view->cache != NULL) { 779 if (view->acache != NULL) 780 dns_acache_putdb(view->acache, view->cachedb); 781 dns_db_detach(&view->cachedb); 782 dns_cache_detach(&view->cache); 783 } 784 dns_cache_attach(cache, &view->cache); 785 dns_cache_attachdb(cache, &view->cachedb); 786 INSIST(DNS_DB_VALID(view->cachedb)); 787 788 if (view->acache != NULL) 789 dns_acache_setdb(view->acache, view->cachedb); 790 } 791 792 isc_boolean_t 793 dns_view_iscacheshared(dns_view_t *view) { 794 REQUIRE(DNS_VIEW_VALID(view)); 795 796 return (view->cacheshared); 797 } 798 799 void 800 dns_view_sethints(dns_view_t *view, dns_db_t *hints) { 801 REQUIRE(DNS_VIEW_VALID(view)); 802 REQUIRE(!view->frozen); 803 REQUIRE(view->hints == NULL); 804 REQUIRE(dns_db_iszone(hints)); 805 806 dns_db_attach(hints, &view->hints); 807 } 808 809 void 810 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 811 REQUIRE(DNS_VIEW_VALID(view)); 812 REQUIRE(ring != NULL); 813 if (view->statickeys != NULL) 814 dns_tsigkeyring_detach(&view->statickeys); 815 dns_tsigkeyring_attach(ring, &view->statickeys); 816 } 817 818 void 819 dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 820 REQUIRE(DNS_VIEW_VALID(view)); 821 REQUIRE(ring != NULL); 822 if (view->dynamickeys != NULL) 823 dns_tsigkeyring_detach(&view->dynamickeys); 824 dns_tsigkeyring_attach(ring, &view->dynamickeys); 825 } 826 827 void 828 dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) { 829 REQUIRE(DNS_VIEW_VALID(view)); 830 REQUIRE(ringp != NULL && *ringp == NULL); 831 if (view->dynamickeys != NULL) 832 dns_tsigkeyring_attach(view->dynamickeys, ringp); 833 } 834 835 void 836 dns_view_restorekeyring(dns_view_t *view) { 837 FILE *fp; 838 char keyfile[20]; 839 int n; 840 841 REQUIRE(DNS_VIEW_VALID(view)); 842 843 if (view->dynamickeys != NULL) { 844 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", 845 view->name); 846 if (n > 0 && (size_t)n < sizeof(keyfile)) { 847 fp = fopen(keyfile, "r"); 848 if (fp != NULL) { 849 dns_keyring_restore(view->dynamickeys, fp); 850 (void)fclose(fp); 851 } 852 } 853 } 854 } 855 856 void 857 dns_view_setdstport(dns_view_t *view, in_port_t dstport) { 858 REQUIRE(DNS_VIEW_VALID(view)); 859 view->dstport = dstport; 860 } 861 862 void 863 dns_view_freeze(dns_view_t *view) { 864 REQUIRE(DNS_VIEW_VALID(view)); 865 REQUIRE(!view->frozen); 866 867 if (view->resolver != NULL) { 868 INSIST(view->cachedb != NULL); 869 dns_resolver_freeze(view->resolver); 870 } 871 view->frozen = ISC_TRUE; 872 } 873 874 void 875 dns_view_thaw(dns_view_t *view) { 876 REQUIRE(DNS_VIEW_VALID(view)); 877 REQUIRE(view->frozen); 878 879 view->frozen = ISC_FALSE; 880 } 881 882 isc_result_t 883 dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { 884 isc_result_t result; 885 886 REQUIRE(DNS_VIEW_VALID(view)); 887 REQUIRE(!view->frozen); 888 REQUIRE(view->zonetable != NULL); 889 890 result = dns_zt_mount(view->zonetable, zone); 891 892 return (result); 893 } 894 895 isc_result_t 896 dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { 897 isc_result_t result; 898 899 REQUIRE(DNS_VIEW_VALID(view)); 900 901 LOCK(&view->lock); 902 if (view->zonetable != NULL) { 903 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); 904 if (result == DNS_R_PARTIALMATCH) { 905 dns_zone_detach(zonep); 906 result = ISC_R_NOTFOUND; 907 } 908 } else 909 result = ISC_R_NOTFOUND; 910 UNLOCK(&view->lock); 911 912 return (result); 913 } 914 915 isc_result_t 916 dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 917 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, 918 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 919 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { 920 return (dns_view_find2(view, name, type, now, options, use_hints, 921 ISC_FALSE, dbp, nodep, foundname, rdataset, 922 sigrdataset)); 923 } 924 925 isc_result_t 926 dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 927 isc_stdtime_t now, unsigned int options, 928 isc_boolean_t use_hints, isc_boolean_t use_static_stub, 929 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 930 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 931 { 932 isc_result_t result; 933 dns_db_t *db, *zdb; 934 dns_dbnode_t *node, *znode; 935 isc_boolean_t is_cache, is_staticstub_zone; 936 dns_rdataset_t zrdataset, zsigrdataset; 937 dns_zone_t *zone; 938 939 /* 940 * Find an rdataset whose owner name is 'name', and whose type is 941 * 'type'. 942 */ 943 944 REQUIRE(DNS_VIEW_VALID(view)); 945 REQUIRE(view->frozen); 946 REQUIRE(type != dns_rdatatype_rrsig); 947 REQUIRE(rdataset != NULL); /* XXXBEW - remove this */ 948 REQUIRE(nodep == NULL || *nodep == NULL); 949 950 /* 951 * Initialize. 952 */ 953 dns_rdataset_init(&zrdataset); 954 dns_rdataset_init(&zsigrdataset); 955 zdb = NULL; 956 znode = NULL; 957 958 /* 959 * Find a database to answer the query. 960 */ 961 db = NULL; 962 node = NULL; 963 is_staticstub_zone = ISC_FALSE; 964 zone = NULL; 965 LOCK(&view->lock); 966 if (view->zonetable != NULL) 967 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 968 else 969 result = ISC_R_NOTFOUND; 970 UNLOCK(&view->lock); 971 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub && 972 !use_static_stub) 973 result = ISC_R_NOTFOUND; 974 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 975 result = dns_zone_getdb(zone, &db); 976 if (result != ISC_R_SUCCESS && view->cachedb != NULL) 977 dns_db_attach(view->cachedb, &db); 978 else if (result != ISC_R_SUCCESS) 979 goto cleanup; 980 if (dns_zone_gettype(zone) == dns_zone_staticstub && 981 dns_name_equal(name, dns_zone_getorigin(zone))) { 982 is_staticstub_zone = ISC_TRUE; 983 } 984 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL) 985 dns_db_attach(view->cachedb, &db); 986 else 987 goto cleanup; 988 989 is_cache = dns_db_iscache(db); 990 991 db_find: 992 /* 993 * Now look for an answer in the database. 994 */ 995 result = dns_db_find(db, name, NULL, type, options, 996 now, &node, foundname, rdataset, sigrdataset); 997 998 if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) { 999 if (dns_rdataset_isassociated(rdataset)) 1000 dns_rdataset_disassociate(rdataset); 1001 if (sigrdataset != NULL && 1002 dns_rdataset_isassociated(sigrdataset)) 1003 dns_rdataset_disassociate(sigrdataset); 1004 if (node != NULL) 1005 dns_db_detachnode(db, &node); 1006 if (!is_cache) { 1007 dns_db_detach(&db); 1008 if (view->cachedb != NULL && !is_staticstub_zone) { 1009 /* 1010 * Either the answer is in the cache, or we 1011 * don't know it. 1012 * Note that if the result comes from a 1013 * static-stub zone we stop the search here 1014 * (see the function description in view.h). 1015 */ 1016 is_cache = ISC_TRUE; 1017 dns_db_attach(view->cachedb, &db); 1018 goto db_find; 1019 } 1020 } else { 1021 /* 1022 * We don't have the data in the cache. If we've got 1023 * glue from the zone, use it. 1024 */ 1025 if (dns_rdataset_isassociated(&zrdataset)) { 1026 dns_rdataset_clone(&zrdataset, rdataset); 1027 if (sigrdataset != NULL && 1028 dns_rdataset_isassociated(&zsigrdataset)) 1029 dns_rdataset_clone(&zsigrdataset, 1030 sigrdataset); 1031 result = DNS_R_GLUE; 1032 if (db != NULL) 1033 dns_db_detach(&db); 1034 dns_db_attach(zdb, &db); 1035 dns_db_attachnode(db, znode, &node); 1036 goto cleanup; 1037 } 1038 } 1039 /* 1040 * We don't know the answer. 1041 */ 1042 result = ISC_R_NOTFOUND; 1043 } else if (result == DNS_R_GLUE) { 1044 if (view->cachedb != NULL && !is_staticstub_zone) { 1045 /* 1046 * We found an answer, but the cache may be better. 1047 * Remember what we've got and go look in the cache. 1048 */ 1049 is_cache = ISC_TRUE; 1050 dns_rdataset_clone(rdataset, &zrdataset); 1051 dns_rdataset_disassociate(rdataset); 1052 if (sigrdataset != NULL && 1053 dns_rdataset_isassociated(sigrdataset)) { 1054 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1055 dns_rdataset_disassociate(sigrdataset); 1056 } 1057 dns_db_attach(db, &zdb); 1058 dns_db_attachnode(zdb, node, &znode); 1059 dns_db_detachnode(db, &node); 1060 dns_db_detach(&db); 1061 dns_db_attach(view->cachedb, &db); 1062 goto db_find; 1063 } 1064 /* 1065 * Otherwise, the glue is the best answer. 1066 */ 1067 result = ISC_R_SUCCESS; 1068 } 1069 1070 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) { 1071 if (dns_rdataset_isassociated(rdataset)) 1072 dns_rdataset_disassociate(rdataset); 1073 if (sigrdataset != NULL && 1074 dns_rdataset_isassociated(sigrdataset)) 1075 dns_rdataset_disassociate(sigrdataset); 1076 if (db != NULL) { 1077 if (node != NULL) 1078 dns_db_detachnode(db, &node); 1079 dns_db_detach(&db); 1080 } 1081 result = dns_db_find(view->hints, name, NULL, type, options, 1082 now, &node, foundname, 1083 rdataset, sigrdataset); 1084 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) { 1085 /* 1086 * We just used a hint. Let the resolver know it 1087 * should consider priming. 1088 */ 1089 dns_resolver_prime(view->resolver); 1090 dns_db_attach(view->hints, &db); 1091 result = DNS_R_HINT; 1092 } else if (result == DNS_R_NXRRSET) { 1093 dns_db_attach(view->hints, &db); 1094 result = DNS_R_HINTNXRRSET; 1095 } else if (result == DNS_R_NXDOMAIN) 1096 result = ISC_R_NOTFOUND; 1097 1098 /* 1099 * Cleanup if non-standard hints are used. 1100 */ 1101 if (db == NULL && node != NULL) 1102 dns_db_detachnode(view->hints, &node); 1103 } 1104 1105 cleanup: 1106 if (dns_rdataset_isassociated(&zrdataset)) { 1107 dns_rdataset_disassociate(&zrdataset); 1108 if (dns_rdataset_isassociated(&zsigrdataset)) 1109 dns_rdataset_disassociate(&zsigrdataset); 1110 } 1111 1112 if (zdb != NULL) { 1113 if (znode != NULL) 1114 dns_db_detachnode(zdb, &znode); 1115 dns_db_detach(&zdb); 1116 } 1117 1118 if (db != NULL) { 1119 if (node != NULL) { 1120 if (nodep != NULL) 1121 *nodep = node; 1122 else 1123 dns_db_detachnode(db, &node); 1124 } 1125 if (dbp != NULL) 1126 *dbp = db; 1127 else 1128 dns_db_detach(&db); 1129 } else 1130 INSIST(node == NULL); 1131 1132 if (zone != NULL) 1133 dns_zone_detach(&zone); 1134 1135 return (result); 1136 } 1137 1138 isc_result_t 1139 dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 1140 isc_stdtime_t now, unsigned int options, 1141 isc_boolean_t use_hints, 1142 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1143 { 1144 isc_result_t result; 1145 dns_fixedname_t foundname; 1146 1147 dns_fixedname_init(&foundname); 1148 result = dns_view_find(view, name, type, now, options, use_hints, 1149 NULL, NULL, dns_fixedname_name(&foundname), 1150 rdataset, sigrdataset); 1151 if (result == DNS_R_NXDOMAIN) { 1152 /* 1153 * The rdataset and sigrdataset of the relevant NSEC record 1154 * may be returned, but the caller cannot use them because 1155 * foundname is not returned by this simplified API. We 1156 * disassociate them here to prevent any misuse by the caller. 1157 */ 1158 if (dns_rdataset_isassociated(rdataset)) 1159 dns_rdataset_disassociate(rdataset); 1160 if (sigrdataset != NULL && 1161 dns_rdataset_isassociated(sigrdataset)) 1162 dns_rdataset_disassociate(sigrdataset); 1163 } else if (result != ISC_R_SUCCESS && 1164 result != DNS_R_GLUE && 1165 result != DNS_R_HINT && 1166 result != DNS_R_NCACHENXDOMAIN && 1167 result != DNS_R_NCACHENXRRSET && 1168 result != DNS_R_NXRRSET && 1169 result != DNS_R_HINTNXRRSET && 1170 result != ISC_R_NOTFOUND) { 1171 if (dns_rdataset_isassociated(rdataset)) 1172 dns_rdataset_disassociate(rdataset); 1173 if (sigrdataset != NULL && 1174 dns_rdataset_isassociated(sigrdataset)) 1175 dns_rdataset_disassociate(sigrdataset); 1176 result = ISC_R_NOTFOUND; 1177 } 1178 1179 return (result); 1180 } 1181 1182 isc_result_t 1183 dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 1184 isc_stdtime_t now, unsigned int options, 1185 isc_boolean_t use_hints, 1186 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1187 { 1188 return(dns_view_findzonecut2(view, name, fname, now, options, 1189 use_hints, ISC_TRUE, 1190 rdataset, sigrdataset)); 1191 } 1192 1193 isc_result_t 1194 dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 1195 isc_stdtime_t now, unsigned int options, 1196 isc_boolean_t use_hints, isc_boolean_t use_cache, 1197 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1198 { 1199 isc_result_t result; 1200 dns_db_t *db; 1201 isc_boolean_t is_cache, use_zone, try_hints; 1202 dns_zone_t *zone; 1203 dns_name_t *zfname; 1204 dns_rdataset_t zrdataset, zsigrdataset; 1205 dns_fixedname_t zfixedname; 1206 unsigned int ztoptions = 0; 1207 1208 REQUIRE(DNS_VIEW_VALID(view)); 1209 REQUIRE(view->frozen); 1210 1211 db = NULL; 1212 use_zone = ISC_FALSE; 1213 try_hints = ISC_FALSE; 1214 zfname = NULL; 1215 1216 /* 1217 * Initialize. 1218 */ 1219 dns_fixedname_init(&zfixedname); 1220 dns_rdataset_init(&zrdataset); 1221 dns_rdataset_init(&zsigrdataset); 1222 1223 /* 1224 * Find the right database. 1225 */ 1226 zone = NULL; 1227 LOCK(&view->lock); 1228 if (view->zonetable != NULL) { 1229 if ((options & DNS_DBFIND_NOEXACT) != 0) 1230 ztoptions |= DNS_ZTFIND_NOEXACT; 1231 result = dns_zt_find(view->zonetable, name, ztoptions, 1232 NULL, &zone); 1233 } else 1234 result = ISC_R_NOTFOUND; 1235 UNLOCK(&view->lock); 1236 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 1237 result = dns_zone_getdb(zone, &db); 1238 if (result == ISC_R_NOTFOUND) { 1239 /* 1240 * We're not directly authoritative for this query name, nor 1241 * is it a subdomain of any zone for which we're 1242 * authoritative. 1243 */ 1244 if (use_cache && view->cachedb != NULL) { 1245 /* 1246 * We have a cache; try it. 1247 */ 1248 dns_db_attach(view->cachedb, &db); 1249 } else { 1250 /* 1251 * Maybe we have hints... 1252 */ 1253 try_hints = ISC_TRUE; 1254 goto finish; 1255 } 1256 } else if (result != ISC_R_SUCCESS) { 1257 /* 1258 * Something is broken. 1259 */ 1260 goto cleanup; 1261 } 1262 is_cache = dns_db_iscache(db); 1263 1264 db_find: 1265 /* 1266 * Look for the zonecut. 1267 */ 1268 if (!is_cache) { 1269 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options, 1270 now, NULL, fname, rdataset, sigrdataset); 1271 if (result == DNS_R_DELEGATION) 1272 result = ISC_R_SUCCESS; 1273 else if (result != ISC_R_SUCCESS) 1274 goto cleanup; 1275 if (use_cache && view->cachedb != NULL && db != view->hints) { 1276 /* 1277 * We found an answer, but the cache may be better. 1278 */ 1279 zfname = dns_fixedname_name(&zfixedname); 1280 result = dns_name_copy(fname, zfname, NULL); 1281 if (result != ISC_R_SUCCESS) 1282 goto cleanup; 1283 dns_rdataset_clone(rdataset, &zrdataset); 1284 dns_rdataset_disassociate(rdataset); 1285 if (sigrdataset != NULL && 1286 dns_rdataset_isassociated(sigrdataset)) { 1287 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1288 dns_rdataset_disassociate(sigrdataset); 1289 } 1290 dns_db_detach(&db); 1291 dns_db_attach(view->cachedb, &db); 1292 is_cache = ISC_TRUE; 1293 goto db_find; 1294 } 1295 } else { 1296 result = dns_db_findzonecut(db, name, options, now, NULL, 1297 fname, rdataset, sigrdataset); 1298 if (result == ISC_R_SUCCESS) { 1299 if (zfname != NULL && 1300 (!dns_name_issubdomain(fname, zfname) || 1301 (dns_zone_staticstub && 1302 dns_name_equal(fname, zfname)))) { 1303 /* 1304 * We found a zonecut in the cache, but our 1305 * zone delegation is better. 1306 */ 1307 use_zone = ISC_TRUE; 1308 } 1309 } else if (result == ISC_R_NOTFOUND) { 1310 if (zfname != NULL) { 1311 /* 1312 * We didn't find anything in the cache, but we 1313 * have a zone delegation, so use it. 1314 */ 1315 use_zone = ISC_TRUE; 1316 } else { 1317 /* 1318 * Maybe we have hints... 1319 */ 1320 try_hints = ISC_TRUE; 1321 } 1322 } else { 1323 /* 1324 * Something bad happened. 1325 */ 1326 goto cleanup; 1327 } 1328 } 1329 1330 finish: 1331 if (use_zone) { 1332 if (dns_rdataset_isassociated(rdataset)) { 1333 dns_rdataset_disassociate(rdataset); 1334 if (sigrdataset != NULL && 1335 dns_rdataset_isassociated(sigrdataset)) 1336 dns_rdataset_disassociate(sigrdataset); 1337 } 1338 result = dns_name_copy(zfname, fname, NULL); 1339 if (result != ISC_R_SUCCESS) 1340 goto cleanup; 1341 dns_rdataset_clone(&zrdataset, rdataset); 1342 if (sigrdataset != NULL && 1343 dns_rdataset_isassociated(&zrdataset)) 1344 dns_rdataset_clone(&zsigrdataset, sigrdataset); 1345 } else if (try_hints && use_hints && view->hints != NULL) { 1346 /* 1347 * We've found nothing so far, but we have hints. 1348 */ 1349 result = dns_db_find(view->hints, dns_rootname, NULL, 1350 dns_rdatatype_ns, 0, now, NULL, fname, 1351 rdataset, NULL); 1352 if (result != ISC_R_SUCCESS) { 1353 /* 1354 * We can't even find the hints for the root 1355 * nameservers! 1356 */ 1357 if (dns_rdataset_isassociated(rdataset)) 1358 dns_rdataset_disassociate(rdataset); 1359 result = ISC_R_NOTFOUND; 1360 } 1361 } 1362 1363 cleanup: 1364 if (dns_rdataset_isassociated(&zrdataset)) { 1365 dns_rdataset_disassociate(&zrdataset); 1366 if (dns_rdataset_isassociated(&zsigrdataset)) 1367 dns_rdataset_disassociate(&zsigrdataset); 1368 } 1369 if (db != NULL) 1370 dns_db_detach(&db); 1371 if (zone != NULL) 1372 dns_zone_detach(&zone); 1373 1374 return (result); 1375 } 1376 1377 isc_result_t 1378 dns_viewlist_find(dns_viewlist_t *list, const char *name, 1379 dns_rdataclass_t rdclass, dns_view_t **viewp) 1380 { 1381 dns_view_t *view; 1382 1383 REQUIRE(list != NULL); 1384 1385 for (view = ISC_LIST_HEAD(*list); 1386 view != NULL; 1387 view = ISC_LIST_NEXT(view, link)) { 1388 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass) 1389 break; 1390 } 1391 if (view == NULL) 1392 return (ISC_R_NOTFOUND); 1393 1394 dns_view_attach(view, viewp); 1395 1396 return (ISC_R_SUCCESS); 1397 } 1398 1399 isc_result_t 1400 dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, 1401 isc_boolean_t allclasses, dns_rdataclass_t rdclass, 1402 dns_zone_t **zonep) 1403 { 1404 dns_view_t *view; 1405 isc_result_t result; 1406 dns_zone_t *zone1 = NULL, *zone2 = NULL; 1407 dns_zone_t **zp = NULL;; 1408 1409 REQUIRE(list != NULL); 1410 REQUIRE(zonep != NULL && *zonep == NULL); 1411 1412 for (view = ISC_LIST_HEAD(*list); 1413 view != NULL; 1414 view = ISC_LIST_NEXT(view, link)) { 1415 if (allclasses == ISC_FALSE && view->rdclass != rdclass) 1416 continue; 1417 1418 /* 1419 * If the zone is defined in more than one view, 1420 * treat it as not found. 1421 */ 1422 zp = (zone1 == NULL) ? &zone1 : &zone2; 1423 LOCK(&view->lock); 1424 if (view->zonetable != NULL) 1425 result = dns_zt_find(view->zonetable, name, 0, 1426 NULL, zp); 1427 else 1428 result = ISC_R_NOTFOUND; 1429 UNLOCK(&view->lock); 1430 INSIST(result == ISC_R_SUCCESS || 1431 result == ISC_R_NOTFOUND || 1432 result == DNS_R_PARTIALMATCH); 1433 1434 /* Treat a partial match as no match */ 1435 if (result == DNS_R_PARTIALMATCH) { 1436 dns_zone_detach(zp); 1437 result = ISC_R_NOTFOUND; 1438 POST(result); 1439 } 1440 1441 if (zone2 != NULL) { 1442 dns_zone_detach(&zone1); 1443 dns_zone_detach(&zone2); 1444 return (ISC_R_MULTIPLE); 1445 } 1446 } 1447 1448 if (zone1 != NULL) { 1449 dns_zone_attach(zone1, zonep); 1450 dns_zone_detach(&zone1); 1451 return (ISC_R_SUCCESS); 1452 } 1453 1454 return (ISC_R_NOTFOUND); 1455 } 1456 1457 isc_result_t 1458 dns_view_load(dns_view_t *view, isc_boolean_t stop) { 1459 1460 REQUIRE(DNS_VIEW_VALID(view)); 1461 REQUIRE(view->zonetable != NULL); 1462 1463 return (dns_zt_load(view->zonetable, stop)); 1464 } 1465 1466 isc_result_t 1467 dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { 1468 1469 REQUIRE(DNS_VIEW_VALID(view)); 1470 REQUIRE(view->zonetable != NULL); 1471 1472 return (dns_zt_loadnew(view->zonetable, stop)); 1473 } 1474 1475 isc_result_t 1476 dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) { 1477 REQUIRE(DNS_VIEW_VALID(view)); 1478 REQUIRE(view->zonetable != NULL); 1479 1480 return (dns_zt_asyncload(view->zonetable, callback, arg)); 1481 } 1482 1483 isc_result_t 1484 dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp) 1485 { 1486 isc_result_t result; 1487 REQUIRE(keyp != NULL && *keyp == NULL); 1488 1489 result = dns_tsigkey_find(keyp, keyname, NULL, 1490 view->statickeys); 1491 if (result == ISC_R_NOTFOUND) 1492 result = dns_tsigkey_find(keyp, keyname, NULL, 1493 view->dynamickeys); 1494 return (result); 1495 } 1496 1497 isc_result_t 1498 dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, 1499 dns_tsigkey_t **keyp) 1500 { 1501 isc_result_t result; 1502 dns_name_t *keyname = NULL; 1503 dns_peer_t *peer = NULL; 1504 1505 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer); 1506 if (result != ISC_R_SUCCESS) 1507 return (result); 1508 1509 result = dns_peer_getkey(peer, &keyname); 1510 if (result != ISC_R_SUCCESS) 1511 return (result); 1512 1513 result = dns_view_gettsig(view, keyname, keyp); 1514 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result); 1515 } 1516 1517 isc_result_t 1518 dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) { 1519 REQUIRE(DNS_VIEW_VALID(view)); 1520 REQUIRE(source != NULL); 1521 1522 return (dns_tsig_verify(source, msg, view->statickeys, 1523 view->dynamickeys)); 1524 } 1525 1526 isc_result_t 1527 dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { 1528 isc_result_t result; 1529 1530 REQUIRE(DNS_VIEW_VALID(view)); 1531 1532 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); 1533 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, 1534 &dns_master_style_cache, fp); 1535 if (result != ISC_R_SUCCESS) 1536 return (result); 1537 dns_adb_dump(view->adb, fp); 1538 dns_resolver_printbadcache(view->resolver, fp); 1539 return (ISC_R_SUCCESS); 1540 } 1541 1542 isc_result_t 1543 dns_view_flushcache(dns_view_t *view) { 1544 return (dns_view_flushcache2(view, ISC_FALSE)); 1545 } 1546 1547 isc_result_t 1548 dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) { 1549 isc_result_t result; 1550 1551 REQUIRE(DNS_VIEW_VALID(view)); 1552 1553 if (view->cachedb == NULL) 1554 return (ISC_R_SUCCESS); 1555 if (!fixuponly) { 1556 result = dns_cache_flush(view->cache); 1557 if (result != ISC_R_SUCCESS) 1558 return (result); 1559 } 1560 if (view->acache != NULL) 1561 dns_acache_putdb(view->acache, view->cachedb); 1562 dns_db_detach(&view->cachedb); 1563 dns_cache_attachdb(view->cache, &view->cachedb); 1564 if (view->acache != NULL) 1565 dns_acache_setdb(view->acache, view->cachedb); 1566 if (view->resolver != NULL) 1567 dns_resolver_flushbadcache(view->resolver, NULL); 1568 1569 dns_adb_flush(view->adb); 1570 return (ISC_R_SUCCESS); 1571 } 1572 1573 isc_result_t 1574 dns_view_flushname(dns_view_t *view, dns_name_t *name) { 1575 return (dns_view_flushnode(view, name, ISC_FALSE)); 1576 } 1577 1578 isc_result_t 1579 dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) { 1580 isc_result_t result = ISC_R_SUCCESS; 1581 1582 REQUIRE(DNS_VIEW_VALID(view)); 1583 1584 if (tree) { 1585 if (view->adb != NULL) 1586 dns_adb_flushnames(view->adb, name); 1587 if (view->resolver != NULL) 1588 dns_resolver_flushbadnames(view->resolver, name); 1589 } else { 1590 if (view->adb != NULL) 1591 dns_adb_flushname(view->adb, name); 1592 if (view->resolver != NULL) 1593 dns_resolver_flushbadcache(view->resolver, name); 1594 } 1595 1596 if (view->cache != NULL) 1597 result = dns_cache_flushnode(view->cache, name, tree); 1598 1599 return (result); 1600 } 1601 1602 isc_result_t 1603 dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) { 1604 isc_result_t result; 1605 dns_name_t *new; 1606 isc_uint32_t hash; 1607 1608 REQUIRE(DNS_VIEW_VALID(view)); 1609 1610 if (view->delonly == NULL) { 1611 view->delonly = isc_mem_get(view->mctx, 1612 sizeof(dns_namelist_t) * 1613 DNS_VIEW_DELONLYHASH); 1614 if (view->delonly == NULL) 1615 return (ISC_R_NOMEMORY); 1616 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1617 ISC_LIST_INIT(view->delonly[hash]); 1618 } 1619 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1620 new = ISC_LIST_HEAD(view->delonly[hash]); 1621 while (new != NULL && !dns_name_equal(new, name)) 1622 new = ISC_LIST_NEXT(new, link); 1623 if (new != NULL) 1624 return (ISC_R_SUCCESS); 1625 new = isc_mem_get(view->mctx, sizeof(*new)); 1626 if (new == NULL) 1627 return (ISC_R_NOMEMORY); 1628 dns_name_init(new, NULL); 1629 result = dns_name_dup(name, view->mctx, new); 1630 if (result == ISC_R_SUCCESS) 1631 ISC_LIST_APPEND(view->delonly[hash], new, link); 1632 else 1633 isc_mem_put(view->mctx, new, sizeof(*new)); 1634 return (result); 1635 } 1636 1637 isc_result_t 1638 dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) { 1639 isc_result_t result; 1640 dns_name_t *new; 1641 isc_uint32_t hash; 1642 1643 REQUIRE(DNS_VIEW_VALID(view)); 1644 1645 if (view->rootexclude == NULL) { 1646 view->rootexclude = isc_mem_get(view->mctx, 1647 sizeof(dns_namelist_t) * 1648 DNS_VIEW_DELONLYHASH); 1649 if (view->rootexclude == NULL) 1650 return (ISC_R_NOMEMORY); 1651 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1652 ISC_LIST_INIT(view->rootexclude[hash]); 1653 } 1654 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1655 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1656 while (new != NULL && !dns_name_equal(new, name)) 1657 new = ISC_LIST_NEXT(new, link); 1658 if (new != NULL) 1659 return (ISC_R_SUCCESS); 1660 new = isc_mem_get(view->mctx, sizeof(*new)); 1661 if (new == NULL) 1662 return (ISC_R_NOMEMORY); 1663 dns_name_init(new, NULL); 1664 result = dns_name_dup(name, view->mctx, new); 1665 if (result == ISC_R_SUCCESS) 1666 ISC_LIST_APPEND(view->rootexclude[hash], new, link); 1667 else 1668 isc_mem_put(view->mctx, new, sizeof(*new)); 1669 return (result); 1670 } 1671 1672 isc_boolean_t 1673 dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { 1674 dns_name_t *new; 1675 isc_uint32_t hash; 1676 1677 REQUIRE(DNS_VIEW_VALID(view)); 1678 1679 if (!view->rootdelonly && view->delonly == NULL) 1680 return (ISC_FALSE); 1681 1682 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1683 if (view->rootdelonly && dns_name_countlabels(name) <= 2) { 1684 if (view->rootexclude == NULL) 1685 return (ISC_TRUE); 1686 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1687 while (new != NULL && !dns_name_equal(new, name)) 1688 new = ISC_LIST_NEXT(new, link); 1689 if (new == NULL) 1690 return (ISC_TRUE); 1691 } 1692 1693 if (view->delonly == NULL) 1694 return (ISC_FALSE); 1695 1696 new = ISC_LIST_HEAD(view->delonly[hash]); 1697 while (new != NULL && !dns_name_equal(new, name)) 1698 new = ISC_LIST_NEXT(new, link); 1699 if (new == NULL) 1700 return (ISC_FALSE); 1701 return (ISC_TRUE); 1702 } 1703 1704 void 1705 dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) { 1706 REQUIRE(DNS_VIEW_VALID(view)); 1707 view->rootdelonly = value; 1708 } 1709 1710 isc_boolean_t 1711 dns_view_getrootdelonly(dns_view_t *view) { 1712 REQUIRE(DNS_VIEW_VALID(view)); 1713 return (view->rootdelonly); 1714 } 1715 1716 isc_result_t 1717 dns_view_freezezones(dns_view_t *view, isc_boolean_t value) { 1718 1719 REQUIRE(DNS_VIEW_VALID(view)); 1720 REQUIRE(view->zonetable != NULL); 1721 1722 return (dns_zt_freezezones(view->zonetable, value)); 1723 } 1724 1725 void 1726 dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats) { 1727 REQUIRE(DNS_VIEW_VALID(view)); 1728 REQUIRE(!view->frozen); 1729 REQUIRE(view->adbstats == NULL); 1730 1731 isc_stats_attach(stats, &view->adbstats); 1732 } 1733 1734 void 1735 dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp) { 1736 REQUIRE(DNS_VIEW_VALID(view)); 1737 REQUIRE(statsp != NULL && *statsp == NULL); 1738 1739 if (view->adbstats != NULL) 1740 isc_stats_attach(view->adbstats, statsp); 1741 } 1742 1743 void 1744 dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) { 1745 1746 REQUIRE(DNS_VIEW_VALID(view)); 1747 REQUIRE(!view->frozen); 1748 REQUIRE(view->resstats == NULL); 1749 1750 isc_stats_attach(stats, &view->resstats); 1751 } 1752 1753 void 1754 dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) { 1755 REQUIRE(DNS_VIEW_VALID(view)); 1756 REQUIRE(statsp != NULL && *statsp == NULL); 1757 1758 if (view->resstats != NULL) 1759 isc_stats_attach(view->resstats, statsp); 1760 } 1761 1762 void 1763 dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) { 1764 REQUIRE(DNS_VIEW_VALID(view)); 1765 REQUIRE(!view->frozen); 1766 REQUIRE(view->resquerystats == NULL); 1767 1768 dns_stats_attach(stats, &view->resquerystats); 1769 } 1770 1771 void 1772 dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) { 1773 REQUIRE(DNS_VIEW_VALID(view)); 1774 REQUIRE(statsp != NULL && *statsp == NULL); 1775 1776 if (view->resquerystats != NULL) 1777 dns_stats_attach(view->resquerystats, statsp); 1778 } 1779 1780 isc_result_t 1781 dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) { 1782 REQUIRE(DNS_VIEW_VALID(view)); 1783 if (view->secroots_priv != NULL) 1784 dns_keytable_detach(&view->secroots_priv); 1785 return (dns_keytable_create(mctx, &view->secroots_priv)); 1786 } 1787 1788 isc_result_t 1789 dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) { 1790 REQUIRE(DNS_VIEW_VALID(view)); 1791 REQUIRE(ktp != NULL && *ktp == NULL); 1792 if (view->secroots_priv == NULL) 1793 return (ISC_R_NOTFOUND); 1794 dns_keytable_attach(view->secroots_priv, ktp); 1795 return (ISC_R_SUCCESS); 1796 } 1797 1798 isc_result_t 1799 dns_view_issecuredomain(dns_view_t *view, dns_name_t *name, 1800 isc_boolean_t *secure_domain) { 1801 REQUIRE(DNS_VIEW_VALID(view)); 1802 1803 if (view->secroots_priv == NULL) 1804 return (ISC_R_NOTFOUND); 1805 return (dns_keytable_issecuredomain(view->secroots_priv, name, 1806 secure_domain)); 1807 } 1808 1809 void 1810 dns_view_untrust(dns_view_t *view, dns_name_t *keyname, 1811 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) 1812 { 1813 isc_result_t result; 1814 unsigned char data[4096]; 1815 dns_rdata_t rdata = DNS_RDATA_INIT; 1816 isc_buffer_t buffer; 1817 dst_key_t *key = NULL; 1818 dns_keytable_t *sr = NULL; 1819 1820 /* 1821 * Clear the revoke bit, if set, so that the key will match what's 1822 * in secroots now. 1823 */ 1824 dnskey->flags &= ~DNS_KEYFLAG_REVOKE; 1825 1826 /* Convert dnskey to DST key. */ 1827 isc_buffer_init(&buffer, data, sizeof(data)); 1828 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 1829 dns_rdatatype_dnskey, dnskey, &buffer); 1830 result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key); 1831 if (result != ISC_R_SUCCESS) 1832 return; 1833 result = dns_view_getsecroots(view, &sr); 1834 if (result == ISC_R_SUCCESS) { 1835 dns_keytable_deletekeynode(sr, key); 1836 dns_keytable_detach(&sr); 1837 } 1838 dst_key_free(&key); 1839 } 1840 1841 #define NZF ".nzf" 1842 1843 void 1844 dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, 1845 void (*cfg_destroy)(void **)) 1846 { 1847 REQUIRE(DNS_VIEW_VALID(view)); 1848 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow); 1849 1850 if (view->new_zone_file != NULL) { 1851 isc_mem_free(view->mctx, view->new_zone_file); 1852 view->new_zone_file = NULL; 1853 } 1854 1855 if (view->new_zone_config != NULL) { 1856 view->cfg_destroy(&view->new_zone_config); 1857 view->cfg_destroy = NULL; 1858 } 1859 1860 if (allow) { 1861 char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)]; 1862 isc_sha256_data((void *)view->name, strlen(view->name), buffer); 1863 /* Truncate the hash at 16 chars; full length is overkill */ 1864 isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF); 1865 view->new_zone_file = isc_mem_strdup(view->mctx, buffer); 1866 view->new_zone_config = cfgctx; 1867 view->cfg_destroy = cfg_destroy; 1868 } 1869 } 1870 1871 isc_result_t 1872 dns_view_searchdlz(dns_view_t *view, dns_name_t *name, unsigned int minlabels, 1873 dns_clientinfomethods_t *methods, 1874 dns_clientinfo_t *clientinfo, 1875 dns_db_t **dbp) 1876 { 1877 dns_fixedname_t fname; 1878 dns_name_t *zonename; 1879 unsigned int namelabels; 1880 unsigned int i; 1881 isc_result_t result; 1882 dns_dlzfindzone_t findzone; 1883 dns_dlzdb_t *dlzdb; 1884 dns_db_t *db, *best = NULL; 1885 1886 /* 1887 * Performs checks to make sure data is as we expect it to be. 1888 */ 1889 REQUIRE(DNS_VIEW_VALID(view)); 1890 REQUIRE(name != NULL); 1891 REQUIRE(dbp != NULL && *dbp == NULL); 1892 1893 /* setup a "fixed" dns name */ 1894 dns_fixedname_init(&fname); 1895 zonename = dns_fixedname_name(&fname); 1896 1897 /* count the number of labels in the name */ 1898 namelabels = dns_name_countlabels(name); 1899 1900 for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); 1901 dlzdb != NULL; 1902 dlzdb = ISC_LIST_NEXT(dlzdb, link)) 1903 { 1904 REQUIRE(DNS_DLZ_VALID(dlzdb)); 1905 1906 /* 1907 * loop through starting with the longest domain name and 1908 * trying shorter names portions of the name until we find a 1909 * match, have an error, or are below the 'minlabels' 1910 * threshold. minlabels is 0, if neither the standard 1911 * database nor any previous DLZ database had a zone name 1912 * match. Otherwise minlabels is the number of labels 1913 * in that name. We need to beat that for a "better" 1914 * match for this DLZ database to be authoritative. 1915 */ 1916 for (i = namelabels; i > minlabels && i > 1; i--) { 1917 if (i == namelabels) { 1918 result = dns_name_copy(name, zonename, NULL); 1919 if (result != ISC_R_SUCCESS) 1920 return (result); 1921 } else 1922 dns_name_split(name, i, NULL, zonename); 1923 1924 /* ask SDLZ driver if the zone is supported */ 1925 db = NULL; 1926 findzone = dlzdb->implementation->methods->findzone; 1927 result = (*findzone)(dlzdb->implementation->driverarg, 1928 dlzdb->dbdata, dlzdb->mctx, 1929 view->rdclass, zonename, 1930 methods, clientinfo, &db); 1931 1932 if (result != ISC_R_NOTFOUND) { 1933 if (best != NULL) 1934 dns_db_detach(&best); 1935 if (result == ISC_R_SUCCESS) { 1936 INSIST(db != NULL); 1937 dns_db_attach(db, &best); 1938 dns_db_detach(&db); 1939 minlabels = i; 1940 } else { 1941 if (db != NULL) 1942 dns_db_detach(&db); 1943 break; 1944 } 1945 } else if (db != NULL) 1946 dns_db_detach(&db); 1947 } 1948 } 1949 1950 if (best != NULL) { 1951 dns_db_attach(best, dbp); 1952 dns_db_detach(&best); 1953 return (ISC_R_SUCCESS); 1954 } 1955 1956 return (ISC_R_NOTFOUND); 1957 } 1958