view.c revision 225361
167754Smsmith/* 267754Smsmith * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") 367754Smsmith * Copyright (C) 1999-2003 Internet Software Consortium. 4117521Snjl * 567754Smsmith * Permission to use, copy, modify, and/or distribute this software for any 667754Smsmith * purpose with or without fee is hereby granted, provided that the above 767754Smsmith * copyright notice and this permission notice appear in all copies. 867754Smsmith * 967754Smsmith * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 1067754Smsmith * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1167754Smsmith * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12114237Snjl * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 1370243Smsmith * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 1467754Smsmith * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 1567754Smsmith * PERFORMANCE OF THIS SOFTWARE. 1667754Smsmith */ 1767754Smsmith 1867754Smsmith/* $Id: view.c,v 1.178.8.1 2011-03-11 06:47:06 marka Exp $ */ 1967754Smsmith 2067754Smsmith/*! \file */ 2167754Smsmith 2267754Smsmith#include <config.h> 2367754Smsmith 2467754Smsmith#include <isc/file.h> 2567754Smsmith#include <isc/hash.h> 2667754Smsmith#include <isc/print.h> 2767754Smsmith#include <isc/sha2.h> 2867754Smsmith#include <isc/stats.h> 2967754Smsmith#include <isc/string.h> /* Required for HP/UX (and others?) */ 3067754Smsmith#include <isc/task.h> 3167754Smsmith#include <isc/util.h> 3267754Smsmith 3367754Smsmith#include <dns/acache.h> 3467754Smsmith#include <dns/acl.h> 3567754Smsmith#include <dns/adb.h> 3667754Smsmith#include <dns/cache.h> 3767754Smsmith#include <dns/db.h> 3867754Smsmith#include <dns/dlz.h> 3967754Smsmith#ifdef BIND9 4067754Smsmith#include <dns/dns64.h> 4167754Smsmith#endif 4267754Smsmith#include <dns/dnssec.h> 4367754Smsmith#include <dns/events.h> 4467754Smsmith#include <dns/forward.h> 4567754Smsmith#include <dns/keytable.h> 4667754Smsmith#include <dns/keyvalues.h> 4767754Smsmith#include <dns/master.h> 4867754Smsmith#include <dns/masterdump.h> 4967754Smsmith#include <dns/order.h> 5067754Smsmith#include <dns/peer.h> 5167754Smsmith#include <dns/rbt.h> 5267754Smsmith#include <dns/rdataset.h> 5367754Smsmith#include <dns/request.h> 5467754Smsmith#include <dns/resolver.h> 5567754Smsmith#include <dns/result.h> 5667754Smsmith#include <dns/rpz.h> 5767754Smsmith#include <dns/stats.h> 5867754Smsmith#include <dns/tsig.h> 5967754Smsmith#include <dns/zone.h> 6067754Smsmith#include <dns/zt.h> 6167754Smsmith 6267754Smsmith#define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0) 6367754Smsmith#define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0) 6467754Smsmith#define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0) 6567754Smsmith 6667754Smsmith#define DNS_VIEW_DELONLYHASH 111 6767754Smsmith 6867754Smsmithstatic void resolver_shutdown(isc_task_t *task, isc_event_t *event); 6967754Smsmithstatic void adb_shutdown(isc_task_t *task, isc_event_t *event); 7067754Smsmithstatic void req_shutdown(isc_task_t *task, isc_event_t *event); 7167754Smsmith 7267754Smsmithisc_result_t 7367754Smsmithdns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, 7467754Smsmith const char *name, dns_view_t **viewp) 7567754Smsmith{ 7667754Smsmith dns_view_t *view; 7767754Smsmith isc_result_t result; 7867754Smsmith 7967754Smsmith /* 8067754Smsmith * Create a view. 8167754Smsmith */ 8267754Smsmith 8367754Smsmith REQUIRE(name != NULL); 8467754Smsmith REQUIRE(viewp != NULL && *viewp == NULL); 8567754Smsmith 8667754Smsmith view = isc_mem_get(mctx, sizeof(*view)); 8767754Smsmith if (view == NULL) 8867754Smsmith return (ISC_R_NOMEMORY); 8967754Smsmith view->name = isc_mem_strdup(mctx, name); 9067754Smsmith if (view->name == NULL) { 9167754Smsmith result = ISC_R_NOMEMORY; 9267754Smsmith goto cleanup_view; 9367754Smsmith } 9467754Smsmith result = isc_mutex_init(&view->lock); 9567754Smsmith if (result != ISC_R_SUCCESS) 9667754Smsmith goto cleanup_name; 9767754Smsmith 9867754Smsmith#ifdef BIND9 9967754Smsmith view->zonetable = NULL; 10067754Smsmith result = dns_zt_create(mctx, rdclass, &view->zonetable); 10167754Smsmith if (result != ISC_R_SUCCESS) { 10267754Smsmith UNEXPECTED_ERROR(__FILE__, __LINE__, 10367754Smsmith "dns_zt_create() failed: %s", 10467754Smsmith isc_result_totext(result)); 10567754Smsmith result = ISC_R_UNEXPECTED; 10667754Smsmith goto cleanup_mutex; 10767754Smsmith } 10867754Smsmith#endif 10967754Smsmith view->secroots_priv = NULL; 11067754Smsmith view->fwdtable = NULL; 11167754Smsmith result = dns_fwdtable_create(mctx, &view->fwdtable); 11267754Smsmith if (result != ISC_R_SUCCESS) { 11367754Smsmith UNEXPECTED_ERROR(__FILE__, __LINE__, 11467754Smsmith "dns_fwdtable_create() failed: %s", 11567754Smsmith isc_result_totext(result)); 11667754Smsmith result = ISC_R_UNEXPECTED; 11767754Smsmith goto cleanup_zt; 11867754Smsmith } 11967754Smsmith 12067754Smsmith view->acache = NULL; 12167754Smsmith view->cache = NULL; 12267754Smsmith view->cachedb = NULL; 12367754Smsmith view->dlzdatabase = NULL; 12467754Smsmith view->hints = NULL; 125117521Snjl view->resolver = NULL; 12667754Smsmith view->adb = NULL; 12767754Smsmith view->requestmgr = NULL; 128102550Siwasaki view->mctx = mctx; 12967754Smsmith view->rdclass = rdclass; 13067754Smsmith view->frozen = ISC_FALSE; 131102550Siwasaki view->task = NULL; 13291116Smsmith result = isc_refcount_init(&view->references, 1); 13367754Smsmith if (result != ISC_R_SUCCESS) 13467754Smsmith goto cleanup_fwdtable; 13567754Smsmith view->weakrefs = 0; 13667754Smsmith view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| 13767754Smsmith DNS_VIEWATTR_REQSHUTDOWN); 13867754Smsmith view->statickeys = NULL; 13967754Smsmith view->dynamickeys = NULL; 14067754Smsmith view->matchclients = NULL; 14167754Smsmith view->matchdestinations = NULL; 14267754Smsmith view->matchrecursiveonly = ISC_FALSE; 14367754Smsmith result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); 14467754Smsmith if (result != ISC_R_SUCCESS) 14567754Smsmith goto cleanup_references; 14667754Smsmith view->peers = NULL; 14767754Smsmith view->order = NULL; 14867754Smsmith view->delonly = NULL; 14967754Smsmith view->rootdelonly = ISC_FALSE; 15067754Smsmith view->rootexclude = NULL; 15167754Smsmith view->resstats = NULL; 15267754Smsmith view->resquerystats = NULL; 15367754Smsmith view->cacheshared = ISC_FALSE; 15499679Siwasaki ISC_LIST_INIT(view->dns64); 15567754Smsmith view->dns64cnt = 0; 15667754Smsmith 15767754Smsmith /* 15867754Smsmith * Initialize configuration data with default values. 15967754Smsmith */ 16067754Smsmith view->recursion = ISC_TRUE; 16167754Smsmith view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */ 16267754Smsmith view->additionalfromcache = ISC_TRUE; 16367754Smsmith view->additionalfromauth = ISC_TRUE; 16467754Smsmith view->enablednssec = ISC_TRUE; 16567754Smsmith view->enablevalidation = ISC_TRUE; 16667754Smsmith view->acceptexpired = ISC_FALSE; 16767754Smsmith view->minimalresponses = ISC_FALSE; 16867754Smsmith view->transfer_format = dns_one_answer; 16991116Smsmith view->cacheacl = NULL; 17067754Smsmith view->cacheonacl = NULL; 17167754Smsmith view->queryacl = NULL; 17267754Smsmith view->queryonacl = NULL; 17367754Smsmith view->recursionacl = NULL; 17467754Smsmith view->recursiononacl = NULL; 17567754Smsmith view->sortlist = NULL; 17667754Smsmith view->transferacl = NULL; 17767754Smsmith view->notifyacl = NULL; 17867754Smsmith view->updateacl = NULL; 17967754Smsmith view->upfwdacl = NULL; 18067754Smsmith view->denyansweracl = NULL; 18167754Smsmith view->answeracl_exclude = NULL; 18267754Smsmith view->denyanswernames = NULL; 18367754Smsmith view->answernames_exclude = NULL; 18467754Smsmith view->requestixfr = ISC_TRUE; 18567754Smsmith view->provideixfr = ISC_TRUE; 18667754Smsmith view->maxcachettl = 7 * 24 * 3600; 18767754Smsmith view->maxncachettl = 3 * 3600; 18867754Smsmith view->dstport = 53; 18967754Smsmith view->preferred_glue = 0; 19067754Smsmith view->flush = ISC_FALSE; 19167754Smsmith view->dlv = NULL; 19283174Smsmith view->maxudp = 0; 19367754Smsmith view->v4_aaaa = dns_v4_aaaa_ok; 19467754Smsmith view->v4_aaaa_acl = NULL; 19599679Siwasaki ISC_LIST_INIT(view->rpz_zones); 19667754Smsmith dns_fixedname_init(&view->dlv_fixed); 19767754Smsmith view->managed_keys = NULL; 19899679Siwasaki#ifdef BIND9 19967754Smsmith view->new_zone_file = NULL; 20091116Smsmith view->new_zone_config = NULL; 20167754Smsmith view->cfg_destroy = NULL; 20299679Siwasaki 20399679Siwasaki result = dns_order_create(view->mctx, &view->order); 20499679Siwasaki if (result != ISC_R_SUCCESS) 20567754Smsmith goto cleanup_dynkeys; 20667754Smsmith#endif 20767754Smsmith 20867754Smsmith result = dns_peerlist_new(view->mctx, &view->peers); 20967754Smsmith if (result != ISC_R_SUCCESS) 21067754Smsmith goto cleanup_order; 21167754Smsmith 21267754Smsmith result = dns_aclenv_init(view->mctx, &view->aclenv); 21367754Smsmith if (result != ISC_R_SUCCESS) 21467754Smsmith goto cleanup_peerlist; 21567754Smsmith 21667754Smsmith ISC_LINK_INIT(view, link); 21767754Smsmith ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL, 21867754Smsmith DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown, 21967754Smsmith view, NULL, NULL, NULL); 22067754Smsmith ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL, 22167754Smsmith DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown, 22267754Smsmith view, NULL, NULL, NULL); 22367754Smsmith ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL, 224114237Snjl DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, 225114237Snjl view, NULL, NULL, NULL); 22667754Smsmith view->magic = DNS_VIEW_MAGIC; 22767754Smsmith 22867754Smsmith *viewp = view; 22987031Smsmith 23067754Smsmith return (ISC_R_SUCCESS); 231114237Snjl 23267754Smsmith cleanup_peerlist: 23367754Smsmith dns_peerlist_detach(&view->peers); 23467754Smsmith 23567754Smsmith cleanup_order: 23667754Smsmith#ifdef BIND9 23767754Smsmith dns_order_detach(&view->order); 23867754Smsmith 23967754Smsmith cleanup_dynkeys: 24067754Smsmith#endif 24167754Smsmith dns_tsigkeyring_detach(&view->dynamickeys); 24267754Smsmith 24367754Smsmith cleanup_references: 24467754Smsmith isc_refcount_destroy(&view->references); 24567754Smsmith 24691116Smsmith cleanup_fwdtable: 24767754Smsmith dns_fwdtable_destroy(&view->fwdtable); 24867754Smsmith 24967754Smsmith cleanup_zt: 25067754Smsmith#ifdef BIND9 25167754Smsmith dns_zt_detach(&view->zonetable); 25267754Smsmith 25367754Smsmith cleanup_mutex: 25467754Smsmith#endif 25567754Smsmith DESTROYLOCK(&view->lock); 25667754Smsmith 25767754Smsmith cleanup_name: 25867754Smsmith isc_mem_free(mctx, view->name); 25967754Smsmith 26067754Smsmith cleanup_view: 26167754Smsmith isc_mem_put(mctx, view, sizeof(*view)); 26267754Smsmith 26367754Smsmith return (result); 26467754Smsmith} 26567754Smsmith 26667754Smsmithstatic inline void 26767754Smsmithdestroy(dns_view_t *view) { 26867754Smsmith#ifdef BIND9 26967754Smsmith dns_dns64_t *dns64; 27067754Smsmith#endif 27167754Smsmith 27267754Smsmith REQUIRE(!ISC_LINK_LINKED(view, link)); 27367754Smsmith REQUIRE(isc_refcount_current(&view->references) == 0); 27467754Smsmith REQUIRE(view->weakrefs == 0); 27567754Smsmith REQUIRE(RESSHUTDOWN(view)); 27667754Smsmith REQUIRE(ADBSHUTDOWN(view)); 27791116Smsmith REQUIRE(REQSHUTDOWN(view)); 27867754Smsmith 27991116Smsmith#ifdef BIND9 28067754Smsmith if (view->order != NULL) 28191116Smsmith dns_order_detach(&view->order); 28291116Smsmith#endif 28367754Smsmith if (view->peers != NULL) 28467754Smsmith dns_peerlist_detach(&view->peers); 28567754Smsmith 28667754Smsmith if (view->dynamickeys != NULL) { 28767754Smsmith isc_result_t result; 28867754Smsmith char template[20]; 28967754Smsmith char keyfile[20]; 29067754Smsmith FILE *fp = NULL; 29167754Smsmith int n; 29267754Smsmith 29399679Siwasaki n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", 29491116Smsmith view->name); 29591116Smsmith if (n > 0 && (size_t)n < sizeof(keyfile)) { 29691116Smsmith result = isc_file_mktemplate(keyfile, template, 29767754Smsmith sizeof(template)); 29867754Smsmith if (result == ISC_R_SUCCESS) 29967754Smsmith (void)isc_file_openuniqueprivate(template, &fp); 30067754Smsmith } 30167754Smsmith if (fp == NULL) 30267754Smsmith dns_tsigkeyring_detach(&view->dynamickeys); 30377424Smsmith else { 30477424Smsmith result = dns_tsigkeyring_dumpanddetach( 30591116Smsmith &view->dynamickeys, fp); 30667754Smsmith if (result == ISC_R_SUCCESS) { 30767754Smsmith if (fclose(fp) == 0) 30891116Smsmith result = isc_file_rename(template, 30991116Smsmith keyfile); 31091116Smsmith if (result != ISC_R_SUCCESS) 31191116Smsmith (void)remove(template); 31267754Smsmith } else { 31367754Smsmith (void)fclose(fp); 31467754Smsmith (void)remove(template); 31567754Smsmith } 31667754Smsmith } 31767754Smsmith } 31877424Smsmith if (view->statickeys != NULL) 31967754Smsmith dns_tsigkeyring_detach(&view->statickeys); 32091116Smsmith if (view->adb != NULL) 32167754Smsmith dns_adb_detach(&view->adb); 32291116Smsmith if (view->resolver != NULL) 32391116Smsmith dns_resolver_detach(&view->resolver); 32491116Smsmith#ifdef BIND9 32591116Smsmith if (view->acache != NULL) { 32691116Smsmith if (view->cachedb != NULL) 32767754Smsmith dns_acache_putdb(view->acache, view->cachedb); 32867754Smsmith dns_acache_detach(&view->acache); 32967754Smsmith } 33067754Smsmith dns_rpz_view_destroy(view); 33167754Smsmith#else 33267754Smsmith INSIST(view->acache == NULL); 33367754Smsmith INSIST(ISC_LIST_EMPTY(view->rpz_zones)); 33467754Smsmith#endif 33577424Smsmith if (view->requestmgr != NULL) 33691116Smsmith dns_requestmgr_detach(&view->requestmgr); 33767754Smsmith if (view->task != NULL) 33867754Smsmith isc_task_detach(&view->task); 33967754Smsmith if (view->hints != NULL) 34067754Smsmith dns_db_detach(&view->hints); 34167754Smsmith if (view->dlzdatabase != NULL) 34267754Smsmith dns_dlzdestroy(&view->dlzdatabase); 34367754Smsmith if (view->cachedb != NULL) 34467754Smsmith dns_db_detach(&view->cachedb); 34567754Smsmith if (view->cache != NULL) 34667754Smsmith dns_cache_detach(&view->cache); 34767754Smsmith if (view->matchclients != NULL) 34867754Smsmith dns_acl_detach(&view->matchclients); 34967754Smsmith if (view->matchdestinations != NULL) 35067754Smsmith dns_acl_detach(&view->matchdestinations); 35167754Smsmith if (view->cacheacl != NULL) 35267754Smsmith dns_acl_detach(&view->cacheacl); 35367754Smsmith if (view->cacheonacl != NULL) 35467754Smsmith dns_acl_detach(&view->cacheonacl); 35567754Smsmith if (view->queryacl != NULL) 35667754Smsmith dns_acl_detach(&view->queryacl); 35767754Smsmith if (view->queryonacl != NULL) 35867754Smsmith dns_acl_detach(&view->queryonacl); 35967754Smsmith if (view->recursionacl != NULL) 36069746Smsmith dns_acl_detach(&view->recursionacl); 36169746Smsmith if (view->recursiononacl != NULL) 362104470Siwasaki dns_acl_detach(&view->recursiononacl); 36369746Smsmith if (view->sortlist != NULL) 36469746Smsmith dns_acl_detach(&view->sortlist); 36567754Smsmith if (view->transferacl != NULL) 36667754Smsmith dns_acl_detach(&view->transferacl); 36767754Smsmith if (view->notifyacl != NULL) 36867754Smsmith dns_acl_detach(&view->notifyacl); 36967754Smsmith if (view->updateacl != NULL) 37067754Smsmith dns_acl_detach(&view->updateacl); 37177424Smsmith if (view->upfwdacl != NULL) 37277424Smsmith dns_acl_detach(&view->upfwdacl); 37367754Smsmith if (view->denyansweracl != NULL) 37487031Smsmith dns_acl_detach(&view->denyansweracl); 37587031Smsmith if (view->v4_aaaa_acl != NULL) 37667754Smsmith dns_acl_detach(&view->v4_aaaa_acl); 37787031Smsmith if (view->answeracl_exclude != NULL) 37887031Smsmith dns_rbt_destroy(&view->answeracl_exclude); 37967754Smsmith if (view->denyanswernames != NULL) 38087031Smsmith dns_rbt_destroy(&view->denyanswernames); 38167754Smsmith if (view->answernames_exclude != NULL) 38267754Smsmith dns_rbt_destroy(&view->answernames_exclude); 38367754Smsmith if (view->delonly != NULL) { 38487031Smsmith dns_name_t *name; 38587031Smsmith int i; 38667754Smsmith 38767754Smsmith for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 38867754Smsmith name = ISC_LIST_HEAD(view->delonly[i]); 38967754Smsmith while (name != NULL) { 39067754Smsmith ISC_LIST_UNLINK(view->delonly[i], name, link); 39167754Smsmith dns_name_free(name, view->mctx); 39267754Smsmith isc_mem_put(view->mctx, name, sizeof(*name)); 39367754Smsmith name = ISC_LIST_HEAD(view->delonly[i]); 39467754Smsmith } 39567754Smsmith } 39667754Smsmith isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) * 39767754Smsmith DNS_VIEW_DELONLYHASH); 39867754Smsmith view->delonly = NULL; 39967754Smsmith } 40067754Smsmith if (view->rootexclude != NULL) { 40167754Smsmith dns_name_t *name; 40267754Smsmith int i; 40367754Smsmith 40467754Smsmith for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 40567754Smsmith name = ISC_LIST_HEAD(view->rootexclude[i]); 40667754Smsmith while (name != NULL) { 40767754Smsmith ISC_LIST_UNLINK(view->rootexclude[i], 40867754Smsmith name, link); 40967754Smsmith dns_name_free(name, view->mctx); 41067754Smsmith isc_mem_put(view->mctx, name, sizeof(*name)); 41183174Smsmith name = ISC_LIST_HEAD(view->rootexclude[i]); 41267754Smsmith } 41367754Smsmith } 41467754Smsmith isc_mem_put(view->mctx, view->rootexclude, 41567754Smsmith sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); 41667754Smsmith view->rootexclude = NULL; 41767754Smsmith } 41867754Smsmith if (view->resstats != NULL) 41967754Smsmith isc_stats_detach(&view->resstats); 42067754Smsmith if (view->resquerystats != NULL) 42167754Smsmith dns_stats_detach(&view->resquerystats); 42267754Smsmith if (view->secroots_priv != NULL) 42367754Smsmith dns_keytable_detach(&view->secroots_priv); 42467754Smsmith#ifdef BIND9 42567754Smsmith for (dns64 = ISC_LIST_HEAD(view->dns64); 42667754Smsmith dns64 != NULL; 42767754Smsmith dns64 = ISC_LIST_HEAD(view->dns64)) { 42867754Smsmith dns_dns64_unlink(&view->dns64, dns64); 42967754Smsmith dns_dns64_destroy(&dns64); 43067754Smsmith } 43187031Smsmith if (view->managed_keys != NULL) 43267754Smsmith dns_zone_detach(&view->managed_keys); 43387031Smsmith dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); 43467754Smsmith#endif 43567754Smsmith dns_fwdtable_destroy(&view->fwdtable); 43699679Siwasaki dns_aclenv_destroy(&view->aclenv); 43769746Smsmith DESTROYLOCK(&view->lock); 43867754Smsmith isc_refcount_destroy(&view->references); 43967754Smsmith isc_mem_free(view->mctx, view->name); 44067754Smsmith isc_mem_put(view->mctx, view, sizeof(*view)); 44199679Siwasaki} 44267754Smsmith 44399679Siwasaki/* 44467754Smsmith * Return true iff 'view' may be freed. 44567754Smsmith * The caller must be holding the view lock. 44667754Smsmith */ 44767754Smsmithstatic isc_boolean_t 44867754Smsmithall_done(dns_view_t *view) { 44967754Smsmith 45067754Smsmith if (isc_refcount_current(&view->references) == 0 && 45167754Smsmith view->weakrefs == 0 && 45267754Smsmith RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) 45367754Smsmith return (ISC_TRUE); 45467754Smsmith 45567754Smsmith return (ISC_FALSE); 45667754Smsmith} 45767754Smsmith 45867754Smsmithvoid 45967754Smsmithdns_view_attach(dns_view_t *source, dns_view_t **targetp) { 46067754Smsmith 46167754Smsmith REQUIRE(DNS_VIEW_VALID(source)); 46267754Smsmith REQUIRE(targetp != NULL && *targetp == NULL); 46399679Siwasaki 46485756Smsmith isc_refcount_increment(&source->references, NULL); 46567754Smsmith 46685756Smsmith *targetp = source; 46767754Smsmith} 46867754Smsmith 46967754Smsmithstatic void 47067754Smsmithview_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { 47167754Smsmith dns_view_t *view; 47267754Smsmith unsigned int refs; 47367754Smsmith isc_boolean_t done = ISC_FALSE; 47467754Smsmith 47585756Smsmith REQUIRE(viewp != NULL); 47685756Smsmith view = *viewp; 47785756Smsmith REQUIRE(DNS_VIEW_VALID(view)); 47885756Smsmith 47985756Smsmith if (flush) 48067754Smsmith view->flush = ISC_TRUE; 48167754Smsmith isc_refcount_decrement(&view->references, &refs); 48267754Smsmith if (refs == 0) { 48367754Smsmith LOCK(&view->lock); 48467754Smsmith if (!RESSHUTDOWN(view)) 48567754Smsmith dns_resolver_shutdown(view->resolver); 48667754Smsmith if (!ADBSHUTDOWN(view)) 48767754Smsmith dns_adb_shutdown(view->adb); 48867754Smsmith if (!REQSHUTDOWN(view)) 48967754Smsmith dns_requestmgr_shutdown(view->requestmgr); 49067754Smsmith#ifdef BIND9 49167754Smsmith if (view->acache != NULL) 49267754Smsmith dns_acache_shutdown(view->acache); 49369746Smsmith if (view->flush) 49467754Smsmith dns_zt_flushanddetach(&view->zonetable); 49567754Smsmith else 49669746Smsmith dns_zt_detach(&view->zonetable); 49767754Smsmith if (view->managed_keys != NULL) { 49867754Smsmith if (view->flush) 49967754Smsmith dns_zone_flush(view->managed_keys); 50067754Smsmith dns_zone_detach(&view->managed_keys); 50167754Smsmith } 50267754Smsmith#endif 50367754Smsmith done = all_done(view); 50467754Smsmith UNLOCK(&view->lock); 50567754Smsmith } 50667754Smsmith 50767754Smsmith *viewp = NULL; 50867754Smsmith 50967754Smsmith if (done) 51067754Smsmith destroy(view); 51167754Smsmith} 51267754Smsmith 51367754Smsmithvoid 51467754Smsmithdns_view_flushanddetach(dns_view_t **viewp) { 51567754Smsmith view_flushanddetach(viewp, ISC_TRUE); 51667754Smsmith} 51767754Smsmith 51867754Smsmithvoid 51967754Smsmithdns_view_detach(dns_view_t **viewp) { 52067754Smsmith view_flushanddetach(viewp, ISC_FALSE); 52167754Smsmith} 52267754Smsmith 52367754Smsmith#ifdef BIND9 52467754Smsmithstatic isc_result_t 52567754Smsmithdialup(dns_zone_t *zone, void *dummy) { 526117521Snjl UNUSED(dummy); 52767754Smsmith dns_zone_dialup(zone); 52867754Smsmith return (ISC_R_SUCCESS); 52967754Smsmith} 53067754Smsmith 53167754Smsmithvoid 53267754Smsmithdns_view_dialup(dns_view_t *view) { 53367754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 53467754Smsmith (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL); 53567754Smsmith} 53667754Smsmith#endif 53767754Smsmith 53867754Smsmithvoid 53967754Smsmithdns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { 54067754Smsmith 54167754Smsmith REQUIRE(DNS_VIEW_VALID(source)); 54267754Smsmith REQUIRE(targetp != NULL && *targetp == NULL); 54367754Smsmith 54467754Smsmith LOCK(&source->lock); 54567754Smsmith source->weakrefs++; 54667754Smsmith UNLOCK(&source->lock); 54767754Smsmith 54867754Smsmith *targetp = source; 54967754Smsmith} 55067754Smsmith 55167754Smsmithvoid 55267754Smsmithdns_view_weakdetach(dns_view_t **viewp) { 55367754Smsmith dns_view_t *view; 55467754Smsmith isc_boolean_t done = ISC_FALSE; 555117521Snjl 55667754Smsmith REQUIRE(viewp != NULL); 55767754Smsmith view = *viewp; 55867754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 55967754Smsmith 56067754Smsmith LOCK(&view->lock); 56167754Smsmith 56267754Smsmith INSIST(view->weakrefs > 0); 56367754Smsmith view->weakrefs--; 56467754Smsmith done = all_done(view); 56567754Smsmith 56667754Smsmith UNLOCK(&view->lock); 56767754Smsmith 56867754Smsmith *viewp = NULL; 56967754Smsmith 57067754Smsmith if (done) 57167754Smsmith destroy(view); 57267754Smsmith} 57367754Smsmith 57467754Smsmithstatic void 57567754Smsmithresolver_shutdown(isc_task_t *task, isc_event_t *event) { 57667754Smsmith dns_view_t *view = event->ev_arg; 57769746Smsmith isc_boolean_t done; 57867754Smsmith 57967754Smsmith REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); 58067754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 58167754Smsmith REQUIRE(view->task == task); 58267754Smsmith 58367754Smsmith UNUSED(task); 58467754Smsmith 58567754Smsmith LOCK(&view->lock); 58667754Smsmith 58767754Smsmith view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; 58867754Smsmith done = all_done(view); 58967754Smsmith 59067754Smsmith UNLOCK(&view->lock); 59169746Smsmith 59269746Smsmith isc_event_free(&event); 59369746Smsmith 59469746Smsmith if (done) 59567754Smsmith destroy(view); 59687031Smsmith} 59799679Siwasaki 59869746Smsmithstatic void 59969746Smsmithadb_shutdown(isc_task_t *task, isc_event_t *event) { 60067754Smsmith dns_view_t *view = event->ev_arg; 60169746Smsmith isc_boolean_t done; 60267754Smsmith 603117521Snjl REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); 60467754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 60567754Smsmith REQUIRE(view->task == task); 60667754Smsmith 60767754Smsmith UNUSED(task); 60867754Smsmith 60967754Smsmith LOCK(&view->lock); 61067754Smsmith 61167754Smsmith view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; 61267754Smsmith done = all_done(view); 61367754Smsmith 61467754Smsmith UNLOCK(&view->lock); 61567754Smsmith 61667754Smsmith isc_event_free(&event); 61767754Smsmith 61867754Smsmith if (done) 61967754Smsmith destroy(view); 62067754Smsmith} 62167754Smsmith 62267754Smsmithstatic void 62367754Smsmithreq_shutdown(isc_task_t *task, isc_event_t *event) { 62467754Smsmith dns_view_t *view = event->ev_arg; 62567754Smsmith isc_boolean_t done; 62667754Smsmith 62767754Smsmith REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); 62867754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 62967754Smsmith REQUIRE(view->task == task); 63067754Smsmith 63167754Smsmith UNUSED(task); 63267754Smsmith 63367754Smsmith LOCK(&view->lock); 63469450Smsmith 63567754Smsmith view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; 63667754Smsmith done = all_done(view); 63799679Siwasaki 63867754Smsmith UNLOCK(&view->lock); 63969450Smsmith 64067754Smsmith isc_event_free(&event); 64199679Siwasaki 64267754Smsmith if (done) 64367754Smsmith destroy(view); 64467754Smsmith} 64567754Smsmith 64667754Smsmithisc_result_t 64767754Smsmithdns_view_createresolver(dns_view_t *view, 64867754Smsmith isc_taskmgr_t *taskmgr, unsigned int ntasks, 64967754Smsmith isc_socketmgr_t *socketmgr, 650117521Snjl isc_timermgr_t *timermgr, 651117521Snjl unsigned int options, 652117521Snjl dns_dispatchmgr_t *dispatchmgr, 653117521Snjl dns_dispatch_t *dispatchv4, 654117521Snjl dns_dispatch_t *dispatchv6) 655117521Snjl{ 656117521Snjl isc_result_t result; 657117521Snjl isc_event_t *event; 658117521Snjl isc_mem_t *mctx = NULL; 659117521Snjl 660117521Snjl REQUIRE(DNS_VIEW_VALID(view)); 661117521Snjl REQUIRE(!view->frozen); 662117521Snjl REQUIRE(view->resolver == NULL); 663117521Snjl 664117521Snjl result = isc_task_create(taskmgr, 0, &view->task); 665117521Snjl if (result != ISC_R_SUCCESS) 666117521Snjl return (result); 667117521Snjl isc_task_setname(view->task, "view", view); 668117521Snjl 669117521Snjl result = dns_resolver_create(view, taskmgr, ntasks, socketmgr, 670117521Snjl timermgr, options, dispatchmgr, 671117521Snjl dispatchv4, dispatchv6, 672117521Snjl &view->resolver); 673117521Snjl if (result != ISC_R_SUCCESS) { 674117521Snjl isc_task_detach(&view->task); 675117521Snjl return (result); 676117521Snjl } 677117521Snjl event = &view->resevent; 678117521Snjl dns_resolver_whenshutdown(view->resolver, view->task, &event); 679117521Snjl view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; 680117521Snjl 681117521Snjl result = isc_mem_create(0, 0, &mctx); 682117521Snjl if (result != ISC_R_SUCCESS) { 683117521Snjl dns_resolver_shutdown(view->resolver); 684117521Snjl return (result); 685117521Snjl } 686117521Snjl 687117521Snjl result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb); 688117521Snjl isc_mem_setname(mctx, "ADB", NULL); 689117521Snjl isc_mem_detach(&mctx); 690117521Snjl if (result != ISC_R_SUCCESS) { 691117521Snjl dns_resolver_shutdown(view->resolver); 692117521Snjl return (result); 693117521Snjl } 694117521Snjl event = &view->adbevent; 695117521Snjl dns_adb_whenshutdown(view->adb, view->task, &event); 696117521Snjl view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; 697117521Snjl 698117521Snjl result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, 699117521Snjl dns_resolver_taskmgr(view->resolver), 700117521Snjl dns_resolver_dispatchmgr(view->resolver), 701117521Snjl dns_resolver_dispatchv4(view->resolver), 702117521Snjl dns_resolver_dispatchv6(view->resolver), 70367754Smsmith &view->requestmgr); 70467754Smsmith if (result != ISC_R_SUCCESS) { 70567754Smsmith dns_adb_shutdown(view->adb); 70667754Smsmith dns_resolver_shutdown(view->resolver); 70767754Smsmith return (result); 70867754Smsmith } 70967754Smsmith event = &view->reqevent; 71067754Smsmith dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); 71167754Smsmith view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; 71291116Smsmith 71391116Smsmith return (ISC_R_SUCCESS); 71491116Smsmith} 71591116Smsmith 71667754Smsmithvoid 71767754Smsmithdns_view_setcache(dns_view_t *view, dns_cache_t *cache) { 71867754Smsmith dns_view_setcache2(view, cache, ISC_FALSE); 71967754Smsmith} 72067754Smsmith 72167754Smsmithvoid 72267754Smsmithdns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) { 72367754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 72491116Smsmith REQUIRE(!view->frozen); 72591116Smsmith 72667754Smsmith view->cacheshared = shared; 72767754Smsmith if (view->cache != NULL) { 72867754Smsmith#ifdef BIND9 72967754Smsmith if (view->acache != NULL) 73067754Smsmith dns_acache_putdb(view->acache, view->cachedb); 73167754Smsmith#endif 732117521Snjl dns_db_detach(&view->cachedb); 73367754Smsmith dns_cache_detach(&view->cache); 73467754Smsmith } 73567754Smsmith dns_cache_attach(cache, &view->cache); 73667754Smsmith dns_cache_attachdb(cache, &view->cachedb); 73767754Smsmith INSIST(DNS_DB_VALID(view->cachedb)); 73867754Smsmith 73967754Smsmith#ifdef BIND9 74067754Smsmith if (view->acache != NULL) 74167754Smsmith dns_acache_setdb(view->acache, view->cachedb); 74267754Smsmith#endif 74367754Smsmith} 74467754Smsmith 74567754Smsmithisc_boolean_t 74667754Smsmithdns_view_iscacheshared(dns_view_t *view) { 74767754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 74867754Smsmith 74967754Smsmith return (view->cacheshared); 75067754Smsmith} 75167754Smsmith 75267754Smsmithvoid 75367754Smsmithdns_view_sethints(dns_view_t *view, dns_db_t *hints) { 75467754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 75567754Smsmith REQUIRE(!view->frozen); 75667754Smsmith REQUIRE(view->hints == NULL); 75767754Smsmith REQUIRE(dns_db_iszone(hints)); 75867754Smsmith 75967754Smsmith dns_db_attach(hints, &view->hints); 76067754Smsmith} 76167754Smsmith 762117521Snjlvoid 76367754Smsmithdns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 76467754Smsmith REQUIRE(DNS_VIEW_VALID(view)); 765114237Snjl REQUIRE(ring != NULL); 766114237Snjl if (view->statickeys != NULL) 767114237Snjl dns_tsigkeyring_detach(&view->statickeys); 768114237Snjl dns_tsigkeyring_attach(ring, &view->statickeys); 769114237Snjl} 770114237Snjl 771114237Snjlvoid 772114237Snjldns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 773114237Snjl REQUIRE(DNS_VIEW_VALID(view)); 774114237Snjl REQUIRE(ring != NULL); 775114237Snjl if (view->dynamickeys != NULL) 776114237Snjl dns_tsigkeyring_detach(&view->dynamickeys); 777114237Snjl dns_tsigkeyring_attach(ring, &view->dynamickeys); 778114237Snjl} 779114237Snjl 780114237Snjlvoid 781114237Snjldns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) { 782117521Snjl REQUIRE(DNS_VIEW_VALID(view)); 783114237Snjl REQUIRE(ringp != NULL && *ringp == NULL); 784114237Snjl if (view->dynamickeys != NULL) 785114237Snjl dns_tsigkeyring_attach(view->dynamickeys, ringp); 786117521Snjl} 787117521Snjl 788114237Snjlvoid 789117521Snjldns_view_restorekeyring(dns_view_t *view) { 790117521Snjl FILE *fp; 791117521Snjl char keyfile[20]; 792117521Snjl int n; 793117521Snjl 794117521Snjl REQUIRE(DNS_VIEW_VALID(view)); 795117521Snjl 796117521Snjl if (view->dynamickeys != NULL) { 797117521Snjl n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", 798117521Snjl view->name); 799114237Snjl if (n > 0 && (size_t)n < sizeof(keyfile)) { 800117521Snjl fp = fopen(keyfile, "r"); 801117521Snjl if (fp != NULL) { 802117521Snjl dns_keyring_restore(view->dynamickeys, fp); 803117521Snjl (void)fclose(fp); 804114237Snjl } 805114237Snjl } 806114237Snjl } 807114237Snjl} 808102550Siwasaki 80967754Smsmithvoid 810dns_view_setdstport(dns_view_t *view, in_port_t dstport) { 811 REQUIRE(DNS_VIEW_VALID(view)); 812 view->dstport = dstport; 813} 814 815void 816dns_view_freeze(dns_view_t *view) { 817 REQUIRE(DNS_VIEW_VALID(view)); 818 REQUIRE(!view->frozen); 819 820 if (view->resolver != NULL) { 821 INSIST(view->cachedb != NULL); 822 dns_resolver_freeze(view->resolver); 823 } 824 view->frozen = ISC_TRUE; 825} 826 827#ifdef BIND9 828void 829dns_view_thaw(dns_view_t *view) { 830 REQUIRE(DNS_VIEW_VALID(view)); 831 REQUIRE(view->frozen); 832 833 view->frozen = ISC_FALSE; 834} 835 836isc_result_t 837dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { 838 isc_result_t result; 839 840 REQUIRE(DNS_VIEW_VALID(view)); 841 REQUIRE(!view->frozen); 842 843 result = dns_zt_mount(view->zonetable, zone); 844 845 return (result); 846} 847#endif 848 849#ifdef BIND9 850isc_result_t 851dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { 852 isc_result_t result; 853 854 REQUIRE(DNS_VIEW_VALID(view)); 855 856 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); 857 if (result == DNS_R_PARTIALMATCH) { 858 dns_zone_detach(zonep); 859 result = ISC_R_NOTFOUND; 860 } 861 862 return (result); 863} 864#endif 865 866isc_result_t 867dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 868 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, 869 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 870 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { 871 return (dns_view_find2(view, name, type, now, options, use_hints, 872 ISC_FALSE, dbp, nodep, foundname, rdataset, 873 sigrdataset)); 874} 875 876isc_result_t 877dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 878 isc_stdtime_t now, unsigned int options, 879 isc_boolean_t use_hints, isc_boolean_t use_static_stub, 880 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 881 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 882{ 883 isc_result_t result; 884 dns_db_t *db, *zdb; 885 dns_dbnode_t *node, *znode; 886 isc_boolean_t is_cache, is_staticstub_zone; 887 dns_rdataset_t zrdataset, zsigrdataset; 888 dns_zone_t *zone; 889 890#ifndef BIND9 891 UNUSED(use_hints); 892 UNUSED(use_static_stub); 893#endif 894 895 /* 896 * Find an rdataset whose owner name is 'name', and whose type is 897 * 'type'. 898 */ 899 900 REQUIRE(DNS_VIEW_VALID(view)); 901 REQUIRE(view->frozen); 902 REQUIRE(type != dns_rdatatype_rrsig); 903 REQUIRE(rdataset != NULL); /* XXXBEW - remove this */ 904 REQUIRE(nodep == NULL || *nodep == NULL); 905 906 /* 907 * Initialize. 908 */ 909 dns_rdataset_init(&zrdataset); 910 dns_rdataset_init(&zsigrdataset); 911 zdb = NULL; 912 znode = NULL; 913 914 /* 915 * Find a database to answer the query. 916 */ 917 zone = NULL; 918 db = NULL; 919 node = NULL; 920 is_staticstub_zone = ISC_FALSE; 921#ifdef BIND9 922 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 923 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub && 924 !use_static_stub) { 925 result = ISC_R_NOTFOUND; 926 } 927 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 928 result = dns_zone_getdb(zone, &db); 929 if (result != ISC_R_SUCCESS && view->cachedb != NULL) 930 dns_db_attach(view->cachedb, &db); 931 else if (result != ISC_R_SUCCESS) 932 goto cleanup; 933 if (dns_zone_gettype(zone) == dns_zone_staticstub && 934 dns_name_equal(name, dns_zone_getorigin(zone))) { 935 is_staticstub_zone = ISC_TRUE; 936 } 937 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL) 938 dns_db_attach(view->cachedb, &db); 939#else 940 result = ISC_R_NOTFOUND; 941 if (view->cachedb != NULL) 942 dns_db_attach(view->cachedb, &db); 943#endif /* BIND9 */ 944 else 945 goto cleanup; 946 947 is_cache = dns_db_iscache(db); 948 949 db_find: 950 /* 951 * Now look for an answer in the database. 952 */ 953 result = dns_db_find(db, name, NULL, type, options, 954 now, &node, foundname, rdataset, sigrdataset); 955 956 if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) { 957 if (dns_rdataset_isassociated(rdataset)) 958 dns_rdataset_disassociate(rdataset); 959 if (sigrdataset != NULL && 960 dns_rdataset_isassociated(sigrdataset)) 961 dns_rdataset_disassociate(sigrdataset); 962 if (node != NULL) 963 dns_db_detachnode(db, &node); 964 if (!is_cache) { 965 dns_db_detach(&db); 966 if (view->cachedb != NULL && !is_staticstub_zone) { 967 /* 968 * Either the answer is in the cache, or we 969 * don't know it. 970 * Note that if the result comes from a 971 * static-stub zone we stop the search here 972 * (see the function description in view.h). 973 */ 974 is_cache = ISC_TRUE; 975 dns_db_attach(view->cachedb, &db); 976 goto db_find; 977 } 978 } else { 979 /* 980 * We don't have the data in the cache. If we've got 981 * glue from the zone, use it. 982 */ 983 if (dns_rdataset_isassociated(&zrdataset)) { 984 dns_rdataset_clone(&zrdataset, rdataset); 985 if (sigrdataset != NULL && 986 dns_rdataset_isassociated(&zsigrdataset)) 987 dns_rdataset_clone(&zsigrdataset, 988 sigrdataset); 989 result = DNS_R_GLUE; 990 if (db != NULL) 991 dns_db_detach(&db); 992 dns_db_attach(zdb, &db); 993 dns_db_attachnode(db, znode, &node); 994 goto cleanup; 995 } 996 } 997 /* 998 * We don't know the answer. 999 */ 1000 result = ISC_R_NOTFOUND; 1001 } else if (result == DNS_R_GLUE) { 1002 if (view->cachedb != NULL && !is_staticstub_zone) { 1003 /* 1004 * We found an answer, but the cache may be better. 1005 * Remember what we've got and go look in the cache. 1006 */ 1007 is_cache = ISC_TRUE; 1008 dns_rdataset_clone(rdataset, &zrdataset); 1009 dns_rdataset_disassociate(rdataset); 1010 if (sigrdataset != NULL && 1011 dns_rdataset_isassociated(sigrdataset)) { 1012 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1013 dns_rdataset_disassociate(sigrdataset); 1014 } 1015 dns_db_attach(db, &zdb); 1016 dns_db_attachnode(zdb, node, &znode); 1017 dns_db_detachnode(db, &node); 1018 dns_db_detach(&db); 1019 dns_db_attach(view->cachedb, &db); 1020 goto db_find; 1021 } 1022 /* 1023 * Otherwise, the glue is the best answer. 1024 */ 1025 result = ISC_R_SUCCESS; 1026 } 1027 1028#ifdef BIND9 1029 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) { 1030 if (dns_rdataset_isassociated(rdataset)) 1031 dns_rdataset_disassociate(rdataset); 1032 if (sigrdataset != NULL && 1033 dns_rdataset_isassociated(sigrdataset)) 1034 dns_rdataset_disassociate(sigrdataset); 1035 if (db != NULL) { 1036 if (node != NULL) 1037 dns_db_detachnode(db, &node); 1038 dns_db_detach(&db); 1039 } 1040 result = dns_db_find(view->hints, name, NULL, type, options, 1041 now, &node, foundname, 1042 rdataset, sigrdataset); 1043 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) { 1044 /* 1045 * We just used a hint. Let the resolver know it 1046 * should consider priming. 1047 */ 1048 dns_resolver_prime(view->resolver); 1049 dns_db_attach(view->hints, &db); 1050 result = DNS_R_HINT; 1051 } else if (result == DNS_R_NXRRSET) { 1052 dns_db_attach(view->hints, &db); 1053 result = DNS_R_HINTNXRRSET; 1054 } else if (result == DNS_R_NXDOMAIN) 1055 result = ISC_R_NOTFOUND; 1056 1057 /* 1058 * Cleanup if non-standard hints are used. 1059 */ 1060 if (db == NULL && node != NULL) 1061 dns_db_detachnode(view->hints, &node); 1062 } 1063#endif /* BIND9 */ 1064 1065 cleanup: 1066 if (dns_rdataset_isassociated(&zrdataset)) { 1067 dns_rdataset_disassociate(&zrdataset); 1068 if (dns_rdataset_isassociated(&zsigrdataset)) 1069 dns_rdataset_disassociate(&zsigrdataset); 1070 } 1071 1072 if (zdb != NULL) { 1073 if (znode != NULL) 1074 dns_db_detachnode(zdb, &znode); 1075 dns_db_detach(&zdb); 1076 } 1077 1078 if (db != NULL) { 1079 if (node != NULL) { 1080 if (nodep != NULL) 1081 *nodep = node; 1082 else 1083 dns_db_detachnode(db, &node); 1084 } 1085 if (dbp != NULL) 1086 *dbp = db; 1087 else 1088 dns_db_detach(&db); 1089 } else 1090 INSIST(node == NULL); 1091 1092#ifdef BIND9 1093 if (zone != NULL) 1094 dns_zone_detach(&zone); 1095#endif 1096 1097 return (result); 1098} 1099 1100isc_result_t 1101dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 1102 isc_stdtime_t now, unsigned int options, 1103 isc_boolean_t use_hints, 1104 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1105{ 1106 isc_result_t result; 1107 dns_fixedname_t foundname; 1108 1109 dns_fixedname_init(&foundname); 1110 result = dns_view_find(view, name, type, now, options, use_hints, 1111 NULL, NULL, dns_fixedname_name(&foundname), 1112 rdataset, sigrdataset); 1113 if (result == DNS_R_NXDOMAIN) { 1114 /* 1115 * The rdataset and sigrdataset of the relevant NSEC record 1116 * may be returned, but the caller cannot use them because 1117 * foundname is not returned by this simplified API. We 1118 * disassociate them here to prevent any misuse by the caller. 1119 */ 1120 if (dns_rdataset_isassociated(rdataset)) 1121 dns_rdataset_disassociate(rdataset); 1122 if (sigrdataset != NULL && 1123 dns_rdataset_isassociated(sigrdataset)) 1124 dns_rdataset_disassociate(sigrdataset); 1125 } else if (result != ISC_R_SUCCESS && 1126 result != DNS_R_GLUE && 1127 result != DNS_R_HINT && 1128 result != DNS_R_NCACHENXDOMAIN && 1129 result != DNS_R_NCACHENXRRSET && 1130 result != DNS_R_NXRRSET && 1131 result != DNS_R_HINTNXRRSET && 1132 result != ISC_R_NOTFOUND) { 1133 if (dns_rdataset_isassociated(rdataset)) 1134 dns_rdataset_disassociate(rdataset); 1135 if (sigrdataset != NULL && 1136 dns_rdataset_isassociated(sigrdataset)) 1137 dns_rdataset_disassociate(sigrdataset); 1138 result = ISC_R_NOTFOUND; 1139 } 1140 1141 return (result); 1142} 1143 1144isc_result_t 1145dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 1146 isc_stdtime_t now, unsigned int options, 1147 isc_boolean_t use_hints, 1148 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1149{ 1150 return(dns_view_findzonecut2(view, name, fname, now, options, 1151 use_hints, ISC_TRUE, 1152 rdataset, sigrdataset)); 1153} 1154 1155isc_result_t 1156dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 1157 isc_stdtime_t now, unsigned int options, 1158 isc_boolean_t use_hints, isc_boolean_t use_cache, 1159 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1160{ 1161 isc_result_t result; 1162 dns_db_t *db; 1163 isc_boolean_t is_cache, use_zone, try_hints; 1164 dns_zone_t *zone; 1165 dns_name_t *zfname; 1166 dns_rdataset_t zrdataset, zsigrdataset; 1167 dns_fixedname_t zfixedname; 1168 1169 REQUIRE(DNS_VIEW_VALID(view)); 1170 REQUIRE(view->frozen); 1171 1172 db = NULL; 1173 zone = NULL; 1174 use_zone = ISC_FALSE; 1175 try_hints = ISC_FALSE; 1176 zfname = NULL; 1177 1178 /* 1179 * Initialize. 1180 */ 1181 dns_fixedname_init(&zfixedname); 1182 dns_rdataset_init(&zrdataset); 1183 dns_rdataset_init(&zsigrdataset); 1184 1185 /* 1186 * Find the right database. 1187 */ 1188#ifdef BIND9 1189 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 1190 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 1191 result = dns_zone_getdb(zone, &db); 1192#else 1193 result = ISC_R_NOTFOUND; 1194#endif 1195 if (result == ISC_R_NOTFOUND) { 1196 /* 1197 * We're not directly authoritative for this query name, nor 1198 * is it a subdomain of any zone for which we're 1199 * authoritative. 1200 */ 1201 if (use_cache && view->cachedb != NULL) { 1202 /* 1203 * We have a cache; try it. 1204 */ 1205 dns_db_attach(view->cachedb, &db); 1206 } else { 1207 /* 1208 * Maybe we have hints... 1209 */ 1210 try_hints = ISC_TRUE; 1211 goto finish; 1212 } 1213 } else if (result != ISC_R_SUCCESS) { 1214 /* 1215 * Something is broken. 1216 */ 1217 goto cleanup; 1218 } 1219 is_cache = dns_db_iscache(db); 1220 1221 db_find: 1222 /* 1223 * Look for the zonecut. 1224 */ 1225 if (!is_cache) { 1226 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options, 1227 now, NULL, fname, rdataset, sigrdataset); 1228 if (result == DNS_R_DELEGATION) 1229 result = ISC_R_SUCCESS; 1230 else if (result != ISC_R_SUCCESS) 1231 goto cleanup; 1232 if (use_cache && view->cachedb != NULL && db != view->hints) { 1233 /* 1234 * We found an answer, but the cache may be better. 1235 */ 1236 zfname = dns_fixedname_name(&zfixedname); 1237 result = dns_name_copy(fname, zfname, NULL); 1238 if (result != ISC_R_SUCCESS) 1239 goto cleanup; 1240 dns_rdataset_clone(rdataset, &zrdataset); 1241 dns_rdataset_disassociate(rdataset); 1242 if (sigrdataset != NULL && 1243 dns_rdataset_isassociated(sigrdataset)) { 1244 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1245 dns_rdataset_disassociate(sigrdataset); 1246 } 1247 dns_db_detach(&db); 1248 dns_db_attach(view->cachedb, &db); 1249 is_cache = ISC_TRUE; 1250 goto db_find; 1251 } 1252 } else { 1253 result = dns_db_findzonecut(db, name, options, now, NULL, 1254 fname, rdataset, sigrdataset); 1255 if (result == ISC_R_SUCCESS) { 1256 if (zfname != NULL && 1257 (!dns_name_issubdomain(fname, zfname) || 1258 (dns_zone_staticstub && 1259 dns_name_equal(fname, zfname)))) { 1260 /* 1261 * We found a zonecut in the cache, but our 1262 * zone delegation is better. 1263 */ 1264 use_zone = ISC_TRUE; 1265 } 1266 } else if (result == ISC_R_NOTFOUND) { 1267 if (zfname != NULL) { 1268 /* 1269 * We didn't find anything in the cache, but we 1270 * have a zone delegation, so use it. 1271 */ 1272 use_zone = ISC_TRUE; 1273 } else { 1274 /* 1275 * Maybe we have hints... 1276 */ 1277 try_hints = ISC_TRUE; 1278 } 1279 } else { 1280 /* 1281 * Something bad happened. 1282 */ 1283 goto cleanup; 1284 } 1285 } 1286 1287 finish: 1288 if (use_zone) { 1289 if (dns_rdataset_isassociated(rdataset)) { 1290 dns_rdataset_disassociate(rdataset); 1291 if (sigrdataset != NULL && 1292 dns_rdataset_isassociated(sigrdataset)) 1293 dns_rdataset_disassociate(sigrdataset); 1294 } 1295 result = dns_name_copy(zfname, fname, NULL); 1296 if (result != ISC_R_SUCCESS) 1297 goto cleanup; 1298 dns_rdataset_clone(&zrdataset, rdataset); 1299 if (sigrdataset != NULL && 1300 dns_rdataset_isassociated(&zrdataset)) 1301 dns_rdataset_clone(&zsigrdataset, sigrdataset); 1302 } else if (try_hints && use_hints && view->hints != NULL) { 1303 /* 1304 * We've found nothing so far, but we have hints. 1305 */ 1306 result = dns_db_find(view->hints, dns_rootname, NULL, 1307 dns_rdatatype_ns, 0, now, NULL, fname, 1308 rdataset, NULL); 1309 if (result != ISC_R_SUCCESS) { 1310 /* 1311 * We can't even find the hints for the root 1312 * nameservers! 1313 */ 1314 if (dns_rdataset_isassociated(rdataset)) 1315 dns_rdataset_disassociate(rdataset); 1316 result = ISC_R_NOTFOUND; 1317 } 1318 } 1319 1320 cleanup: 1321 if (dns_rdataset_isassociated(&zrdataset)) { 1322 dns_rdataset_disassociate(&zrdataset); 1323 if (dns_rdataset_isassociated(&zsigrdataset)) 1324 dns_rdataset_disassociate(&zsigrdataset); 1325 } 1326 if (db != NULL) 1327 dns_db_detach(&db); 1328#ifdef BIND9 1329 if (zone != NULL) 1330 dns_zone_detach(&zone); 1331#endif 1332 1333 return (result); 1334} 1335 1336isc_result_t 1337dns_viewlist_find(dns_viewlist_t *list, const char *name, 1338 dns_rdataclass_t rdclass, dns_view_t **viewp) 1339{ 1340 dns_view_t *view; 1341 1342 REQUIRE(list != NULL); 1343 1344 for (view = ISC_LIST_HEAD(*list); 1345 view != NULL; 1346 view = ISC_LIST_NEXT(view, link)) { 1347 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass) 1348 break; 1349 } 1350 if (view == NULL) 1351 return (ISC_R_NOTFOUND); 1352 1353 dns_view_attach(view, viewp); 1354 1355 return (ISC_R_SUCCESS); 1356} 1357 1358#ifdef BIND9 1359isc_result_t 1360dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, 1361 isc_boolean_t allclasses, dns_rdataclass_t rdclass, 1362 dns_zone_t **zonep) 1363{ 1364 dns_view_t *view; 1365 isc_result_t result; 1366 dns_zone_t *zone1 = NULL, *zone2 = NULL; 1367 dns_zone_t **zp = NULL;; 1368 1369 REQUIRE(list != NULL); 1370 for (view = ISC_LIST_HEAD(*list); 1371 view != NULL; 1372 view = ISC_LIST_NEXT(view, link)) { 1373 if (allclasses == ISC_FALSE && view->rdclass != rdclass) 1374 continue; 1375 1376 /* 1377 * If the zone is defined in more than one view, 1378 * treat it as not found. 1379 */ 1380 zp = (zone1 == NULL) ? &zone1 : &zone2; 1381 result = dns_zt_find(view->zonetable, name, 0, NULL, zp); 1382 INSIST(result == ISC_R_SUCCESS || 1383 result == ISC_R_NOTFOUND || 1384 result == DNS_R_PARTIALMATCH); 1385 1386 /* Treat a partial match as no match */ 1387 if (result == DNS_R_PARTIALMATCH) { 1388 dns_zone_detach(zp); 1389 result = ISC_R_NOTFOUND; 1390 POST(result); 1391 } 1392 1393 if (zone2 != NULL) { 1394 dns_zone_detach(&zone1); 1395 dns_zone_detach(&zone2); 1396 return (ISC_R_NOTFOUND); 1397 } 1398 } 1399 1400 if (zone1 != NULL) { 1401 dns_zone_attach(zone1, zonep); 1402 dns_zone_detach(&zone1); 1403 return (ISC_R_SUCCESS); 1404 } 1405 1406 return (ISC_R_NOTFOUND); 1407} 1408 1409isc_result_t 1410dns_view_load(dns_view_t *view, isc_boolean_t stop) { 1411 1412 REQUIRE(DNS_VIEW_VALID(view)); 1413 1414 return (dns_zt_load(view->zonetable, stop)); 1415} 1416 1417isc_result_t 1418dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { 1419 1420 REQUIRE(DNS_VIEW_VALID(view)); 1421 1422 return (dns_zt_loadnew(view->zonetable, stop)); 1423} 1424#endif /* BIND9 */ 1425 1426isc_result_t 1427dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp) 1428{ 1429 isc_result_t result; 1430 REQUIRE(keyp != NULL && *keyp == NULL); 1431 1432 result = dns_tsigkey_find(keyp, keyname, NULL, 1433 view->statickeys); 1434 if (result == ISC_R_NOTFOUND) 1435 result = dns_tsigkey_find(keyp, keyname, NULL, 1436 view->dynamickeys); 1437 return (result); 1438} 1439 1440isc_result_t 1441dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, 1442 dns_tsigkey_t **keyp) 1443{ 1444 isc_result_t result; 1445 dns_name_t *keyname = NULL; 1446 dns_peer_t *peer = NULL; 1447 1448 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer); 1449 if (result != ISC_R_SUCCESS) 1450 return (result); 1451 1452 result = dns_peer_getkey(peer, &keyname); 1453 if (result != ISC_R_SUCCESS) 1454 return (result); 1455 1456 result = dns_view_gettsig(view, keyname, keyp); 1457 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result); 1458} 1459 1460isc_result_t 1461dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) { 1462 REQUIRE(DNS_VIEW_VALID(view)); 1463 REQUIRE(source != NULL); 1464 1465 return (dns_tsig_verify(source, msg, view->statickeys, 1466 view->dynamickeys)); 1467} 1468 1469#ifdef BIND9 1470isc_result_t 1471dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { 1472 isc_result_t result; 1473 1474 REQUIRE(DNS_VIEW_VALID(view)); 1475 1476 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); 1477 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, 1478 &dns_master_style_cache, fp); 1479 if (result != ISC_R_SUCCESS) 1480 return (result); 1481 dns_adb_dump(view->adb, fp); 1482 dns_resolver_printbadcache(view->resolver, fp); 1483 return (ISC_R_SUCCESS); 1484} 1485#endif 1486 1487isc_result_t 1488dns_view_flushcache(dns_view_t *view) { 1489 return (dns_view_flushcache2(view, ISC_FALSE)); 1490} 1491 1492isc_result_t 1493dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) { 1494 isc_result_t result; 1495 1496 REQUIRE(DNS_VIEW_VALID(view)); 1497 1498 if (view->cachedb == NULL) 1499 return (ISC_R_SUCCESS); 1500 if (!fixuponly) { 1501 result = dns_cache_flush(view->cache); 1502 if (result != ISC_R_SUCCESS) 1503 return (result); 1504 } 1505#ifdef BIND9 1506 if (view->acache != NULL) 1507 dns_acache_putdb(view->acache, view->cachedb); 1508#endif 1509 dns_db_detach(&view->cachedb); 1510 dns_cache_attachdb(view->cache, &view->cachedb); 1511#ifdef BIND9 1512 if (view->acache != NULL) 1513 dns_acache_setdb(view->acache, view->cachedb); 1514 if (view->resolver != NULL) 1515 dns_resolver_flushbadcache(view->resolver, NULL); 1516#endif 1517 1518 dns_adb_flush(view->adb); 1519 return (ISC_R_SUCCESS); 1520} 1521 1522isc_result_t 1523dns_view_flushname(dns_view_t *view, dns_name_t *name) { 1524 1525 REQUIRE(DNS_VIEW_VALID(view)); 1526 1527 if (view->adb != NULL) 1528 dns_adb_flushname(view->adb, name); 1529 if (view->cache == NULL) 1530 return (ISC_R_SUCCESS); 1531 if (view->resolver != NULL) 1532 dns_resolver_flushbadcache(view->resolver, name); 1533 return (dns_cache_flushname(view->cache, name)); 1534} 1535 1536isc_result_t 1537dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) { 1538 isc_result_t result; 1539 dns_name_t *new; 1540 isc_uint32_t hash; 1541 1542 REQUIRE(DNS_VIEW_VALID(view)); 1543 1544 if (view->delonly == NULL) { 1545 view->delonly = isc_mem_get(view->mctx, 1546 sizeof(dns_namelist_t) * 1547 DNS_VIEW_DELONLYHASH); 1548 if (view->delonly == NULL) 1549 return (ISC_R_NOMEMORY); 1550 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1551 ISC_LIST_INIT(view->delonly[hash]); 1552 } 1553 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1554 new = ISC_LIST_HEAD(view->delonly[hash]); 1555 while (new != NULL && !dns_name_equal(new, name)) 1556 new = ISC_LIST_NEXT(new, link); 1557 if (new != NULL) 1558 return (ISC_R_SUCCESS); 1559 new = isc_mem_get(view->mctx, sizeof(*new)); 1560 if (new == NULL) 1561 return (ISC_R_NOMEMORY); 1562 dns_name_init(new, NULL); 1563 result = dns_name_dup(name, view->mctx, new); 1564 if (result == ISC_R_SUCCESS) 1565 ISC_LIST_APPEND(view->delonly[hash], new, link); 1566 else 1567 isc_mem_put(view->mctx, new, sizeof(*new)); 1568 return (result); 1569} 1570 1571isc_result_t 1572dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) { 1573 isc_result_t result; 1574 dns_name_t *new; 1575 isc_uint32_t hash; 1576 1577 REQUIRE(DNS_VIEW_VALID(view)); 1578 1579 if (view->rootexclude == NULL) { 1580 view->rootexclude = isc_mem_get(view->mctx, 1581 sizeof(dns_namelist_t) * 1582 DNS_VIEW_DELONLYHASH); 1583 if (view->rootexclude == NULL) 1584 return (ISC_R_NOMEMORY); 1585 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1586 ISC_LIST_INIT(view->rootexclude[hash]); 1587 } 1588 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1589 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1590 while (new != NULL && !dns_name_equal(new, name)) 1591 new = ISC_LIST_NEXT(new, link); 1592 if (new != NULL) 1593 return (ISC_R_SUCCESS); 1594 new = isc_mem_get(view->mctx, sizeof(*new)); 1595 if (new == NULL) 1596 return (ISC_R_NOMEMORY); 1597 dns_name_init(new, NULL); 1598 result = dns_name_dup(name, view->mctx, new); 1599 if (result == ISC_R_SUCCESS) 1600 ISC_LIST_APPEND(view->rootexclude[hash], new, link); 1601 else 1602 isc_mem_put(view->mctx, new, sizeof(*new)); 1603 return (result); 1604} 1605 1606isc_boolean_t 1607dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { 1608 dns_name_t *new; 1609 isc_uint32_t hash; 1610 1611 REQUIRE(DNS_VIEW_VALID(view)); 1612 1613 if (!view->rootdelonly && view->delonly == NULL) 1614 return (ISC_FALSE); 1615 1616 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1617 if (view->rootdelonly && dns_name_countlabels(name) <= 2) { 1618 if (view->rootexclude == NULL) 1619 return (ISC_TRUE); 1620 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1621 while (new != NULL && !dns_name_equal(new, name)) 1622 new = ISC_LIST_NEXT(new, link); 1623 if (new == NULL) 1624 return (ISC_TRUE); 1625 } 1626 1627 if (view->delonly == NULL) 1628 return (ISC_FALSE); 1629 1630 new = ISC_LIST_HEAD(view->delonly[hash]); 1631 while (new != NULL && !dns_name_equal(new, name)) 1632 new = ISC_LIST_NEXT(new, link); 1633 if (new == NULL) 1634 return (ISC_FALSE); 1635 return (ISC_TRUE); 1636} 1637 1638void 1639dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) { 1640 REQUIRE(DNS_VIEW_VALID(view)); 1641 view->rootdelonly = value; 1642} 1643 1644isc_boolean_t 1645dns_view_getrootdelonly(dns_view_t *view) { 1646 REQUIRE(DNS_VIEW_VALID(view)); 1647 return (view->rootdelonly); 1648} 1649 1650#ifdef BIND9 1651isc_result_t 1652dns_view_freezezones(dns_view_t *view, isc_boolean_t value) { 1653 REQUIRE(DNS_VIEW_VALID(view)); 1654 return (dns_zt_freezezones(view->zonetable, value)); 1655} 1656#endif 1657 1658void 1659dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) { 1660 REQUIRE(DNS_VIEW_VALID(view)); 1661 REQUIRE(!view->frozen); 1662 REQUIRE(view->resstats == NULL); 1663 1664 isc_stats_attach(stats, &view->resstats); 1665} 1666 1667void 1668dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) { 1669 REQUIRE(DNS_VIEW_VALID(view)); 1670 REQUIRE(statsp != NULL && *statsp == NULL); 1671 1672 if (view->resstats != NULL) 1673 isc_stats_attach(view->resstats, statsp); 1674} 1675 1676void 1677dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) { 1678 REQUIRE(DNS_VIEW_VALID(view)); 1679 REQUIRE(!view->frozen); 1680 REQUIRE(view->resquerystats == NULL); 1681 1682 dns_stats_attach(stats, &view->resquerystats); 1683} 1684 1685void 1686dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) { 1687 REQUIRE(DNS_VIEW_VALID(view)); 1688 REQUIRE(statsp != NULL && *statsp == NULL); 1689 1690 if (view->resquerystats != NULL) 1691 dns_stats_attach(view->resquerystats, statsp); 1692} 1693 1694isc_result_t 1695dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) { 1696 REQUIRE(DNS_VIEW_VALID(view)); 1697 if (view->secroots_priv != NULL) 1698 dns_keytable_detach(&view->secroots_priv); 1699 return (dns_keytable_create(mctx, &view->secroots_priv)); 1700} 1701 1702isc_result_t 1703dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) { 1704 REQUIRE(DNS_VIEW_VALID(view)); 1705 REQUIRE(ktp != NULL && *ktp == NULL); 1706 if (view->secroots_priv == NULL) 1707 return (ISC_R_NOTFOUND); 1708 dns_keytable_attach(view->secroots_priv, ktp); 1709 return (ISC_R_SUCCESS); 1710} 1711 1712isc_result_t 1713dns_view_issecuredomain(dns_view_t *view, dns_name_t *name, 1714 isc_boolean_t *secure_domain) { 1715 REQUIRE(DNS_VIEW_VALID(view)); 1716 return (dns_keytable_issecuredomain(view->secroots_priv, name, 1717 secure_domain)); 1718} 1719 1720void 1721dns_view_untrust(dns_view_t *view, dns_name_t *keyname, 1722 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) 1723{ 1724 isc_result_t result; 1725 unsigned char data[4096]; 1726 dns_rdata_t rdata = DNS_RDATA_INIT; 1727 isc_buffer_t buffer; 1728 dst_key_t *key = NULL; 1729 dns_keytable_t *sr = NULL; 1730 1731 /* 1732 * Clear the revoke bit, if set, so that the key will match what's 1733 * in secroots now. 1734 */ 1735 dnskey->flags &= ~DNS_KEYFLAG_REVOKE; 1736 1737 /* Convert dnskey to DST key. */ 1738 isc_buffer_init(&buffer, data, sizeof(data)); 1739 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 1740 dns_rdatatype_dnskey, dnskey, &buffer); 1741 result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key); 1742 if (result != ISC_R_SUCCESS) 1743 return; 1744 result = dns_view_getsecroots(view, &sr); 1745 if (result == ISC_R_SUCCESS) { 1746 dns_keytable_deletekeynode(sr, key); 1747 dns_keytable_detach(&sr); 1748 } 1749 dst_key_free(&key); 1750} 1751 1752#define NZF ".nzf" 1753 1754void 1755dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, 1756 void (*cfg_destroy)(void **)) 1757{ 1758 REQUIRE(DNS_VIEW_VALID(view)); 1759 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow); 1760 1761#ifdef BIND9 1762 if (view->new_zone_file != NULL) { 1763 isc_mem_free(view->mctx, view->new_zone_file); 1764 view->new_zone_file = NULL; 1765 } 1766 1767 if (view->new_zone_config != NULL) { 1768 view->cfg_destroy(&view->new_zone_config); 1769 view->cfg_destroy = NULL; 1770 } 1771 1772 if (allow) { 1773 char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)]; 1774 isc_sha256_data((void *)view->name, strlen(view->name), buffer); 1775 /* Truncate the hash at 16 chars; full length is overkill */ 1776 isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF); 1777 view->new_zone_file = isc_mem_strdup(view->mctx, buffer); 1778 view->new_zone_config = cfgctx; 1779 view->cfg_destroy = cfg_destroy; 1780 } 1781#else 1782 UNUSED(allow); 1783 UNUSED(cfgctx); 1784 UNUSED(cfg_destroy); 1785#endif 1786} 1787