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