2 * Copyright (C) 2004-2013 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.
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>
38 #include <dns/dispatch.h>
41 #include <dns/dns64.h>
43 #include <dns/dnssec.h>
44 #include <dns/events.h>
45 #include <dns/forward.h>
46 #include <dns/keytable.h>
47 #include <dns/keyvalues.h>
48 #include <dns/master.h>
49 #include <dns/masterdump.h>
50 #include <dns/order.h>
54 #include <dns/rdataset.h>
55 #include <dns/request.h>
56 #include <dns/resolver.h>
57 #include <dns/result.h>
59 #include <dns/stats.h>
64 #define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0)
65 #define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0)
66 #define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0)
68 #define DNS_VIEW_DELONLYHASH 111
70 static void resolver_shutdown(isc_task_t *task, isc_event_t *event);
71 static void adb_shutdown(isc_task_t *task, isc_event_t *event);
72 static void req_shutdown(isc_task_t *task, isc_event_t *event);
75 dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
76 const char *name, dns_view_t **viewp)
85 REQUIRE(name != NULL);
86 REQUIRE(viewp != NULL && *viewp == NULL);
88 view = isc_mem_get(mctx, sizeof(*view));
90 return (ISC_R_NOMEMORY);
93 isc_mem_attach(mctx, &view->mctx);
94 view->name = isc_mem_strdup(mctx, name);
95 if (view->name == NULL) {
96 result = ISC_R_NOMEMORY;
99 result = isc_mutex_init(&view->lock);
100 if (result != ISC_R_SUCCESS)
103 view->zonetable = NULL;
105 result = dns_zt_create(mctx, rdclass, &view->zonetable);
106 if (result != ISC_R_SUCCESS) {
107 UNEXPECTED_ERROR(__FILE__, __LINE__,
108 "dns_zt_create() failed: %s",
109 isc_result_totext(result));
110 result = ISC_R_UNEXPECTED;
114 view->secroots_priv = NULL;
115 view->fwdtable = NULL;
116 result = dns_fwdtable_create(mctx, &view->fwdtable);
117 if (result != ISC_R_SUCCESS) {
118 UNEXPECTED_ERROR(__FILE__, __LINE__,
119 "dns_fwdtable_create() failed: %s",
120 isc_result_totext(result));
121 result = ISC_R_UNEXPECTED;
127 view->cachedb = NULL;
128 view->dlzdatabase = NULL;
130 view->resolver = NULL;
132 view->requestmgr = NULL;
133 view->rdclass = rdclass;
134 view->frozen = ISC_FALSE;
136 result = isc_refcount_init(&view->references, 1);
137 if (result != ISC_R_SUCCESS)
138 goto cleanup_fwdtable;
140 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
141 DNS_VIEWATTR_REQSHUTDOWN);
142 view->statickeys = NULL;
143 view->dynamickeys = NULL;
144 view->matchclients = NULL;
145 view->matchdestinations = NULL;
146 view->matchrecursiveonly = ISC_FALSE;
147 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
148 if (result != ISC_R_SUCCESS)
149 goto cleanup_references;
152 view->delonly = NULL;
153 view->rootdelonly = ISC_FALSE;
154 view->rootexclude = NULL;
155 view->resstats = NULL;
156 view->resquerystats = NULL;
157 view->cacheshared = ISC_FALSE;
158 ISC_LIST_INIT(view->dns64);
162 * Initialize configuration data with default values.
164 view->recursion = ISC_TRUE;
165 view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
166 view->additionalfromcache = ISC_TRUE;
167 view->additionalfromauth = ISC_TRUE;
168 view->enablednssec = ISC_TRUE;
169 view->enablevalidation = ISC_TRUE;
170 view->acceptexpired = ISC_FALSE;
171 view->minimalresponses = ISC_FALSE;
172 view->transfer_format = dns_one_answer;
173 view->cacheacl = NULL;
174 view->cacheonacl = NULL;
175 view->queryacl = NULL;
176 view->queryonacl = NULL;
177 view->recursionacl = NULL;
178 view->recursiononacl = NULL;
179 view->sortlist = NULL;
180 view->transferacl = NULL;
181 view->notifyacl = NULL;
182 view->updateacl = NULL;
183 view->upfwdacl = NULL;
184 view->denyansweracl = NULL;
185 view->answeracl_exclude = NULL;
186 view->denyanswernames = NULL;
187 view->answernames_exclude = NULL;
189 view->provideixfr = ISC_TRUE;
190 view->maxcachettl = 7 * 24 * 3600;
191 view->maxncachettl = 3 * 3600;
193 view->preferred_glue = 0;
194 view->flush = ISC_FALSE;
198 view->v4_aaaa = dns_v4_aaaa_ok;
199 view->v4_aaaa_acl = NULL;
200 ISC_LIST_INIT(view->rpz_zones);
201 view->rpz_recursive_only = ISC_TRUE;
202 view->rpz_break_dnssec = ISC_FALSE;
203 dns_fixedname_init(&view->dlv_fixed);
204 view->managed_keys = NULL;
205 view->redirect = NULL;
207 view->new_zone_file = NULL;
208 view->new_zone_config = NULL;
209 view->cfg_destroy = NULL;
211 result = dns_order_create(view->mctx, &view->order);
212 if (result != ISC_R_SUCCESS)
213 goto cleanup_dynkeys;
216 result = dns_peerlist_new(view->mctx, &view->peers);
217 if (result != ISC_R_SUCCESS)
220 result = dns_aclenv_init(view->mctx, &view->aclenv);
221 if (result != ISC_R_SUCCESS)
222 goto cleanup_peerlist;
224 ISC_LINK_INIT(view, link);
225 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
226 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
227 view, NULL, NULL, NULL);
228 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
229 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
230 view, NULL, NULL, NULL);
231 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
232 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
233 view, NULL, NULL, NULL);
234 view->viewlist = NULL;
235 view->magic = DNS_VIEW_MAGIC;
239 return (ISC_R_SUCCESS);
242 dns_peerlist_detach(&view->peers);
246 dns_order_detach(&view->order);
250 dns_tsigkeyring_detach(&view->dynamickeys);
253 isc_refcount_destroy(&view->references);
256 dns_fwdtable_destroy(&view->fwdtable);
260 dns_zt_detach(&view->zonetable);
264 DESTROYLOCK(&view->lock);
267 isc_mem_free(mctx, view->name);
270 isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
276 destroy(dns_view_t *view) {
281 REQUIRE(!ISC_LINK_LINKED(view, link));
282 REQUIRE(isc_refcount_current(&view->references) == 0);
283 REQUIRE(view->weakrefs == 0);
284 REQUIRE(RESSHUTDOWN(view));
285 REQUIRE(ADBSHUTDOWN(view));
286 REQUIRE(REQSHUTDOWN(view));
289 if (view->order != NULL)
290 dns_order_detach(&view->order);
292 if (view->peers != NULL)
293 dns_peerlist_detach(&view->peers);
295 if (view->dynamickeys != NULL) {
302 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
304 if (n > 0 && (size_t)n < sizeof(keyfile)) {
305 result = isc_file_mktemplate(keyfile, template,
307 if (result == ISC_R_SUCCESS)
308 (void)isc_file_openuniqueprivate(template, &fp);
311 dns_tsigkeyring_detach(&view->dynamickeys);
313 result = dns_tsigkeyring_dumpanddetach(
314 &view->dynamickeys, fp);
315 if (result == ISC_R_SUCCESS) {
317 result = isc_file_rename(template,
319 if (result != ISC_R_SUCCESS)
320 (void)remove(template);
323 (void)remove(template);
327 if (view->statickeys != NULL)
328 dns_tsigkeyring_detach(&view->statickeys);
329 if (view->adb != NULL)
330 dns_adb_detach(&view->adb);
331 if (view->resolver != NULL)
332 dns_resolver_detach(&view->resolver);
334 if (view->acache != NULL) {
335 if (view->cachedb != NULL)
336 dns_acache_putdb(view->acache, view->cachedb);
337 dns_acache_detach(&view->acache);
339 dns_rpz_view_destroy(view);
341 dns_rrl_view_destroy(view);
343 INSIST(view->rrl == NULL);
346 INSIST(view->acache == NULL);
347 INSIST(ISC_LIST_EMPTY(view->rpz_zones));
348 INSIST(view->rrl == NULL);
350 if (view->requestmgr != NULL)
351 dns_requestmgr_detach(&view->requestmgr);
352 if (view->task != NULL)
353 isc_task_detach(&view->task);
354 if (view->hints != NULL)
355 dns_db_detach(&view->hints);
356 if (view->dlzdatabase != NULL)
357 dns_dlzdestroy(&view->dlzdatabase);
358 if (view->cachedb != NULL)
359 dns_db_detach(&view->cachedb);
360 if (view->cache != NULL)
361 dns_cache_detach(&view->cache);
362 if (view->matchclients != NULL)
363 dns_acl_detach(&view->matchclients);
364 if (view->matchdestinations != NULL)
365 dns_acl_detach(&view->matchdestinations);
366 if (view->cacheacl != NULL)
367 dns_acl_detach(&view->cacheacl);
368 if (view->cacheonacl != NULL)
369 dns_acl_detach(&view->cacheonacl);
370 if (view->queryacl != NULL)
371 dns_acl_detach(&view->queryacl);
372 if (view->queryonacl != NULL)
373 dns_acl_detach(&view->queryonacl);
374 if (view->recursionacl != NULL)
375 dns_acl_detach(&view->recursionacl);
376 if (view->recursiononacl != NULL)
377 dns_acl_detach(&view->recursiononacl);
378 if (view->sortlist != NULL)
379 dns_acl_detach(&view->sortlist);
380 if (view->transferacl != NULL)
381 dns_acl_detach(&view->transferacl);
382 if (view->notifyacl != NULL)
383 dns_acl_detach(&view->notifyacl);
384 if (view->updateacl != NULL)
385 dns_acl_detach(&view->updateacl);
386 if (view->upfwdacl != NULL)
387 dns_acl_detach(&view->upfwdacl);
388 if (view->denyansweracl != NULL)
389 dns_acl_detach(&view->denyansweracl);
390 if (view->v4_aaaa_acl != NULL)
391 dns_acl_detach(&view->v4_aaaa_acl);
392 if (view->answeracl_exclude != NULL)
393 dns_rbt_destroy(&view->answeracl_exclude);
394 if (view->denyanswernames != NULL)
395 dns_rbt_destroy(&view->denyanswernames);
396 if (view->answernames_exclude != NULL)
397 dns_rbt_destroy(&view->answernames_exclude);
398 if (view->delonly != NULL) {
402 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
403 name = ISC_LIST_HEAD(view->delonly[i]);
404 while (name != NULL) {
405 ISC_LIST_UNLINK(view->delonly[i], name, link);
406 dns_name_free(name, view->mctx);
407 isc_mem_put(view->mctx, name, sizeof(*name));
408 name = ISC_LIST_HEAD(view->delonly[i]);
411 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) *
412 DNS_VIEW_DELONLYHASH);
413 view->delonly = NULL;
415 if (view->rootexclude != NULL) {
419 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
420 name = ISC_LIST_HEAD(view->rootexclude[i]);
421 while (name != NULL) {
422 ISC_LIST_UNLINK(view->rootexclude[i],
424 dns_name_free(name, view->mctx);
425 isc_mem_put(view->mctx, name, sizeof(*name));
426 name = ISC_LIST_HEAD(view->rootexclude[i]);
429 isc_mem_put(view->mctx, view->rootexclude,
430 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
431 view->rootexclude = NULL;
433 if (view->resstats != NULL)
434 isc_stats_detach(&view->resstats);
435 if (view->resquerystats != NULL)
436 dns_stats_detach(&view->resquerystats);
437 if (view->secroots_priv != NULL)
438 dns_keytable_detach(&view->secroots_priv);
440 for (dns64 = ISC_LIST_HEAD(view->dns64);
442 dns64 = ISC_LIST_HEAD(view->dns64)) {
443 dns_dns64_unlink(&view->dns64, dns64);
444 dns_dns64_destroy(&dns64);
446 if (view->managed_keys != NULL)
447 dns_zone_detach(&view->managed_keys);
448 if (view->redirect != NULL)
449 dns_zone_detach(&view->redirect);
450 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
452 dns_fwdtable_destroy(&view->fwdtable);
453 dns_aclenv_destroy(&view->aclenv);
454 DESTROYLOCK(&view->lock);
455 isc_refcount_destroy(&view->references);
456 isc_mem_free(view->mctx, view->name);
457 isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
461 * Return true iff 'view' may be freed.
462 * The caller must be holding the view lock.
465 all_done(dns_view_t *view) {
467 if (isc_refcount_current(&view->references) == 0 &&
468 view->weakrefs == 0 &&
469 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
476 dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
478 REQUIRE(DNS_VIEW_VALID(source));
479 REQUIRE(targetp != NULL && *targetp == NULL);
481 isc_refcount_increment(&source->references, NULL);
487 view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
490 isc_boolean_t done = ISC_FALSE;
492 REQUIRE(viewp != NULL);
494 REQUIRE(DNS_VIEW_VALID(view));
497 view->flush = ISC_TRUE;
498 isc_refcount_decrement(&view->references, &refs);
501 dns_zone_t *mkzone = NULL, *rdzone = NULL;
505 if (!RESSHUTDOWN(view))
506 dns_resolver_shutdown(view->resolver);
507 if (!ADBSHUTDOWN(view))
508 dns_adb_shutdown(view->adb);
509 if (!REQSHUTDOWN(view))
510 dns_requestmgr_shutdown(view->requestmgr);
512 if (view->acache != NULL)
513 dns_acache_shutdown(view->acache);
515 dns_zt_flushanddetach(&view->zonetable);
517 dns_zt_detach(&view->zonetable);
518 if (view->managed_keys != NULL) {
519 mkzone = view->managed_keys;
520 view->managed_keys = NULL;
522 dns_zone_flush(mkzone);
524 if (view->redirect != NULL) {
525 rdzone = view->redirect;
526 view->redirect = NULL;
528 dns_zone_flush(rdzone);
531 done = all_done(view);
535 /* Need to detach zones outside view lock */
537 dns_zone_detach(&mkzone);
540 dns_zone_detach(&rdzone);
551 dns_view_flushanddetach(dns_view_t **viewp) {
552 view_flushanddetach(viewp, ISC_TRUE);
556 dns_view_detach(dns_view_t **viewp) {
557 view_flushanddetach(viewp, ISC_FALSE);
562 dialup(dns_zone_t *zone, void *dummy) {
564 dns_zone_dialup(zone);
565 return (ISC_R_SUCCESS);
569 dns_view_dialup(dns_view_t *view) {
570 REQUIRE(DNS_VIEW_VALID(view));
571 REQUIRE(view->zonetable != NULL);
573 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL);
578 dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
580 REQUIRE(DNS_VIEW_VALID(source));
581 REQUIRE(targetp != NULL && *targetp == NULL);
585 UNLOCK(&source->lock);
591 dns_view_weakdetach(dns_view_t **viewp) {
593 isc_boolean_t done = ISC_FALSE;
595 REQUIRE(viewp != NULL);
597 REQUIRE(DNS_VIEW_VALID(view));
601 INSIST(view->weakrefs > 0);
603 done = all_done(view);
614 resolver_shutdown(isc_task_t *task, isc_event_t *event) {
615 dns_view_t *view = event->ev_arg;
618 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
619 REQUIRE(DNS_VIEW_VALID(view));
620 REQUIRE(view->task == task);
626 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
627 done = all_done(view);
631 isc_event_free(&event);
638 adb_shutdown(isc_task_t *task, isc_event_t *event) {
639 dns_view_t *view = event->ev_arg;
642 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
643 REQUIRE(DNS_VIEW_VALID(view));
644 REQUIRE(view->task == task);
650 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
651 done = all_done(view);
655 isc_event_free(&event);
662 req_shutdown(isc_task_t *task, isc_event_t *event) {
663 dns_view_t *view = event->ev_arg;
666 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
667 REQUIRE(DNS_VIEW_VALID(view));
668 REQUIRE(view->task == task);
674 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
675 done = all_done(view);
679 isc_event_free(&event);
686 dns_view_createresolver(dns_view_t *view,
687 isc_taskmgr_t *taskmgr,
688 unsigned int ntasks, unsigned int ndisp,
689 isc_socketmgr_t *socketmgr,
690 isc_timermgr_t *timermgr,
691 unsigned int options,
692 dns_dispatchmgr_t *dispatchmgr,
693 dns_dispatch_t *dispatchv4,
694 dns_dispatch_t *dispatchv6)
698 isc_mem_t *mctx = NULL;
700 REQUIRE(DNS_VIEW_VALID(view));
701 REQUIRE(!view->frozen);
702 REQUIRE(view->resolver == NULL);
704 result = isc_task_create(taskmgr, 0, &view->task);
705 if (result != ISC_R_SUCCESS)
707 isc_task_setname(view->task, "view", view);
709 result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
710 timermgr, options, dispatchmgr,
711 dispatchv4, dispatchv6,
713 if (result != ISC_R_SUCCESS) {
714 isc_task_detach(&view->task);
717 event = &view->resevent;
718 dns_resolver_whenshutdown(view->resolver, view->task, &event);
719 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
721 result = isc_mem_create(0, 0, &mctx);
722 if (result != ISC_R_SUCCESS) {
723 dns_resolver_shutdown(view->resolver);
727 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb);
728 isc_mem_setname(mctx, "ADB", NULL);
729 isc_mem_detach(&mctx);
730 if (result != ISC_R_SUCCESS) {
731 dns_resolver_shutdown(view->resolver);
734 event = &view->adbevent;
735 dns_adb_whenshutdown(view->adb, view->task, &event);
736 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
738 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
739 dns_resolver_taskmgr(view->resolver),
740 dns_resolver_dispatchmgr(view->resolver),
741 dispatchv4, dispatchv6,
743 if (result != ISC_R_SUCCESS) {
744 dns_adb_shutdown(view->adb);
745 dns_resolver_shutdown(view->resolver);
748 event = &view->reqevent;
749 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
750 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
752 return (ISC_R_SUCCESS);
756 dns_view_setcache(dns_view_t *view, dns_cache_t *cache) {
757 dns_view_setcache2(view, cache, ISC_FALSE);
761 dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
762 REQUIRE(DNS_VIEW_VALID(view));
763 REQUIRE(!view->frozen);
765 view->cacheshared = shared;
766 if (view->cache != NULL) {
768 if (view->acache != NULL)
769 dns_acache_putdb(view->acache, view->cachedb);
771 dns_db_detach(&view->cachedb);
772 dns_cache_detach(&view->cache);
774 dns_cache_attach(cache, &view->cache);
775 dns_cache_attachdb(cache, &view->cachedb);
776 INSIST(DNS_DB_VALID(view->cachedb));
779 if (view->acache != NULL)
780 dns_acache_setdb(view->acache, view->cachedb);
785 dns_view_iscacheshared(dns_view_t *view) {
786 REQUIRE(DNS_VIEW_VALID(view));
788 return (view->cacheshared);
792 dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
793 REQUIRE(DNS_VIEW_VALID(view));
794 REQUIRE(!view->frozen);
795 REQUIRE(view->hints == NULL);
796 REQUIRE(dns_db_iszone(hints));
798 dns_db_attach(hints, &view->hints);
802 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
803 REQUIRE(DNS_VIEW_VALID(view));
804 REQUIRE(ring != NULL);
805 if (view->statickeys != NULL)
806 dns_tsigkeyring_detach(&view->statickeys);
807 dns_tsigkeyring_attach(ring, &view->statickeys);
811 dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
812 REQUIRE(DNS_VIEW_VALID(view));
813 REQUIRE(ring != NULL);
814 if (view->dynamickeys != NULL)
815 dns_tsigkeyring_detach(&view->dynamickeys);
816 dns_tsigkeyring_attach(ring, &view->dynamickeys);
820 dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) {
821 REQUIRE(DNS_VIEW_VALID(view));
822 REQUIRE(ringp != NULL && *ringp == NULL);
823 if (view->dynamickeys != NULL)
824 dns_tsigkeyring_attach(view->dynamickeys, ringp);
828 dns_view_restorekeyring(dns_view_t *view) {
833 REQUIRE(DNS_VIEW_VALID(view));
835 if (view->dynamickeys != NULL) {
836 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
838 if (n > 0 && (size_t)n < sizeof(keyfile)) {
839 fp = fopen(keyfile, "r");
841 dns_keyring_restore(view->dynamickeys, fp);
849 dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
850 REQUIRE(DNS_VIEW_VALID(view));
851 view->dstport = dstport;
855 dns_view_freeze(dns_view_t *view) {
856 REQUIRE(DNS_VIEW_VALID(view));
857 REQUIRE(!view->frozen);
859 if (view->resolver != NULL) {
860 INSIST(view->cachedb != NULL);
861 dns_resolver_freeze(view->resolver);
863 view->frozen = ISC_TRUE;
868 dns_view_thaw(dns_view_t *view) {
869 REQUIRE(DNS_VIEW_VALID(view));
870 REQUIRE(view->frozen);
872 view->frozen = ISC_FALSE;
876 dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
879 REQUIRE(DNS_VIEW_VALID(view));
880 REQUIRE(!view->frozen);
881 REQUIRE(view->zonetable != NULL);
883 result = dns_zt_mount(view->zonetable, zone);
891 dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
894 REQUIRE(DNS_VIEW_VALID(view));
897 if (view->zonetable != NULL) {
898 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep);
899 if (result == DNS_R_PARTIALMATCH) {
900 dns_zone_detach(zonep);
901 result = ISC_R_NOTFOUND;
904 result = ISC_R_NOTFOUND;
912 dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
913 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints,
914 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
915 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
916 return (dns_view_find2(view, name, type, now, options, use_hints,
917 ISC_FALSE, dbp, nodep, foundname, rdataset,
922 dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
923 isc_stdtime_t now, unsigned int options,
924 isc_boolean_t use_hints, isc_boolean_t use_static_stub,
925 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
926 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
930 dns_dbnode_t *node, *znode;
931 isc_boolean_t is_cache, is_staticstub_zone;
932 dns_rdataset_t zrdataset, zsigrdataset;
937 UNUSED(use_static_stub);
942 * Find an rdataset whose owner name is 'name', and whose type is
946 REQUIRE(DNS_VIEW_VALID(view));
947 REQUIRE(view->frozen);
948 REQUIRE(type != dns_rdatatype_rrsig);
949 REQUIRE(rdataset != NULL); /* XXXBEW - remove this */
950 REQUIRE(nodep == NULL || *nodep == NULL);
955 dns_rdataset_init(&zrdataset);
956 dns_rdataset_init(&zsigrdataset);
961 * Find a database to answer the query.
965 is_staticstub_zone = ISC_FALSE;
969 if (view->zonetable != NULL)
970 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
972 result = ISC_R_NOTFOUND;
974 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
976 result = ISC_R_NOTFOUND;
978 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
979 result = dns_zone_getdb(zone, &db);
980 if (result != ISC_R_SUCCESS && view->cachedb != NULL)
981 dns_db_attach(view->cachedb, &db);
982 else if (result != ISC_R_SUCCESS)
984 if (dns_zone_gettype(zone) == dns_zone_staticstub &&
985 dns_name_equal(name, dns_zone_getorigin(zone))) {
986 is_staticstub_zone = ISC_TRUE;
988 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
989 dns_db_attach(view->cachedb, &db);
991 result = ISC_R_NOTFOUND;
992 if (view->cachedb != NULL)
993 dns_db_attach(view->cachedb, &db);
998 is_cache = dns_db_iscache(db);
1002 * Now look for an answer in the database.
1004 result = dns_db_find(db, name, NULL, type, options,
1005 now, &node, foundname, rdataset, sigrdataset);
1007 if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) {
1008 if (dns_rdataset_isassociated(rdataset))
1009 dns_rdataset_disassociate(rdataset);
1010 if (sigrdataset != NULL &&
1011 dns_rdataset_isassociated(sigrdataset))
1012 dns_rdataset_disassociate(sigrdataset);
1014 dns_db_detachnode(db, &node);
1017 if (view->cachedb != NULL && !is_staticstub_zone) {
1019 * Either the answer is in the cache, or we
1021 * Note that if the result comes from a
1022 * static-stub zone we stop the search here
1023 * (see the function description in view.h).
1025 is_cache = ISC_TRUE;
1026 dns_db_attach(view->cachedb, &db);
1031 * We don't have the data in the cache. If we've got
1032 * glue from the zone, use it.
1034 if (dns_rdataset_isassociated(&zrdataset)) {
1035 dns_rdataset_clone(&zrdataset, rdataset);
1036 if (sigrdataset != NULL &&
1037 dns_rdataset_isassociated(&zsigrdataset))
1038 dns_rdataset_clone(&zsigrdataset,
1040 result = DNS_R_GLUE;
1043 dns_db_attach(zdb, &db);
1044 dns_db_attachnode(db, znode, &node);
1049 * We don't know the answer.
1051 result = ISC_R_NOTFOUND;
1052 } else if (result == DNS_R_GLUE) {
1053 if (view->cachedb != NULL && !is_staticstub_zone) {
1055 * We found an answer, but the cache may be better.
1056 * Remember what we've got and go look in the cache.
1058 is_cache = ISC_TRUE;
1059 dns_rdataset_clone(rdataset, &zrdataset);
1060 dns_rdataset_disassociate(rdataset);
1061 if (sigrdataset != NULL &&
1062 dns_rdataset_isassociated(sigrdataset)) {
1063 dns_rdataset_clone(sigrdataset, &zsigrdataset);
1064 dns_rdataset_disassociate(sigrdataset);
1066 dns_db_attach(db, &zdb);
1067 dns_db_attachnode(zdb, node, &znode);
1068 dns_db_detachnode(db, &node);
1070 dns_db_attach(view->cachedb, &db);
1074 * Otherwise, the glue is the best answer.
1076 result = ISC_R_SUCCESS;
1080 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) {
1081 if (dns_rdataset_isassociated(rdataset))
1082 dns_rdataset_disassociate(rdataset);
1083 if (sigrdataset != NULL &&
1084 dns_rdataset_isassociated(sigrdataset))
1085 dns_rdataset_disassociate(sigrdataset);
1088 dns_db_detachnode(db, &node);
1091 result = dns_db_find(view->hints, name, NULL, type, options,
1092 now, &node, foundname,
1093 rdataset, sigrdataset);
1094 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) {
1096 * We just used a hint. Let the resolver know it
1097 * should consider priming.
1099 dns_resolver_prime(view->resolver);
1100 dns_db_attach(view->hints, &db);
1101 result = DNS_R_HINT;
1102 } else if (result == DNS_R_NXRRSET) {
1103 dns_db_attach(view->hints, &db);
1104 result = DNS_R_HINTNXRRSET;
1105 } else if (result == DNS_R_NXDOMAIN)
1106 result = ISC_R_NOTFOUND;
1109 * Cleanup if non-standard hints are used.
1111 if (db == NULL && node != NULL)
1112 dns_db_detachnode(view->hints, &node);
1117 if (dns_rdataset_isassociated(&zrdataset)) {
1118 dns_rdataset_disassociate(&zrdataset);
1119 if (dns_rdataset_isassociated(&zsigrdataset))
1120 dns_rdataset_disassociate(&zsigrdataset);
1125 dns_db_detachnode(zdb, &znode);
1126 dns_db_detach(&zdb);
1134 dns_db_detachnode(db, &node);
1141 INSIST(node == NULL);
1145 dns_zone_detach(&zone);
1152 dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
1153 isc_stdtime_t now, unsigned int options,
1154 isc_boolean_t use_hints,
1155 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1157 isc_result_t result;
1158 dns_fixedname_t foundname;
1160 dns_fixedname_init(&foundname);
1161 result = dns_view_find(view, name, type, now, options, use_hints,
1162 NULL, NULL, dns_fixedname_name(&foundname),
1163 rdataset, sigrdataset);
1164 if (result == DNS_R_NXDOMAIN) {
1166 * The rdataset and sigrdataset of the relevant NSEC record
1167 * may be returned, but the caller cannot use them because
1168 * foundname is not returned by this simplified API. We
1169 * disassociate them here to prevent any misuse by the caller.
1171 if (dns_rdataset_isassociated(rdataset))
1172 dns_rdataset_disassociate(rdataset);
1173 if (sigrdataset != NULL &&
1174 dns_rdataset_isassociated(sigrdataset))
1175 dns_rdataset_disassociate(sigrdataset);
1176 } else if (result != ISC_R_SUCCESS &&
1177 result != DNS_R_GLUE &&
1178 result != DNS_R_HINT &&
1179 result != DNS_R_NCACHENXDOMAIN &&
1180 result != DNS_R_NCACHENXRRSET &&
1181 result != DNS_R_NXRRSET &&
1182 result != DNS_R_HINTNXRRSET &&
1183 result != ISC_R_NOTFOUND) {
1184 if (dns_rdataset_isassociated(rdataset))
1185 dns_rdataset_disassociate(rdataset);
1186 if (sigrdataset != NULL &&
1187 dns_rdataset_isassociated(sigrdataset))
1188 dns_rdataset_disassociate(sigrdataset);
1189 result = ISC_R_NOTFOUND;
1196 dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
1197 isc_stdtime_t now, unsigned int options,
1198 isc_boolean_t use_hints,
1199 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1201 return(dns_view_findzonecut2(view, name, fname, now, options,
1202 use_hints, ISC_TRUE,
1203 rdataset, sigrdataset));
1207 dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
1208 isc_stdtime_t now, unsigned int options,
1209 isc_boolean_t use_hints, isc_boolean_t use_cache,
1210 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1212 isc_result_t result;
1214 isc_boolean_t is_cache, use_zone, try_hints;
1217 dns_rdataset_t zrdataset, zsigrdataset;
1218 dns_fixedname_t zfixedname;
1224 REQUIRE(DNS_VIEW_VALID(view));
1225 REQUIRE(view->frozen);
1228 use_zone = ISC_FALSE;
1229 try_hints = ISC_FALSE;
1235 dns_fixedname_init(&zfixedname);
1236 dns_rdataset_init(&zrdataset);
1237 dns_rdataset_init(&zsigrdataset);
1240 * Find the right database.
1245 if (view->zonetable != NULL)
1246 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
1248 result = ISC_R_NOTFOUND;
1249 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
1250 result = dns_zone_getdb(zone, &db);
1251 UNLOCK(&view->lock);
1253 result = ISC_R_NOTFOUND;
1255 if (result == ISC_R_NOTFOUND) {
1257 * We're not directly authoritative for this query name, nor
1258 * is it a subdomain of any zone for which we're
1261 if (use_cache && view->cachedb != NULL) {
1263 * We have a cache; try it.
1265 dns_db_attach(view->cachedb, &db);
1268 * Maybe we have hints...
1270 try_hints = ISC_TRUE;
1273 } else if (result != ISC_R_SUCCESS) {
1275 * Something is broken.
1279 is_cache = dns_db_iscache(db);
1283 * Look for the zonecut.
1286 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options,
1287 now, NULL, fname, rdataset, sigrdataset);
1288 if (result == DNS_R_DELEGATION)
1289 result = ISC_R_SUCCESS;
1290 else if (result != ISC_R_SUCCESS)
1292 if (use_cache && view->cachedb != NULL && db != view->hints) {
1294 * We found an answer, but the cache may be better.
1296 zfname = dns_fixedname_name(&zfixedname);
1297 result = dns_name_copy(fname, zfname, NULL);
1298 if (result != ISC_R_SUCCESS)
1300 dns_rdataset_clone(rdataset, &zrdataset);
1301 dns_rdataset_disassociate(rdataset);
1302 if (sigrdataset != NULL &&
1303 dns_rdataset_isassociated(sigrdataset)) {
1304 dns_rdataset_clone(sigrdataset, &zsigrdataset);
1305 dns_rdataset_disassociate(sigrdataset);
1308 dns_db_attach(view->cachedb, &db);
1309 is_cache = ISC_TRUE;
1313 result = dns_db_findzonecut(db, name, options, now, NULL,
1314 fname, rdataset, sigrdataset);
1315 if (result == ISC_R_SUCCESS) {
1316 if (zfname != NULL &&
1317 (!dns_name_issubdomain(fname, zfname) ||
1318 (dns_zone_staticstub &&
1319 dns_name_equal(fname, zfname)))) {
1321 * We found a zonecut in the cache, but our
1322 * zone delegation is better.
1324 use_zone = ISC_TRUE;
1326 } else if (result == ISC_R_NOTFOUND) {
1327 if (zfname != NULL) {
1329 * We didn't find anything in the cache, but we
1330 * have a zone delegation, so use it.
1332 use_zone = ISC_TRUE;
1335 * Maybe we have hints...
1337 try_hints = ISC_TRUE;
1341 * Something bad happened.
1349 if (dns_rdataset_isassociated(rdataset)) {
1350 dns_rdataset_disassociate(rdataset);
1351 if (sigrdataset != NULL &&
1352 dns_rdataset_isassociated(sigrdataset))
1353 dns_rdataset_disassociate(sigrdataset);
1355 result = dns_name_copy(zfname, fname, NULL);
1356 if (result != ISC_R_SUCCESS)
1358 dns_rdataset_clone(&zrdataset, rdataset);
1359 if (sigrdataset != NULL &&
1360 dns_rdataset_isassociated(&zrdataset))
1361 dns_rdataset_clone(&zsigrdataset, sigrdataset);
1362 } else if (try_hints && use_hints && view->hints != NULL) {
1364 * We've found nothing so far, but we have hints.
1366 result = dns_db_find(view->hints, dns_rootname, NULL,
1367 dns_rdatatype_ns, 0, now, NULL, fname,
1369 if (result != ISC_R_SUCCESS) {
1371 * We can't even find the hints for the root
1374 if (dns_rdataset_isassociated(rdataset))
1375 dns_rdataset_disassociate(rdataset);
1376 result = ISC_R_NOTFOUND;
1381 if (dns_rdataset_isassociated(&zrdataset)) {
1382 dns_rdataset_disassociate(&zrdataset);
1383 if (dns_rdataset_isassociated(&zsigrdataset))
1384 dns_rdataset_disassociate(&zsigrdataset);
1390 dns_zone_detach(&zone);
1397 dns_viewlist_find(dns_viewlist_t *list, const char *name,
1398 dns_rdataclass_t rdclass, dns_view_t **viewp)
1402 REQUIRE(list != NULL);
1404 for (view = ISC_LIST_HEAD(*list);
1406 view = ISC_LIST_NEXT(view, link)) {
1407 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass)
1411 return (ISC_R_NOTFOUND);
1413 dns_view_attach(view, viewp);
1415 return (ISC_R_SUCCESS);
1420 dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
1421 isc_boolean_t allclasses, dns_rdataclass_t rdclass,
1425 isc_result_t result;
1426 dns_zone_t *zone1 = NULL, *zone2 = NULL;
1427 dns_zone_t **zp = NULL;;
1429 REQUIRE(list != NULL);
1430 REQUIRE(zonep != NULL && *zonep == NULL);
1432 for (view = ISC_LIST_HEAD(*list);
1434 view = ISC_LIST_NEXT(view, link)) {
1435 if (allclasses == ISC_FALSE && view->rdclass != rdclass)
1439 * If the zone is defined in more than one view,
1440 * treat it as not found.
1442 zp = (zone1 == NULL) ? &zone1 : &zone2;
1444 if (view->zonetable != NULL)
1445 result = dns_zt_find(view->zonetable, name, 0,
1448 result = ISC_R_NOTFOUND;
1449 UNLOCK(&view->lock);
1450 INSIST(result == ISC_R_SUCCESS ||
1451 result == ISC_R_NOTFOUND ||
1452 result == DNS_R_PARTIALMATCH);
1454 /* Treat a partial match as no match */
1455 if (result == DNS_R_PARTIALMATCH) {
1456 dns_zone_detach(zp);
1457 result = ISC_R_NOTFOUND;
1461 if (zone2 != NULL) {
1462 dns_zone_detach(&zone1);
1463 dns_zone_detach(&zone2);
1464 return (ISC_R_NOTFOUND);
1468 if (zone1 != NULL) {
1469 dns_zone_attach(zone1, zonep);
1470 dns_zone_detach(&zone1);
1471 return (ISC_R_SUCCESS);
1474 return (ISC_R_NOTFOUND);
1478 dns_view_load(dns_view_t *view, isc_boolean_t stop) {
1480 REQUIRE(DNS_VIEW_VALID(view));
1481 REQUIRE(view->zonetable != NULL);
1483 return (dns_zt_load(view->zonetable, stop));
1487 dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
1489 REQUIRE(DNS_VIEW_VALID(view));
1490 REQUIRE(view->zonetable != NULL);
1492 return (dns_zt_loadnew(view->zonetable, stop));
1496 dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) {
1497 REQUIRE(DNS_VIEW_VALID(view));
1498 REQUIRE(view->zonetable != NULL);
1500 return (dns_zt_asyncload(view->zonetable, callback, arg));
1507 dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
1509 isc_result_t result;
1510 REQUIRE(keyp != NULL && *keyp == NULL);
1512 result = dns_tsigkey_find(keyp, keyname, NULL,
1514 if (result == ISC_R_NOTFOUND)
1515 result = dns_tsigkey_find(keyp, keyname, NULL,
1521 dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
1522 dns_tsigkey_t **keyp)
1524 isc_result_t result;
1525 dns_name_t *keyname = NULL;
1526 dns_peer_t *peer = NULL;
1528 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer);
1529 if (result != ISC_R_SUCCESS)
1532 result = dns_peer_getkey(peer, &keyname);
1533 if (result != ISC_R_SUCCESS)
1536 result = dns_view_gettsig(view, keyname, keyp);
1537 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
1541 dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
1542 REQUIRE(DNS_VIEW_VALID(view));
1543 REQUIRE(source != NULL);
1545 return (dns_tsig_verify(source, msg, view->statickeys,
1546 view->dynamickeys));
1551 dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
1552 isc_result_t result;
1554 REQUIRE(DNS_VIEW_VALID(view));
1556 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name);
1557 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL,
1558 &dns_master_style_cache, fp);
1559 if (result != ISC_R_SUCCESS)
1561 dns_adb_dump(view->adb, fp);
1562 dns_resolver_printbadcache(view->resolver, fp);
1563 return (ISC_R_SUCCESS);
1568 dns_view_flushcache(dns_view_t *view) {
1569 return (dns_view_flushcache2(view, ISC_FALSE));
1573 dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
1574 isc_result_t result;
1576 REQUIRE(DNS_VIEW_VALID(view));
1578 if (view->cachedb == NULL)
1579 return (ISC_R_SUCCESS);
1581 result = dns_cache_flush(view->cache);
1582 if (result != ISC_R_SUCCESS)
1586 if (view->acache != NULL)
1587 dns_acache_putdb(view->acache, view->cachedb);
1589 dns_db_detach(&view->cachedb);
1590 dns_cache_attachdb(view->cache, &view->cachedb);
1592 if (view->acache != NULL)
1593 dns_acache_setdb(view->acache, view->cachedb);
1594 if (view->resolver != NULL)
1595 dns_resolver_flushbadcache(view->resolver, NULL);
1598 dns_adb_flush(view->adb);
1599 return (ISC_R_SUCCESS);
1603 dns_view_flushname(dns_view_t *view, dns_name_t *name) {
1604 return (dns_view_flushnode(view, name, ISC_FALSE));
1608 dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) {
1610 REQUIRE(DNS_VIEW_VALID(view));
1613 if (view->adb != NULL)
1614 dns_adb_flushname(view->adb, name);
1615 if (view->cache == NULL)
1616 return (ISC_R_SUCCESS);
1617 if (view->resolver != NULL)
1618 dns_resolver_flushbadcache(view->resolver, name);
1620 return (dns_cache_flushnode(view->cache, name, tree));
1624 dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) {
1625 isc_result_t result;
1629 REQUIRE(DNS_VIEW_VALID(view));
1631 if (view->delonly == NULL) {
1632 view->delonly = isc_mem_get(view->mctx,
1633 sizeof(dns_namelist_t) *
1634 DNS_VIEW_DELONLYHASH);
1635 if (view->delonly == NULL)
1636 return (ISC_R_NOMEMORY);
1637 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
1638 ISC_LIST_INIT(view->delonly[hash]);
1640 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1641 new = ISC_LIST_HEAD(view->delonly[hash]);
1642 while (new != NULL && !dns_name_equal(new, name))
1643 new = ISC_LIST_NEXT(new, link);
1645 return (ISC_R_SUCCESS);
1646 new = isc_mem_get(view->mctx, sizeof(*new));
1648 return (ISC_R_NOMEMORY);
1649 dns_name_init(new, NULL);
1650 result = dns_name_dup(name, view->mctx, new);
1651 if (result == ISC_R_SUCCESS)
1652 ISC_LIST_APPEND(view->delonly[hash], new, link);
1654 isc_mem_put(view->mctx, new, sizeof(*new));
1659 dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) {
1660 isc_result_t result;
1664 REQUIRE(DNS_VIEW_VALID(view));
1666 if (view->rootexclude == NULL) {
1667 view->rootexclude = isc_mem_get(view->mctx,
1668 sizeof(dns_namelist_t) *
1669 DNS_VIEW_DELONLYHASH);
1670 if (view->rootexclude == NULL)
1671 return (ISC_R_NOMEMORY);
1672 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
1673 ISC_LIST_INIT(view->rootexclude[hash]);
1675 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1676 new = ISC_LIST_HEAD(view->rootexclude[hash]);
1677 while (new != NULL && !dns_name_equal(new, name))
1678 new = ISC_LIST_NEXT(new, link);
1680 return (ISC_R_SUCCESS);
1681 new = isc_mem_get(view->mctx, sizeof(*new));
1683 return (ISC_R_NOMEMORY);
1684 dns_name_init(new, NULL);
1685 result = dns_name_dup(name, view->mctx, new);
1686 if (result == ISC_R_SUCCESS)
1687 ISC_LIST_APPEND(view->rootexclude[hash], new, link);
1689 isc_mem_put(view->mctx, new, sizeof(*new));
1694 dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) {
1698 REQUIRE(DNS_VIEW_VALID(view));
1700 if (!view->rootdelonly && view->delonly == NULL)
1703 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1704 if (view->rootdelonly && dns_name_countlabels(name) <= 2) {
1705 if (view->rootexclude == NULL)
1707 new = ISC_LIST_HEAD(view->rootexclude[hash]);
1708 while (new != NULL && !dns_name_equal(new, name))
1709 new = ISC_LIST_NEXT(new, link);
1714 if (view->delonly == NULL)
1717 new = ISC_LIST_HEAD(view->delonly[hash]);
1718 while (new != NULL && !dns_name_equal(new, name))
1719 new = ISC_LIST_NEXT(new, link);
1726 dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) {
1727 REQUIRE(DNS_VIEW_VALID(view));
1728 view->rootdelonly = value;
1732 dns_view_getrootdelonly(dns_view_t *view) {
1733 REQUIRE(DNS_VIEW_VALID(view));
1734 return (view->rootdelonly);
1739 dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
1741 REQUIRE(DNS_VIEW_VALID(view));
1742 REQUIRE(view->zonetable != NULL);
1744 return (dns_zt_freezezones(view->zonetable, value));
1749 dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) {
1751 REQUIRE(DNS_VIEW_VALID(view));
1752 REQUIRE(!view->frozen);
1753 REQUIRE(view->resstats == NULL);
1755 isc_stats_attach(stats, &view->resstats);
1759 dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) {
1760 REQUIRE(DNS_VIEW_VALID(view));
1761 REQUIRE(statsp != NULL && *statsp == NULL);
1763 if (view->resstats != NULL)
1764 isc_stats_attach(view->resstats, statsp);
1768 dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) {
1769 REQUIRE(DNS_VIEW_VALID(view));
1770 REQUIRE(!view->frozen);
1771 REQUIRE(view->resquerystats == NULL);
1773 dns_stats_attach(stats, &view->resquerystats);
1777 dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
1778 REQUIRE(DNS_VIEW_VALID(view));
1779 REQUIRE(statsp != NULL && *statsp == NULL);
1781 if (view->resquerystats != NULL)
1782 dns_stats_attach(view->resquerystats, statsp);
1786 dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) {
1787 REQUIRE(DNS_VIEW_VALID(view));
1788 if (view->secroots_priv != NULL)
1789 dns_keytable_detach(&view->secroots_priv);
1790 return (dns_keytable_create(mctx, &view->secroots_priv));
1794 dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) {
1795 REQUIRE(DNS_VIEW_VALID(view));
1796 REQUIRE(ktp != NULL && *ktp == NULL);
1797 if (view->secroots_priv == NULL)
1798 return (ISC_R_NOTFOUND);
1799 dns_keytable_attach(view->secroots_priv, ktp);
1800 return (ISC_R_SUCCESS);
1804 dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
1805 isc_boolean_t *secure_domain) {
1806 REQUIRE(DNS_VIEW_VALID(view));
1808 if (view->secroots_priv == NULL)
1809 return (ISC_R_NOTFOUND);
1810 return (dns_keytable_issecuredomain(view->secroots_priv, name,
1815 dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
1816 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
1818 isc_result_t result;
1819 unsigned char data[4096];
1820 dns_rdata_t rdata = DNS_RDATA_INIT;
1821 isc_buffer_t buffer;
1822 dst_key_t *key = NULL;
1823 dns_keytable_t *sr = NULL;
1826 * Clear the revoke bit, if set, so that the key will match what's
1829 dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
1831 /* Convert dnskey to DST key. */
1832 isc_buffer_init(&buffer, data, sizeof(data));
1833 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
1834 dns_rdatatype_dnskey, dnskey, &buffer);
1835 result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key);
1836 if (result != ISC_R_SUCCESS)
1838 result = dns_view_getsecroots(view, &sr);
1839 if (result == ISC_R_SUCCESS) {
1840 dns_keytable_deletekeynode(sr, key);
1841 dns_keytable_detach(&sr);
1849 dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
1850 void (*cfg_destroy)(void **))
1852 REQUIRE(DNS_VIEW_VALID(view));
1853 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow);
1856 if (view->new_zone_file != NULL) {
1857 isc_mem_free(view->mctx, view->new_zone_file);
1858 view->new_zone_file = NULL;
1861 if (view->new_zone_config != NULL) {
1862 view->cfg_destroy(&view->new_zone_config);
1863 view->cfg_destroy = NULL;
1867 char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)];
1868 isc_sha256_data((void *)view->name, strlen(view->name), buffer);
1869 /* Truncate the hash at 16 chars; full length is overkill */
1870 isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF);
1871 view->new_zone_file = isc_mem_strdup(view->mctx, buffer);
1872 view->new_zone_config = cfgctx;
1873 view->cfg_destroy = cfg_destroy;
1878 UNUSED(cfg_destroy);