2 * Copyright (C) 2004-2016 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.
24 #include <isc/print.h>
26 #include <isc/stats.h>
27 #include <isc/string.h> /* Required for HP/UX (and others?) */
31 #include <dns/acache.h>
34 #include <dns/cache.h>
36 #include <dns/dispatch.h>
39 #include <dns/dns64.h>
41 #include <dns/dnssec.h>
42 #include <dns/events.h>
43 #include <dns/forward.h>
44 #include <dns/keytable.h>
45 #include <dns/keyvalues.h>
46 #include <dns/master.h>
47 #include <dns/masterdump.h>
48 #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);
91 isc_mem_attach(mctx, &view->mctx);
92 view->name = isc_mem_strdup(mctx, name);
93 if (view->name == NULL) {
94 result = ISC_R_NOMEMORY;
97 result = isc_mutex_init(&view->lock);
98 if (result != ISC_R_SUCCESS)
101 view->zonetable = NULL;
103 result = dns_zt_create(mctx, rdclass, &view->zonetable);
104 if (result != ISC_R_SUCCESS) {
105 UNEXPECTED_ERROR(__FILE__, __LINE__,
106 "dns_zt_create() failed: %s",
107 isc_result_totext(result));
108 result = ISC_R_UNEXPECTED;
112 view->secroots_priv = NULL;
113 view->fwdtable = NULL;
114 result = dns_fwdtable_create(mctx, &view->fwdtable);
115 if (result != ISC_R_SUCCESS) {
116 UNEXPECTED_ERROR(__FILE__, __LINE__,
117 "dns_fwdtable_create() failed: %s",
118 isc_result_totext(result));
119 result = ISC_R_UNEXPECTED;
125 view->cachedb = NULL;
126 view->dlzdatabase = NULL;
128 view->resolver = NULL;
130 view->requestmgr = NULL;
131 view->rdclass = rdclass;
132 view->frozen = ISC_FALSE;
134 result = isc_refcount_init(&view->references, 1);
135 if (result != ISC_R_SUCCESS)
136 goto cleanup_fwdtable;
138 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
139 DNS_VIEWATTR_REQSHUTDOWN);
140 view->statickeys = NULL;
141 view->dynamickeys = NULL;
142 view->matchclients = NULL;
143 view->matchdestinations = NULL;
144 view->matchrecursiveonly = ISC_FALSE;
145 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
146 if (result != ISC_R_SUCCESS)
147 goto cleanup_references;
150 view->delonly = NULL;
151 view->rootdelonly = ISC_FALSE;
152 view->rootexclude = NULL;
153 view->resstats = NULL;
154 view->resquerystats = NULL;
155 view->cacheshared = ISC_FALSE;
156 ISC_LIST_INIT(view->dns64);
160 * Initialize configuration data with default values.
162 view->recursion = ISC_TRUE;
163 view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
164 view->additionalfromcache = ISC_TRUE;
165 view->additionalfromauth = ISC_TRUE;
166 view->enablednssec = ISC_TRUE;
167 view->enablevalidation = ISC_TRUE;
168 view->acceptexpired = ISC_FALSE;
169 view->minimalresponses = ISC_FALSE;
170 view->transfer_format = dns_one_answer;
171 view->cacheacl = NULL;
172 view->cacheonacl = NULL;
173 view->queryacl = NULL;
174 view->queryonacl = NULL;
175 view->recursionacl = NULL;
176 view->recursiononacl = NULL;
177 view->sortlist = NULL;
178 view->transferacl = NULL;
179 view->notifyacl = NULL;
180 view->updateacl = NULL;
181 view->upfwdacl = NULL;
182 view->denyansweracl = NULL;
183 view->nocasecompress = NULL;
184 view->answeracl_exclude = NULL;
185 view->denyanswernames = NULL;
186 view->answernames_exclude = NULL;
188 view->provideixfr = ISC_TRUE;
189 view->maxcachettl = 7 * 24 * 3600;
190 view->maxncachettl = 3 * 3600;
192 view->preferred_glue = 0;
193 view->flush = ISC_FALSE;
197 view->v4_aaaa = dns_v4_aaaa_ok;
198 view->v4_aaaa_acl = NULL;
199 ISC_LIST_INIT(view->rpz_zones);
200 view->rpz_recursive_only = ISC_TRUE;
201 view->rpz_break_dnssec = ISC_FALSE;
202 dns_fixedname_init(&view->dlv_fixed);
203 view->managed_keys = NULL;
204 view->redirect = NULL;
206 view->new_zone_file = NULL;
207 view->new_zone_config = NULL;
208 view->cfg_destroy = NULL;
210 result = dns_order_create(view->mctx, &view->order);
211 if (result != ISC_R_SUCCESS)
212 goto cleanup_dynkeys;
215 result = dns_peerlist_new(view->mctx, &view->peers);
216 if (result != ISC_R_SUCCESS)
219 result = dns_aclenv_init(view->mctx, &view->aclenv);
220 if (result != ISC_R_SUCCESS)
221 goto cleanup_peerlist;
223 ISC_LINK_INIT(view, link);
224 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
225 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
226 view, NULL, NULL, NULL);
227 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
228 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
229 view, NULL, NULL, NULL);
230 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
231 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
232 view, NULL, NULL, NULL);
233 view->viewlist = NULL;
234 view->magic = DNS_VIEW_MAGIC;
238 return (ISC_R_SUCCESS);
241 dns_peerlist_detach(&view->peers);
245 dns_order_detach(&view->order);
249 dns_tsigkeyring_detach(&view->dynamickeys);
252 isc_refcount_destroy(&view->references);
255 dns_fwdtable_destroy(&view->fwdtable);
259 dns_zt_detach(&view->zonetable);
263 DESTROYLOCK(&view->lock);
266 isc_mem_free(mctx, view->name);
269 isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
275 destroy(dns_view_t *view) {
280 REQUIRE(!ISC_LINK_LINKED(view, link));
281 REQUIRE(isc_refcount_current(&view->references) == 0);
282 REQUIRE(view->weakrefs == 0);
283 REQUIRE(RESSHUTDOWN(view));
284 REQUIRE(ADBSHUTDOWN(view));
285 REQUIRE(REQSHUTDOWN(view));
288 if (view->order != NULL)
289 dns_order_detach(&view->order);
291 if (view->peers != NULL)
292 dns_peerlist_detach(&view->peers);
294 if (view->dynamickeys != NULL) {
301 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
303 if (n > 0 && (size_t)n < sizeof(keyfile)) {
304 result = isc_file_mktemplate(keyfile, template,
306 if (result == ISC_R_SUCCESS)
307 (void)isc_file_openuniqueprivate(template, &fp);
310 dns_tsigkeyring_detach(&view->dynamickeys);
312 result = dns_tsigkeyring_dumpanddetach(
313 &view->dynamickeys, fp);
314 if (result == ISC_R_SUCCESS) {
316 result = isc_file_rename(template,
318 if (result != ISC_R_SUCCESS)
319 (void)remove(template);
322 (void)remove(template);
326 if (view->statickeys != NULL)
327 dns_tsigkeyring_detach(&view->statickeys);
328 if (view->adb != NULL)
329 dns_adb_detach(&view->adb);
330 if (view->resolver != NULL)
331 dns_resolver_detach(&view->resolver);
333 if (view->acache != NULL) {
334 if (view->cachedb != NULL)
335 dns_acache_putdb(view->acache, view->cachedb);
336 dns_acache_detach(&view->acache);
338 dns_rpz_view_destroy(view);
340 dns_rrl_view_destroy(view);
342 INSIST(view->rrl == NULL);
345 INSIST(view->acache == NULL);
346 INSIST(ISC_LIST_EMPTY(view->rpz_zones));
347 INSIST(view->rrl == NULL);
349 if (view->requestmgr != NULL)
350 dns_requestmgr_detach(&view->requestmgr);
351 if (view->task != NULL)
352 isc_task_detach(&view->task);
353 if (view->hints != NULL)
354 dns_db_detach(&view->hints);
355 if (view->dlzdatabase != NULL)
356 dns_dlzdestroy(&view->dlzdatabase);
357 if (view->cachedb != NULL)
358 dns_db_detach(&view->cachedb);
359 if (view->cache != NULL)
360 dns_cache_detach(&view->cache);
361 if (view->nocasecompress != NULL)
362 dns_acl_detach(&view->nocasecompress);
363 if (view->matchclients != NULL)
364 dns_acl_detach(&view->matchclients);
365 if (view->matchdestinations != NULL)
366 dns_acl_detach(&view->matchdestinations);
367 if (view->cacheacl != NULL)
368 dns_acl_detach(&view->cacheacl);
369 if (view->cacheonacl != NULL)
370 dns_acl_detach(&view->cacheonacl);
371 if (view->queryacl != NULL)
372 dns_acl_detach(&view->queryacl);
373 if (view->queryonacl != NULL)
374 dns_acl_detach(&view->queryonacl);
375 if (view->recursionacl != NULL)
376 dns_acl_detach(&view->recursionacl);
377 if (view->recursiononacl != NULL)
378 dns_acl_detach(&view->recursiononacl);
379 if (view->sortlist != NULL)
380 dns_acl_detach(&view->sortlist);
381 if (view->transferacl != NULL)
382 dns_acl_detach(&view->transferacl);
383 if (view->notifyacl != NULL)
384 dns_acl_detach(&view->notifyacl);
385 if (view->updateacl != NULL)
386 dns_acl_detach(&view->updateacl);
387 if (view->upfwdacl != NULL)
388 dns_acl_detach(&view->upfwdacl);
389 if (view->denyansweracl != NULL)
390 dns_acl_detach(&view->denyansweracl);
391 if (view->v4_aaaa_acl != NULL)
392 dns_acl_detach(&view->v4_aaaa_acl);
393 if (view->answeracl_exclude != NULL)
394 dns_rbt_destroy(&view->answeracl_exclude);
395 if (view->denyanswernames != NULL)
396 dns_rbt_destroy(&view->denyanswernames);
397 if (view->answernames_exclude != NULL)
398 dns_rbt_destroy(&view->answernames_exclude);
399 if (view->delonly != NULL) {
403 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
404 name = ISC_LIST_HEAD(view->delonly[i]);
405 while (name != NULL) {
406 ISC_LIST_UNLINK(view->delonly[i], name, link);
407 dns_name_free(name, view->mctx);
408 isc_mem_put(view->mctx, name, sizeof(*name));
409 name = ISC_LIST_HEAD(view->delonly[i]);
412 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) *
413 DNS_VIEW_DELONLYHASH);
414 view->delonly = NULL;
416 if (view->rootexclude != NULL) {
420 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
421 name = ISC_LIST_HEAD(view->rootexclude[i]);
422 while (name != NULL) {
423 ISC_LIST_UNLINK(view->rootexclude[i],
425 dns_name_free(name, view->mctx);
426 isc_mem_put(view->mctx, name, sizeof(*name));
427 name = ISC_LIST_HEAD(view->rootexclude[i]);
430 isc_mem_put(view->mctx, view->rootexclude,
431 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
432 view->rootexclude = NULL;
434 if (view->resstats != NULL)
435 isc_stats_detach(&view->resstats);
436 if (view->resquerystats != NULL)
437 dns_stats_detach(&view->resquerystats);
438 if (view->secroots_priv != NULL)
439 dns_keytable_detach(&view->secroots_priv);
441 for (dns64 = ISC_LIST_HEAD(view->dns64);
443 dns64 = ISC_LIST_HEAD(view->dns64)) {
444 dns_dns64_unlink(&view->dns64, dns64);
445 dns_dns64_destroy(&dns64);
447 if (view->managed_keys != NULL)
448 dns_zone_detach(&view->managed_keys);
449 if (view->redirect != NULL)
450 dns_zone_detach(&view->redirect);
451 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
453 dns_fwdtable_destroy(&view->fwdtable);
454 dns_aclenv_destroy(&view->aclenv);
455 DESTROYLOCK(&view->lock);
456 isc_refcount_destroy(&view->references);
457 isc_mem_free(view->mctx, view->name);
458 isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
462 * Return true iff 'view' may be freed.
463 * The caller must be holding the view lock.
466 all_done(dns_view_t *view) {
468 if (isc_refcount_current(&view->references) == 0 &&
469 view->weakrefs == 0 &&
470 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
477 dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
479 REQUIRE(DNS_VIEW_VALID(source));
480 REQUIRE(targetp != NULL && *targetp == NULL);
482 isc_refcount_increment(&source->references, NULL);
488 view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
491 isc_boolean_t done = ISC_FALSE;
493 REQUIRE(viewp != NULL);
495 REQUIRE(DNS_VIEW_VALID(view));
498 view->flush = ISC_TRUE;
499 isc_refcount_decrement(&view->references, &refs);
502 dns_zone_t *mkzone = NULL, *rdzone = NULL;
506 if (!RESSHUTDOWN(view))
507 dns_resolver_shutdown(view->resolver);
508 if (!ADBSHUTDOWN(view))
509 dns_adb_shutdown(view->adb);
510 if (!REQSHUTDOWN(view))
511 dns_requestmgr_shutdown(view->requestmgr);
513 if (view->acache != NULL)
514 dns_acache_shutdown(view->acache);
516 dns_zt_flushanddetach(&view->zonetable);
518 dns_zt_detach(&view->zonetable);
519 if (view->managed_keys != NULL) {
520 mkzone = view->managed_keys;
521 view->managed_keys = NULL;
523 dns_zone_flush(mkzone);
525 if (view->redirect != NULL) {
526 rdzone = view->redirect;
527 view->redirect = NULL;
529 dns_zone_flush(rdzone);
532 done = all_done(view);
536 /* Need to detach zones outside view lock */
538 dns_zone_detach(&mkzone);
541 dns_zone_detach(&rdzone);
552 dns_view_flushanddetach(dns_view_t **viewp) {
553 view_flushanddetach(viewp, ISC_TRUE);
557 dns_view_detach(dns_view_t **viewp) {
558 view_flushanddetach(viewp, ISC_FALSE);
563 dialup(dns_zone_t *zone, void *dummy) {
565 dns_zone_dialup(zone);
566 return (ISC_R_SUCCESS);
570 dns_view_dialup(dns_view_t *view) {
571 REQUIRE(DNS_VIEW_VALID(view));
572 REQUIRE(view->zonetable != NULL);
574 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL);
579 dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
581 REQUIRE(DNS_VIEW_VALID(source));
582 REQUIRE(targetp != NULL && *targetp == NULL);
586 UNLOCK(&source->lock);
592 dns_view_weakdetach(dns_view_t **viewp) {
594 isc_boolean_t done = ISC_FALSE;
596 REQUIRE(viewp != NULL);
598 REQUIRE(DNS_VIEW_VALID(view));
602 INSIST(view->weakrefs > 0);
604 done = all_done(view);
615 resolver_shutdown(isc_task_t *task, isc_event_t *event) {
616 dns_view_t *view = event->ev_arg;
619 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
620 REQUIRE(DNS_VIEW_VALID(view));
621 REQUIRE(view->task == task);
625 isc_event_free(&event);
629 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
630 done = all_done(view);
639 adb_shutdown(isc_task_t *task, isc_event_t *event) {
640 dns_view_t *view = event->ev_arg;
643 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
644 REQUIRE(DNS_VIEW_VALID(view));
645 REQUIRE(view->task == task);
649 isc_event_free(&event);
653 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
654 done = all_done(view);
663 req_shutdown(isc_task_t *task, isc_event_t *event) {
664 dns_view_t *view = event->ev_arg;
667 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
668 REQUIRE(DNS_VIEW_VALID(view));
669 REQUIRE(view->task == task);
673 isc_event_free(&event);
677 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
678 done = all_done(view);
687 dns_view_createresolver(dns_view_t *view,
688 isc_taskmgr_t *taskmgr,
691 isc_socketmgr_t *socketmgr,
692 isc_timermgr_t *timermgr,
693 unsigned int options,
694 dns_dispatchmgr_t *dispatchmgr,
695 dns_dispatch_t *dispatchv4,
696 dns_dispatch_t *dispatchv6)
700 isc_mem_t *mctx = NULL;
702 REQUIRE(DNS_VIEW_VALID(view));
703 REQUIRE(!view->frozen);
704 REQUIRE(view->resolver == NULL);
706 result = isc_task_create(taskmgr, 0, &view->task);
707 if (result != ISC_R_SUCCESS)
709 isc_task_setname(view->task, "view", view);
711 result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
712 timermgr, options, dispatchmgr,
713 dispatchv4, dispatchv6,
715 if (result != ISC_R_SUCCESS) {
716 isc_task_detach(&view->task);
719 event = &view->resevent;
720 dns_resolver_whenshutdown(view->resolver, view->task, &event);
721 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
723 result = isc_mem_create(0, 0, &mctx);
724 if (result != ISC_R_SUCCESS) {
725 dns_resolver_shutdown(view->resolver);
729 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb);
730 isc_mem_setname(mctx, "ADB", NULL);
731 isc_mem_detach(&mctx);
732 if (result != ISC_R_SUCCESS) {
733 dns_resolver_shutdown(view->resolver);
736 event = &view->adbevent;
737 dns_adb_whenshutdown(view->adb, view->task, &event);
738 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
740 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
741 dns_resolver_taskmgr(view->resolver),
742 dns_resolver_dispatchmgr(view->resolver),
743 dispatchv4, dispatchv6,
745 if (result != ISC_R_SUCCESS) {
746 dns_adb_shutdown(view->adb);
747 dns_resolver_shutdown(view->resolver);
750 event = &view->reqevent;
751 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
752 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
754 return (ISC_R_SUCCESS);
758 dns_view_setcache(dns_view_t *view, dns_cache_t *cache) {
759 dns_view_setcache2(view, cache, ISC_FALSE);
763 dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
764 REQUIRE(DNS_VIEW_VALID(view));
765 REQUIRE(!view->frozen);
767 view->cacheshared = shared;
768 if (view->cache != NULL) {
770 if (view->acache != NULL)
771 dns_acache_putdb(view->acache, view->cachedb);
773 dns_db_detach(&view->cachedb);
774 dns_cache_detach(&view->cache);
776 dns_cache_attach(cache, &view->cache);
777 dns_cache_attachdb(cache, &view->cachedb);
778 INSIST(DNS_DB_VALID(view->cachedb));
781 if (view->acache != NULL)
782 dns_acache_setdb(view->acache, view->cachedb);
787 dns_view_iscacheshared(dns_view_t *view) {
788 REQUIRE(DNS_VIEW_VALID(view));
790 return (view->cacheshared);
794 dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
795 REQUIRE(DNS_VIEW_VALID(view));
796 REQUIRE(!view->frozen);
797 REQUIRE(view->hints == NULL);
798 REQUIRE(dns_db_iszone(hints));
800 dns_db_attach(hints, &view->hints);
804 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
805 REQUIRE(DNS_VIEW_VALID(view));
806 REQUIRE(ring != NULL);
807 if (view->statickeys != NULL)
808 dns_tsigkeyring_detach(&view->statickeys);
809 dns_tsigkeyring_attach(ring, &view->statickeys);
813 dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
814 REQUIRE(DNS_VIEW_VALID(view));
815 REQUIRE(ring != NULL);
816 if (view->dynamickeys != NULL)
817 dns_tsigkeyring_detach(&view->dynamickeys);
818 dns_tsigkeyring_attach(ring, &view->dynamickeys);
822 dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) {
823 REQUIRE(DNS_VIEW_VALID(view));
824 REQUIRE(ringp != NULL && *ringp == NULL);
825 if (view->dynamickeys != NULL)
826 dns_tsigkeyring_attach(view->dynamickeys, ringp);
830 dns_view_restorekeyring(dns_view_t *view) {
835 REQUIRE(DNS_VIEW_VALID(view));
837 if (view->dynamickeys != NULL) {
838 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
840 if (n > 0 && (size_t)n < sizeof(keyfile)) {
841 fp = fopen(keyfile, "r");
843 dns_keyring_restore(view->dynamickeys, fp);
851 dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
852 REQUIRE(DNS_VIEW_VALID(view));
853 view->dstport = dstport;
857 dns_view_freeze(dns_view_t *view) {
858 REQUIRE(DNS_VIEW_VALID(view));
859 REQUIRE(!view->frozen);
861 if (view->resolver != NULL) {
862 INSIST(view->cachedb != NULL);
863 dns_resolver_freeze(view->resolver);
865 view->frozen = ISC_TRUE;
870 dns_view_thaw(dns_view_t *view) {
871 REQUIRE(DNS_VIEW_VALID(view));
872 REQUIRE(view->frozen);
874 view->frozen = ISC_FALSE;
878 dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
881 REQUIRE(DNS_VIEW_VALID(view));
882 REQUIRE(!view->frozen);
883 REQUIRE(view->zonetable != NULL);
885 result = dns_zt_mount(view->zonetable, zone);
893 dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
896 REQUIRE(DNS_VIEW_VALID(view));
899 if (view->zonetable != NULL) {
900 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep);
901 if (result == DNS_R_PARTIALMATCH) {
902 dns_zone_detach(zonep);
903 result = ISC_R_NOTFOUND;
906 result = ISC_R_NOTFOUND;
914 dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
915 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints,
916 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
917 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
918 return (dns_view_find2(view, name, type, now, options, use_hints,
919 ISC_FALSE, dbp, nodep, foundname, rdataset,
924 dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
925 isc_stdtime_t now, unsigned int options,
926 isc_boolean_t use_hints, isc_boolean_t use_static_stub,
927 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
928 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
932 dns_dbnode_t *node, *znode;
933 isc_boolean_t is_cache, is_staticstub_zone;
934 dns_rdataset_t zrdataset, zsigrdataset;
939 UNUSED(use_static_stub);
944 * Find an rdataset whose owner name is 'name', and whose type is
948 REQUIRE(DNS_VIEW_VALID(view));
949 REQUIRE(view->frozen);
950 REQUIRE(type != dns_rdatatype_rrsig);
951 REQUIRE(rdataset != NULL); /* XXXBEW - remove this */
952 REQUIRE(nodep == NULL || *nodep == NULL);
957 dns_rdataset_init(&zrdataset);
958 dns_rdataset_init(&zsigrdataset);
963 * Find a database to answer the query.
967 is_staticstub_zone = ISC_FALSE;
971 if (view->zonetable != NULL)
972 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
974 result = ISC_R_NOTFOUND;
976 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
978 result = ISC_R_NOTFOUND;
980 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
981 result = dns_zone_getdb(zone, &db);
982 if (result != ISC_R_SUCCESS && view->cachedb != NULL)
983 dns_db_attach(view->cachedb, &db);
984 else if (result != ISC_R_SUCCESS)
986 if (dns_zone_gettype(zone) == dns_zone_staticstub &&
987 dns_name_equal(name, dns_zone_getorigin(zone))) {
988 is_staticstub_zone = ISC_TRUE;
990 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
991 dns_db_attach(view->cachedb, &db);
993 result = ISC_R_NOTFOUND;
994 if (view->cachedb != NULL)
995 dns_db_attach(view->cachedb, &db);
1000 is_cache = dns_db_iscache(db);
1004 * Now look for an answer in the database.
1006 result = dns_db_find(db, name, NULL, type, options,
1007 now, &node, foundname, rdataset, sigrdataset);
1009 if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) {
1010 if (dns_rdataset_isassociated(rdataset))
1011 dns_rdataset_disassociate(rdataset);
1012 if (sigrdataset != NULL &&
1013 dns_rdataset_isassociated(sigrdataset))
1014 dns_rdataset_disassociate(sigrdataset);
1016 dns_db_detachnode(db, &node);
1019 if (view->cachedb != NULL && !is_staticstub_zone) {
1021 * Either the answer is in the cache, or we
1023 * Note that if the result comes from a
1024 * static-stub zone we stop the search here
1025 * (see the function description in view.h).
1027 is_cache = ISC_TRUE;
1028 dns_db_attach(view->cachedb, &db);
1033 * We don't have the data in the cache. If we've got
1034 * glue from the zone, use it.
1036 if (dns_rdataset_isassociated(&zrdataset)) {
1037 dns_rdataset_clone(&zrdataset, rdataset);
1038 if (sigrdataset != NULL &&
1039 dns_rdataset_isassociated(&zsigrdataset))
1040 dns_rdataset_clone(&zsigrdataset,
1042 result = DNS_R_GLUE;
1045 dns_db_attach(zdb, &db);
1046 dns_db_attachnode(db, znode, &node);
1051 * We don't know the answer.
1053 result = ISC_R_NOTFOUND;
1054 } else if (result == DNS_R_GLUE) {
1055 if (view->cachedb != NULL && !is_staticstub_zone) {
1057 * We found an answer, but the cache may be better.
1058 * Remember what we've got and go look in the cache.
1060 is_cache = ISC_TRUE;
1061 dns_rdataset_clone(rdataset, &zrdataset);
1062 dns_rdataset_disassociate(rdataset);
1063 if (sigrdataset != NULL &&
1064 dns_rdataset_isassociated(sigrdataset)) {
1065 dns_rdataset_clone(sigrdataset, &zsigrdataset);
1066 dns_rdataset_disassociate(sigrdataset);
1068 dns_db_attach(db, &zdb);
1069 dns_db_attachnode(zdb, node, &znode);
1070 dns_db_detachnode(db, &node);
1072 dns_db_attach(view->cachedb, &db);
1076 * Otherwise, the glue is the best answer.
1078 result = ISC_R_SUCCESS;
1082 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) {
1083 if (dns_rdataset_isassociated(rdataset))
1084 dns_rdataset_disassociate(rdataset);
1085 if (sigrdataset != NULL &&
1086 dns_rdataset_isassociated(sigrdataset))
1087 dns_rdataset_disassociate(sigrdataset);
1090 dns_db_detachnode(db, &node);
1093 result = dns_db_find(view->hints, name, NULL, type, options,
1094 now, &node, foundname,
1095 rdataset, sigrdataset);
1096 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) {
1098 * We just used a hint. Let the resolver know it
1099 * should consider priming.
1101 dns_resolver_prime(view->resolver);
1102 dns_db_attach(view->hints, &db);
1103 result = DNS_R_HINT;
1104 } else if (result == DNS_R_NXRRSET) {
1105 dns_db_attach(view->hints, &db);
1106 result = DNS_R_HINTNXRRSET;
1107 } else if (result == DNS_R_NXDOMAIN)
1108 result = ISC_R_NOTFOUND;
1111 * Cleanup if non-standard hints are used.
1113 if (db == NULL && node != NULL)
1114 dns_db_detachnode(view->hints, &node);
1119 if (dns_rdataset_isassociated(&zrdataset)) {
1120 dns_rdataset_disassociate(&zrdataset);
1121 if (dns_rdataset_isassociated(&zsigrdataset))
1122 dns_rdataset_disassociate(&zsigrdataset);
1127 dns_db_detachnode(zdb, &znode);
1128 dns_db_detach(&zdb);
1136 dns_db_detachnode(db, &node);
1143 INSIST(node == NULL);
1147 dns_zone_detach(&zone);
1154 dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
1155 isc_stdtime_t now, unsigned int options,
1156 isc_boolean_t use_hints,
1157 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1159 isc_result_t result;
1160 dns_fixedname_t foundname;
1162 dns_fixedname_init(&foundname);
1163 result = dns_view_find(view, name, type, now, options, use_hints,
1164 NULL, NULL, dns_fixedname_name(&foundname),
1165 rdataset, sigrdataset);
1166 if (result == DNS_R_NXDOMAIN) {
1168 * The rdataset and sigrdataset of the relevant NSEC record
1169 * may be returned, but the caller cannot use them because
1170 * foundname is not returned by this simplified API. We
1171 * disassociate them here to prevent any misuse by the caller.
1173 if (dns_rdataset_isassociated(rdataset))
1174 dns_rdataset_disassociate(rdataset);
1175 if (sigrdataset != NULL &&
1176 dns_rdataset_isassociated(sigrdataset))
1177 dns_rdataset_disassociate(sigrdataset);
1178 } else if (result != ISC_R_SUCCESS &&
1179 result != DNS_R_GLUE &&
1180 result != DNS_R_HINT &&
1181 result != DNS_R_NCACHENXDOMAIN &&
1182 result != DNS_R_NCACHENXRRSET &&
1183 result != DNS_R_NXRRSET &&
1184 result != DNS_R_HINTNXRRSET &&
1185 result != ISC_R_NOTFOUND) {
1186 if (dns_rdataset_isassociated(rdataset))
1187 dns_rdataset_disassociate(rdataset);
1188 if (sigrdataset != NULL &&
1189 dns_rdataset_isassociated(sigrdataset))
1190 dns_rdataset_disassociate(sigrdataset);
1191 result = ISC_R_NOTFOUND;
1198 dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
1199 isc_stdtime_t now, unsigned int options,
1200 isc_boolean_t use_hints,
1201 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1203 return(dns_view_findzonecut2(view, name, fname, now, options,
1204 use_hints, ISC_TRUE,
1205 rdataset, sigrdataset));
1209 dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
1210 isc_stdtime_t now, unsigned int options,
1211 isc_boolean_t use_hints, isc_boolean_t use_cache,
1212 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1214 isc_result_t result;
1216 isc_boolean_t is_cache, use_zone, try_hints;
1219 dns_rdataset_t zrdataset, zsigrdataset;
1220 dns_fixedname_t zfixedname;
1222 unsigned int ztoptions = 0;
1229 REQUIRE(DNS_VIEW_VALID(view));
1230 REQUIRE(view->frozen);
1233 use_zone = ISC_FALSE;
1234 try_hints = ISC_FALSE;
1240 dns_fixedname_init(&zfixedname);
1241 dns_rdataset_init(&zrdataset);
1242 dns_rdataset_init(&zsigrdataset);
1245 * Find the right database.
1250 if (view->zonetable != NULL) {
1251 if ((options & DNS_DBFIND_NOEXACT) != 0)
1252 ztoptions |= DNS_ZTFIND_NOEXACT;
1253 result = dns_zt_find(view->zonetable, name, ztoptions,
1256 result = ISC_R_NOTFOUND;
1257 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
1258 result = dns_zone_getdb(zone, &db);
1259 UNLOCK(&view->lock);
1261 result = ISC_R_NOTFOUND;
1263 if (result == ISC_R_NOTFOUND) {
1265 * We're not directly authoritative for this query name, nor
1266 * is it a subdomain of any zone for which we're
1269 if (use_cache && view->cachedb != NULL) {
1271 * We have a cache; try it.
1273 dns_db_attach(view->cachedb, &db);
1276 * Maybe we have hints...
1278 try_hints = ISC_TRUE;
1281 } else if (result != ISC_R_SUCCESS) {
1283 * Something is broken.
1287 is_cache = dns_db_iscache(db);
1291 * Look for the zonecut.
1294 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options,
1295 now, NULL, fname, rdataset, sigrdataset);
1296 if (result == DNS_R_DELEGATION)
1297 result = ISC_R_SUCCESS;
1298 else if (result != ISC_R_SUCCESS)
1300 if (use_cache && view->cachedb != NULL && db != view->hints) {
1302 * We found an answer, but the cache may be better.
1304 zfname = dns_fixedname_name(&zfixedname);
1305 result = dns_name_copy(fname, zfname, NULL);
1306 if (result != ISC_R_SUCCESS)
1308 dns_rdataset_clone(rdataset, &zrdataset);
1309 dns_rdataset_disassociate(rdataset);
1310 if (sigrdataset != NULL &&
1311 dns_rdataset_isassociated(sigrdataset)) {
1312 dns_rdataset_clone(sigrdataset, &zsigrdataset);
1313 dns_rdataset_disassociate(sigrdataset);
1316 dns_db_attach(view->cachedb, &db);
1317 is_cache = ISC_TRUE;
1321 result = dns_db_findzonecut(db, name, options, now, NULL,
1322 fname, rdataset, sigrdataset);
1323 if (result == ISC_R_SUCCESS) {
1325 if (zfname != NULL &&
1326 (!dns_name_issubdomain(fname, zfname) ||
1327 (dns_zone_gettype(zone) == dns_zone_staticstub &&
1328 dns_name_equal(fname, zfname))))
1330 if (zfname != NULL &&
1331 !dns_name_issubdomain(fname, zfname))
1335 * We found a zonecut in the cache, but our
1336 * zone delegation is better.
1338 use_zone = ISC_TRUE;
1340 } else if (result == ISC_R_NOTFOUND) {
1341 if (zfname != NULL) {
1343 * We didn't find anything in the cache, but we
1344 * have a zone delegation, so use it.
1346 use_zone = ISC_TRUE;
1349 * Maybe we have hints...
1351 try_hints = ISC_TRUE;
1355 * Something bad happened.
1363 if (dns_rdataset_isassociated(rdataset)) {
1364 dns_rdataset_disassociate(rdataset);
1365 if (sigrdataset != NULL &&
1366 dns_rdataset_isassociated(sigrdataset))
1367 dns_rdataset_disassociate(sigrdataset);
1369 result = dns_name_copy(zfname, fname, NULL);
1370 if (result != ISC_R_SUCCESS)
1372 dns_rdataset_clone(&zrdataset, rdataset);
1373 if (sigrdataset != NULL &&
1374 dns_rdataset_isassociated(&zrdataset))
1375 dns_rdataset_clone(&zsigrdataset, sigrdataset);
1376 } else if (try_hints && use_hints && view->hints != NULL) {
1378 * We've found nothing so far, but we have hints.
1380 result = dns_db_find(view->hints, dns_rootname, NULL,
1381 dns_rdatatype_ns, 0, now, NULL, fname,
1383 if (result != ISC_R_SUCCESS) {
1385 * We can't even find the hints for the root
1388 if (dns_rdataset_isassociated(rdataset))
1389 dns_rdataset_disassociate(rdataset);
1390 result = ISC_R_NOTFOUND;
1395 if (dns_rdataset_isassociated(&zrdataset)) {
1396 dns_rdataset_disassociate(&zrdataset);
1397 if (dns_rdataset_isassociated(&zsigrdataset))
1398 dns_rdataset_disassociate(&zsigrdataset);
1404 dns_zone_detach(&zone);
1411 dns_viewlist_find(dns_viewlist_t *list, const char *name,
1412 dns_rdataclass_t rdclass, dns_view_t **viewp)
1416 REQUIRE(list != NULL);
1418 for (view = ISC_LIST_HEAD(*list);
1420 view = ISC_LIST_NEXT(view, link)) {
1421 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass)
1425 return (ISC_R_NOTFOUND);
1427 dns_view_attach(view, viewp);
1429 return (ISC_R_SUCCESS);
1434 dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
1435 isc_boolean_t allclasses, dns_rdataclass_t rdclass,
1439 isc_result_t result;
1440 dns_zone_t *zone1 = NULL, *zone2 = NULL;
1441 dns_zone_t **zp = NULL;;
1443 REQUIRE(list != NULL);
1444 REQUIRE(zonep != NULL && *zonep == NULL);
1446 for (view = ISC_LIST_HEAD(*list);
1448 view = ISC_LIST_NEXT(view, link)) {
1449 if (allclasses == ISC_FALSE && view->rdclass != rdclass)
1453 * If the zone is defined in more than one view,
1454 * treat it as not found.
1456 zp = (zone1 == NULL) ? &zone1 : &zone2;
1458 if (view->zonetable != NULL)
1459 result = dns_zt_find(view->zonetable, name, 0,
1462 result = ISC_R_NOTFOUND;
1463 UNLOCK(&view->lock);
1464 INSIST(result == ISC_R_SUCCESS ||
1465 result == ISC_R_NOTFOUND ||
1466 result == DNS_R_PARTIALMATCH);
1468 /* Treat a partial match as no match */
1469 if (result == DNS_R_PARTIALMATCH) {
1470 dns_zone_detach(zp);
1471 result = ISC_R_NOTFOUND;
1475 if (zone2 != NULL) {
1476 dns_zone_detach(&zone1);
1477 dns_zone_detach(&zone2);
1478 return (ISC_R_MULTIPLE);
1482 if (zone1 != NULL) {
1483 dns_zone_attach(zone1, zonep);
1484 dns_zone_detach(&zone1);
1485 return (ISC_R_SUCCESS);
1488 return (ISC_R_NOTFOUND);
1492 dns_view_load(dns_view_t *view, isc_boolean_t stop) {
1494 REQUIRE(DNS_VIEW_VALID(view));
1495 REQUIRE(view->zonetable != NULL);
1497 return (dns_zt_load(view->zonetable, stop));
1501 dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
1503 REQUIRE(DNS_VIEW_VALID(view));
1504 REQUIRE(view->zonetable != NULL);
1506 return (dns_zt_loadnew(view->zonetable, stop));
1510 dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) {
1511 REQUIRE(DNS_VIEW_VALID(view));
1512 REQUIRE(view->zonetable != NULL);
1514 return (dns_zt_asyncload(view->zonetable, callback, arg));
1521 dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
1523 isc_result_t result;
1524 REQUIRE(keyp != NULL && *keyp == NULL);
1526 result = dns_tsigkey_find(keyp, keyname, NULL,
1528 if (result == ISC_R_NOTFOUND)
1529 result = dns_tsigkey_find(keyp, keyname, NULL,
1535 dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
1536 dns_tsigkey_t **keyp)
1538 isc_result_t result;
1539 dns_name_t *keyname = NULL;
1540 dns_peer_t *peer = NULL;
1542 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer);
1543 if (result != ISC_R_SUCCESS)
1546 result = dns_peer_getkey(peer, &keyname);
1547 if (result != ISC_R_SUCCESS)
1550 result = dns_view_gettsig(view, keyname, keyp);
1551 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
1555 dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
1556 REQUIRE(DNS_VIEW_VALID(view));
1557 REQUIRE(source != NULL);
1559 return (dns_tsig_verify(source, msg, view->statickeys,
1560 view->dynamickeys));
1565 dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
1566 isc_result_t result;
1568 REQUIRE(DNS_VIEW_VALID(view));
1570 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name);
1571 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL,
1572 &dns_master_style_cache, fp);
1573 if (result != ISC_R_SUCCESS)
1575 dns_adb_dump(view->adb, fp);
1576 dns_resolver_printbadcache(view->resolver, fp);
1577 return (ISC_R_SUCCESS);
1582 dns_view_flushcache(dns_view_t *view) {
1583 return (dns_view_flushcache2(view, ISC_FALSE));
1587 dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
1588 isc_result_t result;
1590 REQUIRE(DNS_VIEW_VALID(view));
1592 if (view->cachedb == NULL)
1593 return (ISC_R_SUCCESS);
1595 result = dns_cache_flush(view->cache);
1596 if (result != ISC_R_SUCCESS)
1600 if (view->acache != NULL)
1601 dns_acache_putdb(view->acache, view->cachedb);
1603 dns_db_detach(&view->cachedb);
1604 dns_cache_attachdb(view->cache, &view->cachedb);
1606 if (view->acache != NULL)
1607 dns_acache_setdb(view->acache, view->cachedb);
1608 if (view->resolver != NULL)
1609 dns_resolver_flushbadcache(view->resolver, NULL);
1612 dns_adb_flush(view->adb);
1613 return (ISC_R_SUCCESS);
1617 dns_view_flushname(dns_view_t *view, dns_name_t *name) {
1618 return (dns_view_flushnode(view, name, ISC_FALSE));
1622 dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) {
1624 REQUIRE(DNS_VIEW_VALID(view));
1627 if (view->adb != NULL)
1628 dns_adb_flushname(view->adb, name);
1629 if (view->cache == NULL)
1630 return (ISC_R_SUCCESS);
1631 if (view->resolver != NULL)
1632 dns_resolver_flushbadcache(view->resolver, name);
1634 return (dns_cache_flushnode(view->cache, name, tree));
1638 dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) {
1639 isc_result_t result;
1643 REQUIRE(DNS_VIEW_VALID(view));
1645 if (view->delonly == NULL) {
1646 view->delonly = isc_mem_get(view->mctx,
1647 sizeof(dns_namelist_t) *
1648 DNS_VIEW_DELONLYHASH);
1649 if (view->delonly == NULL)
1650 return (ISC_R_NOMEMORY);
1651 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
1652 ISC_LIST_INIT(view->delonly[hash]);
1654 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1655 new = ISC_LIST_HEAD(view->delonly[hash]);
1656 while (new != NULL && !dns_name_equal(new, name))
1657 new = ISC_LIST_NEXT(new, link);
1659 return (ISC_R_SUCCESS);
1660 new = isc_mem_get(view->mctx, sizeof(*new));
1662 return (ISC_R_NOMEMORY);
1663 dns_name_init(new, NULL);
1664 result = dns_name_dup(name, view->mctx, new);
1665 if (result == ISC_R_SUCCESS)
1666 ISC_LIST_APPEND(view->delonly[hash], new, link);
1668 isc_mem_put(view->mctx, new, sizeof(*new));
1673 dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) {
1674 isc_result_t result;
1678 REQUIRE(DNS_VIEW_VALID(view));
1680 if (view->rootexclude == NULL) {
1681 view->rootexclude = isc_mem_get(view->mctx,
1682 sizeof(dns_namelist_t) *
1683 DNS_VIEW_DELONLYHASH);
1684 if (view->rootexclude == NULL)
1685 return (ISC_R_NOMEMORY);
1686 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
1687 ISC_LIST_INIT(view->rootexclude[hash]);
1689 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1690 new = ISC_LIST_HEAD(view->rootexclude[hash]);
1691 while (new != NULL && !dns_name_equal(new, name))
1692 new = ISC_LIST_NEXT(new, link);
1694 return (ISC_R_SUCCESS);
1695 new = isc_mem_get(view->mctx, sizeof(*new));
1697 return (ISC_R_NOMEMORY);
1698 dns_name_init(new, NULL);
1699 result = dns_name_dup(name, view->mctx, new);
1700 if (result == ISC_R_SUCCESS)
1701 ISC_LIST_APPEND(view->rootexclude[hash], new, link);
1703 isc_mem_put(view->mctx, new, sizeof(*new));
1708 dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) {
1712 REQUIRE(DNS_VIEW_VALID(view));
1714 if (!view->rootdelonly && view->delonly == NULL)
1717 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1718 if (view->rootdelonly && dns_name_countlabels(name) <= 2) {
1719 if (view->rootexclude == NULL)
1721 new = ISC_LIST_HEAD(view->rootexclude[hash]);
1722 while (new != NULL && !dns_name_equal(new, name))
1723 new = ISC_LIST_NEXT(new, link);
1728 if (view->delonly == NULL)
1731 new = ISC_LIST_HEAD(view->delonly[hash]);
1732 while (new != NULL && !dns_name_equal(new, name))
1733 new = ISC_LIST_NEXT(new, link);
1740 dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) {
1741 REQUIRE(DNS_VIEW_VALID(view));
1742 view->rootdelonly = value;
1746 dns_view_getrootdelonly(dns_view_t *view) {
1747 REQUIRE(DNS_VIEW_VALID(view));
1748 return (view->rootdelonly);
1753 dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
1755 REQUIRE(DNS_VIEW_VALID(view));
1756 REQUIRE(view->zonetable != NULL);
1758 return (dns_zt_freezezones(view->zonetable, value));
1763 dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) {
1765 REQUIRE(DNS_VIEW_VALID(view));
1766 REQUIRE(!view->frozen);
1767 REQUIRE(view->resstats == NULL);
1769 isc_stats_attach(stats, &view->resstats);
1773 dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) {
1774 REQUIRE(DNS_VIEW_VALID(view));
1775 REQUIRE(statsp != NULL && *statsp == NULL);
1777 if (view->resstats != NULL)
1778 isc_stats_attach(view->resstats, statsp);
1782 dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) {
1783 REQUIRE(DNS_VIEW_VALID(view));
1784 REQUIRE(!view->frozen);
1785 REQUIRE(view->resquerystats == NULL);
1787 dns_stats_attach(stats, &view->resquerystats);
1791 dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
1792 REQUIRE(DNS_VIEW_VALID(view));
1793 REQUIRE(statsp != NULL && *statsp == NULL);
1795 if (view->resquerystats != NULL)
1796 dns_stats_attach(view->resquerystats, statsp);
1800 dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) {
1801 REQUIRE(DNS_VIEW_VALID(view));
1802 if (view->secroots_priv != NULL)
1803 dns_keytable_detach(&view->secroots_priv);
1804 return (dns_keytable_create(mctx, &view->secroots_priv));
1808 dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) {
1809 REQUIRE(DNS_VIEW_VALID(view));
1810 REQUIRE(ktp != NULL && *ktp == NULL);
1811 if (view->secroots_priv == NULL)
1812 return (ISC_R_NOTFOUND);
1813 dns_keytable_attach(view->secroots_priv, ktp);
1814 return (ISC_R_SUCCESS);
1818 dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
1819 isc_boolean_t *secure_domain) {
1820 REQUIRE(DNS_VIEW_VALID(view));
1822 if (view->secroots_priv == NULL)
1823 return (ISC_R_NOTFOUND);
1824 return (dns_keytable_issecuredomain(view->secroots_priv, name,
1829 dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
1830 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
1832 isc_result_t result;
1833 unsigned char data[4096];
1834 dns_rdata_t rdata = DNS_RDATA_INIT;
1835 isc_buffer_t buffer;
1836 dst_key_t *key = NULL;
1837 dns_keytable_t *sr = NULL;
1840 * Clear the revoke bit, if set, so that the key will match what's
1843 dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
1845 /* Convert dnskey to DST key. */
1846 isc_buffer_init(&buffer, data, sizeof(data));
1847 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
1848 dns_rdatatype_dnskey, dnskey, &buffer);
1850 result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key);
1851 if (result != ISC_R_SUCCESS)
1854 result = dns_view_getsecroots(view, &sr);
1855 if (result == ISC_R_SUCCESS) {
1856 result = dns_keytable_deletekeynode(sr, key);
1859 * If key was found in secroots, then it was a
1860 * configured trust anchor, and we want to fail
1861 * secure. If there are no other configured keys,
1862 * then leave a null key so that we can't validate
1866 if (result == ISC_R_SUCCESS)
1867 dns_keytable_marksecure(sr, keyname);
1869 dns_keytable_detach(&sr);
1878 dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
1879 void (*cfg_destroy)(void **))
1881 REQUIRE(DNS_VIEW_VALID(view));
1882 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow);
1885 if (view->new_zone_file != NULL) {
1886 isc_mem_free(view->mctx, view->new_zone_file);
1887 view->new_zone_file = NULL;
1890 if (view->new_zone_config != NULL) {
1891 view->cfg_destroy(&view->new_zone_config);
1892 view->cfg_destroy = NULL;
1896 char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)];
1897 isc_sha256_data((void *)view->name, strlen(view->name), buffer);
1898 /* Truncate the hash at 16 chars; full length is overkill */
1899 isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF);
1900 view->new_zone_file = isc_mem_strdup(view->mctx, buffer);
1901 view->new_zone_config = cfgctx;
1902 view->cfg_destroy = cfg_destroy;
1907 UNUSED(cfg_destroy);