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