1 /* $NetBSD: view.c,v 1.10 2014/12/10 04:37:58 christos Exp $ */
4 * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
28 #include <isc/print.h>
30 #include <isc/stats.h>
31 #include <isc/string.h> /* Required for HP/UX (and others?) */
35 #include <dns/acache.h>
38 #include <dns/cache.h>
40 #include <dns/dispatch.h>
42 #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 ISC_LIST_INIT(view
->dlz_searched
);
129 ISC_LIST_INIT(view
->dlz_unsearched
);
131 view
->resolver
= NULL
;
133 view
->requestmgr
= NULL
;
134 view
->rdclass
= rdclass
;
135 view
->frozen
= ISC_FALSE
;
137 result
= isc_refcount_init(&view
->references
, 1);
138 if (result
!= ISC_R_SUCCESS
)
139 goto cleanup_fwdtable
;
141 view
->attributes
= (DNS_VIEWATTR_RESSHUTDOWN
|DNS_VIEWATTR_ADBSHUTDOWN
|
142 DNS_VIEWATTR_REQSHUTDOWN
);
143 view
->statickeys
= NULL
;
144 view
->dynamickeys
= NULL
;
145 view
->matchclients
= NULL
;
146 view
->matchdestinations
= NULL
;
147 view
->matchrecursiveonly
= ISC_FALSE
;
148 result
= dns_tsigkeyring_create(view
->mctx
, &view
->dynamickeys
);
149 if (result
!= ISC_R_SUCCESS
)
150 goto cleanup_references
;
153 view
->delonly
= NULL
;
154 view
->rootdelonly
= ISC_FALSE
;
155 view
->rootexclude
= NULL
;
156 view
->adbstats
= NULL
;
157 view
->resstats
= NULL
;
158 view
->resquerystats
= NULL
;
159 view
->cacheshared
= ISC_FALSE
;
160 ISC_LIST_INIT(view
->dns64
);
164 * Initialize configuration data with default values.
166 view
->recursion
= ISC_TRUE
;
167 view
->auth_nxdomain
= ISC_FALSE
; /* Was true in BIND 8 */
168 view
->additionalfromcache
= ISC_TRUE
;
169 view
->additionalfromauth
= ISC_TRUE
;
170 view
->enablednssec
= ISC_TRUE
;
171 view
->enablevalidation
= ISC_TRUE
;
172 view
->acceptexpired
= ISC_FALSE
;
173 view
->minimalresponses
= ISC_FALSE
;
174 view
->transfer_format
= dns_one_answer
;
175 view
->cacheacl
= NULL
;
176 view
->cacheonacl
= NULL
;
177 view
->queryacl
= NULL
;
178 view
->queryonacl
= NULL
;
179 view
->recursionacl
= NULL
;
180 view
->recursiononacl
= NULL
;
181 view
->sortlist
= NULL
;
182 view
->transferacl
= NULL
;
183 view
->notifyacl
= NULL
;
184 view
->updateacl
= NULL
;
185 view
->upfwdacl
= NULL
;
186 view
->denyansweracl
= NULL
;
187 view
->nocasecompress
= NULL
;
188 view
->answeracl_exclude
= NULL
;
189 view
->denyanswernames
= NULL
;
190 view
->answernames_exclude
= NULL
;
192 view
->provideixfr
= ISC_TRUE
;
193 view
->maxcachettl
= 7 * 24 * 3600;
194 view
->maxncachettl
= 3 * 3600;
195 view
->prefetch_eligible
= 0;
196 view
->prefetch_trigger
= 0;
198 view
->preferred_glue
= 0;
199 view
->flush
= ISC_FALSE
;
204 view
->v4_aaaa
= dns_aaaa_ok
;
205 view
->v6_aaaa
= dns_aaaa_ok
;
206 view
->aaaa_acl
= NULL
;
208 dns_fixedname_init(&view
->dlv_fixed
);
209 view
->managed_keys
= NULL
;
210 view
->redirect
= NULL
;
211 view
->requestnsid
= ISC_FALSE
;
212 view
->requestsit
= ISC_TRUE
;
213 view
->new_zone_file
= NULL
;
214 view
->new_zone_config
= NULL
;
215 view
->cfg_destroy
= NULL
;
218 result
= dns_order_create(view
->mctx
, &view
->order
);
219 if (result
!= ISC_R_SUCCESS
)
220 goto cleanup_dynkeys
;
223 result
= dns_peerlist_new(view
->mctx
, &view
->peers
);
224 if (result
!= ISC_R_SUCCESS
)
227 result
= dns_aclenv_init(view
->mctx
, &view
->aclenv
);
228 if (result
!= ISC_R_SUCCESS
)
229 goto cleanup_peerlist
;
231 ISC_LINK_INIT(view
, link
);
232 ISC_EVENT_INIT(&view
->resevent
, sizeof(view
->resevent
), 0, NULL
,
233 DNS_EVENT_VIEWRESSHUTDOWN
, resolver_shutdown
,
234 view
, NULL
, NULL
, NULL
);
235 ISC_EVENT_INIT(&view
->adbevent
, sizeof(view
->adbevent
), 0, NULL
,
236 DNS_EVENT_VIEWADBSHUTDOWN
, adb_shutdown
,
237 view
, NULL
, NULL
, NULL
);
238 ISC_EVENT_INIT(&view
->reqevent
, sizeof(view
->reqevent
), 0, NULL
,
239 DNS_EVENT_VIEWREQSHUTDOWN
, req_shutdown
,
240 view
, NULL
, NULL
, NULL
);
241 view
->viewlist
= NULL
;
242 view
->magic
= DNS_VIEW_MAGIC
;
246 return (ISC_R_SUCCESS
);
249 if (view
->peers
!= NULL
)
250 dns_peerlist_detach(&view
->peers
);
253 if (view
->order
!= NULL
)
254 dns_order_detach(&view
->order
);
257 if (view
->dynamickeys
!= NULL
)
258 dns_tsigkeyring_detach(&view
->dynamickeys
);
261 isc_refcount_destroy(&view
->references
);
264 if (view
->fwdtable
!= NULL
)
265 dns_fwdtable_destroy(&view
->fwdtable
);
268 if (view
->zonetable
!= NULL
)
269 dns_zt_detach(&view
->zonetable
);
272 DESTROYLOCK(&view
->lock
);
275 isc_mem_free(mctx
, view
->name
);
278 isc_mem_putanddetach(&view
->mctx
, view
, sizeof(*view
));
284 destroy(dns_view_t
*view
) {
288 REQUIRE(!ISC_LINK_LINKED(view
, link
));
289 REQUIRE(isc_refcount_current(&view
->references
) == 0);
290 REQUIRE(view
->weakrefs
== 0);
291 REQUIRE(RESSHUTDOWN(view
));
292 REQUIRE(ADBSHUTDOWN(view
));
293 REQUIRE(REQSHUTDOWN(view
));
295 if (view
->order
!= NULL
)
296 dns_order_detach(&view
->order
);
297 if (view
->peers
!= NULL
)
298 dns_peerlist_detach(&view
->peers
);
300 if (view
->dynamickeys
!= NULL
) {
307 n
= snprintf(keyfile
, sizeof(keyfile
), "%s.tsigkeys",
309 if (n
> 0 && (size_t)n
< sizeof(keyfile
)) {
310 result
= isc_file_mktemplate(keyfile
, template,
312 if (result
== ISC_R_SUCCESS
)
313 (void)isc_file_openuniqueprivate(template, &fp
);
316 dns_tsigkeyring_detach(&view
->dynamickeys
);
318 result
= dns_tsigkeyring_dumpanddetach(
319 &view
->dynamickeys
, fp
);
320 if (result
== ISC_R_SUCCESS
) {
322 result
= isc_file_rename(template,
324 if (result
!= ISC_R_SUCCESS
)
325 (void)remove(template);
328 (void)remove(template);
332 if (view
->statickeys
!= NULL
)
333 dns_tsigkeyring_detach(&view
->statickeys
);
334 if (view
->adb
!= NULL
)
335 dns_adb_detach(&view
->adb
);
336 if (view
->resolver
!= NULL
)
337 dns_resolver_detach(&view
->resolver
);
338 if (view
->acache
!= NULL
) {
339 if (view
->cachedb
!= NULL
)
340 dns_acache_putdb(view
->acache
, view
->cachedb
);
341 dns_acache_detach(&view
->acache
);
343 dns_rrl_view_destroy(view
);
344 if (view
->rpzs
!= NULL
)
345 dns_rpz_detach_rpzs(&view
->rpzs
);
346 for (dlzdb
= ISC_LIST_HEAD(view
->dlz_searched
);
348 dlzdb
= ISC_LIST_HEAD(view
->dlz_searched
)) {
349 ISC_LIST_UNLINK(view
->dlz_searched
, dlzdb
, link
);
350 dns_dlzdestroy(&dlzdb
);
352 for (dlzdb
= ISC_LIST_HEAD(view
->dlz_unsearched
);
354 dlzdb
= ISC_LIST_HEAD(view
->dlz_unsearched
)) {
355 ISC_LIST_UNLINK(view
->dlz_unsearched
, dlzdb
, link
);
356 dns_dlzdestroy(&dlzdb
);
358 if (view
->requestmgr
!= NULL
)
359 dns_requestmgr_detach(&view
->requestmgr
);
360 if (view
->task
!= NULL
)
361 isc_task_detach(&view
->task
);
362 if (view
->hints
!= NULL
)
363 dns_db_detach(&view
->hints
);
364 if (view
->cachedb
!= NULL
)
365 dns_db_detach(&view
->cachedb
);
366 if (view
->cache
!= NULL
)
367 dns_cache_detach(&view
->cache
);
368 if (view
->nocasecompress
!= NULL
)
369 dns_acl_detach(&view
->nocasecompress
);
370 if (view
->matchclients
!= NULL
)
371 dns_acl_detach(&view
->matchclients
);
372 if (view
->matchdestinations
!= NULL
)
373 dns_acl_detach(&view
->matchdestinations
);
374 if (view
->cacheacl
!= NULL
)
375 dns_acl_detach(&view
->cacheacl
);
376 if (view
->cacheonacl
!= NULL
)
377 dns_acl_detach(&view
->cacheonacl
);
378 if (view
->queryacl
!= NULL
)
379 dns_acl_detach(&view
->queryacl
);
380 if (view
->queryonacl
!= NULL
)
381 dns_acl_detach(&view
->queryonacl
);
382 if (view
->recursionacl
!= NULL
)
383 dns_acl_detach(&view
->recursionacl
);
384 if (view
->recursiononacl
!= NULL
)
385 dns_acl_detach(&view
->recursiononacl
);
386 if (view
->sortlist
!= NULL
)
387 dns_acl_detach(&view
->sortlist
);
388 if (view
->transferacl
!= NULL
)
389 dns_acl_detach(&view
->transferacl
);
390 if (view
->notifyacl
!= NULL
)
391 dns_acl_detach(&view
->notifyacl
);
392 if (view
->updateacl
!= NULL
)
393 dns_acl_detach(&view
->updateacl
);
394 if (view
->upfwdacl
!= NULL
)
395 dns_acl_detach(&view
->upfwdacl
);
396 if (view
->denyansweracl
!= NULL
)
397 dns_acl_detach(&view
->denyansweracl
);
398 if (view
->aaaa_acl
!= NULL
)
399 dns_acl_detach(&view
->aaaa_acl
);
400 if (view
->answeracl_exclude
!= NULL
)
401 dns_rbt_destroy(&view
->answeracl_exclude
);
402 if (view
->denyanswernames
!= NULL
)
403 dns_rbt_destroy(&view
->denyanswernames
);
404 if (view
->answernames_exclude
!= NULL
)
405 dns_rbt_destroy(&view
->answernames_exclude
);
406 if (view
->delonly
!= NULL
) {
410 for (i
= 0; i
< DNS_VIEW_DELONLYHASH
; i
++) {
411 name
= ISC_LIST_HEAD(view
->delonly
[i
]);
412 while (name
!= NULL
) {
413 ISC_LIST_UNLINK(view
->delonly
[i
], name
, link
);
414 dns_name_free(name
, view
->mctx
);
415 isc_mem_put(view
->mctx
, name
, sizeof(*name
));
416 name
= ISC_LIST_HEAD(view
->delonly
[i
]);
419 isc_mem_put(view
->mctx
, view
->delonly
, sizeof(dns_namelist_t
) *
420 DNS_VIEW_DELONLYHASH
);
421 view
->delonly
= NULL
;
423 if (view
->rootexclude
!= NULL
) {
427 for (i
= 0; i
< DNS_VIEW_DELONLYHASH
; i
++) {
428 name
= ISC_LIST_HEAD(view
->rootexclude
[i
]);
429 while (name
!= NULL
) {
430 ISC_LIST_UNLINK(view
->rootexclude
[i
],
432 dns_name_free(name
, view
->mctx
);
433 isc_mem_put(view
->mctx
, name
, sizeof(*name
));
434 name
= ISC_LIST_HEAD(view
->rootexclude
[i
]);
437 isc_mem_put(view
->mctx
, view
->rootexclude
,
438 sizeof(dns_namelist_t
) * DNS_VIEW_DELONLYHASH
);
439 view
->rootexclude
= NULL
;
441 if (view
->adbstats
!= NULL
)
442 isc_stats_detach(&view
->adbstats
);
443 if (view
->resstats
!= NULL
)
444 isc_stats_detach(&view
->resstats
);
445 if (view
->resquerystats
!= NULL
)
446 dns_stats_detach(&view
->resquerystats
);
447 if (view
->secroots_priv
!= NULL
)
448 dns_keytable_detach(&view
->secroots_priv
);
449 for (dns64
= ISC_LIST_HEAD(view
->dns64
);
451 dns64
= ISC_LIST_HEAD(view
->dns64
)) {
452 dns_dns64_unlink(&view
->dns64
, dns64
);
453 dns_dns64_destroy(&dns64
);
455 if (view
->managed_keys
!= NULL
)
456 dns_zone_detach(&view
->managed_keys
);
457 if (view
->redirect
!= NULL
)
458 dns_zone_detach(&view
->redirect
);
459 dns_view_setnewzones(view
, ISC_FALSE
, NULL
, NULL
);
460 dns_fwdtable_destroy(&view
->fwdtable
);
461 dns_aclenv_destroy(&view
->aclenv
);
462 DESTROYLOCK(&view
->lock
);
463 isc_refcount_destroy(&view
->references
);
464 isc_mem_free(view
->mctx
, view
->name
);
465 isc_mem_putanddetach(&view
->mctx
, view
, sizeof(*view
));
469 * Return true iff 'view' may be freed.
470 * The caller must be holding the view lock.
473 all_done(dns_view_t
*view
) {
475 if (isc_refcount_current(&view
->references
) == 0 &&
476 view
->weakrefs
== 0 &&
477 RESSHUTDOWN(view
) && ADBSHUTDOWN(view
) && REQSHUTDOWN(view
))
484 dns_view_attach(dns_view_t
*source
, dns_view_t
**targetp
) {
486 REQUIRE(DNS_VIEW_VALID(source
));
487 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
489 isc_refcount_increment(&source
->references
, NULL
);
495 view_flushanddetach(dns_view_t
**viewp
, isc_boolean_t flush
) {
498 isc_boolean_t done
= ISC_FALSE
;
500 REQUIRE(viewp
!= NULL
);
502 REQUIRE(DNS_VIEW_VALID(view
));
505 view
->flush
= ISC_TRUE
;
506 isc_refcount_decrement(&view
->references
, &refs
);
508 dns_zone_t
*mkzone
= NULL
, *rdzone
= NULL
;
511 if (!RESSHUTDOWN(view
))
512 dns_resolver_shutdown(view
->resolver
);
513 if (!ADBSHUTDOWN(view
))
514 dns_adb_shutdown(view
->adb
);
515 if (!REQSHUTDOWN(view
))
516 dns_requestmgr_shutdown(view
->requestmgr
);
517 if (view
->acache
!= NULL
)
518 dns_acache_shutdown(view
->acache
);
519 if (view
->zonetable
!= NULL
) {
521 dns_zt_flushanddetach(&view
->zonetable
);
523 dns_zt_detach(&view
->zonetable
);
525 if (view
->managed_keys
!= NULL
) {
526 mkzone
= view
->managed_keys
;
527 view
->managed_keys
= NULL
;
529 dns_zone_flush(mkzone
);
531 if (view
->redirect
!= NULL
) {
532 rdzone
= view
->redirect
;
533 view
->redirect
= NULL
;
535 dns_zone_flush(rdzone
);
537 done
= all_done(view
);
540 /* Need to detach zones outside view lock */
542 dns_zone_detach(&mkzone
);
545 dns_zone_detach(&rdzone
);
555 dns_view_flushanddetach(dns_view_t
**viewp
) {
556 view_flushanddetach(viewp
, ISC_TRUE
);
560 dns_view_detach(dns_view_t
**viewp
) {
561 view_flushanddetach(viewp
, ISC_FALSE
);
565 dialup(dns_zone_t
*zone
, void *dummy
) {
567 dns_zone_dialup(zone
);
568 return (ISC_R_SUCCESS
);
572 dns_view_dialup(dns_view_t
*view
) {
573 REQUIRE(DNS_VIEW_VALID(view
));
574 REQUIRE(view
->zonetable
!= NULL
);
576 (void)dns_zt_apply(view
->zonetable
, ISC_FALSE
, dialup
, NULL
);
580 dns_view_weakattach(dns_view_t
*source
, dns_view_t
**targetp
) {
582 REQUIRE(DNS_VIEW_VALID(source
));
583 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
587 UNLOCK(&source
->lock
);
593 dns_view_weakdetach(dns_view_t
**viewp
) {
595 isc_boolean_t done
= ISC_FALSE
;
597 REQUIRE(viewp
!= NULL
);
599 REQUIRE(DNS_VIEW_VALID(view
));
603 INSIST(view
->weakrefs
> 0);
605 done
= all_done(view
);
616 resolver_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
617 dns_view_t
*view
= event
->ev_arg
;
620 REQUIRE(event
->ev_type
== DNS_EVENT_VIEWRESSHUTDOWN
);
621 REQUIRE(DNS_VIEW_VALID(view
));
622 REQUIRE(view
->task
== task
);
626 isc_event_free(&event
);
630 view
->attributes
|= DNS_VIEWATTR_RESSHUTDOWN
;
631 done
= all_done(view
);
640 adb_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
641 dns_view_t
*view
= event
->ev_arg
;
644 REQUIRE(event
->ev_type
== DNS_EVENT_VIEWADBSHUTDOWN
);
645 REQUIRE(DNS_VIEW_VALID(view
));
646 REQUIRE(view
->task
== task
);
650 isc_event_free(&event
);
654 view
->attributes
|= DNS_VIEWATTR_ADBSHUTDOWN
;
655 done
= all_done(view
);
664 req_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
665 dns_view_t
*view
= event
->ev_arg
;
668 REQUIRE(event
->ev_type
== DNS_EVENT_VIEWREQSHUTDOWN
);
669 REQUIRE(DNS_VIEW_VALID(view
));
670 REQUIRE(view
->task
== task
);
674 isc_event_free(&event
);
678 view
->attributes
|= DNS_VIEWATTR_REQSHUTDOWN
;
679 done
= all_done(view
);
688 dns_view_createzonetable(dns_view_t
*view
) {
690 REQUIRE(DNS_VIEW_VALID(view
));
691 REQUIRE(!view
->frozen
);
692 REQUIRE(view
->zonetable
== NULL
);
694 return (dns_zt_create(view
->mctx
, view
->rdclass
, &view
->zonetable
));
698 dns_view_createresolver(dns_view_t
*view
,
699 isc_taskmgr_t
*taskmgr
,
700 unsigned int ntasks
, unsigned int ndisp
,
701 isc_socketmgr_t
*socketmgr
,
702 isc_timermgr_t
*timermgr
,
703 unsigned int options
,
704 dns_dispatchmgr_t
*dispatchmgr
,
705 dns_dispatch_t
*dispatchv4
,
706 dns_dispatch_t
*dispatchv6
)
710 isc_mem_t
*mctx
= NULL
;
712 REQUIRE(DNS_VIEW_VALID(view
));
713 REQUIRE(!view
->frozen
);
714 REQUIRE(view
->resolver
== NULL
);
716 result
= isc_task_create(taskmgr
, 0, &view
->task
);
717 if (result
!= ISC_R_SUCCESS
)
719 isc_task_setname(view
->task
, "view", view
);
721 result
= dns_resolver_create(view
, taskmgr
, ntasks
, ndisp
, socketmgr
,
722 timermgr
, options
, dispatchmgr
,
723 dispatchv4
, dispatchv6
,
725 if (result
!= ISC_R_SUCCESS
) {
726 isc_task_detach(&view
->task
);
729 event
= &view
->resevent
;
730 dns_resolver_whenshutdown(view
->resolver
, view
->task
, &event
);
731 view
->attributes
&= ~DNS_VIEWATTR_RESSHUTDOWN
;
733 result
= isc_mem_create(0, 0, &mctx
);
734 if (result
!= ISC_R_SUCCESS
) {
735 dns_resolver_shutdown(view
->resolver
);
739 result
= dns_adb_create(mctx
, view
, timermgr
, taskmgr
, &view
->adb
);
740 isc_mem_setname(mctx
, "ADB", NULL
);
741 isc_mem_detach(&mctx
);
742 if (result
!= ISC_R_SUCCESS
) {
743 dns_resolver_shutdown(view
->resolver
);
746 event
= &view
->adbevent
;
747 dns_adb_whenshutdown(view
->adb
, view
->task
, &event
);
748 view
->attributes
&= ~DNS_VIEWATTR_ADBSHUTDOWN
;
750 result
= dns_requestmgr_create(view
->mctx
, timermgr
, socketmgr
,
751 dns_resolver_taskmgr(view
->resolver
),
752 dns_resolver_dispatchmgr(view
->resolver
),
753 dispatchv4
, dispatchv6
,
755 if (result
!= ISC_R_SUCCESS
) {
756 dns_adb_shutdown(view
->adb
);
757 dns_resolver_shutdown(view
->resolver
);
760 event
= &view
->reqevent
;
761 dns_requestmgr_whenshutdown(view
->requestmgr
, view
->task
, &event
);
762 view
->attributes
&= ~DNS_VIEWATTR_REQSHUTDOWN
;
764 return (ISC_R_SUCCESS
);
768 dns_view_setcache(dns_view_t
*view
, dns_cache_t
*cache
) {
769 dns_view_setcache2(view
, cache
, ISC_FALSE
);
773 dns_view_setcache2(dns_view_t
*view
, dns_cache_t
*cache
, isc_boolean_t shared
) {
774 REQUIRE(DNS_VIEW_VALID(view
));
775 REQUIRE(!view
->frozen
);
777 view
->cacheshared
= shared
;
778 if (view
->cache
!= NULL
) {
779 if (view
->acache
!= NULL
)
780 dns_acache_putdb(view
->acache
, view
->cachedb
);
781 dns_db_detach(&view
->cachedb
);
782 dns_cache_detach(&view
->cache
);
784 dns_cache_attach(cache
, &view
->cache
);
785 dns_cache_attachdb(cache
, &view
->cachedb
);
786 INSIST(DNS_DB_VALID(view
->cachedb
));
788 if (view
->acache
!= NULL
)
789 dns_acache_setdb(view
->acache
, view
->cachedb
);
793 dns_view_iscacheshared(dns_view_t
*view
) {
794 REQUIRE(DNS_VIEW_VALID(view
));
796 return (view
->cacheshared
);
800 dns_view_sethints(dns_view_t
*view
, dns_db_t
*hints
) {
801 REQUIRE(DNS_VIEW_VALID(view
));
802 REQUIRE(!view
->frozen
);
803 REQUIRE(view
->hints
== NULL
);
804 REQUIRE(dns_db_iszone(hints
));
806 dns_db_attach(hints
, &view
->hints
);
810 dns_view_setkeyring(dns_view_t
*view
, dns_tsig_keyring_t
*ring
) {
811 REQUIRE(DNS_VIEW_VALID(view
));
812 REQUIRE(ring
!= NULL
);
813 if (view
->statickeys
!= NULL
)
814 dns_tsigkeyring_detach(&view
->statickeys
);
815 dns_tsigkeyring_attach(ring
, &view
->statickeys
);
819 dns_view_setdynamickeyring(dns_view_t
*view
, dns_tsig_keyring_t
*ring
) {
820 REQUIRE(DNS_VIEW_VALID(view
));
821 REQUIRE(ring
!= NULL
);
822 if (view
->dynamickeys
!= NULL
)
823 dns_tsigkeyring_detach(&view
->dynamickeys
);
824 dns_tsigkeyring_attach(ring
, &view
->dynamickeys
);
828 dns_view_getdynamickeyring(dns_view_t
*view
, dns_tsig_keyring_t
**ringp
) {
829 REQUIRE(DNS_VIEW_VALID(view
));
830 REQUIRE(ringp
!= NULL
&& *ringp
== NULL
);
831 if (view
->dynamickeys
!= NULL
)
832 dns_tsigkeyring_attach(view
->dynamickeys
, ringp
);
836 dns_view_restorekeyring(dns_view_t
*view
) {
841 REQUIRE(DNS_VIEW_VALID(view
));
843 if (view
->dynamickeys
!= NULL
) {
844 n
= snprintf(keyfile
, sizeof(keyfile
), "%s.tsigkeys",
846 if (n
> 0 && (size_t)n
< sizeof(keyfile
)) {
847 fp
= fopen(keyfile
, "r");
849 dns_keyring_restore(view
->dynamickeys
, fp
);
857 dns_view_setdstport(dns_view_t
*view
, in_port_t dstport
) {
858 REQUIRE(DNS_VIEW_VALID(view
));
859 view
->dstport
= dstport
;
863 dns_view_freeze(dns_view_t
*view
) {
864 REQUIRE(DNS_VIEW_VALID(view
));
865 REQUIRE(!view
->frozen
);
867 if (view
->resolver
!= NULL
) {
868 INSIST(view
->cachedb
!= NULL
);
869 dns_resolver_freeze(view
->resolver
);
871 view
->frozen
= ISC_TRUE
;
875 dns_view_thaw(dns_view_t
*view
) {
876 REQUIRE(DNS_VIEW_VALID(view
));
877 REQUIRE(view
->frozen
);
879 view
->frozen
= ISC_FALSE
;
883 dns_view_addzone(dns_view_t
*view
, dns_zone_t
*zone
) {
886 REQUIRE(DNS_VIEW_VALID(view
));
887 REQUIRE(!view
->frozen
);
888 REQUIRE(view
->zonetable
!= NULL
);
890 result
= dns_zt_mount(view
->zonetable
, zone
);
896 dns_view_findzone(dns_view_t
*view
, dns_name_t
*name
, dns_zone_t
**zonep
) {
899 REQUIRE(DNS_VIEW_VALID(view
));
902 if (view
->zonetable
!= NULL
) {
903 result
= dns_zt_find(view
->zonetable
, name
, 0, NULL
, zonep
);
904 if (result
== DNS_R_PARTIALMATCH
) {
905 dns_zone_detach(zonep
);
906 result
= ISC_R_NOTFOUND
;
909 result
= ISC_R_NOTFOUND
;
916 dns_view_find(dns_view_t
*view
, dns_name_t
*name
, dns_rdatatype_t type
,
917 isc_stdtime_t now
, unsigned int options
, isc_boolean_t use_hints
,
918 dns_db_t
**dbp
, dns_dbnode_t
**nodep
, dns_name_t
*foundname
,
919 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
) {
920 return (dns_view_find2(view
, name
, type
, now
, options
, use_hints
,
921 ISC_FALSE
, dbp
, nodep
, foundname
, rdataset
,
926 dns_view_find2(dns_view_t
*view
, dns_name_t
*name
, dns_rdatatype_t type
,
927 isc_stdtime_t now
, unsigned int options
,
928 isc_boolean_t use_hints
, isc_boolean_t use_static_stub
,
929 dns_db_t
**dbp
, dns_dbnode_t
**nodep
, dns_name_t
*foundname
,
930 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
)
934 dns_dbnode_t
*node
, *znode
;
935 isc_boolean_t is_cache
, is_staticstub_zone
;
936 dns_rdataset_t zrdataset
, zsigrdataset
;
940 * Find an rdataset whose owner name is 'name', and whose type is
944 REQUIRE(DNS_VIEW_VALID(view
));
945 REQUIRE(view
->frozen
);
946 REQUIRE(type
!= dns_rdatatype_rrsig
);
947 REQUIRE(rdataset
!= NULL
); /* XXXBEW - remove this */
948 REQUIRE(nodep
== NULL
|| *nodep
== NULL
);
953 dns_rdataset_init(&zrdataset
);
954 dns_rdataset_init(&zsigrdataset
);
959 * Find a database to answer the query.
963 is_staticstub_zone
= ISC_FALSE
;
966 if (view
->zonetable
!= NULL
)
967 result
= dns_zt_find(view
->zonetable
, name
, 0, NULL
, &zone
);
969 result
= ISC_R_NOTFOUND
;
971 if (zone
!= NULL
&& dns_zone_gettype(zone
) == dns_zone_staticstub
&&
973 result
= ISC_R_NOTFOUND
;
974 if (result
== ISC_R_SUCCESS
|| result
== DNS_R_PARTIALMATCH
) {
975 result
= dns_zone_getdb(zone
, &db
);
976 if (result
!= ISC_R_SUCCESS
&& view
->cachedb
!= NULL
)
977 dns_db_attach(view
->cachedb
, &db
);
978 else if (result
!= ISC_R_SUCCESS
)
980 if (dns_zone_gettype(zone
) == dns_zone_staticstub
&&
981 dns_name_equal(name
, dns_zone_getorigin(zone
))) {
982 is_staticstub_zone
= ISC_TRUE
;
984 } else if (result
== ISC_R_NOTFOUND
&& view
->cachedb
!= NULL
)
985 dns_db_attach(view
->cachedb
, &db
);
989 is_cache
= dns_db_iscache(db
);
993 * Now look for an answer in the database.
995 result
= dns_db_find(db
, name
, NULL
, type
, options
,
996 now
, &node
, foundname
, rdataset
, sigrdataset
);
998 if (result
== DNS_R_DELEGATION
|| result
== ISC_R_NOTFOUND
) {
999 if (dns_rdataset_isassociated(rdataset
))
1000 dns_rdataset_disassociate(rdataset
);
1001 if (sigrdataset
!= NULL
&&
1002 dns_rdataset_isassociated(sigrdataset
))
1003 dns_rdataset_disassociate(sigrdataset
);
1005 dns_db_detachnode(db
, &node
);
1008 if (view
->cachedb
!= NULL
&& !is_staticstub_zone
) {
1010 * Either the answer is in the cache, or we
1012 * Note that if the result comes from a
1013 * static-stub zone we stop the search here
1014 * (see the function description in view.h).
1016 is_cache
= ISC_TRUE
;
1017 dns_db_attach(view
->cachedb
, &db
);
1022 * We don't have the data in the cache. If we've got
1023 * glue from the zone, use it.
1025 if (dns_rdataset_isassociated(&zrdataset
)) {
1026 dns_rdataset_clone(&zrdataset
, rdataset
);
1027 if (sigrdataset
!= NULL
&&
1028 dns_rdataset_isassociated(&zsigrdataset
))
1029 dns_rdataset_clone(&zsigrdataset
,
1031 result
= DNS_R_GLUE
;
1034 dns_db_attach(zdb
, &db
);
1035 dns_db_attachnode(db
, znode
, &node
);
1040 * We don't know the answer.
1042 result
= ISC_R_NOTFOUND
;
1043 } else if (result
== DNS_R_GLUE
) {
1044 if (view
->cachedb
!= NULL
&& !is_staticstub_zone
) {
1046 * We found an answer, but the cache may be better.
1047 * Remember what we've got and go look in the cache.
1049 is_cache
= ISC_TRUE
;
1050 dns_rdataset_clone(rdataset
, &zrdataset
);
1051 dns_rdataset_disassociate(rdataset
);
1052 if (sigrdataset
!= NULL
&&
1053 dns_rdataset_isassociated(sigrdataset
)) {
1054 dns_rdataset_clone(sigrdataset
, &zsigrdataset
);
1055 dns_rdataset_disassociate(sigrdataset
);
1057 dns_db_attach(db
, &zdb
);
1058 dns_db_attachnode(zdb
, node
, &znode
);
1059 dns_db_detachnode(db
, &node
);
1061 dns_db_attach(view
->cachedb
, &db
);
1065 * Otherwise, the glue is the best answer.
1067 result
= ISC_R_SUCCESS
;
1070 if (result
== ISC_R_NOTFOUND
&& use_hints
&& view
->hints
!= NULL
) {
1071 if (dns_rdataset_isassociated(rdataset
))
1072 dns_rdataset_disassociate(rdataset
);
1073 if (sigrdataset
!= NULL
&&
1074 dns_rdataset_isassociated(sigrdataset
))
1075 dns_rdataset_disassociate(sigrdataset
);
1078 dns_db_detachnode(db
, &node
);
1081 result
= dns_db_find(view
->hints
, name
, NULL
, type
, options
,
1082 now
, &node
, foundname
,
1083 rdataset
, sigrdataset
);
1084 if (result
== ISC_R_SUCCESS
|| result
== DNS_R_GLUE
) {
1086 * We just used a hint. Let the resolver know it
1087 * should consider priming.
1089 dns_resolver_prime(view
->resolver
);
1090 dns_db_attach(view
->hints
, &db
);
1091 result
= DNS_R_HINT
;
1092 } else if (result
== DNS_R_NXRRSET
) {
1093 dns_db_attach(view
->hints
, &db
);
1094 result
= DNS_R_HINTNXRRSET
;
1095 } else if (result
== DNS_R_NXDOMAIN
)
1096 result
= ISC_R_NOTFOUND
;
1099 * Cleanup if non-standard hints are used.
1101 if (db
== NULL
&& node
!= NULL
)
1102 dns_db_detachnode(view
->hints
, &node
);
1106 if (dns_rdataset_isassociated(&zrdataset
)) {
1107 dns_rdataset_disassociate(&zrdataset
);
1108 if (dns_rdataset_isassociated(&zsigrdataset
))
1109 dns_rdataset_disassociate(&zsigrdataset
);
1114 dns_db_detachnode(zdb
, &znode
);
1115 dns_db_detach(&zdb
);
1123 dns_db_detachnode(db
, &node
);
1130 INSIST(node
== NULL
);
1133 dns_zone_detach(&zone
);
1139 dns_view_simplefind(dns_view_t
*view
, dns_name_t
*name
, dns_rdatatype_t type
,
1140 isc_stdtime_t now
, unsigned int options
,
1141 isc_boolean_t use_hints
,
1142 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
)
1144 isc_result_t result
;
1145 dns_fixedname_t foundname
;
1147 dns_fixedname_init(&foundname
);
1148 result
= dns_view_find(view
, name
, type
, now
, options
, use_hints
,
1149 NULL
, NULL
, dns_fixedname_name(&foundname
),
1150 rdataset
, sigrdataset
);
1151 if (result
== DNS_R_NXDOMAIN
) {
1153 * The rdataset and sigrdataset of the relevant NSEC record
1154 * may be returned, but the caller cannot use them because
1155 * foundname is not returned by this simplified API. We
1156 * disassociate them here to prevent any misuse by the caller.
1158 if (dns_rdataset_isassociated(rdataset
))
1159 dns_rdataset_disassociate(rdataset
);
1160 if (sigrdataset
!= NULL
&&
1161 dns_rdataset_isassociated(sigrdataset
))
1162 dns_rdataset_disassociate(sigrdataset
);
1163 } else if (result
!= ISC_R_SUCCESS
&&
1164 result
!= DNS_R_GLUE
&&
1165 result
!= DNS_R_HINT
&&
1166 result
!= DNS_R_NCACHENXDOMAIN
&&
1167 result
!= DNS_R_NCACHENXRRSET
&&
1168 result
!= DNS_R_NXRRSET
&&
1169 result
!= DNS_R_HINTNXRRSET
&&
1170 result
!= ISC_R_NOTFOUND
) {
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 result
= ISC_R_NOTFOUND
;
1183 dns_view_findzonecut(dns_view_t
*view
, dns_name_t
*name
, dns_name_t
*fname
,
1184 isc_stdtime_t now
, unsigned int options
,
1185 isc_boolean_t use_hints
,
1186 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
)
1188 return(dns_view_findzonecut2(view
, name
, fname
, now
, options
,
1189 use_hints
, ISC_TRUE
,
1190 rdataset
, sigrdataset
));
1194 dns_view_findzonecut2(dns_view_t
*view
, dns_name_t
*name
, dns_name_t
*fname
,
1195 isc_stdtime_t now
, unsigned int options
,
1196 isc_boolean_t use_hints
, isc_boolean_t use_cache
,
1197 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
)
1199 isc_result_t result
;
1201 isc_boolean_t is_cache
, use_zone
, try_hints
;
1204 dns_rdataset_t zrdataset
, zsigrdataset
;
1205 dns_fixedname_t zfixedname
;
1206 unsigned int ztoptions
= 0;
1208 REQUIRE(DNS_VIEW_VALID(view
));
1209 REQUIRE(view
->frozen
);
1212 use_zone
= ISC_FALSE
;
1213 try_hints
= ISC_FALSE
;
1219 dns_fixedname_init(&zfixedname
);
1220 dns_rdataset_init(&zrdataset
);
1221 dns_rdataset_init(&zsigrdataset
);
1224 * Find the right database.
1228 if (view
->zonetable
!= NULL
) {
1229 if ((options
& DNS_DBFIND_NOEXACT
) != 0)
1230 ztoptions
|= DNS_ZTFIND_NOEXACT
;
1231 result
= dns_zt_find(view
->zonetable
, name
, ztoptions
,
1234 result
= ISC_R_NOTFOUND
;
1235 UNLOCK(&view
->lock
);
1236 if (result
== ISC_R_SUCCESS
|| result
== DNS_R_PARTIALMATCH
)
1237 result
= dns_zone_getdb(zone
, &db
);
1238 if (result
== ISC_R_NOTFOUND
) {
1240 * We're not directly authoritative for this query name, nor
1241 * is it a subdomain of any zone for which we're
1244 if (use_cache
&& view
->cachedb
!= NULL
) {
1246 * We have a cache; try it.
1248 dns_db_attach(view
->cachedb
, &db
);
1251 * Maybe we have hints...
1253 try_hints
= ISC_TRUE
;
1256 } else if (result
!= ISC_R_SUCCESS
) {
1258 * Something is broken.
1262 is_cache
= dns_db_iscache(db
);
1266 * Look for the zonecut.
1269 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_ns
, options
,
1270 now
, NULL
, fname
, rdataset
, sigrdataset
);
1271 if (result
== DNS_R_DELEGATION
)
1272 result
= ISC_R_SUCCESS
;
1273 else if (result
!= ISC_R_SUCCESS
)
1275 if (use_cache
&& view
->cachedb
!= NULL
&& db
!= view
->hints
) {
1277 * We found an answer, but the cache may be better.
1279 zfname
= dns_fixedname_name(&zfixedname
);
1280 result
= dns_name_copy(fname
, zfname
, NULL
);
1281 if (result
!= ISC_R_SUCCESS
)
1283 dns_rdataset_clone(rdataset
, &zrdataset
);
1284 dns_rdataset_disassociate(rdataset
);
1285 if (sigrdataset
!= NULL
&&
1286 dns_rdataset_isassociated(sigrdataset
)) {
1287 dns_rdataset_clone(sigrdataset
, &zsigrdataset
);
1288 dns_rdataset_disassociate(sigrdataset
);
1291 dns_db_attach(view
->cachedb
, &db
);
1292 is_cache
= ISC_TRUE
;
1296 result
= dns_db_findzonecut(db
, name
, options
, now
, NULL
,
1297 fname
, rdataset
, sigrdataset
);
1298 if (result
== ISC_R_SUCCESS
) {
1299 if (zfname
!= NULL
&&
1300 (!dns_name_issubdomain(fname
, zfname
) ||
1301 (dns_zone_staticstub
&&
1302 dns_name_equal(fname
, zfname
)))) {
1304 * We found a zonecut in the cache, but our
1305 * zone delegation is better.
1307 use_zone
= ISC_TRUE
;
1309 } else if (result
== ISC_R_NOTFOUND
) {
1310 if (zfname
!= NULL
) {
1312 * We didn't find anything in the cache, but we
1313 * have a zone delegation, so use it.
1315 use_zone
= ISC_TRUE
;
1318 * Maybe we have hints...
1320 try_hints
= ISC_TRUE
;
1324 * Something bad happened.
1332 if (dns_rdataset_isassociated(rdataset
)) {
1333 dns_rdataset_disassociate(rdataset
);
1334 if (sigrdataset
!= NULL
&&
1335 dns_rdataset_isassociated(sigrdataset
))
1336 dns_rdataset_disassociate(sigrdataset
);
1338 result
= dns_name_copy(zfname
, fname
, NULL
);
1339 if (result
!= ISC_R_SUCCESS
)
1341 dns_rdataset_clone(&zrdataset
, rdataset
);
1342 if (sigrdataset
!= NULL
&&
1343 dns_rdataset_isassociated(&zrdataset
))
1344 dns_rdataset_clone(&zsigrdataset
, sigrdataset
);
1345 } else if (try_hints
&& use_hints
&& view
->hints
!= NULL
) {
1347 * We've found nothing so far, but we have hints.
1349 result
= dns_db_find(view
->hints
, dns_rootname
, NULL
,
1350 dns_rdatatype_ns
, 0, now
, NULL
, fname
,
1352 if (result
!= ISC_R_SUCCESS
) {
1354 * We can't even find the hints for the root
1357 if (dns_rdataset_isassociated(rdataset
))
1358 dns_rdataset_disassociate(rdataset
);
1359 result
= ISC_R_NOTFOUND
;
1364 if (dns_rdataset_isassociated(&zrdataset
)) {
1365 dns_rdataset_disassociate(&zrdataset
);
1366 if (dns_rdataset_isassociated(&zsigrdataset
))
1367 dns_rdataset_disassociate(&zsigrdataset
);
1372 dns_zone_detach(&zone
);
1378 dns_viewlist_find(dns_viewlist_t
*list
, const char *name
,
1379 dns_rdataclass_t rdclass
, dns_view_t
**viewp
)
1383 REQUIRE(list
!= NULL
);
1385 for (view
= ISC_LIST_HEAD(*list
);
1387 view
= ISC_LIST_NEXT(view
, link
)) {
1388 if (strcmp(view
->name
, name
) == 0 && view
->rdclass
== rdclass
)
1392 return (ISC_R_NOTFOUND
);
1394 dns_view_attach(view
, viewp
);
1396 return (ISC_R_SUCCESS
);
1400 dns_viewlist_findzone(dns_viewlist_t
*list
, dns_name_t
*name
,
1401 isc_boolean_t allclasses
, dns_rdataclass_t rdclass
,
1405 isc_result_t result
;
1406 dns_zone_t
*zone1
= NULL
, *zone2
= NULL
;
1407 dns_zone_t
**zp
= NULL
;;
1409 REQUIRE(list
!= NULL
);
1410 REQUIRE(zonep
!= NULL
&& *zonep
== NULL
);
1412 for (view
= ISC_LIST_HEAD(*list
);
1414 view
= ISC_LIST_NEXT(view
, link
)) {
1415 if (allclasses
== ISC_FALSE
&& view
->rdclass
!= rdclass
)
1419 * If the zone is defined in more than one view,
1420 * treat it as not found.
1422 zp
= (zone1
== NULL
) ? &zone1
: &zone2
;
1424 if (view
->zonetable
!= NULL
)
1425 result
= dns_zt_find(view
->zonetable
, name
, 0,
1428 result
= ISC_R_NOTFOUND
;
1429 UNLOCK(&view
->lock
);
1430 INSIST(result
== ISC_R_SUCCESS
||
1431 result
== ISC_R_NOTFOUND
||
1432 result
== DNS_R_PARTIALMATCH
);
1434 /* Treat a partial match as no match */
1435 if (result
== DNS_R_PARTIALMATCH
) {
1436 dns_zone_detach(zp
);
1437 result
= ISC_R_NOTFOUND
;
1441 if (zone2
!= NULL
) {
1442 dns_zone_detach(&zone1
);
1443 dns_zone_detach(&zone2
);
1444 return (ISC_R_MULTIPLE
);
1448 if (zone1
!= NULL
) {
1449 dns_zone_attach(zone1
, zonep
);
1450 dns_zone_detach(&zone1
);
1451 return (ISC_R_SUCCESS
);
1454 return (ISC_R_NOTFOUND
);
1458 dns_view_load(dns_view_t
*view
, isc_boolean_t stop
) {
1460 REQUIRE(DNS_VIEW_VALID(view
));
1461 REQUIRE(view
->zonetable
!= NULL
);
1463 return (dns_zt_load(view
->zonetable
, stop
));
1467 dns_view_loadnew(dns_view_t
*view
, isc_boolean_t stop
) {
1469 REQUIRE(DNS_VIEW_VALID(view
));
1470 REQUIRE(view
->zonetable
!= NULL
);
1472 return (dns_zt_loadnew(view
->zonetable
, stop
));
1476 dns_view_asyncload(dns_view_t
*view
, dns_zt_allloaded_t callback
, void *arg
) {
1477 REQUIRE(DNS_VIEW_VALID(view
));
1478 REQUIRE(view
->zonetable
!= NULL
);
1480 return (dns_zt_asyncload(view
->zonetable
, callback
, arg
));
1484 dns_view_gettsig(dns_view_t
*view
, dns_name_t
*keyname
, dns_tsigkey_t
**keyp
)
1486 isc_result_t result
;
1487 REQUIRE(keyp
!= NULL
&& *keyp
== NULL
);
1489 result
= dns_tsigkey_find(keyp
, keyname
, NULL
,
1491 if (result
== ISC_R_NOTFOUND
)
1492 result
= dns_tsigkey_find(keyp
, keyname
, NULL
,
1498 dns_view_getpeertsig(dns_view_t
*view
, isc_netaddr_t
*peeraddr
,
1499 dns_tsigkey_t
**keyp
)
1501 isc_result_t result
;
1502 dns_name_t
*keyname
= NULL
;
1503 dns_peer_t
*peer
= NULL
;
1505 result
= dns_peerlist_peerbyaddr(view
->peers
, peeraddr
, &peer
);
1506 if (result
!= ISC_R_SUCCESS
)
1509 result
= dns_peer_getkey(peer
, &keyname
);
1510 if (result
!= ISC_R_SUCCESS
)
1513 result
= dns_view_gettsig(view
, keyname
, keyp
);
1514 return ((result
== ISC_R_NOTFOUND
) ? ISC_R_FAILURE
: result
);
1518 dns_view_checksig(dns_view_t
*view
, isc_buffer_t
*source
, dns_message_t
*msg
) {
1519 REQUIRE(DNS_VIEW_VALID(view
));
1520 REQUIRE(source
!= NULL
);
1522 return (dns_tsig_verify(source
, msg
, view
->statickeys
,
1523 view
->dynamickeys
));
1527 dns_view_dumpdbtostream(dns_view_t
*view
, FILE *fp
) {
1528 isc_result_t result
;
1530 REQUIRE(DNS_VIEW_VALID(view
));
1532 (void)fprintf(fp
, ";\n; Cache dump of view '%s'\n;\n", view
->name
);
1533 result
= dns_master_dumptostream(view
->mctx
, view
->cachedb
, NULL
,
1534 &dns_master_style_cache
, fp
);
1535 if (result
!= ISC_R_SUCCESS
)
1537 dns_adb_dump(view
->adb
, fp
);
1538 dns_resolver_printbadcache(view
->resolver
, fp
);
1539 return (ISC_R_SUCCESS
);
1543 dns_view_flushcache(dns_view_t
*view
) {
1544 return (dns_view_flushcache2(view
, ISC_FALSE
));
1548 dns_view_flushcache2(dns_view_t
*view
, isc_boolean_t fixuponly
) {
1549 isc_result_t result
;
1551 REQUIRE(DNS_VIEW_VALID(view
));
1553 if (view
->cachedb
== NULL
)
1554 return (ISC_R_SUCCESS
);
1556 result
= dns_cache_flush(view
->cache
);
1557 if (result
!= ISC_R_SUCCESS
)
1560 if (view
->acache
!= NULL
)
1561 dns_acache_putdb(view
->acache
, view
->cachedb
);
1562 dns_db_detach(&view
->cachedb
);
1563 dns_cache_attachdb(view
->cache
, &view
->cachedb
);
1564 if (view
->acache
!= NULL
)
1565 dns_acache_setdb(view
->acache
, view
->cachedb
);
1566 if (view
->resolver
!= NULL
)
1567 dns_resolver_flushbadcache(view
->resolver
, NULL
);
1569 dns_adb_flush(view
->adb
);
1570 return (ISC_R_SUCCESS
);
1574 dns_view_flushname(dns_view_t
*view
, dns_name_t
*name
) {
1575 return (dns_view_flushnode(view
, name
, ISC_FALSE
));
1579 dns_view_flushnode(dns_view_t
*view
, dns_name_t
*name
, isc_boolean_t tree
) {
1580 isc_result_t result
= ISC_R_SUCCESS
;
1582 REQUIRE(DNS_VIEW_VALID(view
));
1585 if (view
->adb
!= NULL
)
1586 dns_adb_flushnames(view
->adb
, name
);
1587 if (view
->resolver
!= NULL
)
1588 dns_resolver_flushbadnames(view
->resolver
, name
);
1590 if (view
->adb
!= NULL
)
1591 dns_adb_flushname(view
->adb
, name
);
1592 if (view
->resolver
!= NULL
)
1593 dns_resolver_flushbadcache(view
->resolver
, name
);
1596 if (view
->cache
!= NULL
)
1597 result
= dns_cache_flushnode(view
->cache
, name
, tree
);
1603 dns_view_adddelegationonly(dns_view_t
*view
, dns_name_t
*name
) {
1604 isc_result_t result
;
1608 REQUIRE(DNS_VIEW_VALID(view
));
1610 if (view
->delonly
== NULL
) {
1611 view
->delonly
= isc_mem_get(view
->mctx
,
1612 sizeof(dns_namelist_t
) *
1613 DNS_VIEW_DELONLYHASH
);
1614 if (view
->delonly
== NULL
)
1615 return (ISC_R_NOMEMORY
);
1616 for (hash
= 0; hash
< DNS_VIEW_DELONLYHASH
; hash
++)
1617 ISC_LIST_INIT(view
->delonly
[hash
]);
1619 hash
= dns_name_hash(name
, ISC_FALSE
) % DNS_VIEW_DELONLYHASH
;
1620 new = ISC_LIST_HEAD(view
->delonly
[hash
]);
1621 while (new != NULL
&& !dns_name_equal(new, name
))
1622 new = ISC_LIST_NEXT(new, link
);
1624 return (ISC_R_SUCCESS
);
1625 new = isc_mem_get(view
->mctx
, sizeof(*new));
1627 return (ISC_R_NOMEMORY
);
1628 dns_name_init(new, NULL
);
1629 result
= dns_name_dup(name
, view
->mctx
, new);
1630 if (result
== ISC_R_SUCCESS
)
1631 ISC_LIST_APPEND(view
->delonly
[hash
], new, link
);
1633 isc_mem_put(view
->mctx
, new, sizeof(*new));
1638 dns_view_excludedelegationonly(dns_view_t
*view
, dns_name_t
*name
) {
1639 isc_result_t result
;
1643 REQUIRE(DNS_VIEW_VALID(view
));
1645 if (view
->rootexclude
== NULL
) {
1646 view
->rootexclude
= isc_mem_get(view
->mctx
,
1647 sizeof(dns_namelist_t
) *
1648 DNS_VIEW_DELONLYHASH
);
1649 if (view
->rootexclude
== NULL
)
1650 return (ISC_R_NOMEMORY
);
1651 for (hash
= 0; hash
< DNS_VIEW_DELONLYHASH
; hash
++)
1652 ISC_LIST_INIT(view
->rootexclude
[hash
]);
1654 hash
= dns_name_hash(name
, ISC_FALSE
) % DNS_VIEW_DELONLYHASH
;
1655 new = ISC_LIST_HEAD(view
->rootexclude
[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
->rootexclude
[hash
], new, link
);
1668 isc_mem_put(view
->mctx
, new, sizeof(*new));
1673 dns_view_isdelegationonly(dns_view_t
*view
, dns_name_t
*name
) {
1677 REQUIRE(DNS_VIEW_VALID(view
));
1679 if (!view
->rootdelonly
&& view
->delonly
== NULL
)
1682 hash
= dns_name_hash(name
, ISC_FALSE
) % DNS_VIEW_DELONLYHASH
;
1683 if (view
->rootdelonly
&& dns_name_countlabels(name
) <= 2) {
1684 if (view
->rootexclude
== NULL
)
1686 new = ISC_LIST_HEAD(view
->rootexclude
[hash
]);
1687 while (new != NULL
&& !dns_name_equal(new, name
))
1688 new = ISC_LIST_NEXT(new, link
);
1693 if (view
->delonly
== NULL
)
1696 new = ISC_LIST_HEAD(view
->delonly
[hash
]);
1697 while (new != NULL
&& !dns_name_equal(new, name
))
1698 new = ISC_LIST_NEXT(new, link
);
1705 dns_view_setrootdelonly(dns_view_t
*view
, isc_boolean_t value
) {
1706 REQUIRE(DNS_VIEW_VALID(view
));
1707 view
->rootdelonly
= value
;
1711 dns_view_getrootdelonly(dns_view_t
*view
) {
1712 REQUIRE(DNS_VIEW_VALID(view
));
1713 return (view
->rootdelonly
);
1717 dns_view_freezezones(dns_view_t
*view
, isc_boolean_t value
) {
1719 REQUIRE(DNS_VIEW_VALID(view
));
1720 REQUIRE(view
->zonetable
!= NULL
);
1722 return (dns_zt_freezezones(view
->zonetable
, value
));
1726 dns_view_setadbstats(dns_view_t
*view
, isc_stats_t
*stats
) {
1727 REQUIRE(DNS_VIEW_VALID(view
));
1728 REQUIRE(!view
->frozen
);
1729 REQUIRE(view
->adbstats
== NULL
);
1731 isc_stats_attach(stats
, &view
->adbstats
);
1735 dns_view_getadbstats(dns_view_t
*view
, isc_stats_t
**statsp
) {
1736 REQUIRE(DNS_VIEW_VALID(view
));
1737 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
1739 if (view
->adbstats
!= NULL
)
1740 isc_stats_attach(view
->adbstats
, statsp
);
1744 dns_view_setresstats(dns_view_t
*view
, isc_stats_t
*stats
) {
1746 REQUIRE(DNS_VIEW_VALID(view
));
1747 REQUIRE(!view
->frozen
);
1748 REQUIRE(view
->resstats
== NULL
);
1750 isc_stats_attach(stats
, &view
->resstats
);
1754 dns_view_getresstats(dns_view_t
*view
, isc_stats_t
**statsp
) {
1755 REQUIRE(DNS_VIEW_VALID(view
));
1756 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
1758 if (view
->resstats
!= NULL
)
1759 isc_stats_attach(view
->resstats
, statsp
);
1763 dns_view_setresquerystats(dns_view_t
*view
, dns_stats_t
*stats
) {
1764 REQUIRE(DNS_VIEW_VALID(view
));
1765 REQUIRE(!view
->frozen
);
1766 REQUIRE(view
->resquerystats
== NULL
);
1768 dns_stats_attach(stats
, &view
->resquerystats
);
1772 dns_view_getresquerystats(dns_view_t
*view
, dns_stats_t
**statsp
) {
1773 REQUIRE(DNS_VIEW_VALID(view
));
1774 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
1776 if (view
->resquerystats
!= NULL
)
1777 dns_stats_attach(view
->resquerystats
, statsp
);
1781 dns_view_initsecroots(dns_view_t
*view
, isc_mem_t
*mctx
) {
1782 REQUIRE(DNS_VIEW_VALID(view
));
1783 if (view
->secroots_priv
!= NULL
)
1784 dns_keytable_detach(&view
->secroots_priv
);
1785 return (dns_keytable_create(mctx
, &view
->secroots_priv
));
1789 dns_view_getsecroots(dns_view_t
*view
, dns_keytable_t
**ktp
) {
1790 REQUIRE(DNS_VIEW_VALID(view
));
1791 REQUIRE(ktp
!= NULL
&& *ktp
== NULL
);
1792 if (view
->secroots_priv
== NULL
)
1793 return (ISC_R_NOTFOUND
);
1794 dns_keytable_attach(view
->secroots_priv
, ktp
);
1795 return (ISC_R_SUCCESS
);
1799 dns_view_issecuredomain(dns_view_t
*view
, dns_name_t
*name
,
1800 isc_boolean_t
*secure_domain
) {
1801 REQUIRE(DNS_VIEW_VALID(view
));
1803 if (view
->secroots_priv
== NULL
)
1804 return (ISC_R_NOTFOUND
);
1805 return (dns_keytable_issecuredomain(view
->secroots_priv
, name
,
1810 dns_view_untrust(dns_view_t
*view
, dns_name_t
*keyname
,
1811 dns_rdata_dnskey_t
*dnskey
, isc_mem_t
*mctx
)
1813 isc_result_t result
;
1814 unsigned char data
[4096];
1815 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1816 isc_buffer_t buffer
;
1817 dst_key_t
*key
= NULL
;
1818 dns_keytable_t
*sr
= NULL
;
1821 * Clear the revoke bit, if set, so that the key will match what's
1824 dnskey
->flags
&= ~DNS_KEYFLAG_REVOKE
;
1826 /* Convert dnskey to DST key. */
1827 isc_buffer_init(&buffer
, data
, sizeof(data
));
1828 dns_rdata_fromstruct(&rdata
, dnskey
->common
.rdclass
,
1829 dns_rdatatype_dnskey
, dnskey
, &buffer
);
1830 result
= dns_dnssec_keyfromrdata(keyname
, &rdata
, mctx
, &key
);
1831 if (result
!= ISC_R_SUCCESS
)
1833 result
= dns_view_getsecroots(view
, &sr
);
1834 if (result
== ISC_R_SUCCESS
) {
1835 dns_keytable_deletekeynode(sr
, key
);
1836 dns_keytable_detach(&sr
);
1844 dns_view_setnewzones(dns_view_t
*view
, isc_boolean_t allow
, void *cfgctx
,
1845 void (*cfg_destroy
)(void **))
1847 REQUIRE(DNS_VIEW_VALID(view
));
1848 REQUIRE((cfgctx
!= NULL
&& cfg_destroy
!= NULL
) || !allow
);
1850 if (view
->new_zone_file
!= NULL
) {
1851 isc_mem_free(view
->mctx
, view
->new_zone_file
);
1852 view
->new_zone_file
= NULL
;
1855 if (view
->new_zone_config
!= NULL
) {
1856 view
->cfg_destroy(&view
->new_zone_config
);
1857 view
->cfg_destroy
= NULL
;
1861 char buffer
[ISC_SHA256_DIGESTSTRINGLENGTH
+ sizeof(NZF
)];
1862 isc_sha256_data((void *)view
->name
, strlen(view
->name
), buffer
);
1863 /* Truncate the hash at 16 chars; full length is overkill */
1864 isc_string_printf(buffer
+ 16, sizeof(NZF
), "%s", NZF
);
1865 view
->new_zone_file
= isc_mem_strdup(view
->mctx
, buffer
);
1866 view
->new_zone_config
= cfgctx
;
1867 view
->cfg_destroy
= cfg_destroy
;
1872 dns_view_searchdlz(dns_view_t
*view
, dns_name_t
*name
, unsigned int minlabels
,
1873 dns_clientinfomethods_t
*methods
,
1874 dns_clientinfo_t
*clientinfo
,
1877 dns_fixedname_t fname
;
1878 dns_name_t
*zonename
;
1879 unsigned int namelabels
;
1881 isc_result_t result
;
1882 dns_dlzfindzone_t findzone
;
1884 dns_db_t
*db
, *best
= NULL
;
1887 * Performs checks to make sure data is as we expect it to be.
1889 REQUIRE(DNS_VIEW_VALID(view
));
1890 REQUIRE(name
!= NULL
);
1891 REQUIRE(dbp
!= NULL
&& *dbp
== NULL
);
1893 /* setup a "fixed" dns name */
1894 dns_fixedname_init(&fname
);
1895 zonename
= dns_fixedname_name(&fname
);
1897 /* count the number of labels in the name */
1898 namelabels
= dns_name_countlabels(name
);
1900 for (dlzdb
= ISC_LIST_HEAD(view
->dlz_searched
);
1902 dlzdb
= ISC_LIST_NEXT(dlzdb
, link
))
1904 REQUIRE(DNS_DLZ_VALID(dlzdb
));
1907 * loop through starting with the longest domain name and
1908 * trying shorter names portions of the name until we find a
1909 * match, have an error, or are below the 'minlabels'
1910 * threshold. minlabels is 0, if neither the standard
1911 * database nor any previous DLZ database had a zone name
1912 * match. Otherwise minlabels is the number of labels
1913 * in that name. We need to beat that for a "better"
1914 * match for this DLZ database to be authoritative.
1916 for (i
= namelabels
; i
> minlabels
&& i
> 1; i
--) {
1917 if (i
== namelabels
) {
1918 result
= dns_name_copy(name
, zonename
, NULL
);
1919 if (result
!= ISC_R_SUCCESS
)
1922 dns_name_split(name
, i
, NULL
, zonename
);
1924 /* ask SDLZ driver if the zone is supported */
1926 findzone
= dlzdb
->implementation
->methods
->findzone
;
1927 result
= (*findzone
)(dlzdb
->implementation
->driverarg
,
1928 dlzdb
->dbdata
, dlzdb
->mctx
,
1929 view
->rdclass
, zonename
,
1930 methods
, clientinfo
, &db
);
1932 if (result
!= ISC_R_NOTFOUND
) {
1934 dns_db_detach(&best
);
1935 if (result
== ISC_R_SUCCESS
) {
1937 dns_db_attach(db
, &best
);
1945 } else if (db
!= NULL
)
1951 dns_db_attach(best
, dbp
);
1952 dns_db_detach(&best
);
1953 return (ISC_R_SUCCESS
);
1956 return (ISC_R_NOTFOUND
);