2 * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: view.c,v 1.178.8.1 2011-03-11 06:47:06 marka Exp $ */
26 #include <isc/print.h>
28 #include <isc/stats.h>
29 #include <isc/string.h> /* Required for HP/UX (and others?) */
33 #include <dns/acache.h>
36 #include <dns/cache.h>
40 #include <dns/dns64.h>
42 #include <dns/dnssec.h>
43 #include <dns/events.h>
44 #include <dns/forward.h>
45 #include <dns/keytable.h>
46 #include <dns/keyvalues.h>
47 #include <dns/master.h>
48 #include <dns/masterdump.h>
49 #include <dns/order.h>
52 #include <dns/rdataset.h>
53 #include <dns/request.h>
54 #include <dns/resolver.h>
55 #include <dns/result.h>
57 #include <dns/stats.h>
62 #define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0)
63 #define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0)
64 #define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0)
66 #define DNS_VIEW_DELONLYHASH 111
68 static void resolver_shutdown(isc_task_t *task, isc_event_t *event);
69 static void adb_shutdown(isc_task_t *task, isc_event_t *event);
70 static void req_shutdown(isc_task_t *task, isc_event_t *event);
73 dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
74 const char *name, dns_view_t **viewp)
83 REQUIRE(name != NULL);
84 REQUIRE(viewp != NULL && *viewp == NULL);
86 view = isc_mem_get(mctx, sizeof(*view));
88 return (ISC_R_NOMEMORY);
89 view->name = isc_mem_strdup(mctx, name);
90 if (view->name == NULL) {
91 result = ISC_R_NOMEMORY;
94 result = isc_mutex_init(&view->lock);
95 if (result != ISC_R_SUCCESS)
99 view->zonetable = NULL;
100 result = dns_zt_create(mctx, rdclass, &view->zonetable);
101 if (result != ISC_R_SUCCESS) {
102 UNEXPECTED_ERROR(__FILE__, __LINE__,
103 "dns_zt_create() failed: %s",
104 isc_result_totext(result));
105 result = ISC_R_UNEXPECTED;
109 view->secroots_priv = NULL;
110 view->fwdtable = NULL;
111 result = dns_fwdtable_create(mctx, &view->fwdtable);
112 if (result != ISC_R_SUCCESS) {
113 UNEXPECTED_ERROR(__FILE__, __LINE__,
114 "dns_fwdtable_create() failed: %s",
115 isc_result_totext(result));
116 result = ISC_R_UNEXPECTED;
122 view->cachedb = NULL;
123 view->dlzdatabase = NULL;
125 view->resolver = NULL;
127 view->requestmgr = NULL;
129 view->rdclass = rdclass;
130 view->frozen = ISC_FALSE;
132 result = isc_refcount_init(&view->references, 1);
133 if (result != ISC_R_SUCCESS)
134 goto cleanup_fwdtable;
136 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
137 DNS_VIEWATTR_REQSHUTDOWN);
138 view->statickeys = NULL;
139 view->dynamickeys = NULL;
140 view->matchclients = NULL;
141 view->matchdestinations = NULL;
142 view->matchrecursiveonly = ISC_FALSE;
143 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
144 if (result != ISC_R_SUCCESS)
145 goto cleanup_references;
148 view->delonly = NULL;
149 view->rootdelonly = ISC_FALSE;
150 view->rootexclude = NULL;
151 view->resstats = NULL;
152 view->resquerystats = NULL;
153 view->cacheshared = ISC_FALSE;
154 ISC_LIST_INIT(view->dns64);
158 * Initialize configuration data with default values.
160 view->recursion = ISC_TRUE;
161 view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
162 view->additionalfromcache = ISC_TRUE;
163 view->additionalfromauth = ISC_TRUE;
164 view->enablednssec = ISC_TRUE;
165 view->enablevalidation = ISC_TRUE;
166 view->acceptexpired = ISC_FALSE;
167 view->minimalresponses = ISC_FALSE;
168 view->transfer_format = dns_one_answer;
169 view->cacheacl = NULL;
170 view->cacheonacl = NULL;
171 view->queryacl = NULL;
172 view->queryonacl = NULL;
173 view->recursionacl = NULL;
174 view->recursiononacl = NULL;
175 view->sortlist = NULL;
176 view->transferacl = NULL;
177 view->notifyacl = NULL;
178 view->updateacl = NULL;
179 view->upfwdacl = NULL;
180 view->denyansweracl = NULL;
181 view->answeracl_exclude = NULL;
182 view->denyanswernames = NULL;
183 view->answernames_exclude = NULL;
184 view->requestixfr = ISC_TRUE;
185 view->provideixfr = ISC_TRUE;
186 view->maxcachettl = 7 * 24 * 3600;
187 view->maxncachettl = 3 * 3600;
189 view->preferred_glue = 0;
190 view->flush = ISC_FALSE;
193 view->v4_aaaa = dns_v4_aaaa_ok;
194 view->v4_aaaa_acl = NULL;
195 ISC_LIST_INIT(view->rpz_zones);
196 dns_fixedname_init(&view->dlv_fixed);
197 view->managed_keys = NULL;
199 view->new_zone_file = NULL;
200 view->new_zone_config = NULL;
201 view->cfg_destroy = NULL;
203 result = dns_order_create(view->mctx, &view->order);
204 if (result != ISC_R_SUCCESS)
205 goto cleanup_dynkeys;
208 result = dns_peerlist_new(view->mctx, &view->peers);
209 if (result != ISC_R_SUCCESS)
212 result = dns_aclenv_init(view->mctx, &view->aclenv);
213 if (result != ISC_R_SUCCESS)
214 goto cleanup_peerlist;
216 ISC_LINK_INIT(view, link);
217 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
218 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
219 view, NULL, NULL, NULL);
220 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
221 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
222 view, NULL, NULL, NULL);
223 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
224 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
225 view, NULL, NULL, NULL);
226 view->magic = DNS_VIEW_MAGIC;
230 return (ISC_R_SUCCESS);
233 dns_peerlist_detach(&view->peers);
237 dns_order_detach(&view->order);
241 dns_tsigkeyring_detach(&view->dynamickeys);
244 isc_refcount_destroy(&view->references);
247 dns_fwdtable_destroy(&view->fwdtable);
251 dns_zt_detach(&view->zonetable);
255 DESTROYLOCK(&view->lock);
258 isc_mem_free(mctx, view->name);
261 isc_mem_put(mctx, view, sizeof(*view));
267 destroy(dns_view_t *view) {
272 REQUIRE(!ISC_LINK_LINKED(view, link));
273 REQUIRE(isc_refcount_current(&view->references) == 0);
274 REQUIRE(view->weakrefs == 0);
275 REQUIRE(RESSHUTDOWN(view));
276 REQUIRE(ADBSHUTDOWN(view));
277 REQUIRE(REQSHUTDOWN(view));
280 if (view->order != NULL)
281 dns_order_detach(&view->order);
283 if (view->peers != NULL)
284 dns_peerlist_detach(&view->peers);
286 if (view->dynamickeys != NULL) {
293 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
295 if (n > 0 && (size_t)n < sizeof(keyfile)) {
296 result = isc_file_mktemplate(keyfile, template,
298 if (result == ISC_R_SUCCESS)
299 (void)isc_file_openuniqueprivate(template, &fp);
302 dns_tsigkeyring_detach(&view->dynamickeys);
304 result = dns_tsigkeyring_dumpanddetach(
305 &view->dynamickeys, fp);
306 if (result == ISC_R_SUCCESS) {
308 result = isc_file_rename(template,
310 if (result != ISC_R_SUCCESS)
311 (void)remove(template);
314 (void)remove(template);
318 if (view->statickeys != NULL)
319 dns_tsigkeyring_detach(&view->statickeys);
320 if (view->adb != NULL)
321 dns_adb_detach(&view->adb);
322 if (view->resolver != NULL)
323 dns_resolver_detach(&view->resolver);
325 if (view->acache != NULL) {
326 if (view->cachedb != NULL)
327 dns_acache_putdb(view->acache, view->cachedb);
328 dns_acache_detach(&view->acache);
330 dns_rpz_view_destroy(view);
332 INSIST(view->acache == NULL);
333 INSIST(ISC_LIST_EMPTY(view->rpz_zones));
335 if (view->requestmgr != NULL)
336 dns_requestmgr_detach(&view->requestmgr);
337 if (view->task != NULL)
338 isc_task_detach(&view->task);
339 if (view->hints != NULL)
340 dns_db_detach(&view->hints);
341 if (view->dlzdatabase != NULL)
342 dns_dlzdestroy(&view->dlzdatabase);
343 if (view->cachedb != NULL)
344 dns_db_detach(&view->cachedb);
345 if (view->cache != NULL)
346 dns_cache_detach(&view->cache);
347 if (view->matchclients != NULL)
348 dns_acl_detach(&view->matchclients);
349 if (view->matchdestinations != NULL)
350 dns_acl_detach(&view->matchdestinations);
351 if (view->cacheacl != NULL)
352 dns_acl_detach(&view->cacheacl);
353 if (view->cacheonacl != NULL)
354 dns_acl_detach(&view->cacheonacl);
355 if (view->queryacl != NULL)
356 dns_acl_detach(&view->queryacl);
357 if (view->queryonacl != NULL)
358 dns_acl_detach(&view->queryonacl);
359 if (view->recursionacl != NULL)
360 dns_acl_detach(&view->recursionacl);
361 if (view->recursiononacl != NULL)
362 dns_acl_detach(&view->recursiononacl);
363 if (view->sortlist != NULL)
364 dns_acl_detach(&view->sortlist);
365 if (view->transferacl != NULL)
366 dns_acl_detach(&view->transferacl);
367 if (view->notifyacl != NULL)
368 dns_acl_detach(&view->notifyacl);
369 if (view->updateacl != NULL)
370 dns_acl_detach(&view->updateacl);
371 if (view->upfwdacl != NULL)
372 dns_acl_detach(&view->upfwdacl);
373 if (view->denyansweracl != NULL)
374 dns_acl_detach(&view->denyansweracl);
375 if (view->v4_aaaa_acl != NULL)
376 dns_acl_detach(&view->v4_aaaa_acl);
377 if (view->answeracl_exclude != NULL)
378 dns_rbt_destroy(&view->answeracl_exclude);
379 if (view->denyanswernames != NULL)
380 dns_rbt_destroy(&view->denyanswernames);
381 if (view->answernames_exclude != NULL)
382 dns_rbt_destroy(&view->answernames_exclude);
383 if (view->delonly != NULL) {
387 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
388 name = ISC_LIST_HEAD(view->delonly[i]);
389 while (name != NULL) {
390 ISC_LIST_UNLINK(view->delonly[i], name, link);
391 dns_name_free(name, view->mctx);
392 isc_mem_put(view->mctx, name, sizeof(*name));
393 name = ISC_LIST_HEAD(view->delonly[i]);
396 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) *
397 DNS_VIEW_DELONLYHASH);
398 view->delonly = NULL;
400 if (view->rootexclude != NULL) {
404 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
405 name = ISC_LIST_HEAD(view->rootexclude[i]);
406 while (name != NULL) {
407 ISC_LIST_UNLINK(view->rootexclude[i],
409 dns_name_free(name, view->mctx);
410 isc_mem_put(view->mctx, name, sizeof(*name));
411 name = ISC_LIST_HEAD(view->rootexclude[i]);
414 isc_mem_put(view->mctx, view->rootexclude,
415 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
416 view->rootexclude = NULL;
418 if (view->resstats != NULL)
419 isc_stats_detach(&view->resstats);
420 if (view->resquerystats != NULL)
421 dns_stats_detach(&view->resquerystats);
422 if (view->secroots_priv != NULL)
423 dns_keytable_detach(&view->secroots_priv);
425 for (dns64 = ISC_LIST_HEAD(view->dns64);
427 dns64 = ISC_LIST_HEAD(view->dns64)) {
428 dns_dns64_unlink(&view->dns64, dns64);
429 dns_dns64_destroy(&dns64);
431 if (view->managed_keys != NULL)
432 dns_zone_detach(&view->managed_keys);
433 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
435 dns_fwdtable_destroy(&view->fwdtable);
436 dns_aclenv_destroy(&view->aclenv);
437 DESTROYLOCK(&view->lock);
438 isc_refcount_destroy(&view->references);
439 isc_mem_free(view->mctx, view->name);
440 isc_mem_put(view->mctx, view, sizeof(*view));
444 * Return true iff 'view' may be freed.
445 * The caller must be holding the view lock.
448 all_done(dns_view_t *view) {
450 if (isc_refcount_current(&view->references) == 0 &&
451 view->weakrefs == 0 &&
452 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
459 dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
461 REQUIRE(DNS_VIEW_VALID(source));
462 REQUIRE(targetp != NULL && *targetp == NULL);
464 isc_refcount_increment(&source->references, NULL);
470 view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
473 isc_boolean_t done = ISC_FALSE;
475 REQUIRE(viewp != NULL);
477 REQUIRE(DNS_VIEW_VALID(view));
480 view->flush = ISC_TRUE;
481 isc_refcount_decrement(&view->references, &refs);
484 if (!RESSHUTDOWN(view))
485 dns_resolver_shutdown(view->resolver);
486 if (!ADBSHUTDOWN(view))
487 dns_adb_shutdown(view->adb);
488 if (!REQSHUTDOWN(view))
489 dns_requestmgr_shutdown(view->requestmgr);
491 if (view->acache != NULL)
492 dns_acache_shutdown(view->acache);
494 dns_zt_flushanddetach(&view->zonetable);
496 dns_zt_detach(&view->zonetable);
497 if (view->managed_keys != NULL) {
499 dns_zone_flush(view->managed_keys);
500 dns_zone_detach(&view->managed_keys);
503 done = all_done(view);
514 dns_view_flushanddetach(dns_view_t **viewp) {
515 view_flushanddetach(viewp, ISC_TRUE);
519 dns_view_detach(dns_view_t **viewp) {
520 view_flushanddetach(viewp, ISC_FALSE);
525 dialup(dns_zone_t *zone, void *dummy) {
527 dns_zone_dialup(zone);
528 return (ISC_R_SUCCESS);
532 dns_view_dialup(dns_view_t *view) {
533 REQUIRE(DNS_VIEW_VALID(view));
534 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL);
539 dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
541 REQUIRE(DNS_VIEW_VALID(source));
542 REQUIRE(targetp != NULL && *targetp == NULL);
546 UNLOCK(&source->lock);
552 dns_view_weakdetach(dns_view_t **viewp) {
554 isc_boolean_t done = ISC_FALSE;
556 REQUIRE(viewp != NULL);
558 REQUIRE(DNS_VIEW_VALID(view));
562 INSIST(view->weakrefs > 0);
564 done = all_done(view);
575 resolver_shutdown(isc_task_t *task, isc_event_t *event) {
576 dns_view_t *view = event->ev_arg;
579 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
580 REQUIRE(DNS_VIEW_VALID(view));
581 REQUIRE(view->task == task);
587 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
588 done = all_done(view);
592 isc_event_free(&event);
599 adb_shutdown(isc_task_t *task, isc_event_t *event) {
600 dns_view_t *view = event->ev_arg;
603 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
604 REQUIRE(DNS_VIEW_VALID(view));
605 REQUIRE(view->task == task);
611 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
612 done = all_done(view);
616 isc_event_free(&event);
623 req_shutdown(isc_task_t *task, isc_event_t *event) {
624 dns_view_t *view = event->ev_arg;
627 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
628 REQUIRE(DNS_VIEW_VALID(view));
629 REQUIRE(view->task == task);
635 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
636 done = all_done(view);
640 isc_event_free(&event);
647 dns_view_createresolver(dns_view_t *view,
648 isc_taskmgr_t *taskmgr, unsigned int ntasks,
649 isc_socketmgr_t *socketmgr,
650 isc_timermgr_t *timermgr,
651 unsigned int options,
652 dns_dispatchmgr_t *dispatchmgr,
653 dns_dispatch_t *dispatchv4,
654 dns_dispatch_t *dispatchv6)
658 isc_mem_t *mctx = NULL;
660 REQUIRE(DNS_VIEW_VALID(view));
661 REQUIRE(!view->frozen);
662 REQUIRE(view->resolver == NULL);
664 result = isc_task_create(taskmgr, 0, &view->task);
665 if (result != ISC_R_SUCCESS)
667 isc_task_setname(view->task, "view", view);
669 result = dns_resolver_create(view, taskmgr, ntasks, socketmgr,
670 timermgr, options, dispatchmgr,
671 dispatchv4, dispatchv6,
673 if (result != ISC_R_SUCCESS) {
674 isc_task_detach(&view->task);
677 event = &view->resevent;
678 dns_resolver_whenshutdown(view->resolver, view->task, &event);
679 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
681 result = isc_mem_create(0, 0, &mctx);
682 if (result != ISC_R_SUCCESS) {
683 dns_resolver_shutdown(view->resolver);
687 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb);
688 isc_mem_setname(mctx, "ADB", NULL);
689 isc_mem_detach(&mctx);
690 if (result != ISC_R_SUCCESS) {
691 dns_resolver_shutdown(view->resolver);
694 event = &view->adbevent;
695 dns_adb_whenshutdown(view->adb, view->task, &event);
696 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
698 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
699 dns_resolver_taskmgr(view->resolver),
700 dns_resolver_dispatchmgr(view->resolver),
701 dns_resolver_dispatchv4(view->resolver),
702 dns_resolver_dispatchv6(view->resolver),
704 if (result != ISC_R_SUCCESS) {
705 dns_adb_shutdown(view->adb);
706 dns_resolver_shutdown(view->resolver);
709 event = &view->reqevent;
710 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
711 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
713 return (ISC_R_SUCCESS);
717 dns_view_setcache(dns_view_t *view, dns_cache_t *cache) {
718 dns_view_setcache2(view, cache, ISC_FALSE);
722 dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
723 REQUIRE(DNS_VIEW_VALID(view));
724 REQUIRE(!view->frozen);
726 view->cacheshared = shared;
727 if (view->cache != NULL) {
729 if (view->acache != NULL)
730 dns_acache_putdb(view->acache, view->cachedb);
732 dns_db_detach(&view->cachedb);
733 dns_cache_detach(&view->cache);
735 dns_cache_attach(cache, &view->cache);
736 dns_cache_attachdb(cache, &view->cachedb);
737 INSIST(DNS_DB_VALID(view->cachedb));
740 if (view->acache != NULL)
741 dns_acache_setdb(view->acache, view->cachedb);
746 dns_view_iscacheshared(dns_view_t *view) {
747 REQUIRE(DNS_VIEW_VALID(view));
749 return (view->cacheshared);
753 dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
754 REQUIRE(DNS_VIEW_VALID(view));
755 REQUIRE(!view->frozen);
756 REQUIRE(view->hints == NULL);
757 REQUIRE(dns_db_iszone(hints));
759 dns_db_attach(hints, &view->hints);
763 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
764 REQUIRE(DNS_VIEW_VALID(view));
765 REQUIRE(ring != NULL);
766 if (view->statickeys != NULL)
767 dns_tsigkeyring_detach(&view->statickeys);
768 dns_tsigkeyring_attach(ring, &view->statickeys);
772 dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
773 REQUIRE(DNS_VIEW_VALID(view));
774 REQUIRE(ring != NULL);
775 if (view->dynamickeys != NULL)
776 dns_tsigkeyring_detach(&view->dynamickeys);
777 dns_tsigkeyring_attach(ring, &view->dynamickeys);
781 dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) {
782 REQUIRE(DNS_VIEW_VALID(view));
783 REQUIRE(ringp != NULL && *ringp == NULL);
784 if (view->dynamickeys != NULL)
785 dns_tsigkeyring_attach(view->dynamickeys, ringp);
789 dns_view_restorekeyring(dns_view_t *view) {
794 REQUIRE(DNS_VIEW_VALID(view));
796 if (view->dynamickeys != NULL) {
797 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
799 if (n > 0 && (size_t)n < sizeof(keyfile)) {
800 fp = fopen(keyfile, "r");
802 dns_keyring_restore(view->dynamickeys, fp);
810 dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
811 REQUIRE(DNS_VIEW_VALID(view));
812 view->dstport = dstport;
816 dns_view_freeze(dns_view_t *view) {
817 REQUIRE(DNS_VIEW_VALID(view));
818 REQUIRE(!view->frozen);
820 if (view->resolver != NULL) {
821 INSIST(view->cachedb != NULL);
822 dns_resolver_freeze(view->resolver);
824 view->frozen = ISC_TRUE;
829 dns_view_thaw(dns_view_t *view) {
830 REQUIRE(DNS_VIEW_VALID(view));
831 REQUIRE(view->frozen);
833 view->frozen = ISC_FALSE;
837 dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
840 REQUIRE(DNS_VIEW_VALID(view));
841 REQUIRE(!view->frozen);
843 result = dns_zt_mount(view->zonetable, zone);
851 dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
854 REQUIRE(DNS_VIEW_VALID(view));
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;
867 dns_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,
877 dns_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)
885 dns_dbnode_t *node, *znode;
886 isc_boolean_t is_cache, is_staticstub_zone;
887 dns_rdataset_t zrdataset, zsigrdataset;
892 UNUSED(use_static_stub);
896 * Find an rdataset whose owner name is 'name', and whose type is
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);
909 dns_rdataset_init(&zrdataset);
910 dns_rdataset_init(&zsigrdataset);
915 * Find a database to answer the query.
920 is_staticstub_zone = ISC_FALSE;
922 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
923 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
925 result = ISC_R_NOTFOUND;
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)
933 if (dns_zone_gettype(zone) == dns_zone_staticstub &&
934 dns_name_equal(name, dns_zone_getorigin(zone))) {
935 is_staticstub_zone = ISC_TRUE;
937 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
938 dns_db_attach(view->cachedb, &db);
940 result = ISC_R_NOTFOUND;
941 if (view->cachedb != NULL)
942 dns_db_attach(view->cachedb, &db);
947 is_cache = dns_db_iscache(db);
951 * Now look for an answer in the database.
953 result = dns_db_find(db, name, NULL, type, options,
954 now, &node, foundname, rdataset, sigrdataset);
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);
963 dns_db_detachnode(db, &node);
966 if (view->cachedb != NULL && !is_staticstub_zone) {
968 * Either the answer is in the cache, or we
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).
975 dns_db_attach(view->cachedb, &db);
980 * We don't have the data in the cache. If we've got
981 * glue from the zone, use it.
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,
992 dns_db_attach(zdb, &db);
993 dns_db_attachnode(db, znode, &node);
998 * We don't know the answer.
1000 result = ISC_R_NOTFOUND;
1001 } else if (result == DNS_R_GLUE) {
1002 if (view->cachedb != NULL && !is_staticstub_zone) {
1004 * We found an answer, but the cache may be better.
1005 * Remember what we've got and go look in the cache.
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);
1015 dns_db_attach(db, &zdb);
1016 dns_db_attachnode(zdb, node, &znode);
1017 dns_db_detachnode(db, &node);
1019 dns_db_attach(view->cachedb, &db);
1023 * Otherwise, the glue is the best answer.
1025 result = ISC_R_SUCCESS;
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);
1037 dns_db_detachnode(db, &node);
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) {
1045 * We just used a hint. Let the resolver know it
1046 * should consider priming.
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;
1058 * Cleanup if non-standard hints are used.
1060 if (db == NULL && node != NULL)
1061 dns_db_detachnode(view->hints, &node);
1066 if (dns_rdataset_isassociated(&zrdataset)) {
1067 dns_rdataset_disassociate(&zrdataset);
1068 if (dns_rdataset_isassociated(&zsigrdataset))
1069 dns_rdataset_disassociate(&zsigrdataset);
1074 dns_db_detachnode(zdb, &znode);
1075 dns_db_detach(&zdb);
1083 dns_db_detachnode(db, &node);
1090 INSIST(node == NULL);
1094 dns_zone_detach(&zone);
1101 dns_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)
1106 isc_result_t result;
1107 dns_fixedname_t foundname;
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) {
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.
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;
1145 dns_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)
1150 return(dns_view_findzonecut2(view, name, fname, now, options,
1151 use_hints, ISC_TRUE,
1152 rdataset, sigrdataset));
1156 dns_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)
1161 isc_result_t result;
1163 isc_boolean_t is_cache, use_zone, try_hints;
1166 dns_rdataset_t zrdataset, zsigrdataset;
1167 dns_fixedname_t zfixedname;
1169 REQUIRE(DNS_VIEW_VALID(view));
1170 REQUIRE(view->frozen);
1174 use_zone = ISC_FALSE;
1175 try_hints = ISC_FALSE;
1181 dns_fixedname_init(&zfixedname);
1182 dns_rdataset_init(&zrdataset);
1183 dns_rdataset_init(&zsigrdataset);
1186 * Find the right database.
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);
1193 result = ISC_R_NOTFOUND;
1195 if (result == ISC_R_NOTFOUND) {
1197 * We're not directly authoritative for this query name, nor
1198 * is it a subdomain of any zone for which we're
1201 if (use_cache && view->cachedb != NULL) {
1203 * We have a cache; try it.
1205 dns_db_attach(view->cachedb, &db);
1208 * Maybe we have hints...
1210 try_hints = ISC_TRUE;
1213 } else if (result != ISC_R_SUCCESS) {
1215 * Something is broken.
1219 is_cache = dns_db_iscache(db);
1223 * Look for the zonecut.
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)
1232 if (use_cache && view->cachedb != NULL && db != view->hints) {
1234 * We found an answer, but the cache may be better.
1236 zfname = dns_fixedname_name(&zfixedname);
1237 result = dns_name_copy(fname, zfname, NULL);
1238 if (result != ISC_R_SUCCESS)
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);
1248 dns_db_attach(view->cachedb, &db);
1249 is_cache = ISC_TRUE;
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)))) {
1261 * We found a zonecut in the cache, but our
1262 * zone delegation is better.
1264 use_zone = ISC_TRUE;
1266 } else if (result == ISC_R_NOTFOUND) {
1267 if (zfname != NULL) {
1269 * We didn't find anything in the cache, but we
1270 * have a zone delegation, so use it.
1272 use_zone = ISC_TRUE;
1275 * Maybe we have hints...
1277 try_hints = ISC_TRUE;
1281 * Something bad happened.
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);
1295 result = dns_name_copy(zfname, fname, NULL);
1296 if (result != ISC_R_SUCCESS)
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) {
1304 * We've found nothing so far, but we have hints.
1306 result = dns_db_find(view->hints, dns_rootname, NULL,
1307 dns_rdatatype_ns, 0, now, NULL, fname,
1309 if (result != ISC_R_SUCCESS) {
1311 * We can't even find the hints for the root
1314 if (dns_rdataset_isassociated(rdataset))
1315 dns_rdataset_disassociate(rdataset);
1316 result = ISC_R_NOTFOUND;
1321 if (dns_rdataset_isassociated(&zrdataset)) {
1322 dns_rdataset_disassociate(&zrdataset);
1323 if (dns_rdataset_isassociated(&zsigrdataset))
1324 dns_rdataset_disassociate(&zsigrdataset);
1330 dns_zone_detach(&zone);
1337 dns_viewlist_find(dns_viewlist_t *list, const char *name,
1338 dns_rdataclass_t rdclass, dns_view_t **viewp)
1342 REQUIRE(list != NULL);
1344 for (view = ISC_LIST_HEAD(*list);
1346 view = ISC_LIST_NEXT(view, link)) {
1347 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass)
1351 return (ISC_R_NOTFOUND);
1353 dns_view_attach(view, viewp);
1355 return (ISC_R_SUCCESS);
1360 dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
1361 isc_boolean_t allclasses, dns_rdataclass_t rdclass,
1365 isc_result_t result;
1366 dns_zone_t *zone1 = NULL, *zone2 = NULL;
1367 dns_zone_t **zp = NULL;;
1369 REQUIRE(list != NULL);
1370 for (view = ISC_LIST_HEAD(*list);
1372 view = ISC_LIST_NEXT(view, link)) {
1373 if (allclasses == ISC_FALSE && view->rdclass != rdclass)
1377 * If the zone is defined in more than one view,
1378 * treat it as not found.
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);
1386 /* Treat a partial match as no match */
1387 if (result == DNS_R_PARTIALMATCH) {
1388 dns_zone_detach(zp);
1389 result = ISC_R_NOTFOUND;
1393 if (zone2 != NULL) {
1394 dns_zone_detach(&zone1);
1395 dns_zone_detach(&zone2);
1396 return (ISC_R_NOTFOUND);
1400 if (zone1 != NULL) {
1401 dns_zone_attach(zone1, zonep);
1402 dns_zone_detach(&zone1);
1403 return (ISC_R_SUCCESS);
1406 return (ISC_R_NOTFOUND);
1410 dns_view_load(dns_view_t *view, isc_boolean_t stop) {
1412 REQUIRE(DNS_VIEW_VALID(view));
1414 return (dns_zt_load(view->zonetable, stop));
1418 dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
1420 REQUIRE(DNS_VIEW_VALID(view));
1422 return (dns_zt_loadnew(view->zonetable, stop));
1427 dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
1429 isc_result_t result;
1430 REQUIRE(keyp != NULL && *keyp == NULL);
1432 result = dns_tsigkey_find(keyp, keyname, NULL,
1434 if (result == ISC_R_NOTFOUND)
1435 result = dns_tsigkey_find(keyp, keyname, NULL,
1441 dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
1442 dns_tsigkey_t **keyp)
1444 isc_result_t result;
1445 dns_name_t *keyname = NULL;
1446 dns_peer_t *peer = NULL;
1448 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer);
1449 if (result != ISC_R_SUCCESS)
1452 result = dns_peer_getkey(peer, &keyname);
1453 if (result != ISC_R_SUCCESS)
1456 result = dns_view_gettsig(view, keyname, keyp);
1457 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
1461 dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
1462 REQUIRE(DNS_VIEW_VALID(view));
1463 REQUIRE(source != NULL);
1465 return (dns_tsig_verify(source, msg, view->statickeys,
1466 view->dynamickeys));
1471 dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
1472 isc_result_t result;
1474 REQUIRE(DNS_VIEW_VALID(view));
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)
1481 dns_adb_dump(view->adb, fp);
1482 dns_resolver_printbadcache(view->resolver, fp);
1483 return (ISC_R_SUCCESS);
1488 dns_view_flushcache(dns_view_t *view) {
1489 return (dns_view_flushcache2(view, ISC_FALSE));
1493 dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
1494 isc_result_t result;
1496 REQUIRE(DNS_VIEW_VALID(view));
1498 if (view->cachedb == NULL)
1499 return (ISC_R_SUCCESS);
1501 result = dns_cache_flush(view->cache);
1502 if (result != ISC_R_SUCCESS)
1506 if (view->acache != NULL)
1507 dns_acache_putdb(view->acache, view->cachedb);
1509 dns_db_detach(&view->cachedb);
1510 dns_cache_attachdb(view->cache, &view->cachedb);
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);
1518 dns_adb_flush(view->adb);
1519 return (ISC_R_SUCCESS);
1523 dns_view_flushname(dns_view_t *view, dns_name_t *name) {
1525 REQUIRE(DNS_VIEW_VALID(view));
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));
1537 dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) {
1538 isc_result_t result;
1542 REQUIRE(DNS_VIEW_VALID(view));
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]);
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);
1558 return (ISC_R_SUCCESS);
1559 new = isc_mem_get(view->mctx, sizeof(*new));
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);
1567 isc_mem_put(view->mctx, new, sizeof(*new));
1572 dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) {
1573 isc_result_t result;
1577 REQUIRE(DNS_VIEW_VALID(view));
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]);
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);
1593 return (ISC_R_SUCCESS);
1594 new = isc_mem_get(view->mctx, sizeof(*new));
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);
1602 isc_mem_put(view->mctx, new, sizeof(*new));
1607 dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) {
1611 REQUIRE(DNS_VIEW_VALID(view));
1613 if (!view->rootdelonly && view->delonly == NULL)
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)
1620 new = ISC_LIST_HEAD(view->rootexclude[hash]);
1621 while (new != NULL && !dns_name_equal(new, name))
1622 new = ISC_LIST_NEXT(new, link);
1627 if (view->delonly == NULL)
1630 new = ISC_LIST_HEAD(view->delonly[hash]);
1631 while (new != NULL && !dns_name_equal(new, name))
1632 new = ISC_LIST_NEXT(new, link);
1639 dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) {
1640 REQUIRE(DNS_VIEW_VALID(view));
1641 view->rootdelonly = value;
1645 dns_view_getrootdelonly(dns_view_t *view) {
1646 REQUIRE(DNS_VIEW_VALID(view));
1647 return (view->rootdelonly);
1652 dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
1653 REQUIRE(DNS_VIEW_VALID(view));
1654 return (dns_zt_freezezones(view->zonetable, value));
1659 dns_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);
1664 isc_stats_attach(stats, &view->resstats);
1668 dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) {
1669 REQUIRE(DNS_VIEW_VALID(view));
1670 REQUIRE(statsp != NULL && *statsp == NULL);
1672 if (view->resstats != NULL)
1673 isc_stats_attach(view->resstats, statsp);
1677 dns_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);
1682 dns_stats_attach(stats, &view->resquerystats);
1686 dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
1687 REQUIRE(DNS_VIEW_VALID(view));
1688 REQUIRE(statsp != NULL && *statsp == NULL);
1690 if (view->resquerystats != NULL)
1691 dns_stats_attach(view->resquerystats, statsp);
1695 dns_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));
1703 dns_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);
1713 dns_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,
1721 dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
1722 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
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;
1732 * Clear the revoke bit, if set, so that the key will match what's
1735 dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
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)
1744 result = dns_view_getsecroots(view, &sr);
1745 if (result == ISC_R_SUCCESS) {
1746 dns_keytable_deletekeynode(sr, key);
1747 dns_keytable_detach(&sr);
1755 dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
1756 void (*cfg_destroy)(void **))
1758 REQUIRE(DNS_VIEW_VALID(view));
1759 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow);
1762 if (view->new_zone_file != NULL) {
1763 isc_mem_free(view->mctx, view->new_zone_file);
1764 view->new_zone_file = NULL;
1767 if (view->new_zone_config != NULL) {
1768 view->cfg_destroy(&view->new_zone_config);
1769 view->cfg_destroy = NULL;
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;
1784 UNUSED(cfg_destroy);