view.c revision 135446
1/* 2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: view.c,v 1.103.2.5.2.14 2004/03/10 02:55:58 marka Exp $ */ 19 20#include <config.h> 21 22#include <isc/hash.h> 23#include <isc/task.h> 24#include <isc/string.h> /* Required for HP/UX (and others?) */ 25#include <isc/util.h> 26 27#include <dns/acl.h> 28#include <dns/adb.h> 29#include <dns/cache.h> 30#include <dns/db.h> 31#include <dns/events.h> 32#include <dns/forward.h> 33#include <dns/keytable.h> 34#include <dns/master.h> 35#include <dns/masterdump.h> 36#include <dns/order.h> 37#include <dns/peer.h> 38#include <dns/rdataset.h> 39#include <dns/request.h> 40#include <dns/resolver.h> 41#include <dns/result.h> 42#include <dns/tsig.h> 43#include <dns/zone.h> 44#include <dns/zt.h> 45 46#define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0) 47#define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0) 48#define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0) 49 50#define DNS_VIEW_DELONLYHASH 111 51 52static void resolver_shutdown(isc_task_t *task, isc_event_t *event); 53static void adb_shutdown(isc_task_t *task, isc_event_t *event); 54static void req_shutdown(isc_task_t *task, isc_event_t *event); 55 56isc_result_t 57dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, 58 const char *name, dns_view_t **viewp) 59{ 60 dns_view_t *view; 61 isc_result_t result; 62 63 /* 64 * Create a view. 65 */ 66 67 REQUIRE(name != NULL); 68 REQUIRE(viewp != NULL && *viewp == NULL); 69 70 view = isc_mem_get(mctx, sizeof(*view)); 71 if (view == NULL) 72 return (ISC_R_NOMEMORY); 73 view->name = isc_mem_strdup(mctx, name); 74 if (view->name == NULL) { 75 result = ISC_R_NOMEMORY; 76 goto cleanup_view; 77 } 78 result = isc_mutex_init(&view->lock); 79 if (result != ISC_R_SUCCESS) { 80 UNEXPECTED_ERROR(__FILE__, __LINE__, 81 "isc_mutex_init() failed: %s", 82 isc_result_totext(result)); 83 result = ISC_R_UNEXPECTED; 84 goto cleanup_name; 85 } 86 view->zonetable = NULL; 87 result = dns_zt_create(mctx, rdclass, &view->zonetable); 88 if (result != ISC_R_SUCCESS) { 89 UNEXPECTED_ERROR(__FILE__, __LINE__, 90 "dns_zt_create() failed: %s", 91 isc_result_totext(result)); 92 result = ISC_R_UNEXPECTED; 93 goto cleanup_mutex; 94 } 95 view->secroots = NULL; 96 result = dns_keytable_create(mctx, &view->secroots); 97 if (result != ISC_R_SUCCESS) { 98 UNEXPECTED_ERROR(__FILE__, __LINE__, 99 "dns_keytable_create() failed: %s", 100 isc_result_totext(result)); 101 result = ISC_R_UNEXPECTED; 102 goto cleanup_zt; 103 } 104 view->trustedkeys = NULL; 105 result = dns_keytable_create(mctx, &view->trustedkeys); 106 if (result != ISC_R_SUCCESS) { 107 UNEXPECTED_ERROR(__FILE__, __LINE__, 108 "dns_keytable_create() failed: %s", 109 isc_result_totext(result)); 110 result = ISC_R_UNEXPECTED; 111 goto cleanup_secroots; 112 } 113 view->fwdtable = NULL; 114 result = dns_fwdtable_create(mctx, &view->fwdtable); 115 if (result != ISC_R_SUCCESS) { 116 UNEXPECTED_ERROR(__FILE__, __LINE__, 117 "dns_fwdtable_create() failed: %s", 118 isc_result_totext(result)); 119 result = ISC_R_UNEXPECTED; 120 goto cleanup_trustedkeys; 121 } 122 123 view->cache = NULL; 124 view->cachedb = NULL; 125 view->hints = NULL; 126 view->resolver = NULL; 127 view->adb = NULL; 128 view->requestmgr = NULL; 129 view->mctx = mctx; 130 view->rdclass = rdclass; 131 view->frozen = ISC_FALSE; 132 view->task = NULL; 133 isc_refcount_init(&view->references, 1); 134 view->weakrefs = 0; 135 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| 136 DNS_VIEWATTR_REQSHUTDOWN); 137 view->statickeys = NULL; 138 view->dynamickeys = NULL; 139 view->matchclients = NULL; 140 view->matchdestinations = NULL; 141 view->matchrecursiveonly = ISC_FALSE; 142 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); 143 if (result != ISC_R_SUCCESS) 144 goto cleanup_fwdtable; 145 view->peers = NULL; 146 view->order = NULL; 147 view->delonly = NULL; 148 view->rootdelonly = ISC_FALSE; 149 view->rootexclude = NULL; 150 151 /* 152 * Initialize configuration data with default values. 153 */ 154 view->recursion = ISC_TRUE; 155 view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */ 156 view->additionalfromcache = ISC_TRUE; 157 view->additionalfromauth = ISC_TRUE; 158 view->enablednssec = ISC_TRUE; 159 view->minimalresponses = ISC_FALSE; 160 view->transfer_format = dns_one_answer; 161 view->queryacl = NULL; 162 view->recursionacl = NULL; 163 view->sortlist = NULL; 164 view->requestixfr = ISC_TRUE; 165 view->provideixfr = ISC_TRUE; 166 view->maxcachettl = 7 * 24 * 3600; 167 view->maxncachettl = 3 * 3600; 168 view->dstport = 53; 169 view->preferred_glue = 0; 170 view->flush = ISC_FALSE; 171 view->dlv = NULL; 172 dns_fixedname_init(&view->dlv_fixed); 173 174 result = dns_order_create(view->mctx, &view->order); 175 if (result != ISC_R_SUCCESS) 176 goto cleanup_dynkeys; 177 178 result = dns_peerlist_new(view->mctx, &view->peers); 179 if (result != ISC_R_SUCCESS) 180 goto cleanup_order; 181 182 result = dns_aclenv_init(view->mctx, &view->aclenv); 183 if (result != ISC_R_SUCCESS) 184 goto cleanup_peerlist; 185 186 ISC_LINK_INIT(view, link); 187 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL, 188 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown, 189 view, NULL, NULL, NULL); 190 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL, 191 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown, 192 view, NULL, NULL, NULL); 193 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL, 194 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, 195 view, NULL, NULL, NULL); 196 view->magic = DNS_VIEW_MAGIC; 197 198 *viewp = view; 199 200 return (ISC_R_SUCCESS); 201 202 cleanup_peerlist: 203 dns_peerlist_detach(&view->peers); 204 205 cleanup_order: 206 dns_order_detach(&view->order); 207 208 cleanup_dynkeys: 209 dns_tsigkeyring_destroy(&view->dynamickeys); 210 211 cleanup_fwdtable: 212 dns_fwdtable_destroy(&view->fwdtable); 213 214 cleanup_trustedkeys: 215 dns_keytable_detach(&view->trustedkeys); 216 217 cleanup_secroots: 218 dns_keytable_detach(&view->secroots); 219 220 cleanup_zt: 221 dns_zt_detach(&view->zonetable); 222 223 cleanup_mutex: 224 DESTROYLOCK(&view->lock); 225 226 cleanup_name: 227 isc_mem_free(mctx, view->name); 228 229 cleanup_view: 230 isc_mem_put(mctx, view, sizeof(*view)); 231 232 return (result); 233} 234 235static inline void 236destroy(dns_view_t *view) { 237 REQUIRE(!ISC_LINK_LINKED(view, link)); 238 REQUIRE(isc_refcount_current(&view->references) == 0); 239 REQUIRE(view->weakrefs == 0); 240 REQUIRE(RESSHUTDOWN(view)); 241 REQUIRE(ADBSHUTDOWN(view)); 242 REQUIRE(REQSHUTDOWN(view)); 243 244 if (view->order != NULL) 245 dns_order_detach(&view->order); 246 if (view->peers != NULL) 247 dns_peerlist_detach(&view->peers); 248 if (view->dynamickeys != NULL) 249 dns_tsigkeyring_destroy(&view->dynamickeys); 250 if (view->statickeys != NULL) 251 dns_tsigkeyring_destroy(&view->statickeys); 252 if (view->adb != NULL) 253 dns_adb_detach(&view->adb); 254 if (view->resolver != NULL) 255 dns_resolver_detach(&view->resolver); 256 if (view->requestmgr != NULL) 257 dns_requestmgr_detach(&view->requestmgr); 258 if (view->task != NULL) 259 isc_task_detach(&view->task); 260 if (view->hints != NULL) 261 dns_db_detach(&view->hints); 262 if (view->cachedb != NULL) 263 dns_db_detach(&view->cachedb); 264 if (view->cache != NULL) 265 dns_cache_detach(&view->cache); 266 if (view->matchclients != NULL) 267 dns_acl_detach(&view->matchclients); 268 if (view->matchdestinations != NULL) 269 dns_acl_detach(&view->matchdestinations); 270 if (view->queryacl != NULL) 271 dns_acl_detach(&view->queryacl); 272 if (view->recursionacl != NULL) 273 dns_acl_detach(&view->recursionacl); 274 if (view->sortlist != NULL) 275 dns_acl_detach(&view->sortlist); 276 if (view->delonly != NULL) { 277 dns_name_t *name; 278 int i; 279 280 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 281 name = ISC_LIST_HEAD(view->delonly[i]); 282 while (name != NULL) { 283 ISC_LIST_UNLINK(view->delonly[i], name, link); 284 dns_name_free(name, view->mctx); 285 isc_mem_put(view->mctx, name, sizeof(*name)); 286 name = ISC_LIST_HEAD(view->delonly[i]); 287 } 288 } 289 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) * 290 DNS_VIEW_DELONLYHASH); 291 view->delonly = NULL; 292 } 293 if (view->rootexclude != NULL) { 294 dns_name_t *name; 295 int i; 296 297 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 298 name = ISC_LIST_HEAD(view->rootexclude[i]); 299 while (name != NULL) { 300 ISC_LIST_UNLINK(view->rootexclude[i], 301 name, link); 302 dns_name_free(name, view->mctx); 303 isc_mem_put(view->mctx, name, sizeof(*name)); 304 name = ISC_LIST_HEAD(view->rootexclude[i]); 305 } 306 } 307 isc_mem_put(view->mctx, view->rootexclude, 308 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); 309 view->rootexclude = NULL; 310 } 311 dns_keytable_detach(&view->trustedkeys); 312 dns_keytable_detach(&view->secroots); 313 dns_fwdtable_destroy(&view->fwdtable); 314 dns_aclenv_destroy(&view->aclenv); 315 DESTROYLOCK(&view->lock); 316 isc_refcount_destroy(&view->references); 317 isc_mem_free(view->mctx, view->name); 318 isc_mem_put(view->mctx, view, sizeof(*view)); 319} 320 321/* 322 * Return true iff 'view' may be freed. 323 * The caller must be holding the view lock. 324 */ 325static isc_boolean_t 326all_done(dns_view_t *view) { 327 328 if (isc_refcount_current(&view->references) == 0 && 329 view->weakrefs == 0 && 330 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) 331 return (ISC_TRUE); 332 333 return (ISC_FALSE); 334} 335 336void 337dns_view_attach(dns_view_t *source, dns_view_t **targetp) { 338 339 REQUIRE(DNS_VIEW_VALID(source)); 340 REQUIRE(targetp != NULL && *targetp == NULL); 341 342 isc_refcount_increment(&source->references, NULL); 343 344 *targetp = source; 345} 346 347static void 348view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { 349 dns_view_t *view; 350 unsigned int refs; 351 isc_boolean_t done = ISC_FALSE; 352 353 REQUIRE(viewp != NULL); 354 view = *viewp; 355 REQUIRE(DNS_VIEW_VALID(view)); 356 357 if (flush) 358 view->flush = ISC_TRUE; 359 isc_refcount_decrement(&view->references, &refs); 360 if (refs == 0) { 361 LOCK(&view->lock); 362 if (!RESSHUTDOWN(view)) 363 dns_resolver_shutdown(view->resolver); 364 if (!ADBSHUTDOWN(view)) 365 dns_adb_shutdown(view->adb); 366 if (!REQSHUTDOWN(view)) 367 dns_requestmgr_shutdown(view->requestmgr); 368 if (view->flush) 369 dns_zt_flushanddetach(&view->zonetable); 370 else 371 dns_zt_detach(&view->zonetable); 372 done = all_done(view); 373 UNLOCK(&view->lock); 374 } 375 376 *viewp = NULL; 377 378 if (done) 379 destroy(view); 380} 381 382void 383dns_view_flushanddetach(dns_view_t **viewp) { 384 view_flushanddetach(viewp, ISC_TRUE); 385} 386 387void 388dns_view_detach(dns_view_t **viewp) { 389 view_flushanddetach(viewp, ISC_FALSE); 390} 391 392static isc_result_t 393dialup(dns_zone_t *zone, void *dummy) { 394 UNUSED(dummy); 395 dns_zone_dialup(zone); 396 return (ISC_R_SUCCESS); 397} 398 399void 400dns_view_dialup(dns_view_t *view) { 401 REQUIRE(DNS_VIEW_VALID(view)); 402 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL); 403} 404 405void 406dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { 407 408 REQUIRE(DNS_VIEW_VALID(source)); 409 REQUIRE(targetp != NULL && *targetp == NULL); 410 411 LOCK(&source->lock); 412 source->weakrefs++; 413 UNLOCK(&source->lock); 414 415 *targetp = source; 416} 417 418void 419dns_view_weakdetach(dns_view_t **viewp) { 420 dns_view_t *view; 421 isc_boolean_t done = ISC_FALSE; 422 423 REQUIRE(viewp != NULL); 424 view = *viewp; 425 REQUIRE(DNS_VIEW_VALID(view)); 426 427 LOCK(&view->lock); 428 429 INSIST(view->weakrefs > 0); 430 view->weakrefs--; 431 done = all_done(view); 432 433 UNLOCK(&view->lock); 434 435 *viewp = NULL; 436 437 if (done) 438 destroy(view); 439} 440 441static void 442resolver_shutdown(isc_task_t *task, isc_event_t *event) { 443 dns_view_t *view = event->ev_arg; 444 isc_boolean_t done; 445 446 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); 447 REQUIRE(DNS_VIEW_VALID(view)); 448 REQUIRE(view->task == task); 449 450 UNUSED(task); 451 452 LOCK(&view->lock); 453 454 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; 455 done = all_done(view); 456 457 UNLOCK(&view->lock); 458 459 isc_event_free(&event); 460 461 if (done) 462 destroy(view); 463} 464 465static void 466adb_shutdown(isc_task_t *task, isc_event_t *event) { 467 dns_view_t *view = event->ev_arg; 468 isc_boolean_t done; 469 470 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); 471 REQUIRE(DNS_VIEW_VALID(view)); 472 REQUIRE(view->task == task); 473 474 UNUSED(task); 475 476 LOCK(&view->lock); 477 478 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; 479 done = all_done(view); 480 481 UNLOCK(&view->lock); 482 483 isc_event_free(&event); 484 485 if (done) 486 destroy(view); 487} 488 489static void 490req_shutdown(isc_task_t *task, isc_event_t *event) { 491 dns_view_t *view = event->ev_arg; 492 isc_boolean_t done; 493 494 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); 495 REQUIRE(DNS_VIEW_VALID(view)); 496 REQUIRE(view->task == task); 497 498 UNUSED(task); 499 500 LOCK(&view->lock); 501 502 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; 503 done = all_done(view); 504 505 UNLOCK(&view->lock); 506 507 isc_event_free(&event); 508 509 if (done) 510 destroy(view); 511} 512 513isc_result_t 514dns_view_createresolver(dns_view_t *view, 515 isc_taskmgr_t *taskmgr, unsigned int ntasks, 516 isc_socketmgr_t *socketmgr, 517 isc_timermgr_t *timermgr, 518 unsigned int options, 519 dns_dispatchmgr_t *dispatchmgr, 520 dns_dispatch_t *dispatchv4, 521 dns_dispatch_t *dispatchv6) 522{ 523 isc_result_t result; 524 isc_event_t *event; 525 isc_mem_t *mctx = NULL; 526 527 REQUIRE(DNS_VIEW_VALID(view)); 528 REQUIRE(!view->frozen); 529 REQUIRE(view->resolver == NULL); 530 531 result = isc_task_create(taskmgr, 0, &view->task); 532 if (result != ISC_R_SUCCESS) 533 return (result); 534 isc_task_setname(view->task, "view", view); 535 536 result = dns_resolver_create(view, taskmgr, ntasks, socketmgr, 537 timermgr, options, dispatchmgr, 538 dispatchv4, dispatchv6, 539 &view->resolver); 540 if (result != ISC_R_SUCCESS) { 541 isc_task_detach(&view->task); 542 return (result); 543 } 544 event = &view->resevent; 545 dns_resolver_whenshutdown(view->resolver, view->task, &event); 546 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; 547 548 result = isc_mem_create(0, 0, &mctx); 549 if (result != ISC_R_SUCCESS) { 550 dns_resolver_shutdown(view->resolver); 551 return (result); 552 } 553 554 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb); 555 isc_mem_detach(&mctx); 556 if (result != ISC_R_SUCCESS) { 557 dns_resolver_shutdown(view->resolver); 558 return (result); 559 } 560 event = &view->adbevent; 561 dns_adb_whenshutdown(view->adb, view->task, &event); 562 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; 563 564 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, 565 dns_resolver_taskmgr(view->resolver), 566 dns_resolver_dispatchmgr(view->resolver), 567 dns_resolver_dispatchv4(view->resolver), 568 dns_resolver_dispatchv6(view->resolver), 569 &view->requestmgr); 570 if (result != ISC_R_SUCCESS) { 571 dns_adb_shutdown(view->adb); 572 dns_resolver_shutdown(view->resolver); 573 return (result); 574 } 575 event = &view->reqevent; 576 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); 577 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; 578 579 return (ISC_R_SUCCESS); 580} 581 582void 583dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { 584 REQUIRE(DNS_VIEW_VALID(view)); 585 REQUIRE(!view->frozen); 586 587 if (view->cache != NULL) { 588 dns_db_detach(&view->cachedb); 589 dns_cache_detach(&view->cache); 590 } 591 dns_cache_attach(cache, &view->cache); 592 dns_cache_attachdb(cache, &view->cachedb); 593 INSIST(DNS_DB_VALID(view->cachedb)); 594} 595 596void 597dns_view_sethints(dns_view_t *view, dns_db_t *hints) { 598 REQUIRE(DNS_VIEW_VALID(view)); 599 REQUIRE(!view->frozen); 600 REQUIRE(view->hints == NULL); 601 REQUIRE(dns_db_iszone(hints)); 602 603 dns_db_attach(hints, &view->hints); 604} 605 606void 607dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 608 REQUIRE(DNS_VIEW_VALID(view)); 609 REQUIRE(ring != NULL); 610 if (view->statickeys != NULL) 611 dns_tsigkeyring_destroy(&view->statickeys); 612 view->statickeys = ring; 613} 614 615void 616dns_view_setdstport(dns_view_t *view, in_port_t dstport) { 617 REQUIRE(DNS_VIEW_VALID(view)); 618 view->dstport = dstport; 619} 620 621isc_result_t 622dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { 623 isc_result_t result; 624 625 REQUIRE(DNS_VIEW_VALID(view)); 626 REQUIRE(!view->frozen); 627 628 result = dns_zt_mount(view->zonetable, zone); 629 630 return (result); 631} 632 633void 634dns_view_freeze(dns_view_t *view) { 635 REQUIRE(DNS_VIEW_VALID(view)); 636 REQUIRE(!view->frozen); 637 638 if (view->resolver != NULL) { 639 INSIST(view->cachedb != NULL); 640 dns_resolver_freeze(view->resolver); 641 } 642 view->frozen = ISC_TRUE; 643} 644 645isc_result_t 646dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { 647 isc_result_t result; 648 649 REQUIRE(DNS_VIEW_VALID(view)); 650 651 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); 652 if (result == DNS_R_PARTIALMATCH) { 653 dns_zone_detach(zonep); 654 result = ISC_R_NOTFOUND; 655 } 656 657 return (result); 658} 659 660isc_result_t 661dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 662 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, 663 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 664 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 665{ 666 isc_result_t result; 667 dns_db_t *db, *zdb; 668 dns_dbnode_t *node, *znode; 669 isc_boolean_t is_cache; 670 dns_rdataset_t zrdataset, zsigrdataset; 671 dns_zone_t *zone; 672 673 /* 674 * Find an rdataset whose owner name is 'name', and whose type is 675 * 'type'. 676 */ 677 678 REQUIRE(DNS_VIEW_VALID(view)); 679 REQUIRE(view->frozen); 680 REQUIRE(type != dns_rdatatype_rrsig); 681 REQUIRE(rdataset != NULL); /* XXXBEW - remove this */ 682 683 /* 684 * Initialize. 685 */ 686 dns_rdataset_init(&zrdataset); 687 dns_rdataset_init(&zsigrdataset); 688 zdb = NULL; 689 znode = NULL; 690 691 /* 692 * Find a database to answer the query. 693 */ 694 zone = NULL; 695 db = NULL; 696 node = NULL; 697 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 698 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 699 result = dns_zone_getdb(zone, &db); 700 if (result != ISC_R_SUCCESS && view->cachedb != NULL) 701 dns_db_attach(view->cachedb, &db); 702 else if (result != ISC_R_SUCCESS) 703 goto cleanup; 704 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL) 705 dns_db_attach(view->cachedb, &db); 706 else 707 goto cleanup; 708 709 is_cache = dns_db_iscache(db); 710 711 db_find: 712 /* 713 * Now look for an answer in the database. 714 */ 715 result = dns_db_find(db, name, NULL, type, options, 716 now, &node, foundname, rdataset, sigrdataset); 717 718 if (result == DNS_R_DELEGATION || 719 result == ISC_R_NOTFOUND) { 720 if (dns_rdataset_isassociated(rdataset)) 721 dns_rdataset_disassociate(rdataset); 722 if (sigrdataset != NULL && 723 dns_rdataset_isassociated(sigrdataset)) 724 dns_rdataset_disassociate(sigrdataset); 725 if (node != NULL) 726 dns_db_detachnode(db, &node); 727 if (!is_cache) { 728 dns_db_detach(&db); 729 if (view->cachedb != NULL) { 730 /* 731 * Either the answer is in the cache, or we 732 * don't know it. 733 */ 734 is_cache = ISC_TRUE; 735 dns_db_attach(view->cachedb, &db); 736 goto db_find; 737 } 738 } else { 739 /* 740 * We don't have the data in the cache. If we've got 741 * glue from the zone, use it. 742 */ 743 if (dns_rdataset_isassociated(&zrdataset)) { 744 dns_rdataset_clone(&zrdataset, rdataset); 745 if (sigrdataset != NULL && 746 dns_rdataset_isassociated(&zsigrdataset)) 747 dns_rdataset_clone(&zsigrdataset, 748 sigrdataset); 749 result = DNS_R_GLUE; 750 if (db != NULL) 751 dns_db_detach(&db); 752 dns_db_attach(zdb, &db); 753 dns_db_attachnode(db, znode, &node); 754 goto cleanup; 755 } 756 } 757 /* 758 * We don't know the answer. 759 */ 760 result = ISC_R_NOTFOUND; 761 } else if (result == DNS_R_GLUE) { 762 if (view->cachedb != NULL) { 763 /* 764 * We found an answer, but the cache may be better. 765 * Remember what we've got and go look in the cache. 766 */ 767 is_cache = ISC_TRUE; 768 dns_rdataset_clone(rdataset, &zrdataset); 769 dns_rdataset_disassociate(rdataset); 770 if (sigrdataset != NULL && 771 dns_rdataset_isassociated(sigrdataset)) { 772 dns_rdataset_clone(sigrdataset, &zsigrdataset); 773 dns_rdataset_disassociate(sigrdataset); 774 } 775 dns_db_attach(db, &zdb); 776 dns_db_attachnode(zdb, node, &znode); 777 dns_db_detachnode(db, &node); 778 dns_db_detach(&db); 779 dns_db_attach(view->cachedb, &db); 780 goto db_find; 781 } 782 /* 783 * Otherwise, the glue is the best answer. 784 */ 785 result = ISC_R_SUCCESS; 786 } 787 788 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) { 789 if (dns_rdataset_isassociated(rdataset)) 790 dns_rdataset_disassociate(rdataset); 791 if (sigrdataset != NULL && 792 dns_rdataset_isassociated(sigrdataset)) 793 dns_rdataset_disassociate(sigrdataset); 794 if (db != NULL) { 795 if (node != NULL) 796 dns_db_detachnode(db, &node); 797 dns_db_detach(&db); 798 } 799 result = dns_db_find(view->hints, name, NULL, type, options, 800 now, &node, foundname, 801 rdataset, sigrdataset); 802 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) { 803 /* 804 * We just used a hint. Let the resolver know it 805 * should consider priming. 806 */ 807 dns_resolver_prime(view->resolver); 808 dns_db_attach(view->hints, &db); 809 result = DNS_R_HINT; 810 } else if (result == DNS_R_NXRRSET) { 811 dns_db_attach(view->hints, &db); 812 result = DNS_R_HINTNXRRSET; 813 } else if (result == DNS_R_NXDOMAIN) 814 result = ISC_R_NOTFOUND; 815 816 /* 817 * Cleanup if non-standard hints are used. 818 */ 819 if (db == NULL && node != NULL) 820 dns_db_detachnode(view->hints, &node); 821 } 822 823 cleanup: 824 if (result == DNS_R_NXDOMAIN || result == DNS_R_NXRRSET) { 825 /* 826 * We don't care about any DNSSEC proof data in these cases. 827 */ 828 if (dns_rdataset_isassociated(rdataset)) 829 dns_rdataset_disassociate(rdataset); 830 if (sigrdataset != NULL && 831 dns_rdataset_isassociated(sigrdataset)) 832 dns_rdataset_disassociate(sigrdataset); 833 } 834 835 if (dns_rdataset_isassociated(&zrdataset)) { 836 dns_rdataset_disassociate(&zrdataset); 837 if (dns_rdataset_isassociated(&zsigrdataset)) 838 dns_rdataset_disassociate(&zsigrdataset); 839 } 840 841 if (zdb != NULL) { 842 if (znode != NULL) 843 dns_db_detachnode(zdb, &znode); 844 dns_db_detach(&zdb); 845 } 846 847 if (db != NULL) { 848 if (node != NULL) { 849 if (nodep != NULL) 850 *nodep = node; 851 else 852 dns_db_detachnode(db, &node); 853 } 854 if (dbp != NULL) 855 *dbp = db; 856 else 857 dns_db_detach(&db); 858 } else 859 INSIST(node == NULL); 860 861 if (zone != NULL) 862 dns_zone_detach(&zone); 863 864 return (result); 865} 866 867isc_result_t 868dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 869 isc_stdtime_t now, unsigned int options, 870 isc_boolean_t use_hints, 871 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 872{ 873 isc_result_t result; 874 dns_fixedname_t foundname; 875 876 dns_fixedname_init(&foundname); 877 result = dns_view_find(view, name, type, now, options, use_hints, 878 NULL, NULL, dns_fixedname_name(&foundname), 879 rdataset, sigrdataset); 880 if (result == DNS_R_NXDOMAIN) { 881 /* 882 * The rdataset and sigrdataset of the relevant NSEC record 883 * may be returned, but the caller cannot use them because 884 * foundname is not returned by this simplified API. We 885 * disassociate them here to prevent any misuse by the caller. 886 */ 887 if (dns_rdataset_isassociated(rdataset)) 888 dns_rdataset_disassociate(rdataset); 889 if (sigrdataset != NULL && 890 dns_rdataset_isassociated(sigrdataset)) 891 dns_rdataset_disassociate(sigrdataset); 892 } else if (result != ISC_R_SUCCESS && 893 result != DNS_R_GLUE && 894 result != DNS_R_HINT && 895 result != DNS_R_NCACHENXDOMAIN && 896 result != DNS_R_NCACHENXRRSET && 897 result != DNS_R_NXRRSET && 898 result != DNS_R_HINTNXRRSET && 899 result != ISC_R_NOTFOUND) { 900 if (dns_rdataset_isassociated(rdataset)) 901 dns_rdataset_disassociate(rdataset); 902 if (sigrdataset != NULL && 903 dns_rdataset_isassociated(sigrdataset)) 904 dns_rdataset_disassociate(sigrdataset); 905 result = ISC_R_NOTFOUND; 906 } 907 908 return (result); 909} 910 911isc_result_t 912dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 913 isc_stdtime_t now, unsigned int options, 914 isc_boolean_t use_hints, 915 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 916{ 917 return(dns_view_findzonecut2(view, name, fname, now, options, 918 use_hints, ISC_TRUE, 919 rdataset, sigrdataset)); 920} 921 922isc_result_t 923dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 924 isc_stdtime_t now, unsigned int options, 925 isc_boolean_t use_hints, isc_boolean_t use_cache, 926 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 927{ 928 isc_result_t result; 929 dns_db_t *db; 930 isc_boolean_t is_cache, use_zone, try_hints; 931 dns_zone_t *zone; 932 dns_name_t *zfname; 933 dns_rdataset_t zrdataset, zsigrdataset; 934 dns_fixedname_t zfixedname; 935 936 REQUIRE(DNS_VIEW_VALID(view)); 937 REQUIRE(view->frozen); 938 939 db = NULL; 940 zone = NULL; 941 use_zone = ISC_FALSE; 942 try_hints = ISC_FALSE; 943 zfname = NULL; 944 945 /* 946 * Initialize. 947 */ 948 dns_fixedname_init(&zfixedname); 949 dns_rdataset_init(&zrdataset); 950 dns_rdataset_init(&zsigrdataset); 951 952 /* 953 * Find the right database. 954 */ 955 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 956 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 957 result = dns_zone_getdb(zone, &db); 958 if (result == ISC_R_NOTFOUND) { 959 /* 960 * We're not directly authoritative for this query name, nor 961 * is it a subdomain of any zone for which we're 962 * authoritative. 963 */ 964 if (use_cache && view->cachedb != NULL) { 965 /* 966 * We have a cache; try it. 967 */ 968 dns_db_attach(view->cachedb, &db); 969 } else { 970 /* 971 * Maybe we have hints... 972 */ 973 try_hints = ISC_TRUE; 974 goto finish; 975 } 976 } else if (result != ISC_R_SUCCESS) { 977 /* 978 * Something is broken. 979 */ 980 goto cleanup; 981 } 982 is_cache = dns_db_iscache(db); 983 984 db_find: 985 /* 986 * Look for the zonecut. 987 */ 988 if (!is_cache) { 989 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options, 990 now, NULL, fname, rdataset, sigrdataset); 991 if (result == DNS_R_DELEGATION) 992 result = ISC_R_SUCCESS; 993 else if (result != ISC_R_SUCCESS) 994 goto cleanup; 995 if (use_cache && view->cachedb != NULL && db != view->hints) { 996 /* 997 * We found an answer, but the cache may be better. 998 */ 999 zfname = dns_fixedname_name(&zfixedname); 1000 result = dns_name_copy(fname, zfname, NULL); 1001 if (result != ISC_R_SUCCESS) 1002 goto cleanup; 1003 dns_rdataset_clone(rdataset, &zrdataset); 1004 dns_rdataset_disassociate(rdataset); 1005 if (sigrdataset != NULL && 1006 dns_rdataset_isassociated(sigrdataset)) { 1007 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1008 dns_rdataset_disassociate(sigrdataset); 1009 } 1010 dns_db_detach(&db); 1011 dns_db_attach(view->cachedb, &db); 1012 is_cache = ISC_TRUE; 1013 goto db_find; 1014 } 1015 } else { 1016 result = dns_db_findzonecut(db, name, options, now, NULL, 1017 fname, rdataset, sigrdataset); 1018 if (result == ISC_R_SUCCESS) { 1019 if (zfname != NULL && 1020 !dns_name_issubdomain(fname, zfname)) { 1021 /* 1022 * We found a zonecut in the cache, but our 1023 * zone delegation is better. 1024 */ 1025 use_zone = ISC_TRUE; 1026 } 1027 } else if (result == ISC_R_NOTFOUND) { 1028 if (zfname != NULL) { 1029 /* 1030 * We didn't find anything in the cache, but we 1031 * have a zone delegation, so use it. 1032 */ 1033 use_zone = ISC_TRUE; 1034 } else { 1035 /* 1036 * Maybe we have hints... 1037 */ 1038 try_hints = ISC_TRUE; 1039 } 1040 } else { 1041 /* 1042 * Something bad happened. 1043 */ 1044 goto cleanup; 1045 } 1046 } 1047 1048 finish: 1049 if (use_zone) { 1050 if (dns_rdataset_isassociated(rdataset)) { 1051 dns_rdataset_disassociate(rdataset); 1052 if (sigrdataset != NULL && 1053 dns_rdataset_isassociated(sigrdataset)) 1054 dns_rdataset_disassociate(sigrdataset); 1055 } 1056 result = dns_name_copy(zfname, fname, NULL); 1057 if (result != ISC_R_SUCCESS) 1058 goto cleanup; 1059 dns_rdataset_clone(&zrdataset, rdataset); 1060 if (sigrdataset != NULL && 1061 dns_rdataset_isassociated(&zrdataset)) 1062 dns_rdataset_clone(&zsigrdataset, sigrdataset); 1063 } else if (try_hints && use_hints && view->hints != NULL) { 1064 /* 1065 * We've found nothing so far, but we have hints. 1066 */ 1067 result = dns_db_find(view->hints, dns_rootname, NULL, 1068 dns_rdatatype_ns, 0, now, NULL, fname, 1069 rdataset, NULL); 1070 if (result != ISC_R_SUCCESS) { 1071 /* 1072 * We can't even find the hints for the root 1073 * nameservers! 1074 */ 1075 if (dns_rdataset_isassociated(rdataset)) 1076 dns_rdataset_disassociate(rdataset); 1077 result = ISC_R_NOTFOUND; 1078 } 1079 } 1080 1081 cleanup: 1082 if (dns_rdataset_isassociated(&zrdataset)) { 1083 dns_rdataset_disassociate(&zrdataset); 1084 if (dns_rdataset_isassociated(&zsigrdataset)) 1085 dns_rdataset_disassociate(&zsigrdataset); 1086 } 1087 if (db != NULL) 1088 dns_db_detach(&db); 1089 if (zone != NULL) 1090 dns_zone_detach(&zone); 1091 1092 return (result); 1093} 1094 1095isc_result_t 1096dns_viewlist_find(dns_viewlist_t *list, const char *name, 1097 dns_rdataclass_t rdclass, dns_view_t **viewp) 1098{ 1099 dns_view_t *view; 1100 1101 REQUIRE(list != NULL); 1102 1103 for (view = ISC_LIST_HEAD(*list); 1104 view != NULL; 1105 view = ISC_LIST_NEXT(view, link)) { 1106 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass) 1107 break; 1108 } 1109 if (view == NULL) 1110 return (ISC_R_NOTFOUND); 1111 1112 dns_view_attach(view, viewp); 1113 1114 return (ISC_R_SUCCESS); 1115} 1116 1117isc_result_t 1118dns_view_load(dns_view_t *view, isc_boolean_t stop) { 1119 1120 REQUIRE(DNS_VIEW_VALID(view)); 1121 1122 return (dns_zt_load(view->zonetable, stop)); 1123} 1124 1125isc_result_t 1126dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { 1127 1128 REQUIRE(DNS_VIEW_VALID(view)); 1129 1130 return (dns_zt_loadnew(view->zonetable, stop)); 1131} 1132 1133isc_result_t 1134dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp) 1135{ 1136 isc_result_t result; 1137 REQUIRE(keyp != NULL && *keyp == NULL); 1138 1139 result = dns_tsigkey_find(keyp, keyname, NULL, 1140 view->statickeys); 1141 if (result == ISC_R_NOTFOUND) 1142 result = dns_tsigkey_find(keyp, keyname, NULL, 1143 view->dynamickeys); 1144 return (result); 1145} 1146 1147isc_result_t 1148dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, 1149 dns_tsigkey_t **keyp) 1150{ 1151 isc_result_t result; 1152 dns_name_t *keyname = NULL; 1153 dns_peer_t *peer = NULL; 1154 1155 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer); 1156 if (result != ISC_R_SUCCESS) 1157 return (result); 1158 1159 result = dns_peer_getkey(peer, &keyname); 1160 if (result != ISC_R_SUCCESS) 1161 return (result); 1162 1163 return (dns_view_gettsig(view, keyname, keyp)); 1164} 1165 1166isc_result_t 1167dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) { 1168 REQUIRE(DNS_VIEW_VALID(view)); 1169 REQUIRE(source != NULL); 1170 1171 return (dns_tsig_verify(source, msg, view->statickeys, 1172 view->dynamickeys)); 1173} 1174 1175isc_result_t 1176dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { 1177 isc_result_t result; 1178 1179 REQUIRE(DNS_VIEW_VALID(view)); 1180 1181 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); 1182 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, 1183 &dns_master_style_cache, fp); 1184 if (result != ISC_R_SUCCESS) 1185 return (result); 1186 dns_adb_dump(view->adb, fp); 1187 return (ISC_R_SUCCESS); 1188} 1189 1190isc_result_t 1191dns_view_flushcache(dns_view_t *view) { 1192 isc_result_t result; 1193 1194 REQUIRE(DNS_VIEW_VALID(view)); 1195 1196 if (view->cachedb == NULL) 1197 return (ISC_R_SUCCESS); 1198 result = dns_cache_flush(view->cache); 1199 if (result != ISC_R_SUCCESS) 1200 return (result); 1201 dns_db_detach(&view->cachedb); 1202 dns_cache_attachdb(view->cache, &view->cachedb); 1203 1204 dns_adb_flush(view->adb); 1205 return (ISC_R_SUCCESS); 1206} 1207 1208isc_result_t 1209dns_view_flushname(dns_view_t *view, dns_name_t *name) { 1210 1211 REQUIRE(DNS_VIEW_VALID(view)); 1212 1213 if (view->adb != NULL) 1214 dns_adb_flushname(view->adb, name); 1215 if (view->cache == NULL) 1216 return (ISC_R_SUCCESS); 1217 return (dns_cache_flushname(view->cache, name)); 1218} 1219 1220isc_result_t 1221dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) { 1222 isc_result_t result; 1223 dns_name_t *new; 1224 isc_uint32_t hash; 1225 1226 REQUIRE(DNS_VIEW_VALID(view)); 1227 1228 if (view->delonly == NULL) { 1229 view->delonly = isc_mem_get(view->mctx, 1230 sizeof(dns_namelist_t) * 1231 DNS_VIEW_DELONLYHASH); 1232 if (view->delonly == NULL) 1233 return (ISC_R_NOMEMORY); 1234 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1235 ISC_LIST_INIT(view->delonly[hash]); 1236 } 1237 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1238 new = ISC_LIST_HEAD(view->delonly[hash]); 1239 while (new != NULL && !dns_name_equal(new, name)) 1240 new = ISC_LIST_NEXT(new, link); 1241 if (new != NULL) 1242 return (ISC_R_SUCCESS); 1243 new = isc_mem_get(view->mctx, sizeof(*new)); 1244 if (new == NULL) 1245 return (ISC_R_NOMEMORY); 1246 dns_name_init(new, NULL); 1247 result = dns_name_dup(name, view->mctx, new); 1248 if (result == ISC_R_SUCCESS) 1249 ISC_LIST_APPEND(view->delonly[hash], new, link); 1250 else 1251 isc_mem_put(view->mctx, new, sizeof(*new)); 1252 return (result); 1253} 1254 1255isc_result_t 1256dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) { 1257 isc_result_t result; 1258 dns_name_t *new; 1259 isc_uint32_t hash; 1260 1261 REQUIRE(DNS_VIEW_VALID(view)); 1262 1263 if (view->rootexclude == NULL) { 1264 view->rootexclude = isc_mem_get(view->mctx, 1265 sizeof(dns_namelist_t) * 1266 DNS_VIEW_DELONLYHASH); 1267 if (view->rootexclude == NULL) 1268 return (ISC_R_NOMEMORY); 1269 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1270 ISC_LIST_INIT(view->rootexclude[hash]); 1271 } 1272 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1273 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1274 while (new != NULL && !dns_name_equal(new, name)) 1275 new = ISC_LIST_NEXT(new, link); 1276 if (new != NULL) 1277 return (ISC_R_SUCCESS); 1278 new = isc_mem_get(view->mctx, sizeof(*new)); 1279 if (new == NULL) 1280 return (ISC_R_NOMEMORY); 1281 dns_name_init(new, NULL); 1282 result = dns_name_dup(name, view->mctx, new); 1283 if (result == ISC_R_SUCCESS) 1284 ISC_LIST_APPEND(view->rootexclude[hash], new, link); 1285 else 1286 isc_mem_put(view->mctx, new, sizeof(*new)); 1287 return (result); 1288} 1289 1290isc_boolean_t 1291dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { 1292 dns_name_t *new; 1293 isc_uint32_t hash; 1294 1295 REQUIRE(DNS_VIEW_VALID(view)); 1296 1297 if (!view->rootdelonly && view->delonly == NULL) 1298 return (ISC_FALSE); 1299 1300 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1301 if (view->rootdelonly && dns_name_countlabels(name) <= 2) { 1302 if (view->rootexclude == NULL) 1303 return (ISC_TRUE); 1304 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1305 while (new != NULL && !dns_name_equal(new, name)) 1306 new = ISC_LIST_NEXT(new, link); 1307 if (new == NULL) 1308 return (ISC_TRUE); 1309 } 1310 1311 if (view->delonly == NULL) 1312 return (ISC_FALSE); 1313 1314 new = ISC_LIST_HEAD(view->delonly[hash]); 1315 while (new != NULL && !dns_name_equal(new, name)) 1316 new = ISC_LIST_NEXT(new, link); 1317 if (new == NULL) 1318 return (ISC_FALSE); 1319 return (ISC_TRUE); 1320} 1321 1322void 1323dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) { 1324 REQUIRE(DNS_VIEW_VALID(view)); 1325 view->rootdelonly = value; 1326} 1327 1328isc_boolean_t 1329dns_view_getrootdelonly(dns_view_t *view) { 1330 REQUIRE(DNS_VIEW_VALID(view)); 1331 return (view->rootdelonly); 1332} 1333