1*00b67f09SDavid van Moolenbroek /* $NetBSD: view.c,v 1.10 2014/12/10 04:37:58 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 1999-2003 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek
26*00b67f09SDavid van Moolenbroek #include <isc/file.h>
27*00b67f09SDavid van Moolenbroek #include <isc/hash.h>
28*00b67f09SDavid van Moolenbroek #include <isc/print.h>
29*00b67f09SDavid van Moolenbroek #include <isc/sha2.h>
30*00b67f09SDavid van Moolenbroek #include <isc/stats.h>
31*00b67f09SDavid van Moolenbroek #include <isc/string.h> /* Required for HP/UX (and others?) */
32*00b67f09SDavid van Moolenbroek #include <isc/task.h>
33*00b67f09SDavid van Moolenbroek #include <isc/util.h>
34*00b67f09SDavid van Moolenbroek
35*00b67f09SDavid van Moolenbroek #include <dns/acache.h>
36*00b67f09SDavid van Moolenbroek #include <dns/acl.h>
37*00b67f09SDavid van Moolenbroek #include <dns/adb.h>
38*00b67f09SDavid van Moolenbroek #include <dns/cache.h>
39*00b67f09SDavid van Moolenbroek #include <dns/db.h>
40*00b67f09SDavid van Moolenbroek #include <dns/dispatch.h>
41*00b67f09SDavid van Moolenbroek #include <dns/dlz.h>
42*00b67f09SDavid van Moolenbroek #include <dns/dns64.h>
43*00b67f09SDavid van Moolenbroek #include <dns/dnssec.h>
44*00b67f09SDavid van Moolenbroek #include <dns/events.h>
45*00b67f09SDavid van Moolenbroek #include <dns/forward.h>
46*00b67f09SDavid van Moolenbroek #include <dns/keytable.h>
47*00b67f09SDavid van Moolenbroek #include <dns/keyvalues.h>
48*00b67f09SDavid van Moolenbroek #include <dns/master.h>
49*00b67f09SDavid van Moolenbroek #include <dns/masterdump.h>
50*00b67f09SDavid van Moolenbroek #include <dns/order.h>
51*00b67f09SDavid van Moolenbroek #include <dns/peer.h>
52*00b67f09SDavid van Moolenbroek #include <dns/rrl.h>
53*00b67f09SDavid van Moolenbroek #include <dns/rbt.h>
54*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
55*00b67f09SDavid van Moolenbroek #include <dns/request.h>
56*00b67f09SDavid van Moolenbroek #include <dns/resolver.h>
57*00b67f09SDavid van Moolenbroek #include <dns/result.h>
58*00b67f09SDavid van Moolenbroek #include <dns/rpz.h>
59*00b67f09SDavid van Moolenbroek #include <dns/stats.h>
60*00b67f09SDavid van Moolenbroek #include <dns/tsig.h>
61*00b67f09SDavid van Moolenbroek #include <dns/zone.h>
62*00b67f09SDavid van Moolenbroek #include <dns/zt.h>
63*00b67f09SDavid van Moolenbroek
64*00b67f09SDavid van Moolenbroek #define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0)
65*00b67f09SDavid van Moolenbroek #define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0)
66*00b67f09SDavid van Moolenbroek #define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0)
67*00b67f09SDavid van Moolenbroek
68*00b67f09SDavid van Moolenbroek #define DNS_VIEW_DELONLYHASH 111
69*00b67f09SDavid van Moolenbroek
70*00b67f09SDavid van Moolenbroek static void resolver_shutdown(isc_task_t *task, isc_event_t *event);
71*00b67f09SDavid van Moolenbroek static void adb_shutdown(isc_task_t *task, isc_event_t *event);
72*00b67f09SDavid van Moolenbroek static void req_shutdown(isc_task_t *task, isc_event_t *event);
73*00b67f09SDavid van Moolenbroek
74*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_create(isc_mem_t * mctx,dns_rdataclass_t rdclass,const char * name,dns_view_t ** viewp)75*00b67f09SDavid van Moolenbroek dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
76*00b67f09SDavid van Moolenbroek const char *name, dns_view_t **viewp)
77*00b67f09SDavid van Moolenbroek {
78*00b67f09SDavid van Moolenbroek dns_view_t *view;
79*00b67f09SDavid van Moolenbroek isc_result_t result;
80*00b67f09SDavid van Moolenbroek
81*00b67f09SDavid van Moolenbroek /*
82*00b67f09SDavid van Moolenbroek * Create a view.
83*00b67f09SDavid van Moolenbroek */
84*00b67f09SDavid van Moolenbroek
85*00b67f09SDavid van Moolenbroek REQUIRE(name != NULL);
86*00b67f09SDavid van Moolenbroek REQUIRE(viewp != NULL && *viewp == NULL);
87*00b67f09SDavid van Moolenbroek
88*00b67f09SDavid van Moolenbroek view = isc_mem_get(mctx, sizeof(*view));
89*00b67f09SDavid van Moolenbroek if (view == NULL)
90*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
91*00b67f09SDavid van Moolenbroek
92*00b67f09SDavid van Moolenbroek view->mctx = NULL;
93*00b67f09SDavid van Moolenbroek isc_mem_attach(mctx, &view->mctx);
94*00b67f09SDavid van Moolenbroek view->name = isc_mem_strdup(mctx, name);
95*00b67f09SDavid van Moolenbroek if (view->name == NULL) {
96*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
97*00b67f09SDavid van Moolenbroek goto cleanup_view;
98*00b67f09SDavid van Moolenbroek }
99*00b67f09SDavid van Moolenbroek result = isc_mutex_init(&view->lock);
100*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
101*00b67f09SDavid van Moolenbroek goto cleanup_name;
102*00b67f09SDavid van Moolenbroek
103*00b67f09SDavid van Moolenbroek view->zonetable = NULL;
104*00b67f09SDavid van Moolenbroek if (isc_bind9) {
105*00b67f09SDavid van Moolenbroek result = dns_zt_create(mctx, rdclass, &view->zonetable);
106*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
107*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
108*00b67f09SDavid van Moolenbroek "dns_zt_create() failed: %s",
109*00b67f09SDavid van Moolenbroek isc_result_totext(result));
110*00b67f09SDavid van Moolenbroek result = ISC_R_UNEXPECTED;
111*00b67f09SDavid van Moolenbroek goto cleanup_mutex;
112*00b67f09SDavid van Moolenbroek }
113*00b67f09SDavid van Moolenbroek }
114*00b67f09SDavid van Moolenbroek view->secroots_priv = NULL;
115*00b67f09SDavid van Moolenbroek view->fwdtable = NULL;
116*00b67f09SDavid van Moolenbroek result = dns_fwdtable_create(mctx, &view->fwdtable);
117*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
118*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
119*00b67f09SDavid van Moolenbroek "dns_fwdtable_create() failed: %s",
120*00b67f09SDavid van Moolenbroek isc_result_totext(result));
121*00b67f09SDavid van Moolenbroek result = ISC_R_UNEXPECTED;
122*00b67f09SDavid van Moolenbroek goto cleanup_zt;
123*00b67f09SDavid van Moolenbroek }
124*00b67f09SDavid van Moolenbroek
125*00b67f09SDavid van Moolenbroek view->acache = NULL;
126*00b67f09SDavid van Moolenbroek view->cache = NULL;
127*00b67f09SDavid van Moolenbroek view->cachedb = NULL;
128*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(view->dlz_searched);
129*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(view->dlz_unsearched);
130*00b67f09SDavid van Moolenbroek view->hints = NULL;
131*00b67f09SDavid van Moolenbroek view->resolver = NULL;
132*00b67f09SDavid van Moolenbroek view->adb = NULL;
133*00b67f09SDavid van Moolenbroek view->requestmgr = NULL;
134*00b67f09SDavid van Moolenbroek view->rdclass = rdclass;
135*00b67f09SDavid van Moolenbroek view->frozen = ISC_FALSE;
136*00b67f09SDavid van Moolenbroek view->task = NULL;
137*00b67f09SDavid van Moolenbroek result = isc_refcount_init(&view->references, 1);
138*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
139*00b67f09SDavid van Moolenbroek goto cleanup_fwdtable;
140*00b67f09SDavid van Moolenbroek view->weakrefs = 0;
141*00b67f09SDavid van Moolenbroek view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
142*00b67f09SDavid van Moolenbroek DNS_VIEWATTR_REQSHUTDOWN);
143*00b67f09SDavid van Moolenbroek view->statickeys = NULL;
144*00b67f09SDavid van Moolenbroek view->dynamickeys = NULL;
145*00b67f09SDavid van Moolenbroek view->matchclients = NULL;
146*00b67f09SDavid van Moolenbroek view->matchdestinations = NULL;
147*00b67f09SDavid van Moolenbroek view->matchrecursiveonly = ISC_FALSE;
148*00b67f09SDavid van Moolenbroek result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
149*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
150*00b67f09SDavid van Moolenbroek goto cleanup_references;
151*00b67f09SDavid van Moolenbroek view->peers = NULL;
152*00b67f09SDavid van Moolenbroek view->order = NULL;
153*00b67f09SDavid van Moolenbroek view->delonly = NULL;
154*00b67f09SDavid van Moolenbroek view->rootdelonly = ISC_FALSE;
155*00b67f09SDavid van Moolenbroek view->rootexclude = NULL;
156*00b67f09SDavid van Moolenbroek view->adbstats = NULL;
157*00b67f09SDavid van Moolenbroek view->resstats = NULL;
158*00b67f09SDavid van Moolenbroek view->resquerystats = NULL;
159*00b67f09SDavid van Moolenbroek view->cacheshared = ISC_FALSE;
160*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(view->dns64);
161*00b67f09SDavid van Moolenbroek view->dns64cnt = 0;
162*00b67f09SDavid van Moolenbroek
163*00b67f09SDavid van Moolenbroek /*
164*00b67f09SDavid van Moolenbroek * Initialize configuration data with default values.
165*00b67f09SDavid van Moolenbroek */
166*00b67f09SDavid van Moolenbroek view->recursion = ISC_TRUE;
167*00b67f09SDavid van Moolenbroek view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
168*00b67f09SDavid van Moolenbroek view->additionalfromcache = ISC_TRUE;
169*00b67f09SDavid van Moolenbroek view->additionalfromauth = ISC_TRUE;
170*00b67f09SDavid van Moolenbroek view->enablednssec = ISC_TRUE;
171*00b67f09SDavid van Moolenbroek view->enablevalidation = ISC_TRUE;
172*00b67f09SDavid van Moolenbroek view->acceptexpired = ISC_FALSE;
173*00b67f09SDavid van Moolenbroek view->minimalresponses = ISC_FALSE;
174*00b67f09SDavid van Moolenbroek view->transfer_format = dns_one_answer;
175*00b67f09SDavid van Moolenbroek view->cacheacl = NULL;
176*00b67f09SDavid van Moolenbroek view->cacheonacl = NULL;
177*00b67f09SDavid van Moolenbroek view->queryacl = NULL;
178*00b67f09SDavid van Moolenbroek view->queryonacl = NULL;
179*00b67f09SDavid van Moolenbroek view->recursionacl = NULL;
180*00b67f09SDavid van Moolenbroek view->recursiononacl = NULL;
181*00b67f09SDavid van Moolenbroek view->sortlist = NULL;
182*00b67f09SDavid van Moolenbroek view->transferacl = NULL;
183*00b67f09SDavid van Moolenbroek view->notifyacl = NULL;
184*00b67f09SDavid van Moolenbroek view->updateacl = NULL;
185*00b67f09SDavid van Moolenbroek view->upfwdacl = NULL;
186*00b67f09SDavid van Moolenbroek view->denyansweracl = NULL;
187*00b67f09SDavid van Moolenbroek view->nocasecompress = NULL;
188*00b67f09SDavid van Moolenbroek view->answeracl_exclude = NULL;
189*00b67f09SDavid van Moolenbroek view->denyanswernames = NULL;
190*00b67f09SDavid van Moolenbroek view->answernames_exclude = NULL;
191*00b67f09SDavid van Moolenbroek view->rrl = NULL;
192*00b67f09SDavid van Moolenbroek view->provideixfr = ISC_TRUE;
193*00b67f09SDavid van Moolenbroek view->maxcachettl = 7 * 24 * 3600;
194*00b67f09SDavid van Moolenbroek view->maxncachettl = 3 * 3600;
195*00b67f09SDavid van Moolenbroek view->prefetch_eligible = 0;
196*00b67f09SDavid van Moolenbroek view->prefetch_trigger = 0;
197*00b67f09SDavid van Moolenbroek view->dstport = 53;
198*00b67f09SDavid van Moolenbroek view->preferred_glue = 0;
199*00b67f09SDavid van Moolenbroek view->flush = ISC_FALSE;
200*00b67f09SDavid van Moolenbroek view->dlv = NULL;
201*00b67f09SDavid van Moolenbroek view->maxudp = 0;
202*00b67f09SDavid van Moolenbroek view->situdp = 0;
203*00b67f09SDavid van Moolenbroek view->maxbits = 0;
204*00b67f09SDavid van Moolenbroek view->v4_aaaa = dns_aaaa_ok;
205*00b67f09SDavid van Moolenbroek view->v6_aaaa = dns_aaaa_ok;
206*00b67f09SDavid van Moolenbroek view->aaaa_acl = NULL;
207*00b67f09SDavid van Moolenbroek view->rpzs = NULL;
208*00b67f09SDavid van Moolenbroek dns_fixedname_init(&view->dlv_fixed);
209*00b67f09SDavid van Moolenbroek view->managed_keys = NULL;
210*00b67f09SDavid van Moolenbroek view->redirect = NULL;
211*00b67f09SDavid van Moolenbroek view->requestnsid = ISC_FALSE;
212*00b67f09SDavid van Moolenbroek view->requestsit = ISC_TRUE;
213*00b67f09SDavid van Moolenbroek view->new_zone_file = NULL;
214*00b67f09SDavid van Moolenbroek view->new_zone_config = NULL;
215*00b67f09SDavid van Moolenbroek view->cfg_destroy = NULL;
216*00b67f09SDavid van Moolenbroek
217*00b67f09SDavid van Moolenbroek if (isc_bind9) {
218*00b67f09SDavid van Moolenbroek result = dns_order_create(view->mctx, &view->order);
219*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
220*00b67f09SDavid van Moolenbroek goto cleanup_dynkeys;
221*00b67f09SDavid van Moolenbroek }
222*00b67f09SDavid van Moolenbroek
223*00b67f09SDavid van Moolenbroek result = dns_peerlist_new(view->mctx, &view->peers);
224*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
225*00b67f09SDavid van Moolenbroek goto cleanup_order;
226*00b67f09SDavid van Moolenbroek
227*00b67f09SDavid van Moolenbroek result = dns_aclenv_init(view->mctx, &view->aclenv);
228*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
229*00b67f09SDavid van Moolenbroek goto cleanup_peerlist;
230*00b67f09SDavid van Moolenbroek
231*00b67f09SDavid van Moolenbroek ISC_LINK_INIT(view, link);
232*00b67f09SDavid van Moolenbroek ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
233*00b67f09SDavid van Moolenbroek DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
234*00b67f09SDavid van Moolenbroek view, NULL, NULL, NULL);
235*00b67f09SDavid van Moolenbroek ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
236*00b67f09SDavid van Moolenbroek DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
237*00b67f09SDavid van Moolenbroek view, NULL, NULL, NULL);
238*00b67f09SDavid van Moolenbroek ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
239*00b67f09SDavid van Moolenbroek DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
240*00b67f09SDavid van Moolenbroek view, NULL, NULL, NULL);
241*00b67f09SDavid van Moolenbroek view->viewlist = NULL;
242*00b67f09SDavid van Moolenbroek view->magic = DNS_VIEW_MAGIC;
243*00b67f09SDavid van Moolenbroek
244*00b67f09SDavid van Moolenbroek *viewp = view;
245*00b67f09SDavid van Moolenbroek
246*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
247*00b67f09SDavid van Moolenbroek
248*00b67f09SDavid van Moolenbroek cleanup_peerlist:
249*00b67f09SDavid van Moolenbroek if (view->peers != NULL)
250*00b67f09SDavid van Moolenbroek dns_peerlist_detach(&view->peers);
251*00b67f09SDavid van Moolenbroek
252*00b67f09SDavid van Moolenbroek cleanup_order:
253*00b67f09SDavid van Moolenbroek if (view->order != NULL)
254*00b67f09SDavid van Moolenbroek dns_order_detach(&view->order);
255*00b67f09SDavid van Moolenbroek
256*00b67f09SDavid van Moolenbroek cleanup_dynkeys:
257*00b67f09SDavid van Moolenbroek if (view->dynamickeys != NULL)
258*00b67f09SDavid van Moolenbroek dns_tsigkeyring_detach(&view->dynamickeys);
259*00b67f09SDavid van Moolenbroek
260*00b67f09SDavid van Moolenbroek cleanup_references:
261*00b67f09SDavid van Moolenbroek isc_refcount_destroy(&view->references);
262*00b67f09SDavid van Moolenbroek
263*00b67f09SDavid van Moolenbroek cleanup_fwdtable:
264*00b67f09SDavid van Moolenbroek if (view->fwdtable != NULL)
265*00b67f09SDavid van Moolenbroek dns_fwdtable_destroy(&view->fwdtable);
266*00b67f09SDavid van Moolenbroek
267*00b67f09SDavid van Moolenbroek cleanup_zt:
268*00b67f09SDavid van Moolenbroek if (view->zonetable != NULL)
269*00b67f09SDavid van Moolenbroek dns_zt_detach(&view->zonetable);
270*00b67f09SDavid van Moolenbroek
271*00b67f09SDavid van Moolenbroek cleanup_mutex:
272*00b67f09SDavid van Moolenbroek DESTROYLOCK(&view->lock);
273*00b67f09SDavid van Moolenbroek
274*00b67f09SDavid van Moolenbroek cleanup_name:
275*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, view->name);
276*00b67f09SDavid van Moolenbroek
277*00b67f09SDavid van Moolenbroek cleanup_view:
278*00b67f09SDavid van Moolenbroek isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
279*00b67f09SDavid van Moolenbroek
280*00b67f09SDavid van Moolenbroek return (result);
281*00b67f09SDavid van Moolenbroek }
282*00b67f09SDavid van Moolenbroek
283*00b67f09SDavid van Moolenbroek static inline void
destroy(dns_view_t * view)284*00b67f09SDavid van Moolenbroek destroy(dns_view_t *view) {
285*00b67f09SDavid van Moolenbroek dns_dns64_t *dns64;
286*00b67f09SDavid van Moolenbroek dns_dlzdb_t *dlzdb;
287*00b67f09SDavid van Moolenbroek
288*00b67f09SDavid van Moolenbroek REQUIRE(!ISC_LINK_LINKED(view, link));
289*00b67f09SDavid van Moolenbroek REQUIRE(isc_refcount_current(&view->references) == 0);
290*00b67f09SDavid van Moolenbroek REQUIRE(view->weakrefs == 0);
291*00b67f09SDavid van Moolenbroek REQUIRE(RESSHUTDOWN(view));
292*00b67f09SDavid van Moolenbroek REQUIRE(ADBSHUTDOWN(view));
293*00b67f09SDavid van Moolenbroek REQUIRE(REQSHUTDOWN(view));
294*00b67f09SDavid van Moolenbroek
295*00b67f09SDavid van Moolenbroek if (view->order != NULL)
296*00b67f09SDavid van Moolenbroek dns_order_detach(&view->order);
297*00b67f09SDavid van Moolenbroek if (view->peers != NULL)
298*00b67f09SDavid van Moolenbroek dns_peerlist_detach(&view->peers);
299*00b67f09SDavid van Moolenbroek
300*00b67f09SDavid van Moolenbroek if (view->dynamickeys != NULL) {
301*00b67f09SDavid van Moolenbroek isc_result_t result;
302*00b67f09SDavid van Moolenbroek char template[20];
303*00b67f09SDavid van Moolenbroek char keyfile[20];
304*00b67f09SDavid van Moolenbroek FILE *fp = NULL;
305*00b67f09SDavid van Moolenbroek int n;
306*00b67f09SDavid van Moolenbroek
307*00b67f09SDavid van Moolenbroek n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
308*00b67f09SDavid van Moolenbroek view->name);
309*00b67f09SDavid van Moolenbroek if (n > 0 && (size_t)n < sizeof(keyfile)) {
310*00b67f09SDavid van Moolenbroek result = isc_file_mktemplate(keyfile, template,
311*00b67f09SDavid van Moolenbroek sizeof(template));
312*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
313*00b67f09SDavid van Moolenbroek (void)isc_file_openuniqueprivate(template, &fp);
314*00b67f09SDavid van Moolenbroek }
315*00b67f09SDavid van Moolenbroek if (fp == NULL)
316*00b67f09SDavid van Moolenbroek dns_tsigkeyring_detach(&view->dynamickeys);
317*00b67f09SDavid van Moolenbroek else {
318*00b67f09SDavid van Moolenbroek result = dns_tsigkeyring_dumpanddetach(
319*00b67f09SDavid van Moolenbroek &view->dynamickeys, fp);
320*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
321*00b67f09SDavid van Moolenbroek if (fclose(fp) == 0)
322*00b67f09SDavid van Moolenbroek result = isc_file_rename(template,
323*00b67f09SDavid van Moolenbroek keyfile);
324*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
325*00b67f09SDavid van Moolenbroek (void)remove(template);
326*00b67f09SDavid van Moolenbroek } else {
327*00b67f09SDavid van Moolenbroek (void)fclose(fp);
328*00b67f09SDavid van Moolenbroek (void)remove(template);
329*00b67f09SDavid van Moolenbroek }
330*00b67f09SDavid van Moolenbroek }
331*00b67f09SDavid van Moolenbroek }
332*00b67f09SDavid van Moolenbroek if (view->statickeys != NULL)
333*00b67f09SDavid van Moolenbroek dns_tsigkeyring_detach(&view->statickeys);
334*00b67f09SDavid van Moolenbroek if (view->adb != NULL)
335*00b67f09SDavid van Moolenbroek dns_adb_detach(&view->adb);
336*00b67f09SDavid van Moolenbroek if (view->resolver != NULL)
337*00b67f09SDavid van Moolenbroek dns_resolver_detach(&view->resolver);
338*00b67f09SDavid van Moolenbroek if (view->acache != NULL) {
339*00b67f09SDavid van Moolenbroek if (view->cachedb != NULL)
340*00b67f09SDavid van Moolenbroek dns_acache_putdb(view->acache, view->cachedb);
341*00b67f09SDavid van Moolenbroek dns_acache_detach(&view->acache);
342*00b67f09SDavid van Moolenbroek }
343*00b67f09SDavid van Moolenbroek dns_rrl_view_destroy(view);
344*00b67f09SDavid van Moolenbroek if (view->rpzs != NULL)
345*00b67f09SDavid van Moolenbroek dns_rpz_detach_rpzs(&view->rpzs);
346*00b67f09SDavid van Moolenbroek for (dlzdb = ISC_LIST_HEAD(view->dlz_searched);
347*00b67f09SDavid van Moolenbroek dlzdb != NULL;
348*00b67f09SDavid van Moolenbroek dlzdb = ISC_LIST_HEAD(view->dlz_searched)) {
349*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(view->dlz_searched, dlzdb, link);
350*00b67f09SDavid van Moolenbroek dns_dlzdestroy(&dlzdb);
351*00b67f09SDavid van Moolenbroek }
352*00b67f09SDavid van Moolenbroek for (dlzdb = ISC_LIST_HEAD(view->dlz_unsearched);
353*00b67f09SDavid van Moolenbroek dlzdb != NULL;
354*00b67f09SDavid van Moolenbroek dlzdb = ISC_LIST_HEAD(view->dlz_unsearched)) {
355*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(view->dlz_unsearched, dlzdb, link);
356*00b67f09SDavid van Moolenbroek dns_dlzdestroy(&dlzdb);
357*00b67f09SDavid van Moolenbroek }
358*00b67f09SDavid van Moolenbroek if (view->requestmgr != NULL)
359*00b67f09SDavid van Moolenbroek dns_requestmgr_detach(&view->requestmgr);
360*00b67f09SDavid van Moolenbroek if (view->task != NULL)
361*00b67f09SDavid van Moolenbroek isc_task_detach(&view->task);
362*00b67f09SDavid van Moolenbroek if (view->hints != NULL)
363*00b67f09SDavid van Moolenbroek dns_db_detach(&view->hints);
364*00b67f09SDavid van Moolenbroek if (view->cachedb != NULL)
365*00b67f09SDavid van Moolenbroek dns_db_detach(&view->cachedb);
366*00b67f09SDavid van Moolenbroek if (view->cache != NULL)
367*00b67f09SDavid van Moolenbroek dns_cache_detach(&view->cache);
368*00b67f09SDavid van Moolenbroek if (view->nocasecompress != NULL)
369*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->nocasecompress);
370*00b67f09SDavid van Moolenbroek if (view->matchclients != NULL)
371*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->matchclients);
372*00b67f09SDavid van Moolenbroek if (view->matchdestinations != NULL)
373*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->matchdestinations);
374*00b67f09SDavid van Moolenbroek if (view->cacheacl != NULL)
375*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->cacheacl);
376*00b67f09SDavid van Moolenbroek if (view->cacheonacl != NULL)
377*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->cacheonacl);
378*00b67f09SDavid van Moolenbroek if (view->queryacl != NULL)
379*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->queryacl);
380*00b67f09SDavid van Moolenbroek if (view->queryonacl != NULL)
381*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->queryonacl);
382*00b67f09SDavid van Moolenbroek if (view->recursionacl != NULL)
383*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->recursionacl);
384*00b67f09SDavid van Moolenbroek if (view->recursiononacl != NULL)
385*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->recursiononacl);
386*00b67f09SDavid van Moolenbroek if (view->sortlist != NULL)
387*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->sortlist);
388*00b67f09SDavid van Moolenbroek if (view->transferacl != NULL)
389*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->transferacl);
390*00b67f09SDavid van Moolenbroek if (view->notifyacl != NULL)
391*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->notifyacl);
392*00b67f09SDavid van Moolenbroek if (view->updateacl != NULL)
393*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->updateacl);
394*00b67f09SDavid van Moolenbroek if (view->upfwdacl != NULL)
395*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->upfwdacl);
396*00b67f09SDavid van Moolenbroek if (view->denyansweracl != NULL)
397*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->denyansweracl);
398*00b67f09SDavid van Moolenbroek if (view->aaaa_acl != NULL)
399*00b67f09SDavid van Moolenbroek dns_acl_detach(&view->aaaa_acl);
400*00b67f09SDavid van Moolenbroek if (view->answeracl_exclude != NULL)
401*00b67f09SDavid van Moolenbroek dns_rbt_destroy(&view->answeracl_exclude);
402*00b67f09SDavid van Moolenbroek if (view->denyanswernames != NULL)
403*00b67f09SDavid van Moolenbroek dns_rbt_destroy(&view->denyanswernames);
404*00b67f09SDavid van Moolenbroek if (view->answernames_exclude != NULL)
405*00b67f09SDavid van Moolenbroek dns_rbt_destroy(&view->answernames_exclude);
406*00b67f09SDavid van Moolenbroek if (view->delonly != NULL) {
407*00b67f09SDavid van Moolenbroek dns_name_t *name;
408*00b67f09SDavid van Moolenbroek int i;
409*00b67f09SDavid van Moolenbroek
410*00b67f09SDavid van Moolenbroek for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
411*00b67f09SDavid van Moolenbroek name = ISC_LIST_HEAD(view->delonly[i]);
412*00b67f09SDavid van Moolenbroek while (name != NULL) {
413*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(view->delonly[i], name, link);
414*00b67f09SDavid van Moolenbroek dns_name_free(name, view->mctx);
415*00b67f09SDavid van Moolenbroek isc_mem_put(view->mctx, name, sizeof(*name));
416*00b67f09SDavid van Moolenbroek name = ISC_LIST_HEAD(view->delonly[i]);
417*00b67f09SDavid van Moolenbroek }
418*00b67f09SDavid van Moolenbroek }
419*00b67f09SDavid van Moolenbroek isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) *
420*00b67f09SDavid van Moolenbroek DNS_VIEW_DELONLYHASH);
421*00b67f09SDavid van Moolenbroek view->delonly = NULL;
422*00b67f09SDavid van Moolenbroek }
423*00b67f09SDavid van Moolenbroek if (view->rootexclude != NULL) {
424*00b67f09SDavid van Moolenbroek dns_name_t *name;
425*00b67f09SDavid van Moolenbroek int i;
426*00b67f09SDavid van Moolenbroek
427*00b67f09SDavid van Moolenbroek for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
428*00b67f09SDavid van Moolenbroek name = ISC_LIST_HEAD(view->rootexclude[i]);
429*00b67f09SDavid van Moolenbroek while (name != NULL) {
430*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(view->rootexclude[i],
431*00b67f09SDavid van Moolenbroek name, link);
432*00b67f09SDavid van Moolenbroek dns_name_free(name, view->mctx);
433*00b67f09SDavid van Moolenbroek isc_mem_put(view->mctx, name, sizeof(*name));
434*00b67f09SDavid van Moolenbroek name = ISC_LIST_HEAD(view->rootexclude[i]);
435*00b67f09SDavid van Moolenbroek }
436*00b67f09SDavid van Moolenbroek }
437*00b67f09SDavid van Moolenbroek isc_mem_put(view->mctx, view->rootexclude,
438*00b67f09SDavid van Moolenbroek sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
439*00b67f09SDavid van Moolenbroek view->rootexclude = NULL;
440*00b67f09SDavid van Moolenbroek }
441*00b67f09SDavid van Moolenbroek if (view->adbstats != NULL)
442*00b67f09SDavid van Moolenbroek isc_stats_detach(&view->adbstats);
443*00b67f09SDavid van Moolenbroek if (view->resstats != NULL)
444*00b67f09SDavid van Moolenbroek isc_stats_detach(&view->resstats);
445*00b67f09SDavid van Moolenbroek if (view->resquerystats != NULL)
446*00b67f09SDavid van Moolenbroek dns_stats_detach(&view->resquerystats);
447*00b67f09SDavid van Moolenbroek if (view->secroots_priv != NULL)
448*00b67f09SDavid van Moolenbroek dns_keytable_detach(&view->secroots_priv);
449*00b67f09SDavid van Moolenbroek for (dns64 = ISC_LIST_HEAD(view->dns64);
450*00b67f09SDavid van Moolenbroek dns64 != NULL;
451*00b67f09SDavid van Moolenbroek dns64 = ISC_LIST_HEAD(view->dns64)) {
452*00b67f09SDavid van Moolenbroek dns_dns64_unlink(&view->dns64, dns64);
453*00b67f09SDavid van Moolenbroek dns_dns64_destroy(&dns64);
454*00b67f09SDavid van Moolenbroek }
455*00b67f09SDavid van Moolenbroek if (view->managed_keys != NULL)
456*00b67f09SDavid van Moolenbroek dns_zone_detach(&view->managed_keys);
457*00b67f09SDavid van Moolenbroek if (view->redirect != NULL)
458*00b67f09SDavid van Moolenbroek dns_zone_detach(&view->redirect);
459*00b67f09SDavid van Moolenbroek dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
460*00b67f09SDavid van Moolenbroek dns_fwdtable_destroy(&view->fwdtable);
461*00b67f09SDavid van Moolenbroek dns_aclenv_destroy(&view->aclenv);
462*00b67f09SDavid van Moolenbroek DESTROYLOCK(&view->lock);
463*00b67f09SDavid van Moolenbroek isc_refcount_destroy(&view->references);
464*00b67f09SDavid van Moolenbroek isc_mem_free(view->mctx, view->name);
465*00b67f09SDavid van Moolenbroek isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
466*00b67f09SDavid van Moolenbroek }
467*00b67f09SDavid van Moolenbroek
468*00b67f09SDavid van Moolenbroek /*
469*00b67f09SDavid van Moolenbroek * Return true iff 'view' may be freed.
470*00b67f09SDavid van Moolenbroek * The caller must be holding the view lock.
471*00b67f09SDavid van Moolenbroek */
472*00b67f09SDavid van Moolenbroek static isc_boolean_t
all_done(dns_view_t * view)473*00b67f09SDavid van Moolenbroek all_done(dns_view_t *view) {
474*00b67f09SDavid van Moolenbroek
475*00b67f09SDavid van Moolenbroek if (isc_refcount_current(&view->references) == 0 &&
476*00b67f09SDavid van Moolenbroek view->weakrefs == 0 &&
477*00b67f09SDavid van Moolenbroek RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
478*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
479*00b67f09SDavid van Moolenbroek
480*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
481*00b67f09SDavid van Moolenbroek }
482*00b67f09SDavid van Moolenbroek
483*00b67f09SDavid van Moolenbroek void
dns_view_attach(dns_view_t * source,dns_view_t ** targetp)484*00b67f09SDavid van Moolenbroek dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
485*00b67f09SDavid van Moolenbroek
486*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(source));
487*00b67f09SDavid van Moolenbroek REQUIRE(targetp != NULL && *targetp == NULL);
488*00b67f09SDavid van Moolenbroek
489*00b67f09SDavid van Moolenbroek isc_refcount_increment(&source->references, NULL);
490*00b67f09SDavid van Moolenbroek
491*00b67f09SDavid van Moolenbroek *targetp = source;
492*00b67f09SDavid van Moolenbroek }
493*00b67f09SDavid van Moolenbroek
494*00b67f09SDavid van Moolenbroek static void
view_flushanddetach(dns_view_t ** viewp,isc_boolean_t flush)495*00b67f09SDavid van Moolenbroek view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
496*00b67f09SDavid van Moolenbroek dns_view_t *view;
497*00b67f09SDavid van Moolenbroek unsigned int refs;
498*00b67f09SDavid van Moolenbroek isc_boolean_t done = ISC_FALSE;
499*00b67f09SDavid van Moolenbroek
500*00b67f09SDavid van Moolenbroek REQUIRE(viewp != NULL);
501*00b67f09SDavid van Moolenbroek view = *viewp;
502*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
503*00b67f09SDavid van Moolenbroek
504*00b67f09SDavid van Moolenbroek if (flush)
505*00b67f09SDavid van Moolenbroek view->flush = ISC_TRUE;
506*00b67f09SDavid van Moolenbroek isc_refcount_decrement(&view->references, &refs);
507*00b67f09SDavid van Moolenbroek if (refs == 0) {
508*00b67f09SDavid van Moolenbroek dns_zone_t *mkzone = NULL, *rdzone = NULL;
509*00b67f09SDavid van Moolenbroek
510*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
511*00b67f09SDavid van Moolenbroek if (!RESSHUTDOWN(view))
512*00b67f09SDavid van Moolenbroek dns_resolver_shutdown(view->resolver);
513*00b67f09SDavid van Moolenbroek if (!ADBSHUTDOWN(view))
514*00b67f09SDavid van Moolenbroek dns_adb_shutdown(view->adb);
515*00b67f09SDavid van Moolenbroek if (!REQSHUTDOWN(view))
516*00b67f09SDavid van Moolenbroek dns_requestmgr_shutdown(view->requestmgr);
517*00b67f09SDavid van Moolenbroek if (view->acache != NULL)
518*00b67f09SDavid van Moolenbroek dns_acache_shutdown(view->acache);
519*00b67f09SDavid van Moolenbroek if (view->zonetable != NULL) {
520*00b67f09SDavid van Moolenbroek if (view->flush)
521*00b67f09SDavid van Moolenbroek dns_zt_flushanddetach(&view->zonetable);
522*00b67f09SDavid van Moolenbroek else
523*00b67f09SDavid van Moolenbroek dns_zt_detach(&view->zonetable);
524*00b67f09SDavid van Moolenbroek }
525*00b67f09SDavid van Moolenbroek if (view->managed_keys != NULL) {
526*00b67f09SDavid van Moolenbroek mkzone = view->managed_keys;
527*00b67f09SDavid van Moolenbroek view->managed_keys = NULL;
528*00b67f09SDavid van Moolenbroek if (view->flush)
529*00b67f09SDavid van Moolenbroek dns_zone_flush(mkzone);
530*00b67f09SDavid van Moolenbroek }
531*00b67f09SDavid van Moolenbroek if (view->redirect != NULL) {
532*00b67f09SDavid van Moolenbroek rdzone = view->redirect;
533*00b67f09SDavid van Moolenbroek view->redirect = NULL;
534*00b67f09SDavid van Moolenbroek if (view->flush)
535*00b67f09SDavid van Moolenbroek dns_zone_flush(rdzone);
536*00b67f09SDavid van Moolenbroek }
537*00b67f09SDavid van Moolenbroek done = all_done(view);
538*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
539*00b67f09SDavid van Moolenbroek
540*00b67f09SDavid van Moolenbroek /* Need to detach zones outside view lock */
541*00b67f09SDavid van Moolenbroek if (mkzone != NULL)
542*00b67f09SDavid van Moolenbroek dns_zone_detach(&mkzone);
543*00b67f09SDavid van Moolenbroek
544*00b67f09SDavid van Moolenbroek if (rdzone != NULL)
545*00b67f09SDavid van Moolenbroek dns_zone_detach(&rdzone);
546*00b67f09SDavid van Moolenbroek }
547*00b67f09SDavid van Moolenbroek
548*00b67f09SDavid van Moolenbroek *viewp = NULL;
549*00b67f09SDavid van Moolenbroek
550*00b67f09SDavid van Moolenbroek if (done)
551*00b67f09SDavid van Moolenbroek destroy(view);
552*00b67f09SDavid van Moolenbroek }
553*00b67f09SDavid van Moolenbroek
554*00b67f09SDavid van Moolenbroek void
dns_view_flushanddetach(dns_view_t ** viewp)555*00b67f09SDavid van Moolenbroek dns_view_flushanddetach(dns_view_t **viewp) {
556*00b67f09SDavid van Moolenbroek view_flushanddetach(viewp, ISC_TRUE);
557*00b67f09SDavid van Moolenbroek }
558*00b67f09SDavid van Moolenbroek
559*00b67f09SDavid van Moolenbroek void
dns_view_detach(dns_view_t ** viewp)560*00b67f09SDavid van Moolenbroek dns_view_detach(dns_view_t **viewp) {
561*00b67f09SDavid van Moolenbroek view_flushanddetach(viewp, ISC_FALSE);
562*00b67f09SDavid van Moolenbroek }
563*00b67f09SDavid van Moolenbroek
564*00b67f09SDavid van Moolenbroek static isc_result_t
dialup(dns_zone_t * zone,void * dummy)565*00b67f09SDavid van Moolenbroek dialup(dns_zone_t *zone, void *dummy) {
566*00b67f09SDavid van Moolenbroek UNUSED(dummy);
567*00b67f09SDavid van Moolenbroek dns_zone_dialup(zone);
568*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
569*00b67f09SDavid van Moolenbroek }
570*00b67f09SDavid van Moolenbroek
571*00b67f09SDavid van Moolenbroek void
dns_view_dialup(dns_view_t * view)572*00b67f09SDavid van Moolenbroek dns_view_dialup(dns_view_t *view) {
573*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
574*00b67f09SDavid van Moolenbroek REQUIRE(view->zonetable != NULL);
575*00b67f09SDavid van Moolenbroek
576*00b67f09SDavid van Moolenbroek (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL);
577*00b67f09SDavid van Moolenbroek }
578*00b67f09SDavid van Moolenbroek
579*00b67f09SDavid van Moolenbroek void
dns_view_weakattach(dns_view_t * source,dns_view_t ** targetp)580*00b67f09SDavid van Moolenbroek dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
581*00b67f09SDavid van Moolenbroek
582*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(source));
583*00b67f09SDavid van Moolenbroek REQUIRE(targetp != NULL && *targetp == NULL);
584*00b67f09SDavid van Moolenbroek
585*00b67f09SDavid van Moolenbroek LOCK(&source->lock);
586*00b67f09SDavid van Moolenbroek source->weakrefs++;
587*00b67f09SDavid van Moolenbroek UNLOCK(&source->lock);
588*00b67f09SDavid van Moolenbroek
589*00b67f09SDavid van Moolenbroek *targetp = source;
590*00b67f09SDavid van Moolenbroek }
591*00b67f09SDavid van Moolenbroek
592*00b67f09SDavid van Moolenbroek void
dns_view_weakdetach(dns_view_t ** viewp)593*00b67f09SDavid van Moolenbroek dns_view_weakdetach(dns_view_t **viewp) {
594*00b67f09SDavid van Moolenbroek dns_view_t *view;
595*00b67f09SDavid van Moolenbroek isc_boolean_t done = ISC_FALSE;
596*00b67f09SDavid van Moolenbroek
597*00b67f09SDavid van Moolenbroek REQUIRE(viewp != NULL);
598*00b67f09SDavid van Moolenbroek view = *viewp;
599*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
600*00b67f09SDavid van Moolenbroek
601*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
602*00b67f09SDavid van Moolenbroek
603*00b67f09SDavid van Moolenbroek INSIST(view->weakrefs > 0);
604*00b67f09SDavid van Moolenbroek view->weakrefs--;
605*00b67f09SDavid van Moolenbroek done = all_done(view);
606*00b67f09SDavid van Moolenbroek
607*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
608*00b67f09SDavid van Moolenbroek
609*00b67f09SDavid van Moolenbroek *viewp = NULL;
610*00b67f09SDavid van Moolenbroek
611*00b67f09SDavid van Moolenbroek if (done)
612*00b67f09SDavid van Moolenbroek destroy(view);
613*00b67f09SDavid van Moolenbroek }
614*00b67f09SDavid van Moolenbroek
615*00b67f09SDavid van Moolenbroek static void
resolver_shutdown(isc_task_t * task,isc_event_t * event)616*00b67f09SDavid van Moolenbroek resolver_shutdown(isc_task_t *task, isc_event_t *event) {
617*00b67f09SDavid van Moolenbroek dns_view_t *view = event->ev_arg;
618*00b67f09SDavid van Moolenbroek isc_boolean_t done;
619*00b67f09SDavid van Moolenbroek
620*00b67f09SDavid van Moolenbroek REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
621*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
622*00b67f09SDavid van Moolenbroek REQUIRE(view->task == task);
623*00b67f09SDavid van Moolenbroek
624*00b67f09SDavid van Moolenbroek UNUSED(task);
625*00b67f09SDavid van Moolenbroek
626*00b67f09SDavid van Moolenbroek isc_event_free(&event);
627*00b67f09SDavid van Moolenbroek
628*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
629*00b67f09SDavid van Moolenbroek
630*00b67f09SDavid van Moolenbroek view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
631*00b67f09SDavid van Moolenbroek done = all_done(view);
632*00b67f09SDavid van Moolenbroek
633*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
634*00b67f09SDavid van Moolenbroek
635*00b67f09SDavid van Moolenbroek if (done)
636*00b67f09SDavid van Moolenbroek destroy(view);
637*00b67f09SDavid van Moolenbroek }
638*00b67f09SDavid van Moolenbroek
639*00b67f09SDavid van Moolenbroek static void
adb_shutdown(isc_task_t * task,isc_event_t * event)640*00b67f09SDavid van Moolenbroek adb_shutdown(isc_task_t *task, isc_event_t *event) {
641*00b67f09SDavid van Moolenbroek dns_view_t *view = event->ev_arg;
642*00b67f09SDavid van Moolenbroek isc_boolean_t done;
643*00b67f09SDavid van Moolenbroek
644*00b67f09SDavid van Moolenbroek REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
645*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
646*00b67f09SDavid van Moolenbroek REQUIRE(view->task == task);
647*00b67f09SDavid van Moolenbroek
648*00b67f09SDavid van Moolenbroek UNUSED(task);
649*00b67f09SDavid van Moolenbroek
650*00b67f09SDavid van Moolenbroek isc_event_free(&event);
651*00b67f09SDavid van Moolenbroek
652*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
653*00b67f09SDavid van Moolenbroek
654*00b67f09SDavid van Moolenbroek view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
655*00b67f09SDavid van Moolenbroek done = all_done(view);
656*00b67f09SDavid van Moolenbroek
657*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
658*00b67f09SDavid van Moolenbroek
659*00b67f09SDavid van Moolenbroek if (done)
660*00b67f09SDavid van Moolenbroek destroy(view);
661*00b67f09SDavid van Moolenbroek }
662*00b67f09SDavid van Moolenbroek
663*00b67f09SDavid van Moolenbroek static void
req_shutdown(isc_task_t * task,isc_event_t * event)664*00b67f09SDavid van Moolenbroek req_shutdown(isc_task_t *task, isc_event_t *event) {
665*00b67f09SDavid van Moolenbroek dns_view_t *view = event->ev_arg;
666*00b67f09SDavid van Moolenbroek isc_boolean_t done;
667*00b67f09SDavid van Moolenbroek
668*00b67f09SDavid van Moolenbroek REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
669*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
670*00b67f09SDavid van Moolenbroek REQUIRE(view->task == task);
671*00b67f09SDavid van Moolenbroek
672*00b67f09SDavid van Moolenbroek UNUSED(task);
673*00b67f09SDavid van Moolenbroek
674*00b67f09SDavid van Moolenbroek isc_event_free(&event);
675*00b67f09SDavid van Moolenbroek
676*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
677*00b67f09SDavid van Moolenbroek
678*00b67f09SDavid van Moolenbroek view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
679*00b67f09SDavid van Moolenbroek done = all_done(view);
680*00b67f09SDavid van Moolenbroek
681*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
682*00b67f09SDavid van Moolenbroek
683*00b67f09SDavid van Moolenbroek if (done)
684*00b67f09SDavid van Moolenbroek destroy(view);
685*00b67f09SDavid van Moolenbroek }
686*00b67f09SDavid van Moolenbroek
687*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_createzonetable(dns_view_t * view)688*00b67f09SDavid van Moolenbroek dns_view_createzonetable(dns_view_t *view) {
689*00b67f09SDavid van Moolenbroek
690*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
691*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
692*00b67f09SDavid van Moolenbroek REQUIRE(view->zonetable == NULL);
693*00b67f09SDavid van Moolenbroek
694*00b67f09SDavid van Moolenbroek return (dns_zt_create(view->mctx, view->rdclass, &view->zonetable));
695*00b67f09SDavid van Moolenbroek }
696*00b67f09SDavid van Moolenbroek
697*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_createresolver(dns_view_t * view,isc_taskmgr_t * taskmgr,unsigned int ntasks,unsigned int ndisp,isc_socketmgr_t * socketmgr,isc_timermgr_t * timermgr,unsigned int options,dns_dispatchmgr_t * dispatchmgr,dns_dispatch_t * dispatchv4,dns_dispatch_t * dispatchv6)698*00b67f09SDavid van Moolenbroek dns_view_createresolver(dns_view_t *view,
699*00b67f09SDavid van Moolenbroek isc_taskmgr_t *taskmgr,
700*00b67f09SDavid van Moolenbroek unsigned int ntasks, unsigned int ndisp,
701*00b67f09SDavid van Moolenbroek isc_socketmgr_t *socketmgr,
702*00b67f09SDavid van Moolenbroek isc_timermgr_t *timermgr,
703*00b67f09SDavid van Moolenbroek unsigned int options,
704*00b67f09SDavid van Moolenbroek dns_dispatchmgr_t *dispatchmgr,
705*00b67f09SDavid van Moolenbroek dns_dispatch_t *dispatchv4,
706*00b67f09SDavid van Moolenbroek dns_dispatch_t *dispatchv6)
707*00b67f09SDavid van Moolenbroek {
708*00b67f09SDavid van Moolenbroek isc_result_t result;
709*00b67f09SDavid van Moolenbroek isc_event_t *event;
710*00b67f09SDavid van Moolenbroek isc_mem_t *mctx = NULL;
711*00b67f09SDavid van Moolenbroek
712*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
713*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
714*00b67f09SDavid van Moolenbroek REQUIRE(view->resolver == NULL);
715*00b67f09SDavid van Moolenbroek
716*00b67f09SDavid van Moolenbroek result = isc_task_create(taskmgr, 0, &view->task);
717*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
718*00b67f09SDavid van Moolenbroek return (result);
719*00b67f09SDavid van Moolenbroek isc_task_setname(view->task, "view", view);
720*00b67f09SDavid van Moolenbroek
721*00b67f09SDavid van Moolenbroek result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
722*00b67f09SDavid van Moolenbroek timermgr, options, dispatchmgr,
723*00b67f09SDavid van Moolenbroek dispatchv4, dispatchv6,
724*00b67f09SDavid van Moolenbroek &view->resolver);
725*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
726*00b67f09SDavid van Moolenbroek isc_task_detach(&view->task);
727*00b67f09SDavid van Moolenbroek return (result);
728*00b67f09SDavid van Moolenbroek }
729*00b67f09SDavid van Moolenbroek event = &view->resevent;
730*00b67f09SDavid van Moolenbroek dns_resolver_whenshutdown(view->resolver, view->task, &event);
731*00b67f09SDavid van Moolenbroek view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
732*00b67f09SDavid van Moolenbroek
733*00b67f09SDavid van Moolenbroek result = isc_mem_create(0, 0, &mctx);
734*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
735*00b67f09SDavid van Moolenbroek dns_resolver_shutdown(view->resolver);
736*00b67f09SDavid van Moolenbroek return (result);
737*00b67f09SDavid van Moolenbroek }
738*00b67f09SDavid van Moolenbroek
739*00b67f09SDavid van Moolenbroek result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb);
740*00b67f09SDavid van Moolenbroek isc_mem_setname(mctx, "ADB", NULL);
741*00b67f09SDavid van Moolenbroek isc_mem_detach(&mctx);
742*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
743*00b67f09SDavid van Moolenbroek dns_resolver_shutdown(view->resolver);
744*00b67f09SDavid van Moolenbroek return (result);
745*00b67f09SDavid van Moolenbroek }
746*00b67f09SDavid van Moolenbroek event = &view->adbevent;
747*00b67f09SDavid van Moolenbroek dns_adb_whenshutdown(view->adb, view->task, &event);
748*00b67f09SDavid van Moolenbroek view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
749*00b67f09SDavid van Moolenbroek
750*00b67f09SDavid van Moolenbroek result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
751*00b67f09SDavid van Moolenbroek dns_resolver_taskmgr(view->resolver),
752*00b67f09SDavid van Moolenbroek dns_resolver_dispatchmgr(view->resolver),
753*00b67f09SDavid van Moolenbroek dispatchv4, dispatchv6,
754*00b67f09SDavid van Moolenbroek &view->requestmgr);
755*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
756*00b67f09SDavid van Moolenbroek dns_adb_shutdown(view->adb);
757*00b67f09SDavid van Moolenbroek dns_resolver_shutdown(view->resolver);
758*00b67f09SDavid van Moolenbroek return (result);
759*00b67f09SDavid van Moolenbroek }
760*00b67f09SDavid van Moolenbroek event = &view->reqevent;
761*00b67f09SDavid van Moolenbroek dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
762*00b67f09SDavid van Moolenbroek view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
763*00b67f09SDavid van Moolenbroek
764*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
765*00b67f09SDavid van Moolenbroek }
766*00b67f09SDavid van Moolenbroek
767*00b67f09SDavid van Moolenbroek void
dns_view_setcache(dns_view_t * view,dns_cache_t * cache)768*00b67f09SDavid van Moolenbroek dns_view_setcache(dns_view_t *view, dns_cache_t *cache) {
769*00b67f09SDavid van Moolenbroek dns_view_setcache2(view, cache, ISC_FALSE);
770*00b67f09SDavid van Moolenbroek }
771*00b67f09SDavid van Moolenbroek
772*00b67f09SDavid van Moolenbroek void
dns_view_setcache2(dns_view_t * view,dns_cache_t * cache,isc_boolean_t shared)773*00b67f09SDavid van Moolenbroek dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
774*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
775*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
776*00b67f09SDavid van Moolenbroek
777*00b67f09SDavid van Moolenbroek view->cacheshared = shared;
778*00b67f09SDavid van Moolenbroek if (view->cache != NULL) {
779*00b67f09SDavid van Moolenbroek if (view->acache != NULL)
780*00b67f09SDavid van Moolenbroek dns_acache_putdb(view->acache, view->cachedb);
781*00b67f09SDavid van Moolenbroek dns_db_detach(&view->cachedb);
782*00b67f09SDavid van Moolenbroek dns_cache_detach(&view->cache);
783*00b67f09SDavid van Moolenbroek }
784*00b67f09SDavid van Moolenbroek dns_cache_attach(cache, &view->cache);
785*00b67f09SDavid van Moolenbroek dns_cache_attachdb(cache, &view->cachedb);
786*00b67f09SDavid van Moolenbroek INSIST(DNS_DB_VALID(view->cachedb));
787*00b67f09SDavid van Moolenbroek
788*00b67f09SDavid van Moolenbroek if (view->acache != NULL)
789*00b67f09SDavid van Moolenbroek dns_acache_setdb(view->acache, view->cachedb);
790*00b67f09SDavid van Moolenbroek }
791*00b67f09SDavid van Moolenbroek
792*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_view_iscacheshared(dns_view_t * view)793*00b67f09SDavid van Moolenbroek dns_view_iscacheshared(dns_view_t *view) {
794*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
795*00b67f09SDavid van Moolenbroek
796*00b67f09SDavid van Moolenbroek return (view->cacheshared);
797*00b67f09SDavid van Moolenbroek }
798*00b67f09SDavid van Moolenbroek
799*00b67f09SDavid van Moolenbroek void
dns_view_sethints(dns_view_t * view,dns_db_t * hints)800*00b67f09SDavid van Moolenbroek dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
801*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
802*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
803*00b67f09SDavid van Moolenbroek REQUIRE(view->hints == NULL);
804*00b67f09SDavid van Moolenbroek REQUIRE(dns_db_iszone(hints));
805*00b67f09SDavid van Moolenbroek
806*00b67f09SDavid van Moolenbroek dns_db_attach(hints, &view->hints);
807*00b67f09SDavid van Moolenbroek }
808*00b67f09SDavid van Moolenbroek
809*00b67f09SDavid van Moolenbroek void
dns_view_setkeyring(dns_view_t * view,dns_tsig_keyring_t * ring)810*00b67f09SDavid van Moolenbroek dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
811*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
812*00b67f09SDavid van Moolenbroek REQUIRE(ring != NULL);
813*00b67f09SDavid van Moolenbroek if (view->statickeys != NULL)
814*00b67f09SDavid van Moolenbroek dns_tsigkeyring_detach(&view->statickeys);
815*00b67f09SDavid van Moolenbroek dns_tsigkeyring_attach(ring, &view->statickeys);
816*00b67f09SDavid van Moolenbroek }
817*00b67f09SDavid van Moolenbroek
818*00b67f09SDavid van Moolenbroek void
dns_view_setdynamickeyring(dns_view_t * view,dns_tsig_keyring_t * ring)819*00b67f09SDavid van Moolenbroek dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
820*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
821*00b67f09SDavid van Moolenbroek REQUIRE(ring != NULL);
822*00b67f09SDavid van Moolenbroek if (view->dynamickeys != NULL)
823*00b67f09SDavid van Moolenbroek dns_tsigkeyring_detach(&view->dynamickeys);
824*00b67f09SDavid van Moolenbroek dns_tsigkeyring_attach(ring, &view->dynamickeys);
825*00b67f09SDavid van Moolenbroek }
826*00b67f09SDavid van Moolenbroek
827*00b67f09SDavid van Moolenbroek void
dns_view_getdynamickeyring(dns_view_t * view,dns_tsig_keyring_t ** ringp)828*00b67f09SDavid van Moolenbroek dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) {
829*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
830*00b67f09SDavid van Moolenbroek REQUIRE(ringp != NULL && *ringp == NULL);
831*00b67f09SDavid van Moolenbroek if (view->dynamickeys != NULL)
832*00b67f09SDavid van Moolenbroek dns_tsigkeyring_attach(view->dynamickeys, ringp);
833*00b67f09SDavid van Moolenbroek }
834*00b67f09SDavid van Moolenbroek
835*00b67f09SDavid van Moolenbroek void
dns_view_restorekeyring(dns_view_t * view)836*00b67f09SDavid van Moolenbroek dns_view_restorekeyring(dns_view_t *view) {
837*00b67f09SDavid van Moolenbroek FILE *fp;
838*00b67f09SDavid van Moolenbroek char keyfile[20];
839*00b67f09SDavid van Moolenbroek int n;
840*00b67f09SDavid van Moolenbroek
841*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
842*00b67f09SDavid van Moolenbroek
843*00b67f09SDavid van Moolenbroek if (view->dynamickeys != NULL) {
844*00b67f09SDavid van Moolenbroek n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
845*00b67f09SDavid van Moolenbroek view->name);
846*00b67f09SDavid van Moolenbroek if (n > 0 && (size_t)n < sizeof(keyfile)) {
847*00b67f09SDavid van Moolenbroek fp = fopen(keyfile, "r");
848*00b67f09SDavid van Moolenbroek if (fp != NULL) {
849*00b67f09SDavid van Moolenbroek dns_keyring_restore(view->dynamickeys, fp);
850*00b67f09SDavid van Moolenbroek (void)fclose(fp);
851*00b67f09SDavid van Moolenbroek }
852*00b67f09SDavid van Moolenbroek }
853*00b67f09SDavid van Moolenbroek }
854*00b67f09SDavid van Moolenbroek }
855*00b67f09SDavid van Moolenbroek
856*00b67f09SDavid van Moolenbroek void
dns_view_setdstport(dns_view_t * view,in_port_t dstport)857*00b67f09SDavid van Moolenbroek dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
858*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
859*00b67f09SDavid van Moolenbroek view->dstport = dstport;
860*00b67f09SDavid van Moolenbroek }
861*00b67f09SDavid van Moolenbroek
862*00b67f09SDavid van Moolenbroek void
dns_view_freeze(dns_view_t * view)863*00b67f09SDavid van Moolenbroek dns_view_freeze(dns_view_t *view) {
864*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
865*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
866*00b67f09SDavid van Moolenbroek
867*00b67f09SDavid van Moolenbroek if (view->resolver != NULL) {
868*00b67f09SDavid van Moolenbroek INSIST(view->cachedb != NULL);
869*00b67f09SDavid van Moolenbroek dns_resolver_freeze(view->resolver);
870*00b67f09SDavid van Moolenbroek }
871*00b67f09SDavid van Moolenbroek view->frozen = ISC_TRUE;
872*00b67f09SDavid van Moolenbroek }
873*00b67f09SDavid van Moolenbroek
874*00b67f09SDavid van Moolenbroek void
dns_view_thaw(dns_view_t * view)875*00b67f09SDavid van Moolenbroek dns_view_thaw(dns_view_t *view) {
876*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
877*00b67f09SDavid van Moolenbroek REQUIRE(view->frozen);
878*00b67f09SDavid van Moolenbroek
879*00b67f09SDavid van Moolenbroek view->frozen = ISC_FALSE;
880*00b67f09SDavid van Moolenbroek }
881*00b67f09SDavid van Moolenbroek
882*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_addzone(dns_view_t * view,dns_zone_t * zone)883*00b67f09SDavid van Moolenbroek dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
884*00b67f09SDavid van Moolenbroek isc_result_t result;
885*00b67f09SDavid van Moolenbroek
886*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
887*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
888*00b67f09SDavid van Moolenbroek REQUIRE(view->zonetable != NULL);
889*00b67f09SDavid van Moolenbroek
890*00b67f09SDavid van Moolenbroek result = dns_zt_mount(view->zonetable, zone);
891*00b67f09SDavid van Moolenbroek
892*00b67f09SDavid van Moolenbroek return (result);
893*00b67f09SDavid van Moolenbroek }
894*00b67f09SDavid van Moolenbroek
895*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_findzone(dns_view_t * view,dns_name_t * name,dns_zone_t ** zonep)896*00b67f09SDavid van Moolenbroek dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
897*00b67f09SDavid van Moolenbroek isc_result_t result;
898*00b67f09SDavid van Moolenbroek
899*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
900*00b67f09SDavid van Moolenbroek
901*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
902*00b67f09SDavid van Moolenbroek if (view->zonetable != NULL) {
903*00b67f09SDavid van Moolenbroek result = dns_zt_find(view->zonetable, name, 0, NULL, zonep);
904*00b67f09SDavid van Moolenbroek if (result == DNS_R_PARTIALMATCH) {
905*00b67f09SDavid van Moolenbroek dns_zone_detach(zonep);
906*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
907*00b67f09SDavid van Moolenbroek }
908*00b67f09SDavid van Moolenbroek } else
909*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
910*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
911*00b67f09SDavid van Moolenbroek
912*00b67f09SDavid van Moolenbroek return (result);
913*00b67f09SDavid van Moolenbroek }
914*00b67f09SDavid van Moolenbroek
915*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_find(dns_view_t * view,dns_name_t * name,dns_rdatatype_t type,isc_stdtime_t now,unsigned int options,isc_boolean_t use_hints,dns_db_t ** dbp,dns_dbnode_t ** nodep,dns_name_t * foundname,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)916*00b67f09SDavid van Moolenbroek dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
917*00b67f09SDavid van Moolenbroek isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints,
918*00b67f09SDavid van Moolenbroek dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
919*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
920*00b67f09SDavid van Moolenbroek return (dns_view_find2(view, name, type, now, options, use_hints,
921*00b67f09SDavid van Moolenbroek ISC_FALSE, dbp, nodep, foundname, rdataset,
922*00b67f09SDavid van Moolenbroek sigrdataset));
923*00b67f09SDavid van Moolenbroek }
924*00b67f09SDavid van Moolenbroek
925*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_find2(dns_view_t * view,dns_name_t * name,dns_rdatatype_t type,isc_stdtime_t now,unsigned int options,isc_boolean_t use_hints,isc_boolean_t use_static_stub,dns_db_t ** dbp,dns_dbnode_t ** nodep,dns_name_t * foundname,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)926*00b67f09SDavid van Moolenbroek dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
927*00b67f09SDavid van Moolenbroek isc_stdtime_t now, unsigned int options,
928*00b67f09SDavid van Moolenbroek isc_boolean_t use_hints, isc_boolean_t use_static_stub,
929*00b67f09SDavid van Moolenbroek dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
930*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
931*00b67f09SDavid van Moolenbroek {
932*00b67f09SDavid van Moolenbroek isc_result_t result;
933*00b67f09SDavid van Moolenbroek dns_db_t *db, *zdb;
934*00b67f09SDavid van Moolenbroek dns_dbnode_t *node, *znode;
935*00b67f09SDavid van Moolenbroek isc_boolean_t is_cache, is_staticstub_zone;
936*00b67f09SDavid van Moolenbroek dns_rdataset_t zrdataset, zsigrdataset;
937*00b67f09SDavid van Moolenbroek dns_zone_t *zone;
938*00b67f09SDavid van Moolenbroek
939*00b67f09SDavid van Moolenbroek /*
940*00b67f09SDavid van Moolenbroek * Find an rdataset whose owner name is 'name', and whose type is
941*00b67f09SDavid van Moolenbroek * 'type'.
942*00b67f09SDavid van Moolenbroek */
943*00b67f09SDavid van Moolenbroek
944*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
945*00b67f09SDavid van Moolenbroek REQUIRE(view->frozen);
946*00b67f09SDavid van Moolenbroek REQUIRE(type != dns_rdatatype_rrsig);
947*00b67f09SDavid van Moolenbroek REQUIRE(rdataset != NULL); /* XXXBEW - remove this */
948*00b67f09SDavid van Moolenbroek REQUIRE(nodep == NULL || *nodep == NULL);
949*00b67f09SDavid van Moolenbroek
950*00b67f09SDavid van Moolenbroek /*
951*00b67f09SDavid van Moolenbroek * Initialize.
952*00b67f09SDavid van Moolenbroek */
953*00b67f09SDavid van Moolenbroek dns_rdataset_init(&zrdataset);
954*00b67f09SDavid van Moolenbroek dns_rdataset_init(&zsigrdataset);
955*00b67f09SDavid van Moolenbroek zdb = NULL;
956*00b67f09SDavid van Moolenbroek znode = NULL;
957*00b67f09SDavid van Moolenbroek
958*00b67f09SDavid van Moolenbroek /*
959*00b67f09SDavid van Moolenbroek * Find a database to answer the query.
960*00b67f09SDavid van Moolenbroek */
961*00b67f09SDavid van Moolenbroek db = NULL;
962*00b67f09SDavid van Moolenbroek node = NULL;
963*00b67f09SDavid van Moolenbroek is_staticstub_zone = ISC_FALSE;
964*00b67f09SDavid van Moolenbroek zone = NULL;
965*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
966*00b67f09SDavid van Moolenbroek if (view->zonetable != NULL)
967*00b67f09SDavid van Moolenbroek result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
968*00b67f09SDavid van Moolenbroek else
969*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
970*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
971*00b67f09SDavid van Moolenbroek if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
972*00b67f09SDavid van Moolenbroek !use_static_stub)
973*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
974*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
975*00b67f09SDavid van Moolenbroek result = dns_zone_getdb(zone, &db);
976*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS && view->cachedb != NULL)
977*00b67f09SDavid van Moolenbroek dns_db_attach(view->cachedb, &db);
978*00b67f09SDavid van Moolenbroek else if (result != ISC_R_SUCCESS)
979*00b67f09SDavid van Moolenbroek goto cleanup;
980*00b67f09SDavid van Moolenbroek if (dns_zone_gettype(zone) == dns_zone_staticstub &&
981*00b67f09SDavid van Moolenbroek dns_name_equal(name, dns_zone_getorigin(zone))) {
982*00b67f09SDavid van Moolenbroek is_staticstub_zone = ISC_TRUE;
983*00b67f09SDavid van Moolenbroek }
984*00b67f09SDavid van Moolenbroek } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
985*00b67f09SDavid van Moolenbroek dns_db_attach(view->cachedb, &db);
986*00b67f09SDavid van Moolenbroek else
987*00b67f09SDavid van Moolenbroek goto cleanup;
988*00b67f09SDavid van Moolenbroek
989*00b67f09SDavid van Moolenbroek is_cache = dns_db_iscache(db);
990*00b67f09SDavid van Moolenbroek
991*00b67f09SDavid van Moolenbroek db_find:
992*00b67f09SDavid van Moolenbroek /*
993*00b67f09SDavid van Moolenbroek * Now look for an answer in the database.
994*00b67f09SDavid van Moolenbroek */
995*00b67f09SDavid van Moolenbroek result = dns_db_find(db, name, NULL, type, options,
996*00b67f09SDavid van Moolenbroek now, &node, foundname, rdataset, sigrdataset);
997*00b67f09SDavid van Moolenbroek
998*00b67f09SDavid van Moolenbroek if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) {
999*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(rdataset))
1000*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1001*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1002*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(sigrdataset))
1003*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(sigrdataset);
1004*00b67f09SDavid van Moolenbroek if (node != NULL)
1005*00b67f09SDavid van Moolenbroek dns_db_detachnode(db, &node);
1006*00b67f09SDavid van Moolenbroek if (!is_cache) {
1007*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1008*00b67f09SDavid van Moolenbroek if (view->cachedb != NULL && !is_staticstub_zone) {
1009*00b67f09SDavid van Moolenbroek /*
1010*00b67f09SDavid van Moolenbroek * Either the answer is in the cache, or we
1011*00b67f09SDavid van Moolenbroek * don't know it.
1012*00b67f09SDavid van Moolenbroek * Note that if the result comes from a
1013*00b67f09SDavid van Moolenbroek * static-stub zone we stop the search here
1014*00b67f09SDavid van Moolenbroek * (see the function description in view.h).
1015*00b67f09SDavid van Moolenbroek */
1016*00b67f09SDavid van Moolenbroek is_cache = ISC_TRUE;
1017*00b67f09SDavid van Moolenbroek dns_db_attach(view->cachedb, &db);
1018*00b67f09SDavid van Moolenbroek goto db_find;
1019*00b67f09SDavid van Moolenbroek }
1020*00b67f09SDavid van Moolenbroek } else {
1021*00b67f09SDavid van Moolenbroek /*
1022*00b67f09SDavid van Moolenbroek * We don't have the data in the cache. If we've got
1023*00b67f09SDavid van Moolenbroek * glue from the zone, use it.
1024*00b67f09SDavid van Moolenbroek */
1025*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(&zrdataset)) {
1026*00b67f09SDavid van Moolenbroek dns_rdataset_clone(&zrdataset, rdataset);
1027*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1028*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(&zsigrdataset))
1029*00b67f09SDavid van Moolenbroek dns_rdataset_clone(&zsigrdataset,
1030*00b67f09SDavid van Moolenbroek sigrdataset);
1031*00b67f09SDavid van Moolenbroek result = DNS_R_GLUE;
1032*00b67f09SDavid van Moolenbroek if (db != NULL)
1033*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1034*00b67f09SDavid van Moolenbroek dns_db_attach(zdb, &db);
1035*00b67f09SDavid van Moolenbroek dns_db_attachnode(db, znode, &node);
1036*00b67f09SDavid van Moolenbroek goto cleanup;
1037*00b67f09SDavid van Moolenbroek }
1038*00b67f09SDavid van Moolenbroek }
1039*00b67f09SDavid van Moolenbroek /*
1040*00b67f09SDavid van Moolenbroek * We don't know the answer.
1041*00b67f09SDavid van Moolenbroek */
1042*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
1043*00b67f09SDavid van Moolenbroek } else if (result == DNS_R_GLUE) {
1044*00b67f09SDavid van Moolenbroek if (view->cachedb != NULL && !is_staticstub_zone) {
1045*00b67f09SDavid van Moolenbroek /*
1046*00b67f09SDavid van Moolenbroek * We found an answer, but the cache may be better.
1047*00b67f09SDavid van Moolenbroek * Remember what we've got and go look in the cache.
1048*00b67f09SDavid van Moolenbroek */
1049*00b67f09SDavid van Moolenbroek is_cache = ISC_TRUE;
1050*00b67f09SDavid van Moolenbroek dns_rdataset_clone(rdataset, &zrdataset);
1051*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1052*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1053*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(sigrdataset)) {
1054*00b67f09SDavid van Moolenbroek dns_rdataset_clone(sigrdataset, &zsigrdataset);
1055*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(sigrdataset);
1056*00b67f09SDavid van Moolenbroek }
1057*00b67f09SDavid van Moolenbroek dns_db_attach(db, &zdb);
1058*00b67f09SDavid van Moolenbroek dns_db_attachnode(zdb, node, &znode);
1059*00b67f09SDavid van Moolenbroek dns_db_detachnode(db, &node);
1060*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1061*00b67f09SDavid van Moolenbroek dns_db_attach(view->cachedb, &db);
1062*00b67f09SDavid van Moolenbroek goto db_find;
1063*00b67f09SDavid van Moolenbroek }
1064*00b67f09SDavid van Moolenbroek /*
1065*00b67f09SDavid van Moolenbroek * Otherwise, the glue is the best answer.
1066*00b67f09SDavid van Moolenbroek */
1067*00b67f09SDavid van Moolenbroek result = ISC_R_SUCCESS;
1068*00b67f09SDavid van Moolenbroek }
1069*00b67f09SDavid van Moolenbroek
1070*00b67f09SDavid van Moolenbroek if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) {
1071*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(rdataset))
1072*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1073*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1074*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(sigrdataset))
1075*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(sigrdataset);
1076*00b67f09SDavid van Moolenbroek if (db != NULL) {
1077*00b67f09SDavid van Moolenbroek if (node != NULL)
1078*00b67f09SDavid van Moolenbroek dns_db_detachnode(db, &node);
1079*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1080*00b67f09SDavid van Moolenbroek }
1081*00b67f09SDavid van Moolenbroek result = dns_db_find(view->hints, name, NULL, type, options,
1082*00b67f09SDavid van Moolenbroek now, &node, foundname,
1083*00b67f09SDavid van Moolenbroek rdataset, sigrdataset);
1084*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) {
1085*00b67f09SDavid van Moolenbroek /*
1086*00b67f09SDavid van Moolenbroek * We just used a hint. Let the resolver know it
1087*00b67f09SDavid van Moolenbroek * should consider priming.
1088*00b67f09SDavid van Moolenbroek */
1089*00b67f09SDavid van Moolenbroek dns_resolver_prime(view->resolver);
1090*00b67f09SDavid van Moolenbroek dns_db_attach(view->hints, &db);
1091*00b67f09SDavid van Moolenbroek result = DNS_R_HINT;
1092*00b67f09SDavid van Moolenbroek } else if (result == DNS_R_NXRRSET) {
1093*00b67f09SDavid van Moolenbroek dns_db_attach(view->hints, &db);
1094*00b67f09SDavid van Moolenbroek result = DNS_R_HINTNXRRSET;
1095*00b67f09SDavid van Moolenbroek } else if (result == DNS_R_NXDOMAIN)
1096*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
1097*00b67f09SDavid van Moolenbroek
1098*00b67f09SDavid van Moolenbroek /*
1099*00b67f09SDavid van Moolenbroek * Cleanup if non-standard hints are used.
1100*00b67f09SDavid van Moolenbroek */
1101*00b67f09SDavid van Moolenbroek if (db == NULL && node != NULL)
1102*00b67f09SDavid van Moolenbroek dns_db_detachnode(view->hints, &node);
1103*00b67f09SDavid van Moolenbroek }
1104*00b67f09SDavid van Moolenbroek
1105*00b67f09SDavid van Moolenbroek cleanup:
1106*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(&zrdataset)) {
1107*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(&zrdataset);
1108*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(&zsigrdataset))
1109*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(&zsigrdataset);
1110*00b67f09SDavid van Moolenbroek }
1111*00b67f09SDavid van Moolenbroek
1112*00b67f09SDavid van Moolenbroek if (zdb != NULL) {
1113*00b67f09SDavid van Moolenbroek if (znode != NULL)
1114*00b67f09SDavid van Moolenbroek dns_db_detachnode(zdb, &znode);
1115*00b67f09SDavid van Moolenbroek dns_db_detach(&zdb);
1116*00b67f09SDavid van Moolenbroek }
1117*00b67f09SDavid van Moolenbroek
1118*00b67f09SDavid van Moolenbroek if (db != NULL) {
1119*00b67f09SDavid van Moolenbroek if (node != NULL) {
1120*00b67f09SDavid van Moolenbroek if (nodep != NULL)
1121*00b67f09SDavid van Moolenbroek *nodep = node;
1122*00b67f09SDavid van Moolenbroek else
1123*00b67f09SDavid van Moolenbroek dns_db_detachnode(db, &node);
1124*00b67f09SDavid van Moolenbroek }
1125*00b67f09SDavid van Moolenbroek if (dbp != NULL)
1126*00b67f09SDavid van Moolenbroek *dbp = db;
1127*00b67f09SDavid van Moolenbroek else
1128*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1129*00b67f09SDavid van Moolenbroek } else
1130*00b67f09SDavid van Moolenbroek INSIST(node == NULL);
1131*00b67f09SDavid van Moolenbroek
1132*00b67f09SDavid van Moolenbroek if (zone != NULL)
1133*00b67f09SDavid van Moolenbroek dns_zone_detach(&zone);
1134*00b67f09SDavid van Moolenbroek
1135*00b67f09SDavid van Moolenbroek return (result);
1136*00b67f09SDavid van Moolenbroek }
1137*00b67f09SDavid van Moolenbroek
1138*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_simplefind(dns_view_t * view,dns_name_t * name,dns_rdatatype_t type,isc_stdtime_t now,unsigned int options,isc_boolean_t use_hints,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)1139*00b67f09SDavid van Moolenbroek dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
1140*00b67f09SDavid van Moolenbroek isc_stdtime_t now, unsigned int options,
1141*00b67f09SDavid van Moolenbroek isc_boolean_t use_hints,
1142*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1143*00b67f09SDavid van Moolenbroek {
1144*00b67f09SDavid van Moolenbroek isc_result_t result;
1145*00b67f09SDavid van Moolenbroek dns_fixedname_t foundname;
1146*00b67f09SDavid van Moolenbroek
1147*00b67f09SDavid van Moolenbroek dns_fixedname_init(&foundname);
1148*00b67f09SDavid van Moolenbroek result = dns_view_find(view, name, type, now, options, use_hints,
1149*00b67f09SDavid van Moolenbroek NULL, NULL, dns_fixedname_name(&foundname),
1150*00b67f09SDavid van Moolenbroek rdataset, sigrdataset);
1151*00b67f09SDavid van Moolenbroek if (result == DNS_R_NXDOMAIN) {
1152*00b67f09SDavid van Moolenbroek /*
1153*00b67f09SDavid van Moolenbroek * The rdataset and sigrdataset of the relevant NSEC record
1154*00b67f09SDavid van Moolenbroek * may be returned, but the caller cannot use them because
1155*00b67f09SDavid van Moolenbroek * foundname is not returned by this simplified API. We
1156*00b67f09SDavid van Moolenbroek * disassociate them here to prevent any misuse by the caller.
1157*00b67f09SDavid van Moolenbroek */
1158*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(rdataset))
1159*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1160*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1161*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(sigrdataset))
1162*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(sigrdataset);
1163*00b67f09SDavid van Moolenbroek } else if (result != ISC_R_SUCCESS &&
1164*00b67f09SDavid van Moolenbroek result != DNS_R_GLUE &&
1165*00b67f09SDavid van Moolenbroek result != DNS_R_HINT &&
1166*00b67f09SDavid van Moolenbroek result != DNS_R_NCACHENXDOMAIN &&
1167*00b67f09SDavid van Moolenbroek result != DNS_R_NCACHENXRRSET &&
1168*00b67f09SDavid van Moolenbroek result != DNS_R_NXRRSET &&
1169*00b67f09SDavid van Moolenbroek result != DNS_R_HINTNXRRSET &&
1170*00b67f09SDavid van Moolenbroek result != ISC_R_NOTFOUND) {
1171*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(rdataset))
1172*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1173*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1174*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(sigrdataset))
1175*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(sigrdataset);
1176*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
1177*00b67f09SDavid van Moolenbroek }
1178*00b67f09SDavid van Moolenbroek
1179*00b67f09SDavid van Moolenbroek return (result);
1180*00b67f09SDavid van Moolenbroek }
1181*00b67f09SDavid van Moolenbroek
1182*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_findzonecut(dns_view_t * view,dns_name_t * name,dns_name_t * fname,isc_stdtime_t now,unsigned int options,isc_boolean_t use_hints,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)1183*00b67f09SDavid van Moolenbroek dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
1184*00b67f09SDavid van Moolenbroek isc_stdtime_t now, unsigned int options,
1185*00b67f09SDavid van Moolenbroek isc_boolean_t use_hints,
1186*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1187*00b67f09SDavid van Moolenbroek {
1188*00b67f09SDavid van Moolenbroek return(dns_view_findzonecut2(view, name, fname, now, options,
1189*00b67f09SDavid van Moolenbroek use_hints, ISC_TRUE,
1190*00b67f09SDavid van Moolenbroek rdataset, sigrdataset));
1191*00b67f09SDavid van Moolenbroek }
1192*00b67f09SDavid van Moolenbroek
1193*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_findzonecut2(dns_view_t * view,dns_name_t * name,dns_name_t * fname,isc_stdtime_t now,unsigned int options,isc_boolean_t use_hints,isc_boolean_t use_cache,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)1194*00b67f09SDavid van Moolenbroek dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
1195*00b67f09SDavid van Moolenbroek isc_stdtime_t now, unsigned int options,
1196*00b67f09SDavid van Moolenbroek isc_boolean_t use_hints, isc_boolean_t use_cache,
1197*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1198*00b67f09SDavid van Moolenbroek {
1199*00b67f09SDavid van Moolenbroek isc_result_t result;
1200*00b67f09SDavid van Moolenbroek dns_db_t *db;
1201*00b67f09SDavid van Moolenbroek isc_boolean_t is_cache, use_zone, try_hints;
1202*00b67f09SDavid van Moolenbroek dns_zone_t *zone;
1203*00b67f09SDavid van Moolenbroek dns_name_t *zfname;
1204*00b67f09SDavid van Moolenbroek dns_rdataset_t zrdataset, zsigrdataset;
1205*00b67f09SDavid van Moolenbroek dns_fixedname_t zfixedname;
1206*00b67f09SDavid van Moolenbroek unsigned int ztoptions = 0;
1207*00b67f09SDavid van Moolenbroek
1208*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1209*00b67f09SDavid van Moolenbroek REQUIRE(view->frozen);
1210*00b67f09SDavid van Moolenbroek
1211*00b67f09SDavid van Moolenbroek db = NULL;
1212*00b67f09SDavid van Moolenbroek use_zone = ISC_FALSE;
1213*00b67f09SDavid van Moolenbroek try_hints = ISC_FALSE;
1214*00b67f09SDavid van Moolenbroek zfname = NULL;
1215*00b67f09SDavid van Moolenbroek
1216*00b67f09SDavid van Moolenbroek /*
1217*00b67f09SDavid van Moolenbroek * Initialize.
1218*00b67f09SDavid van Moolenbroek */
1219*00b67f09SDavid van Moolenbroek dns_fixedname_init(&zfixedname);
1220*00b67f09SDavid van Moolenbroek dns_rdataset_init(&zrdataset);
1221*00b67f09SDavid van Moolenbroek dns_rdataset_init(&zsigrdataset);
1222*00b67f09SDavid van Moolenbroek
1223*00b67f09SDavid van Moolenbroek /*
1224*00b67f09SDavid van Moolenbroek * Find the right database.
1225*00b67f09SDavid van Moolenbroek */
1226*00b67f09SDavid van Moolenbroek zone = NULL;
1227*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
1228*00b67f09SDavid van Moolenbroek if (view->zonetable != NULL) {
1229*00b67f09SDavid van Moolenbroek if ((options & DNS_DBFIND_NOEXACT) != 0)
1230*00b67f09SDavid van Moolenbroek ztoptions |= DNS_ZTFIND_NOEXACT;
1231*00b67f09SDavid van Moolenbroek result = dns_zt_find(view->zonetable, name, ztoptions,
1232*00b67f09SDavid van Moolenbroek NULL, &zone);
1233*00b67f09SDavid van Moolenbroek } else
1234*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
1235*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
1236*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
1237*00b67f09SDavid van Moolenbroek result = dns_zone_getdb(zone, &db);
1238*00b67f09SDavid van Moolenbroek if (result == ISC_R_NOTFOUND) {
1239*00b67f09SDavid van Moolenbroek /*
1240*00b67f09SDavid van Moolenbroek * We're not directly authoritative for this query name, nor
1241*00b67f09SDavid van Moolenbroek * is it a subdomain of any zone for which we're
1242*00b67f09SDavid van Moolenbroek * authoritative.
1243*00b67f09SDavid van Moolenbroek */
1244*00b67f09SDavid van Moolenbroek if (use_cache && view->cachedb != NULL) {
1245*00b67f09SDavid van Moolenbroek /*
1246*00b67f09SDavid van Moolenbroek * We have a cache; try it.
1247*00b67f09SDavid van Moolenbroek */
1248*00b67f09SDavid van Moolenbroek dns_db_attach(view->cachedb, &db);
1249*00b67f09SDavid van Moolenbroek } else {
1250*00b67f09SDavid van Moolenbroek /*
1251*00b67f09SDavid van Moolenbroek * Maybe we have hints...
1252*00b67f09SDavid van Moolenbroek */
1253*00b67f09SDavid van Moolenbroek try_hints = ISC_TRUE;
1254*00b67f09SDavid van Moolenbroek goto finish;
1255*00b67f09SDavid van Moolenbroek }
1256*00b67f09SDavid van Moolenbroek } else if (result != ISC_R_SUCCESS) {
1257*00b67f09SDavid van Moolenbroek /*
1258*00b67f09SDavid van Moolenbroek * Something is broken.
1259*00b67f09SDavid van Moolenbroek */
1260*00b67f09SDavid van Moolenbroek goto cleanup;
1261*00b67f09SDavid van Moolenbroek }
1262*00b67f09SDavid van Moolenbroek is_cache = dns_db_iscache(db);
1263*00b67f09SDavid van Moolenbroek
1264*00b67f09SDavid van Moolenbroek db_find:
1265*00b67f09SDavid van Moolenbroek /*
1266*00b67f09SDavid van Moolenbroek * Look for the zonecut.
1267*00b67f09SDavid van Moolenbroek */
1268*00b67f09SDavid van Moolenbroek if (!is_cache) {
1269*00b67f09SDavid van Moolenbroek result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options,
1270*00b67f09SDavid van Moolenbroek now, NULL, fname, rdataset, sigrdataset);
1271*00b67f09SDavid van Moolenbroek if (result == DNS_R_DELEGATION)
1272*00b67f09SDavid van Moolenbroek result = ISC_R_SUCCESS;
1273*00b67f09SDavid van Moolenbroek else if (result != ISC_R_SUCCESS)
1274*00b67f09SDavid van Moolenbroek goto cleanup;
1275*00b67f09SDavid van Moolenbroek if (use_cache && view->cachedb != NULL && db != view->hints) {
1276*00b67f09SDavid van Moolenbroek /*
1277*00b67f09SDavid van Moolenbroek * We found an answer, but the cache may be better.
1278*00b67f09SDavid van Moolenbroek */
1279*00b67f09SDavid van Moolenbroek zfname = dns_fixedname_name(&zfixedname);
1280*00b67f09SDavid van Moolenbroek result = dns_name_copy(fname, zfname, NULL);
1281*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1282*00b67f09SDavid van Moolenbroek goto cleanup;
1283*00b67f09SDavid van Moolenbroek dns_rdataset_clone(rdataset, &zrdataset);
1284*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1285*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1286*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(sigrdataset)) {
1287*00b67f09SDavid van Moolenbroek dns_rdataset_clone(sigrdataset, &zsigrdataset);
1288*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(sigrdataset);
1289*00b67f09SDavid van Moolenbroek }
1290*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1291*00b67f09SDavid van Moolenbroek dns_db_attach(view->cachedb, &db);
1292*00b67f09SDavid van Moolenbroek is_cache = ISC_TRUE;
1293*00b67f09SDavid van Moolenbroek goto db_find;
1294*00b67f09SDavid van Moolenbroek }
1295*00b67f09SDavid van Moolenbroek } else {
1296*00b67f09SDavid van Moolenbroek result = dns_db_findzonecut(db, name, options, now, NULL,
1297*00b67f09SDavid van Moolenbroek fname, rdataset, sigrdataset);
1298*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
1299*00b67f09SDavid van Moolenbroek if (zfname != NULL &&
1300*00b67f09SDavid van Moolenbroek (!dns_name_issubdomain(fname, zfname) ||
1301*00b67f09SDavid van Moolenbroek (dns_zone_staticstub &&
1302*00b67f09SDavid van Moolenbroek dns_name_equal(fname, zfname)))) {
1303*00b67f09SDavid van Moolenbroek /*
1304*00b67f09SDavid van Moolenbroek * We found a zonecut in the cache, but our
1305*00b67f09SDavid van Moolenbroek * zone delegation is better.
1306*00b67f09SDavid van Moolenbroek */
1307*00b67f09SDavid van Moolenbroek use_zone = ISC_TRUE;
1308*00b67f09SDavid van Moolenbroek }
1309*00b67f09SDavid van Moolenbroek } else if (result == ISC_R_NOTFOUND) {
1310*00b67f09SDavid van Moolenbroek if (zfname != NULL) {
1311*00b67f09SDavid van Moolenbroek /*
1312*00b67f09SDavid van Moolenbroek * We didn't find anything in the cache, but we
1313*00b67f09SDavid van Moolenbroek * have a zone delegation, so use it.
1314*00b67f09SDavid van Moolenbroek */
1315*00b67f09SDavid van Moolenbroek use_zone = ISC_TRUE;
1316*00b67f09SDavid van Moolenbroek } else {
1317*00b67f09SDavid van Moolenbroek /*
1318*00b67f09SDavid van Moolenbroek * Maybe we have hints...
1319*00b67f09SDavid van Moolenbroek */
1320*00b67f09SDavid van Moolenbroek try_hints = ISC_TRUE;
1321*00b67f09SDavid van Moolenbroek }
1322*00b67f09SDavid van Moolenbroek } else {
1323*00b67f09SDavid van Moolenbroek /*
1324*00b67f09SDavid van Moolenbroek * Something bad happened.
1325*00b67f09SDavid van Moolenbroek */
1326*00b67f09SDavid van Moolenbroek goto cleanup;
1327*00b67f09SDavid van Moolenbroek }
1328*00b67f09SDavid van Moolenbroek }
1329*00b67f09SDavid van Moolenbroek
1330*00b67f09SDavid van Moolenbroek finish:
1331*00b67f09SDavid van Moolenbroek if (use_zone) {
1332*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(rdataset)) {
1333*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1334*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1335*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(sigrdataset))
1336*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(sigrdataset);
1337*00b67f09SDavid van Moolenbroek }
1338*00b67f09SDavid van Moolenbroek result = dns_name_copy(zfname, fname, NULL);
1339*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1340*00b67f09SDavid van Moolenbroek goto cleanup;
1341*00b67f09SDavid van Moolenbroek dns_rdataset_clone(&zrdataset, rdataset);
1342*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
1343*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated(&zrdataset))
1344*00b67f09SDavid van Moolenbroek dns_rdataset_clone(&zsigrdataset, sigrdataset);
1345*00b67f09SDavid van Moolenbroek } else if (try_hints && use_hints && view->hints != NULL) {
1346*00b67f09SDavid van Moolenbroek /*
1347*00b67f09SDavid van Moolenbroek * We've found nothing so far, but we have hints.
1348*00b67f09SDavid van Moolenbroek */
1349*00b67f09SDavid van Moolenbroek result = dns_db_find(view->hints, dns_rootname, NULL,
1350*00b67f09SDavid van Moolenbroek dns_rdatatype_ns, 0, now, NULL, fname,
1351*00b67f09SDavid van Moolenbroek rdataset, NULL);
1352*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
1353*00b67f09SDavid van Moolenbroek /*
1354*00b67f09SDavid van Moolenbroek * We can't even find the hints for the root
1355*00b67f09SDavid van Moolenbroek * nameservers!
1356*00b67f09SDavid van Moolenbroek */
1357*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(rdataset))
1358*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
1359*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
1360*00b67f09SDavid van Moolenbroek }
1361*00b67f09SDavid van Moolenbroek }
1362*00b67f09SDavid van Moolenbroek
1363*00b67f09SDavid van Moolenbroek cleanup:
1364*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(&zrdataset)) {
1365*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(&zrdataset);
1366*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(&zsigrdataset))
1367*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(&zsigrdataset);
1368*00b67f09SDavid van Moolenbroek }
1369*00b67f09SDavid van Moolenbroek if (db != NULL)
1370*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1371*00b67f09SDavid van Moolenbroek if (zone != NULL)
1372*00b67f09SDavid van Moolenbroek dns_zone_detach(&zone);
1373*00b67f09SDavid van Moolenbroek
1374*00b67f09SDavid van Moolenbroek return (result);
1375*00b67f09SDavid van Moolenbroek }
1376*00b67f09SDavid van Moolenbroek
1377*00b67f09SDavid van Moolenbroek isc_result_t
dns_viewlist_find(dns_viewlist_t * list,const char * name,dns_rdataclass_t rdclass,dns_view_t ** viewp)1378*00b67f09SDavid van Moolenbroek dns_viewlist_find(dns_viewlist_t *list, const char *name,
1379*00b67f09SDavid van Moolenbroek dns_rdataclass_t rdclass, dns_view_t **viewp)
1380*00b67f09SDavid van Moolenbroek {
1381*00b67f09SDavid van Moolenbroek dns_view_t *view;
1382*00b67f09SDavid van Moolenbroek
1383*00b67f09SDavid van Moolenbroek REQUIRE(list != NULL);
1384*00b67f09SDavid van Moolenbroek
1385*00b67f09SDavid van Moolenbroek for (view = ISC_LIST_HEAD(*list);
1386*00b67f09SDavid van Moolenbroek view != NULL;
1387*00b67f09SDavid van Moolenbroek view = ISC_LIST_NEXT(view, link)) {
1388*00b67f09SDavid van Moolenbroek if (strcmp(view->name, name) == 0 && view->rdclass == rdclass)
1389*00b67f09SDavid van Moolenbroek break;
1390*00b67f09SDavid van Moolenbroek }
1391*00b67f09SDavid van Moolenbroek if (view == NULL)
1392*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1393*00b67f09SDavid van Moolenbroek
1394*00b67f09SDavid van Moolenbroek dns_view_attach(view, viewp);
1395*00b67f09SDavid van Moolenbroek
1396*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1397*00b67f09SDavid van Moolenbroek }
1398*00b67f09SDavid van Moolenbroek
1399*00b67f09SDavid van Moolenbroek isc_result_t
dns_viewlist_findzone(dns_viewlist_t * list,dns_name_t * name,isc_boolean_t allclasses,dns_rdataclass_t rdclass,dns_zone_t ** zonep)1400*00b67f09SDavid van Moolenbroek dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
1401*00b67f09SDavid van Moolenbroek isc_boolean_t allclasses, dns_rdataclass_t rdclass,
1402*00b67f09SDavid van Moolenbroek dns_zone_t **zonep)
1403*00b67f09SDavid van Moolenbroek {
1404*00b67f09SDavid van Moolenbroek dns_view_t *view;
1405*00b67f09SDavid van Moolenbroek isc_result_t result;
1406*00b67f09SDavid van Moolenbroek dns_zone_t *zone1 = NULL, *zone2 = NULL;
1407*00b67f09SDavid van Moolenbroek dns_zone_t **zp = NULL;;
1408*00b67f09SDavid van Moolenbroek
1409*00b67f09SDavid van Moolenbroek REQUIRE(list != NULL);
1410*00b67f09SDavid van Moolenbroek REQUIRE(zonep != NULL && *zonep == NULL);
1411*00b67f09SDavid van Moolenbroek
1412*00b67f09SDavid van Moolenbroek for (view = ISC_LIST_HEAD(*list);
1413*00b67f09SDavid van Moolenbroek view != NULL;
1414*00b67f09SDavid van Moolenbroek view = ISC_LIST_NEXT(view, link)) {
1415*00b67f09SDavid van Moolenbroek if (allclasses == ISC_FALSE && view->rdclass != rdclass)
1416*00b67f09SDavid van Moolenbroek continue;
1417*00b67f09SDavid van Moolenbroek
1418*00b67f09SDavid van Moolenbroek /*
1419*00b67f09SDavid van Moolenbroek * If the zone is defined in more than one view,
1420*00b67f09SDavid van Moolenbroek * treat it as not found.
1421*00b67f09SDavid van Moolenbroek */
1422*00b67f09SDavid van Moolenbroek zp = (zone1 == NULL) ? &zone1 : &zone2;
1423*00b67f09SDavid van Moolenbroek LOCK(&view->lock);
1424*00b67f09SDavid van Moolenbroek if (view->zonetable != NULL)
1425*00b67f09SDavid van Moolenbroek result = dns_zt_find(view->zonetable, name, 0,
1426*00b67f09SDavid van Moolenbroek NULL, zp);
1427*00b67f09SDavid van Moolenbroek else
1428*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
1429*00b67f09SDavid van Moolenbroek UNLOCK(&view->lock);
1430*00b67f09SDavid van Moolenbroek INSIST(result == ISC_R_SUCCESS ||
1431*00b67f09SDavid van Moolenbroek result == ISC_R_NOTFOUND ||
1432*00b67f09SDavid van Moolenbroek result == DNS_R_PARTIALMATCH);
1433*00b67f09SDavid van Moolenbroek
1434*00b67f09SDavid van Moolenbroek /* Treat a partial match as no match */
1435*00b67f09SDavid van Moolenbroek if (result == DNS_R_PARTIALMATCH) {
1436*00b67f09SDavid van Moolenbroek dns_zone_detach(zp);
1437*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
1438*00b67f09SDavid van Moolenbroek POST(result);
1439*00b67f09SDavid van Moolenbroek }
1440*00b67f09SDavid van Moolenbroek
1441*00b67f09SDavid van Moolenbroek if (zone2 != NULL) {
1442*00b67f09SDavid van Moolenbroek dns_zone_detach(&zone1);
1443*00b67f09SDavid van Moolenbroek dns_zone_detach(&zone2);
1444*00b67f09SDavid van Moolenbroek return (ISC_R_MULTIPLE);
1445*00b67f09SDavid van Moolenbroek }
1446*00b67f09SDavid van Moolenbroek }
1447*00b67f09SDavid van Moolenbroek
1448*00b67f09SDavid van Moolenbroek if (zone1 != NULL) {
1449*00b67f09SDavid van Moolenbroek dns_zone_attach(zone1, zonep);
1450*00b67f09SDavid van Moolenbroek dns_zone_detach(&zone1);
1451*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1452*00b67f09SDavid van Moolenbroek }
1453*00b67f09SDavid van Moolenbroek
1454*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1455*00b67f09SDavid van Moolenbroek }
1456*00b67f09SDavid van Moolenbroek
1457*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_load(dns_view_t * view,isc_boolean_t stop)1458*00b67f09SDavid van Moolenbroek dns_view_load(dns_view_t *view, isc_boolean_t stop) {
1459*00b67f09SDavid van Moolenbroek
1460*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1461*00b67f09SDavid van Moolenbroek REQUIRE(view->zonetable != NULL);
1462*00b67f09SDavid van Moolenbroek
1463*00b67f09SDavid van Moolenbroek return (dns_zt_load(view->zonetable, stop));
1464*00b67f09SDavid van Moolenbroek }
1465*00b67f09SDavid van Moolenbroek
1466*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_loadnew(dns_view_t * view,isc_boolean_t stop)1467*00b67f09SDavid van Moolenbroek dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
1468*00b67f09SDavid van Moolenbroek
1469*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1470*00b67f09SDavid van Moolenbroek REQUIRE(view->zonetable != NULL);
1471*00b67f09SDavid van Moolenbroek
1472*00b67f09SDavid van Moolenbroek return (dns_zt_loadnew(view->zonetable, stop));
1473*00b67f09SDavid van Moolenbroek }
1474*00b67f09SDavid van Moolenbroek
1475*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_asyncload(dns_view_t * view,dns_zt_allloaded_t callback,void * arg)1476*00b67f09SDavid van Moolenbroek dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) {
1477*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1478*00b67f09SDavid van Moolenbroek REQUIRE(view->zonetable != NULL);
1479*00b67f09SDavid van Moolenbroek
1480*00b67f09SDavid van Moolenbroek return (dns_zt_asyncload(view->zonetable, callback, arg));
1481*00b67f09SDavid van Moolenbroek }
1482*00b67f09SDavid van Moolenbroek
1483*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_gettsig(dns_view_t * view,dns_name_t * keyname,dns_tsigkey_t ** keyp)1484*00b67f09SDavid van Moolenbroek dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
1485*00b67f09SDavid van Moolenbroek {
1486*00b67f09SDavid van Moolenbroek isc_result_t result;
1487*00b67f09SDavid van Moolenbroek REQUIRE(keyp != NULL && *keyp == NULL);
1488*00b67f09SDavid van Moolenbroek
1489*00b67f09SDavid van Moolenbroek result = dns_tsigkey_find(keyp, keyname, NULL,
1490*00b67f09SDavid van Moolenbroek view->statickeys);
1491*00b67f09SDavid van Moolenbroek if (result == ISC_R_NOTFOUND)
1492*00b67f09SDavid van Moolenbroek result = dns_tsigkey_find(keyp, keyname, NULL,
1493*00b67f09SDavid van Moolenbroek view->dynamickeys);
1494*00b67f09SDavid van Moolenbroek return (result);
1495*00b67f09SDavid van Moolenbroek }
1496*00b67f09SDavid van Moolenbroek
1497*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_getpeertsig(dns_view_t * view,isc_netaddr_t * peeraddr,dns_tsigkey_t ** keyp)1498*00b67f09SDavid van Moolenbroek dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
1499*00b67f09SDavid van Moolenbroek dns_tsigkey_t **keyp)
1500*00b67f09SDavid van Moolenbroek {
1501*00b67f09SDavid van Moolenbroek isc_result_t result;
1502*00b67f09SDavid van Moolenbroek dns_name_t *keyname = NULL;
1503*00b67f09SDavid van Moolenbroek dns_peer_t *peer = NULL;
1504*00b67f09SDavid van Moolenbroek
1505*00b67f09SDavid van Moolenbroek result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer);
1506*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1507*00b67f09SDavid van Moolenbroek return (result);
1508*00b67f09SDavid van Moolenbroek
1509*00b67f09SDavid van Moolenbroek result = dns_peer_getkey(peer, &keyname);
1510*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1511*00b67f09SDavid van Moolenbroek return (result);
1512*00b67f09SDavid van Moolenbroek
1513*00b67f09SDavid van Moolenbroek result = dns_view_gettsig(view, keyname, keyp);
1514*00b67f09SDavid van Moolenbroek return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
1515*00b67f09SDavid van Moolenbroek }
1516*00b67f09SDavid van Moolenbroek
1517*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_checksig(dns_view_t * view,isc_buffer_t * source,dns_message_t * msg)1518*00b67f09SDavid van Moolenbroek dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
1519*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1520*00b67f09SDavid van Moolenbroek REQUIRE(source != NULL);
1521*00b67f09SDavid van Moolenbroek
1522*00b67f09SDavid van Moolenbroek return (dns_tsig_verify(source, msg, view->statickeys,
1523*00b67f09SDavid van Moolenbroek view->dynamickeys));
1524*00b67f09SDavid van Moolenbroek }
1525*00b67f09SDavid van Moolenbroek
1526*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_dumpdbtostream(dns_view_t * view,FILE * fp)1527*00b67f09SDavid van Moolenbroek dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
1528*00b67f09SDavid van Moolenbroek isc_result_t result;
1529*00b67f09SDavid van Moolenbroek
1530*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1531*00b67f09SDavid van Moolenbroek
1532*00b67f09SDavid van Moolenbroek (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name);
1533*00b67f09SDavid van Moolenbroek result = dns_master_dumptostream(view->mctx, view->cachedb, NULL,
1534*00b67f09SDavid van Moolenbroek &dns_master_style_cache, fp);
1535*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1536*00b67f09SDavid van Moolenbroek return (result);
1537*00b67f09SDavid van Moolenbroek dns_adb_dump(view->adb, fp);
1538*00b67f09SDavid van Moolenbroek dns_resolver_printbadcache(view->resolver, fp);
1539*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1540*00b67f09SDavid van Moolenbroek }
1541*00b67f09SDavid van Moolenbroek
1542*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_flushcache(dns_view_t * view)1543*00b67f09SDavid van Moolenbroek dns_view_flushcache(dns_view_t *view) {
1544*00b67f09SDavid van Moolenbroek return (dns_view_flushcache2(view, ISC_FALSE));
1545*00b67f09SDavid van Moolenbroek }
1546*00b67f09SDavid van Moolenbroek
1547*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_flushcache2(dns_view_t * view,isc_boolean_t fixuponly)1548*00b67f09SDavid van Moolenbroek dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
1549*00b67f09SDavid van Moolenbroek isc_result_t result;
1550*00b67f09SDavid van Moolenbroek
1551*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1552*00b67f09SDavid van Moolenbroek
1553*00b67f09SDavid van Moolenbroek if (view->cachedb == NULL)
1554*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1555*00b67f09SDavid van Moolenbroek if (!fixuponly) {
1556*00b67f09SDavid van Moolenbroek result = dns_cache_flush(view->cache);
1557*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1558*00b67f09SDavid van Moolenbroek return (result);
1559*00b67f09SDavid van Moolenbroek }
1560*00b67f09SDavid van Moolenbroek if (view->acache != NULL)
1561*00b67f09SDavid van Moolenbroek dns_acache_putdb(view->acache, view->cachedb);
1562*00b67f09SDavid van Moolenbroek dns_db_detach(&view->cachedb);
1563*00b67f09SDavid van Moolenbroek dns_cache_attachdb(view->cache, &view->cachedb);
1564*00b67f09SDavid van Moolenbroek if (view->acache != NULL)
1565*00b67f09SDavid van Moolenbroek dns_acache_setdb(view->acache, view->cachedb);
1566*00b67f09SDavid van Moolenbroek if (view->resolver != NULL)
1567*00b67f09SDavid van Moolenbroek dns_resolver_flushbadcache(view->resolver, NULL);
1568*00b67f09SDavid van Moolenbroek
1569*00b67f09SDavid van Moolenbroek dns_adb_flush(view->adb);
1570*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1571*00b67f09SDavid van Moolenbroek }
1572*00b67f09SDavid van Moolenbroek
1573*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_flushname(dns_view_t * view,dns_name_t * name)1574*00b67f09SDavid van Moolenbroek dns_view_flushname(dns_view_t *view, dns_name_t *name) {
1575*00b67f09SDavid van Moolenbroek return (dns_view_flushnode(view, name, ISC_FALSE));
1576*00b67f09SDavid van Moolenbroek }
1577*00b67f09SDavid van Moolenbroek
1578*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_flushnode(dns_view_t * view,dns_name_t * name,isc_boolean_t tree)1579*00b67f09SDavid van Moolenbroek dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) {
1580*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
1581*00b67f09SDavid van Moolenbroek
1582*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1583*00b67f09SDavid van Moolenbroek
1584*00b67f09SDavid van Moolenbroek if (tree) {
1585*00b67f09SDavid van Moolenbroek if (view->adb != NULL)
1586*00b67f09SDavid van Moolenbroek dns_adb_flushnames(view->adb, name);
1587*00b67f09SDavid van Moolenbroek if (view->resolver != NULL)
1588*00b67f09SDavid van Moolenbroek dns_resolver_flushbadnames(view->resolver, name);
1589*00b67f09SDavid van Moolenbroek } else {
1590*00b67f09SDavid van Moolenbroek if (view->adb != NULL)
1591*00b67f09SDavid van Moolenbroek dns_adb_flushname(view->adb, name);
1592*00b67f09SDavid van Moolenbroek if (view->resolver != NULL)
1593*00b67f09SDavid van Moolenbroek dns_resolver_flushbadcache(view->resolver, name);
1594*00b67f09SDavid van Moolenbroek }
1595*00b67f09SDavid van Moolenbroek
1596*00b67f09SDavid van Moolenbroek if (view->cache != NULL)
1597*00b67f09SDavid van Moolenbroek result = dns_cache_flushnode(view->cache, name, tree);
1598*00b67f09SDavid van Moolenbroek
1599*00b67f09SDavid van Moolenbroek return (result);
1600*00b67f09SDavid van Moolenbroek }
1601*00b67f09SDavid van Moolenbroek
1602*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_adddelegationonly(dns_view_t * view,dns_name_t * name)1603*00b67f09SDavid van Moolenbroek dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) {
1604*00b67f09SDavid van Moolenbroek isc_result_t result;
1605*00b67f09SDavid van Moolenbroek dns_name_t *new;
1606*00b67f09SDavid van Moolenbroek isc_uint32_t hash;
1607*00b67f09SDavid van Moolenbroek
1608*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1609*00b67f09SDavid van Moolenbroek
1610*00b67f09SDavid van Moolenbroek if (view->delonly == NULL) {
1611*00b67f09SDavid van Moolenbroek view->delonly = isc_mem_get(view->mctx,
1612*00b67f09SDavid van Moolenbroek sizeof(dns_namelist_t) *
1613*00b67f09SDavid van Moolenbroek DNS_VIEW_DELONLYHASH);
1614*00b67f09SDavid van Moolenbroek if (view->delonly == NULL)
1615*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
1616*00b67f09SDavid van Moolenbroek for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
1617*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(view->delonly[hash]);
1618*00b67f09SDavid van Moolenbroek }
1619*00b67f09SDavid van Moolenbroek hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1620*00b67f09SDavid van Moolenbroek new = ISC_LIST_HEAD(view->delonly[hash]);
1621*00b67f09SDavid van Moolenbroek while (new != NULL && !dns_name_equal(new, name))
1622*00b67f09SDavid van Moolenbroek new = ISC_LIST_NEXT(new, link);
1623*00b67f09SDavid van Moolenbroek if (new != NULL)
1624*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1625*00b67f09SDavid van Moolenbroek new = isc_mem_get(view->mctx, sizeof(*new));
1626*00b67f09SDavid van Moolenbroek if (new == NULL)
1627*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
1628*00b67f09SDavid van Moolenbroek dns_name_init(new, NULL);
1629*00b67f09SDavid van Moolenbroek result = dns_name_dup(name, view->mctx, new);
1630*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
1631*00b67f09SDavid van Moolenbroek ISC_LIST_APPEND(view->delonly[hash], new, link);
1632*00b67f09SDavid van Moolenbroek else
1633*00b67f09SDavid van Moolenbroek isc_mem_put(view->mctx, new, sizeof(*new));
1634*00b67f09SDavid van Moolenbroek return (result);
1635*00b67f09SDavid van Moolenbroek }
1636*00b67f09SDavid van Moolenbroek
1637*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_excludedelegationonly(dns_view_t * view,dns_name_t * name)1638*00b67f09SDavid van Moolenbroek dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) {
1639*00b67f09SDavid van Moolenbroek isc_result_t result;
1640*00b67f09SDavid van Moolenbroek dns_name_t *new;
1641*00b67f09SDavid van Moolenbroek isc_uint32_t hash;
1642*00b67f09SDavid van Moolenbroek
1643*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1644*00b67f09SDavid van Moolenbroek
1645*00b67f09SDavid van Moolenbroek if (view->rootexclude == NULL) {
1646*00b67f09SDavid van Moolenbroek view->rootexclude = isc_mem_get(view->mctx,
1647*00b67f09SDavid van Moolenbroek sizeof(dns_namelist_t) *
1648*00b67f09SDavid van Moolenbroek DNS_VIEW_DELONLYHASH);
1649*00b67f09SDavid van Moolenbroek if (view->rootexclude == NULL)
1650*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
1651*00b67f09SDavid van Moolenbroek for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
1652*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(view->rootexclude[hash]);
1653*00b67f09SDavid van Moolenbroek }
1654*00b67f09SDavid van Moolenbroek hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1655*00b67f09SDavid van Moolenbroek new = ISC_LIST_HEAD(view->rootexclude[hash]);
1656*00b67f09SDavid van Moolenbroek while (new != NULL && !dns_name_equal(new, name))
1657*00b67f09SDavid van Moolenbroek new = ISC_LIST_NEXT(new, link);
1658*00b67f09SDavid van Moolenbroek if (new != NULL)
1659*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1660*00b67f09SDavid van Moolenbroek new = isc_mem_get(view->mctx, sizeof(*new));
1661*00b67f09SDavid van Moolenbroek if (new == NULL)
1662*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
1663*00b67f09SDavid van Moolenbroek dns_name_init(new, NULL);
1664*00b67f09SDavid van Moolenbroek result = dns_name_dup(name, view->mctx, new);
1665*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
1666*00b67f09SDavid van Moolenbroek ISC_LIST_APPEND(view->rootexclude[hash], new, link);
1667*00b67f09SDavid van Moolenbroek else
1668*00b67f09SDavid van Moolenbroek isc_mem_put(view->mctx, new, sizeof(*new));
1669*00b67f09SDavid van Moolenbroek return (result);
1670*00b67f09SDavid van Moolenbroek }
1671*00b67f09SDavid van Moolenbroek
1672*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_view_isdelegationonly(dns_view_t * view,dns_name_t * name)1673*00b67f09SDavid van Moolenbroek dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) {
1674*00b67f09SDavid van Moolenbroek dns_name_t *new;
1675*00b67f09SDavid van Moolenbroek isc_uint32_t hash;
1676*00b67f09SDavid van Moolenbroek
1677*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1678*00b67f09SDavid van Moolenbroek
1679*00b67f09SDavid van Moolenbroek if (!view->rootdelonly && view->delonly == NULL)
1680*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
1681*00b67f09SDavid van Moolenbroek
1682*00b67f09SDavid van Moolenbroek hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
1683*00b67f09SDavid van Moolenbroek if (view->rootdelonly && dns_name_countlabels(name) <= 2) {
1684*00b67f09SDavid van Moolenbroek if (view->rootexclude == NULL)
1685*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
1686*00b67f09SDavid van Moolenbroek new = ISC_LIST_HEAD(view->rootexclude[hash]);
1687*00b67f09SDavid van Moolenbroek while (new != NULL && !dns_name_equal(new, name))
1688*00b67f09SDavid van Moolenbroek new = ISC_LIST_NEXT(new, link);
1689*00b67f09SDavid van Moolenbroek if (new == NULL)
1690*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
1691*00b67f09SDavid van Moolenbroek }
1692*00b67f09SDavid van Moolenbroek
1693*00b67f09SDavid van Moolenbroek if (view->delonly == NULL)
1694*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
1695*00b67f09SDavid van Moolenbroek
1696*00b67f09SDavid van Moolenbroek new = ISC_LIST_HEAD(view->delonly[hash]);
1697*00b67f09SDavid van Moolenbroek while (new != NULL && !dns_name_equal(new, name))
1698*00b67f09SDavid van Moolenbroek new = ISC_LIST_NEXT(new, link);
1699*00b67f09SDavid van Moolenbroek if (new == NULL)
1700*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
1701*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
1702*00b67f09SDavid van Moolenbroek }
1703*00b67f09SDavid van Moolenbroek
1704*00b67f09SDavid van Moolenbroek void
dns_view_setrootdelonly(dns_view_t * view,isc_boolean_t value)1705*00b67f09SDavid van Moolenbroek dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) {
1706*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1707*00b67f09SDavid van Moolenbroek view->rootdelonly = value;
1708*00b67f09SDavid van Moolenbroek }
1709*00b67f09SDavid van Moolenbroek
1710*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_view_getrootdelonly(dns_view_t * view)1711*00b67f09SDavid van Moolenbroek dns_view_getrootdelonly(dns_view_t *view) {
1712*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1713*00b67f09SDavid van Moolenbroek return (view->rootdelonly);
1714*00b67f09SDavid van Moolenbroek }
1715*00b67f09SDavid van Moolenbroek
1716*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_freezezones(dns_view_t * view,isc_boolean_t value)1717*00b67f09SDavid van Moolenbroek dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
1718*00b67f09SDavid van Moolenbroek
1719*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1720*00b67f09SDavid van Moolenbroek REQUIRE(view->zonetable != NULL);
1721*00b67f09SDavid van Moolenbroek
1722*00b67f09SDavid van Moolenbroek return (dns_zt_freezezones(view->zonetable, value));
1723*00b67f09SDavid van Moolenbroek }
1724*00b67f09SDavid van Moolenbroek
1725*00b67f09SDavid van Moolenbroek void
dns_view_setadbstats(dns_view_t * view,isc_stats_t * stats)1726*00b67f09SDavid van Moolenbroek dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats) {
1727*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1728*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
1729*00b67f09SDavid van Moolenbroek REQUIRE(view->adbstats == NULL);
1730*00b67f09SDavid van Moolenbroek
1731*00b67f09SDavid van Moolenbroek isc_stats_attach(stats, &view->adbstats);
1732*00b67f09SDavid van Moolenbroek }
1733*00b67f09SDavid van Moolenbroek
1734*00b67f09SDavid van Moolenbroek void
dns_view_getadbstats(dns_view_t * view,isc_stats_t ** statsp)1735*00b67f09SDavid van Moolenbroek dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp) {
1736*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1737*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
1738*00b67f09SDavid van Moolenbroek
1739*00b67f09SDavid van Moolenbroek if (view->adbstats != NULL)
1740*00b67f09SDavid van Moolenbroek isc_stats_attach(view->adbstats, statsp);
1741*00b67f09SDavid van Moolenbroek }
1742*00b67f09SDavid van Moolenbroek
1743*00b67f09SDavid van Moolenbroek void
dns_view_setresstats(dns_view_t * view,isc_stats_t * stats)1744*00b67f09SDavid van Moolenbroek dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) {
1745*00b67f09SDavid van Moolenbroek
1746*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1747*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
1748*00b67f09SDavid van Moolenbroek REQUIRE(view->resstats == NULL);
1749*00b67f09SDavid van Moolenbroek
1750*00b67f09SDavid van Moolenbroek isc_stats_attach(stats, &view->resstats);
1751*00b67f09SDavid van Moolenbroek }
1752*00b67f09SDavid van Moolenbroek
1753*00b67f09SDavid van Moolenbroek void
dns_view_getresstats(dns_view_t * view,isc_stats_t ** statsp)1754*00b67f09SDavid van Moolenbroek dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) {
1755*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1756*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
1757*00b67f09SDavid van Moolenbroek
1758*00b67f09SDavid van Moolenbroek if (view->resstats != NULL)
1759*00b67f09SDavid van Moolenbroek isc_stats_attach(view->resstats, statsp);
1760*00b67f09SDavid van Moolenbroek }
1761*00b67f09SDavid van Moolenbroek
1762*00b67f09SDavid van Moolenbroek void
dns_view_setresquerystats(dns_view_t * view,dns_stats_t * stats)1763*00b67f09SDavid van Moolenbroek dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) {
1764*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1765*00b67f09SDavid van Moolenbroek REQUIRE(!view->frozen);
1766*00b67f09SDavid van Moolenbroek REQUIRE(view->resquerystats == NULL);
1767*00b67f09SDavid van Moolenbroek
1768*00b67f09SDavid van Moolenbroek dns_stats_attach(stats, &view->resquerystats);
1769*00b67f09SDavid van Moolenbroek }
1770*00b67f09SDavid van Moolenbroek
1771*00b67f09SDavid van Moolenbroek void
dns_view_getresquerystats(dns_view_t * view,dns_stats_t ** statsp)1772*00b67f09SDavid van Moolenbroek dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
1773*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1774*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
1775*00b67f09SDavid van Moolenbroek
1776*00b67f09SDavid van Moolenbroek if (view->resquerystats != NULL)
1777*00b67f09SDavid van Moolenbroek dns_stats_attach(view->resquerystats, statsp);
1778*00b67f09SDavid van Moolenbroek }
1779*00b67f09SDavid van Moolenbroek
1780*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_initsecroots(dns_view_t * view,isc_mem_t * mctx)1781*00b67f09SDavid van Moolenbroek dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) {
1782*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1783*00b67f09SDavid van Moolenbroek if (view->secroots_priv != NULL)
1784*00b67f09SDavid van Moolenbroek dns_keytable_detach(&view->secroots_priv);
1785*00b67f09SDavid van Moolenbroek return (dns_keytable_create(mctx, &view->secroots_priv));
1786*00b67f09SDavid van Moolenbroek }
1787*00b67f09SDavid van Moolenbroek
1788*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_getsecroots(dns_view_t * view,dns_keytable_t ** ktp)1789*00b67f09SDavid van Moolenbroek dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) {
1790*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1791*00b67f09SDavid van Moolenbroek REQUIRE(ktp != NULL && *ktp == NULL);
1792*00b67f09SDavid van Moolenbroek if (view->secroots_priv == NULL)
1793*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1794*00b67f09SDavid van Moolenbroek dns_keytable_attach(view->secroots_priv, ktp);
1795*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1796*00b67f09SDavid van Moolenbroek }
1797*00b67f09SDavid van Moolenbroek
1798*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_issecuredomain(dns_view_t * view,dns_name_t * name,isc_boolean_t * secure_domain)1799*00b67f09SDavid van Moolenbroek dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
1800*00b67f09SDavid van Moolenbroek isc_boolean_t *secure_domain) {
1801*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1802*00b67f09SDavid van Moolenbroek
1803*00b67f09SDavid van Moolenbroek if (view->secroots_priv == NULL)
1804*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1805*00b67f09SDavid van Moolenbroek return (dns_keytable_issecuredomain(view->secroots_priv, name,
1806*00b67f09SDavid van Moolenbroek secure_domain));
1807*00b67f09SDavid van Moolenbroek }
1808*00b67f09SDavid van Moolenbroek
1809*00b67f09SDavid van Moolenbroek void
dns_view_untrust(dns_view_t * view,dns_name_t * keyname,dns_rdata_dnskey_t * dnskey,isc_mem_t * mctx)1810*00b67f09SDavid van Moolenbroek dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
1811*00b67f09SDavid van Moolenbroek dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
1812*00b67f09SDavid van Moolenbroek {
1813*00b67f09SDavid van Moolenbroek isc_result_t result;
1814*00b67f09SDavid van Moolenbroek unsigned char data[4096];
1815*00b67f09SDavid van Moolenbroek dns_rdata_t rdata = DNS_RDATA_INIT;
1816*00b67f09SDavid van Moolenbroek isc_buffer_t buffer;
1817*00b67f09SDavid van Moolenbroek dst_key_t *key = NULL;
1818*00b67f09SDavid van Moolenbroek dns_keytable_t *sr = NULL;
1819*00b67f09SDavid van Moolenbroek
1820*00b67f09SDavid van Moolenbroek /*
1821*00b67f09SDavid van Moolenbroek * Clear the revoke bit, if set, so that the key will match what's
1822*00b67f09SDavid van Moolenbroek * in secroots now.
1823*00b67f09SDavid van Moolenbroek */
1824*00b67f09SDavid van Moolenbroek dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
1825*00b67f09SDavid van Moolenbroek
1826*00b67f09SDavid van Moolenbroek /* Convert dnskey to DST key. */
1827*00b67f09SDavid van Moolenbroek isc_buffer_init(&buffer, data, sizeof(data));
1828*00b67f09SDavid van Moolenbroek dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
1829*00b67f09SDavid van Moolenbroek dns_rdatatype_dnskey, dnskey, &buffer);
1830*00b67f09SDavid van Moolenbroek result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key);
1831*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1832*00b67f09SDavid van Moolenbroek return;
1833*00b67f09SDavid van Moolenbroek result = dns_view_getsecroots(view, &sr);
1834*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
1835*00b67f09SDavid van Moolenbroek dns_keytable_deletekeynode(sr, key);
1836*00b67f09SDavid van Moolenbroek dns_keytable_detach(&sr);
1837*00b67f09SDavid van Moolenbroek }
1838*00b67f09SDavid van Moolenbroek dst_key_free(&key);
1839*00b67f09SDavid van Moolenbroek }
1840*00b67f09SDavid van Moolenbroek
1841*00b67f09SDavid van Moolenbroek #define NZF ".nzf"
1842*00b67f09SDavid van Moolenbroek
1843*00b67f09SDavid van Moolenbroek void
dns_view_setnewzones(dns_view_t * view,isc_boolean_t allow,void * cfgctx,void (* cfg_destroy)(void **))1844*00b67f09SDavid van Moolenbroek dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
1845*00b67f09SDavid van Moolenbroek void (*cfg_destroy)(void **))
1846*00b67f09SDavid van Moolenbroek {
1847*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1848*00b67f09SDavid van Moolenbroek REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow);
1849*00b67f09SDavid van Moolenbroek
1850*00b67f09SDavid van Moolenbroek if (view->new_zone_file != NULL) {
1851*00b67f09SDavid van Moolenbroek isc_mem_free(view->mctx, view->new_zone_file);
1852*00b67f09SDavid van Moolenbroek view->new_zone_file = NULL;
1853*00b67f09SDavid van Moolenbroek }
1854*00b67f09SDavid van Moolenbroek
1855*00b67f09SDavid van Moolenbroek if (view->new_zone_config != NULL) {
1856*00b67f09SDavid van Moolenbroek view->cfg_destroy(&view->new_zone_config);
1857*00b67f09SDavid van Moolenbroek view->cfg_destroy = NULL;
1858*00b67f09SDavid van Moolenbroek }
1859*00b67f09SDavid van Moolenbroek
1860*00b67f09SDavid van Moolenbroek if (allow) {
1861*00b67f09SDavid van Moolenbroek char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)];
1862*00b67f09SDavid van Moolenbroek isc_sha256_data((void *)view->name, strlen(view->name), buffer);
1863*00b67f09SDavid van Moolenbroek /* Truncate the hash at 16 chars; full length is overkill */
1864*00b67f09SDavid van Moolenbroek isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF);
1865*00b67f09SDavid van Moolenbroek view->new_zone_file = isc_mem_strdup(view->mctx, buffer);
1866*00b67f09SDavid van Moolenbroek view->new_zone_config = cfgctx;
1867*00b67f09SDavid van Moolenbroek view->cfg_destroy = cfg_destroy;
1868*00b67f09SDavid van Moolenbroek }
1869*00b67f09SDavid van Moolenbroek }
1870*00b67f09SDavid van Moolenbroek
1871*00b67f09SDavid van Moolenbroek isc_result_t
dns_view_searchdlz(dns_view_t * view,dns_name_t * name,unsigned int minlabels,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo,dns_db_t ** dbp)1872*00b67f09SDavid van Moolenbroek dns_view_searchdlz(dns_view_t *view, dns_name_t *name, unsigned int minlabels,
1873*00b67f09SDavid van Moolenbroek dns_clientinfomethods_t *methods,
1874*00b67f09SDavid van Moolenbroek dns_clientinfo_t *clientinfo,
1875*00b67f09SDavid van Moolenbroek dns_db_t **dbp)
1876*00b67f09SDavid van Moolenbroek {
1877*00b67f09SDavid van Moolenbroek dns_fixedname_t fname;
1878*00b67f09SDavid van Moolenbroek dns_name_t *zonename;
1879*00b67f09SDavid van Moolenbroek unsigned int namelabels;
1880*00b67f09SDavid van Moolenbroek unsigned int i;
1881*00b67f09SDavid van Moolenbroek isc_result_t result;
1882*00b67f09SDavid van Moolenbroek dns_dlzfindzone_t findzone;
1883*00b67f09SDavid van Moolenbroek dns_dlzdb_t *dlzdb;
1884*00b67f09SDavid van Moolenbroek dns_db_t *db, *best = NULL;
1885*00b67f09SDavid van Moolenbroek
1886*00b67f09SDavid van Moolenbroek /*
1887*00b67f09SDavid van Moolenbroek * Performs checks to make sure data is as we expect it to be.
1888*00b67f09SDavid van Moolenbroek */
1889*00b67f09SDavid van Moolenbroek REQUIRE(DNS_VIEW_VALID(view));
1890*00b67f09SDavid van Moolenbroek REQUIRE(name != NULL);
1891*00b67f09SDavid van Moolenbroek REQUIRE(dbp != NULL && *dbp == NULL);
1892*00b67f09SDavid van Moolenbroek
1893*00b67f09SDavid van Moolenbroek /* setup a "fixed" dns name */
1894*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fname);
1895*00b67f09SDavid van Moolenbroek zonename = dns_fixedname_name(&fname);
1896*00b67f09SDavid van Moolenbroek
1897*00b67f09SDavid van Moolenbroek /* count the number of labels in the name */
1898*00b67f09SDavid van Moolenbroek namelabels = dns_name_countlabels(name);
1899*00b67f09SDavid van Moolenbroek
1900*00b67f09SDavid van Moolenbroek for (dlzdb = ISC_LIST_HEAD(view->dlz_searched);
1901*00b67f09SDavid van Moolenbroek dlzdb != NULL;
1902*00b67f09SDavid van Moolenbroek dlzdb = ISC_LIST_NEXT(dlzdb, link))
1903*00b67f09SDavid van Moolenbroek {
1904*00b67f09SDavid van Moolenbroek REQUIRE(DNS_DLZ_VALID(dlzdb));
1905*00b67f09SDavid van Moolenbroek
1906*00b67f09SDavid van Moolenbroek /*
1907*00b67f09SDavid van Moolenbroek * loop through starting with the longest domain name and
1908*00b67f09SDavid van Moolenbroek * trying shorter names portions of the name until we find a
1909*00b67f09SDavid van Moolenbroek * match, have an error, or are below the 'minlabels'
1910*00b67f09SDavid van Moolenbroek * threshold. minlabels is 0, if neither the standard
1911*00b67f09SDavid van Moolenbroek * database nor any previous DLZ database had a zone name
1912*00b67f09SDavid van Moolenbroek * match. Otherwise minlabels is the number of labels
1913*00b67f09SDavid van Moolenbroek * in that name. We need to beat that for a "better"
1914*00b67f09SDavid van Moolenbroek * match for this DLZ database to be authoritative.
1915*00b67f09SDavid van Moolenbroek */
1916*00b67f09SDavid van Moolenbroek for (i = namelabels; i > minlabels && i > 1; i--) {
1917*00b67f09SDavid van Moolenbroek if (i == namelabels) {
1918*00b67f09SDavid van Moolenbroek result = dns_name_copy(name, zonename, NULL);
1919*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1920*00b67f09SDavid van Moolenbroek return (result);
1921*00b67f09SDavid van Moolenbroek } else
1922*00b67f09SDavid van Moolenbroek dns_name_split(name, i, NULL, zonename);
1923*00b67f09SDavid van Moolenbroek
1924*00b67f09SDavid van Moolenbroek /* ask SDLZ driver if the zone is supported */
1925*00b67f09SDavid van Moolenbroek db = NULL;
1926*00b67f09SDavid van Moolenbroek findzone = dlzdb->implementation->methods->findzone;
1927*00b67f09SDavid van Moolenbroek result = (*findzone)(dlzdb->implementation->driverarg,
1928*00b67f09SDavid van Moolenbroek dlzdb->dbdata, dlzdb->mctx,
1929*00b67f09SDavid van Moolenbroek view->rdclass, zonename,
1930*00b67f09SDavid van Moolenbroek methods, clientinfo, &db);
1931*00b67f09SDavid van Moolenbroek
1932*00b67f09SDavid van Moolenbroek if (result != ISC_R_NOTFOUND) {
1933*00b67f09SDavid van Moolenbroek if (best != NULL)
1934*00b67f09SDavid van Moolenbroek dns_db_detach(&best);
1935*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
1936*00b67f09SDavid van Moolenbroek INSIST(db != NULL);
1937*00b67f09SDavid van Moolenbroek dns_db_attach(db, &best);
1938*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1939*00b67f09SDavid van Moolenbroek minlabels = i;
1940*00b67f09SDavid van Moolenbroek } else {
1941*00b67f09SDavid van Moolenbroek if (db != NULL)
1942*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1943*00b67f09SDavid van Moolenbroek break;
1944*00b67f09SDavid van Moolenbroek }
1945*00b67f09SDavid van Moolenbroek } else if (db != NULL)
1946*00b67f09SDavid van Moolenbroek dns_db_detach(&db);
1947*00b67f09SDavid van Moolenbroek }
1948*00b67f09SDavid van Moolenbroek }
1949*00b67f09SDavid van Moolenbroek
1950*00b67f09SDavid van Moolenbroek if (best != NULL) {
1951*00b67f09SDavid van Moolenbroek dns_db_attach(best, dbp);
1952*00b67f09SDavid van Moolenbroek dns_db_detach(&best);
1953*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1954*00b67f09SDavid van Moolenbroek }
1955*00b67f09SDavid van Moolenbroek
1956*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1957*00b67f09SDavid van Moolenbroek }
1958