xref: /minix3/external/bsd/bind/dist/lib/irs/context.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: context.c,v 1.5 2014/12/10 04:37:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2009, 2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek  */
18*00b67f09SDavid van Moolenbroek 
19*00b67f09SDavid van Moolenbroek /* Id: context.c,v 1.3 2009/09/02 23:48:02 tbox Exp  */
20*00b67f09SDavid van Moolenbroek 
21*00b67f09SDavid van Moolenbroek #include <config.h>
22*00b67f09SDavid van Moolenbroek 
23*00b67f09SDavid van Moolenbroek #include <isc/app.h>
24*00b67f09SDavid van Moolenbroek #include <isc/lib.h>
25*00b67f09SDavid van Moolenbroek #include <isc/magic.h>
26*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
27*00b67f09SDavid van Moolenbroek #include <isc/once.h>
28*00b67f09SDavid van Moolenbroek #include <isc/socket.h>
29*00b67f09SDavid van Moolenbroek #include <isc/task.h>
30*00b67f09SDavid van Moolenbroek #include <isc/thread.h>
31*00b67f09SDavid van Moolenbroek #include <isc/timer.h>
32*00b67f09SDavid van Moolenbroek #include <isc/util.h>
33*00b67f09SDavid van Moolenbroek 
34*00b67f09SDavid van Moolenbroek #include <dns/client.h>
35*00b67f09SDavid van Moolenbroek #include <dns/lib.h>
36*00b67f09SDavid van Moolenbroek 
37*00b67f09SDavid van Moolenbroek #include <irs/context.h>
38*00b67f09SDavid van Moolenbroek #include <irs/dnsconf.h>
39*00b67f09SDavid van Moolenbroek #include <irs/resconf.h>
40*00b67f09SDavid van Moolenbroek 
41*00b67f09SDavid van Moolenbroek #define IRS_CONTEXT_MAGIC		ISC_MAGIC('I', 'R', 'S', 'c')
42*00b67f09SDavid van Moolenbroek #define IRS_CONTEXT_VALID(c)		ISC_MAGIC_VALID(c, IRS_CONTEXT_MAGIC)
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek #ifndef RESOLV_CONF
45*00b67f09SDavid van Moolenbroek /*% location of resolve.conf */
46*00b67f09SDavid van Moolenbroek #define RESOLV_CONF "/etc/resolv.conf"
47*00b67f09SDavid van Moolenbroek #endif
48*00b67f09SDavid van Moolenbroek 
49*00b67f09SDavid van Moolenbroek #ifndef DNS_CONF
50*00b67f09SDavid van Moolenbroek /*% location of dns.conf */
51*00b67f09SDavid van Moolenbroek #define DNS_CONF "/etc/dns.conf"
52*00b67f09SDavid van Moolenbroek #endif
53*00b67f09SDavid van Moolenbroek 
54*00b67f09SDavid van Moolenbroek #ifndef ISC_PLATFORM_USETHREADS
55*00b67f09SDavid van Moolenbroek irs_context_t *irs_g_context = NULL;
56*00b67f09SDavid van Moolenbroek #else
57*00b67f09SDavid van Moolenbroek static isc_boolean_t thread_key_initialized = ISC_FALSE;
58*00b67f09SDavid van Moolenbroek static isc_mutex_t thread_key_mutex;
59*00b67f09SDavid van Moolenbroek static isc_thread_key_t irs_context_key;
60*00b67f09SDavid van Moolenbroek static isc_once_t once = ISC_ONCE_INIT;
61*00b67f09SDavid van Moolenbroek #endif
62*00b67f09SDavid van Moolenbroek 
63*00b67f09SDavid van Moolenbroek 
64*00b67f09SDavid van Moolenbroek struct irs_context {
65*00b67f09SDavid van Moolenbroek 	/*
66*00b67f09SDavid van Moolenbroek 	 * An IRS context is a thread-specific object, and does not need to
67*00b67f09SDavid van Moolenbroek 	 * be locked.
68*00b67f09SDavid van Moolenbroek 	 */
69*00b67f09SDavid van Moolenbroek 	unsigned int			magic;
70*00b67f09SDavid van Moolenbroek 	isc_mem_t			*mctx;
71*00b67f09SDavid van Moolenbroek 	isc_appctx_t			*actx;
72*00b67f09SDavid van Moolenbroek 	isc_taskmgr_t			*taskmgr;
73*00b67f09SDavid van Moolenbroek 	isc_task_t			*task;
74*00b67f09SDavid van Moolenbroek 	isc_socketmgr_t			*socketmgr;
75*00b67f09SDavid van Moolenbroek 	isc_timermgr_t			*timermgr;
76*00b67f09SDavid van Moolenbroek 	dns_client_t			*dnsclient;
77*00b67f09SDavid van Moolenbroek 	irs_resconf_t			*resconf;
78*00b67f09SDavid van Moolenbroek 	irs_dnsconf_t			*dnsconf;
79*00b67f09SDavid van Moolenbroek };
80*00b67f09SDavid van Moolenbroek 
81*00b67f09SDavid van Moolenbroek static void
ctxs_destroy(isc_mem_t ** mctxp,isc_appctx_t ** actxp,isc_taskmgr_t ** taskmgrp,isc_socketmgr_t ** socketmgrp,isc_timermgr_t ** timermgrp)82*00b67f09SDavid van Moolenbroek ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp,
83*00b67f09SDavid van Moolenbroek 	     isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
84*00b67f09SDavid van Moolenbroek 	     isc_timermgr_t **timermgrp)
85*00b67f09SDavid van Moolenbroek {
86*00b67f09SDavid van Moolenbroek 	if (taskmgrp != NULL)
87*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(taskmgrp);
88*00b67f09SDavid van Moolenbroek 
89*00b67f09SDavid van Moolenbroek 	if (timermgrp != NULL)
90*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(timermgrp);
91*00b67f09SDavid van Moolenbroek 
92*00b67f09SDavid van Moolenbroek 	if (socketmgrp != NULL)
93*00b67f09SDavid van Moolenbroek 		isc_socketmgr_destroy(socketmgrp);
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek 	if (actxp != NULL)
96*00b67f09SDavid van Moolenbroek 		isc_appctx_destroy(actxp);
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek 	if (mctxp != NULL)
99*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(mctxp);
100*00b67f09SDavid van Moolenbroek }
101*00b67f09SDavid van Moolenbroek 
102*00b67f09SDavid van Moolenbroek static isc_result_t
ctxs_init(isc_mem_t ** mctxp,isc_appctx_t ** actxp,isc_taskmgr_t ** taskmgrp,isc_socketmgr_t ** socketmgrp,isc_timermgr_t ** timermgrp)103*00b67f09SDavid van Moolenbroek ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
104*00b67f09SDavid van Moolenbroek 	  isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
105*00b67f09SDavid van Moolenbroek 	  isc_timermgr_t **timermgrp)
106*00b67f09SDavid van Moolenbroek {
107*00b67f09SDavid van Moolenbroek 	isc_result_t result;
108*00b67f09SDavid van Moolenbroek 
109*00b67f09SDavid van Moolenbroek 	result = isc_mem_create(0, 0, mctxp);
110*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
111*00b67f09SDavid van Moolenbroek 		goto fail;
112*00b67f09SDavid van Moolenbroek 
113*00b67f09SDavid van Moolenbroek 	result = isc_appctx_create(*mctxp, actxp);
114*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
115*00b67f09SDavid van Moolenbroek 		goto fail;
116*00b67f09SDavid van Moolenbroek 
117*00b67f09SDavid van Moolenbroek 	result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
118*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
119*00b67f09SDavid van Moolenbroek 		goto fail;
120*00b67f09SDavid van Moolenbroek 
121*00b67f09SDavid van Moolenbroek 	result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp);
122*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
123*00b67f09SDavid van Moolenbroek 		goto fail;
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 	result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp);
126*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
127*00b67f09SDavid van Moolenbroek 		goto fail;
128*00b67f09SDavid van Moolenbroek 
129*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
130*00b67f09SDavid van Moolenbroek 
131*00b67f09SDavid van Moolenbroek  fail:
132*00b67f09SDavid van Moolenbroek 	ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp);
133*00b67f09SDavid van Moolenbroek 
134*00b67f09SDavid van Moolenbroek 	return (result);
135*00b67f09SDavid van Moolenbroek }
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
138*00b67f09SDavid van Moolenbroek static void
free_specific_context(void * arg)139*00b67f09SDavid van Moolenbroek free_specific_context(void *arg) {
140*00b67f09SDavid van Moolenbroek 	irs_context_t *context = arg;
141*00b67f09SDavid van Moolenbroek 
142*00b67f09SDavid van Moolenbroek 	irs_context_destroy(&context);
143*00b67f09SDavid van Moolenbroek 
144*00b67f09SDavid van Moolenbroek 	isc_thread_key_setspecific(irs_context_key, NULL);
145*00b67f09SDavid van Moolenbroek }
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek static void
thread_key_mutex_init(void)148*00b67f09SDavid van Moolenbroek thread_key_mutex_init(void) {
149*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
150*00b67f09SDavid van Moolenbroek }
151*00b67f09SDavid van Moolenbroek 
152*00b67f09SDavid van Moolenbroek static isc_result_t
thread_key_init(void)153*00b67f09SDavid van Moolenbroek thread_key_init(void) {
154*00b67f09SDavid van Moolenbroek 	isc_result_t result;
155*00b67f09SDavid van Moolenbroek 
156*00b67f09SDavid van Moolenbroek 	result = isc_once_do(&once, thread_key_mutex_init);
157*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
158*00b67f09SDavid van Moolenbroek 		return (result);
159*00b67f09SDavid van Moolenbroek 
160*00b67f09SDavid van Moolenbroek 	if (!thread_key_initialized) {
161*00b67f09SDavid van Moolenbroek 		LOCK(&thread_key_mutex);
162*00b67f09SDavid van Moolenbroek 
163*00b67f09SDavid van Moolenbroek 		if (!thread_key_initialized &&
164*00b67f09SDavid van Moolenbroek 		    isc_thread_key_create(&irs_context_key,
165*00b67f09SDavid van Moolenbroek 					  free_specific_context) != 0) {
166*00b67f09SDavid van Moolenbroek 			result = ISC_R_FAILURE;
167*00b67f09SDavid van Moolenbroek 		} else
168*00b67f09SDavid van Moolenbroek 			thread_key_initialized = ISC_TRUE;
169*00b67f09SDavid van Moolenbroek 
170*00b67f09SDavid van Moolenbroek 		UNLOCK(&thread_key_mutex);
171*00b67f09SDavid van Moolenbroek 	}
172*00b67f09SDavid van Moolenbroek 
173*00b67f09SDavid van Moolenbroek 	return (result);
174*00b67f09SDavid van Moolenbroek }
175*00b67f09SDavid van Moolenbroek #endif /* ISC_PLATFORM_USETHREADS */
176*00b67f09SDavid van Moolenbroek 
177*00b67f09SDavid van Moolenbroek isc_result_t
irs_context_get(irs_context_t ** contextp)178*00b67f09SDavid van Moolenbroek irs_context_get(irs_context_t **contextp) {
179*00b67f09SDavid van Moolenbroek 	irs_context_t *context;
180*00b67f09SDavid van Moolenbroek 	isc_result_t result;
181*00b67f09SDavid van Moolenbroek 
182*00b67f09SDavid van Moolenbroek 	REQUIRE(contextp != NULL && *contextp == NULL);
183*00b67f09SDavid van Moolenbroek 
184*00b67f09SDavid van Moolenbroek #ifndef ISC_PLATFORM_USETHREADS
185*00b67f09SDavid van Moolenbroek 	if (irs_g_context == NULL) {
186*00b67f09SDavid van Moolenbroek 		result = irs_context_create(&irs_g_context);
187*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
188*00b67f09SDavid van Moolenbroek 			return (result);
189*00b67f09SDavid van Moolenbroek 	}
190*00b67f09SDavid van Moolenbroek 
191*00b67f09SDavid van Moolenbroek 	context = irs_g_context;
192*00b67f09SDavid van Moolenbroek #else
193*00b67f09SDavid van Moolenbroek 	result = thread_key_init();
194*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
195*00b67f09SDavid van Moolenbroek 		return (result);
196*00b67f09SDavid van Moolenbroek 
197*00b67f09SDavid van Moolenbroek 	context = isc_thread_key_getspecific(irs_context_key);
198*00b67f09SDavid van Moolenbroek 	if (context == NULL) {
199*00b67f09SDavid van Moolenbroek 		result = irs_context_create(&context);
200*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
201*00b67f09SDavid van Moolenbroek 			return (result);
202*00b67f09SDavid van Moolenbroek 		result = isc_thread_key_setspecific(irs_context_key, context);
203*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) {
204*00b67f09SDavid van Moolenbroek 			irs_context_destroy(&context);
205*00b67f09SDavid van Moolenbroek 			return (result);
206*00b67f09SDavid van Moolenbroek 		}
207*00b67f09SDavid van Moolenbroek 	}
208*00b67f09SDavid van Moolenbroek #endif /* ISC_PLATFORM_USETHREADS */
209*00b67f09SDavid van Moolenbroek 
210*00b67f09SDavid van Moolenbroek 	*contextp = context;
211*00b67f09SDavid van Moolenbroek 
212*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
213*00b67f09SDavid van Moolenbroek }
214*00b67f09SDavid van Moolenbroek 
215*00b67f09SDavid van Moolenbroek isc_result_t
irs_context_create(irs_context_t ** contextp)216*00b67f09SDavid van Moolenbroek irs_context_create(irs_context_t **contextp) {
217*00b67f09SDavid van Moolenbroek 	isc_result_t result;
218*00b67f09SDavid van Moolenbroek 	irs_context_t *context;
219*00b67f09SDavid van Moolenbroek 	isc_appctx_t *actx = NULL;
220*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx = NULL;
221*00b67f09SDavid van Moolenbroek 	isc_taskmgr_t *taskmgr = NULL;
222*00b67f09SDavid van Moolenbroek 	isc_socketmgr_t *socketmgr = NULL;
223*00b67f09SDavid van Moolenbroek 	isc_timermgr_t *timermgr = NULL;
224*00b67f09SDavid van Moolenbroek 	dns_client_t *client = NULL;
225*00b67f09SDavid van Moolenbroek 	isc_sockaddrlist_t *nameservers;
226*00b67f09SDavid van Moolenbroek 	irs_dnsconf_dnskeylist_t *trustedkeys;
227*00b67f09SDavid van Moolenbroek 	irs_dnsconf_dnskey_t *trustedkey;
228*00b67f09SDavid van Moolenbroek 
229*00b67f09SDavid van Moolenbroek 	isc_lib_register();
230*00b67f09SDavid van Moolenbroek 	result = dns_lib_init();
231*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
232*00b67f09SDavid van Moolenbroek 		return (result);
233*00b67f09SDavid van Moolenbroek 
234*00b67f09SDavid van Moolenbroek 	result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
235*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
236*00b67f09SDavid van Moolenbroek 		return (result);
237*00b67f09SDavid van Moolenbroek 
238*00b67f09SDavid van Moolenbroek 	result = isc_app_ctxstart(actx);
239*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
240*00b67f09SDavid van Moolenbroek 		ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
241*00b67f09SDavid van Moolenbroek 		return (result);
242*00b67f09SDavid van Moolenbroek 	}
243*00b67f09SDavid van Moolenbroek 
244*00b67f09SDavid van Moolenbroek 	context = isc_mem_get(mctx, sizeof(*context));
245*00b67f09SDavid van Moolenbroek 	if (context == NULL) {
246*00b67f09SDavid van Moolenbroek 		ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
247*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
248*00b67f09SDavid van Moolenbroek 	}
249*00b67f09SDavid van Moolenbroek 
250*00b67f09SDavid van Moolenbroek 	context->mctx = mctx;
251*00b67f09SDavid van Moolenbroek 	context->actx = actx;
252*00b67f09SDavid van Moolenbroek 	context->taskmgr = taskmgr;
253*00b67f09SDavid van Moolenbroek 	context->socketmgr = socketmgr;
254*00b67f09SDavid van Moolenbroek 	context->timermgr = timermgr;
255*00b67f09SDavid van Moolenbroek 	context->resconf = NULL;
256*00b67f09SDavid van Moolenbroek 	context->dnsconf = NULL;
257*00b67f09SDavid van Moolenbroek 	context->task = NULL;
258*00b67f09SDavid van Moolenbroek 	result = isc_task_create(taskmgr, 0, &context->task);
259*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
260*00b67f09SDavid van Moolenbroek 		goto fail;
261*00b67f09SDavid van Moolenbroek 
262*00b67f09SDavid van Moolenbroek 	/* Create a DNS client object */
263*00b67f09SDavid van Moolenbroek 	result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
264*00b67f09SDavid van Moolenbroek 				    0, &client);
265*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
266*00b67f09SDavid van Moolenbroek 		goto fail;
267*00b67f09SDavid van Moolenbroek 	context->dnsclient = client;
268*00b67f09SDavid van Moolenbroek 
269*00b67f09SDavid van Moolenbroek 	/* Read resolver configuration file */
270*00b67f09SDavid van Moolenbroek 	result = irs_resconf_load(mctx, RESOLV_CONF, &context->resconf);
271*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
272*00b67f09SDavid van Moolenbroek 		goto fail;
273*00b67f09SDavid van Moolenbroek 	/* Set nameservers */
274*00b67f09SDavid van Moolenbroek 	nameservers = irs_resconf_getnameservers(context->resconf);
275*00b67f09SDavid van Moolenbroek 	result = dns_client_setservers(client, dns_rdataclass_in, NULL,
276*00b67f09SDavid van Moolenbroek 				       nameservers);
277*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
278*00b67f09SDavid van Moolenbroek 		goto fail;
279*00b67f09SDavid van Moolenbroek 
280*00b67f09SDavid van Moolenbroek 	/* Read advanced DNS configuration (if any) */
281*00b67f09SDavid van Moolenbroek 	result = irs_dnsconf_load(mctx, DNS_CONF, &context->dnsconf);
282*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
283*00b67f09SDavid van Moolenbroek 		goto fail;
284*00b67f09SDavid van Moolenbroek 	trustedkeys = irs_dnsconf_gettrustedkeys(context->dnsconf);
285*00b67f09SDavid van Moolenbroek 	for (trustedkey = ISC_LIST_HEAD(*trustedkeys);
286*00b67f09SDavid van Moolenbroek 	     trustedkey != NULL;
287*00b67f09SDavid van Moolenbroek 	     trustedkey = ISC_LIST_NEXT(trustedkey, link)) {
288*00b67f09SDavid van Moolenbroek 		result = dns_client_addtrustedkey(client, dns_rdataclass_in,
289*00b67f09SDavid van Moolenbroek 						  trustedkey->keyname,
290*00b67f09SDavid van Moolenbroek 						  trustedkey->keydatabuf);
291*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
292*00b67f09SDavid van Moolenbroek 			goto fail;
293*00b67f09SDavid van Moolenbroek 	}
294*00b67f09SDavid van Moolenbroek 
295*00b67f09SDavid van Moolenbroek 	context->magic = IRS_CONTEXT_MAGIC;
296*00b67f09SDavid van Moolenbroek 	*contextp = context;
297*00b67f09SDavid van Moolenbroek 
298*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
299*00b67f09SDavid van Moolenbroek 
300*00b67f09SDavid van Moolenbroek   fail:
301*00b67f09SDavid van Moolenbroek 	if (context->task != NULL)
302*00b67f09SDavid van Moolenbroek 		isc_task_detach(&context->task);
303*00b67f09SDavid van Moolenbroek 	if (context->resconf != NULL)
304*00b67f09SDavid van Moolenbroek 		irs_resconf_destroy(&context->resconf);
305*00b67f09SDavid van Moolenbroek 	if (context->dnsconf != NULL)
306*00b67f09SDavid van Moolenbroek 		irs_dnsconf_destroy(&context->dnsconf);
307*00b67f09SDavid van Moolenbroek 	if (client != NULL)
308*00b67f09SDavid van Moolenbroek 		dns_client_destroy(&client);
309*00b67f09SDavid van Moolenbroek 	ctxs_destroy(NULL, &actx, &taskmgr, &socketmgr, &timermgr);
310*00b67f09SDavid van Moolenbroek 	isc_mem_putanddetach(&mctx, context, sizeof(*context));
311*00b67f09SDavid van Moolenbroek 
312*00b67f09SDavid van Moolenbroek 	return (result);
313*00b67f09SDavid van Moolenbroek }
314*00b67f09SDavid van Moolenbroek 
315*00b67f09SDavid van Moolenbroek void
irs_context_destroy(irs_context_t ** contextp)316*00b67f09SDavid van Moolenbroek irs_context_destroy(irs_context_t **contextp) {
317*00b67f09SDavid van Moolenbroek 	irs_context_t *context;
318*00b67f09SDavid van Moolenbroek 
319*00b67f09SDavid van Moolenbroek 	REQUIRE(contextp != NULL);
320*00b67f09SDavid van Moolenbroek 	context = *contextp;
321*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
322*00b67f09SDavid van Moolenbroek 
323*00b67f09SDavid van Moolenbroek 	isc_task_detach(&context->task);
324*00b67f09SDavid van Moolenbroek 	irs_dnsconf_destroy(&context->dnsconf);
325*00b67f09SDavid van Moolenbroek 	irs_resconf_destroy(&context->resconf);
326*00b67f09SDavid van Moolenbroek 	dns_client_destroy(&context->dnsclient);
327*00b67f09SDavid van Moolenbroek 
328*00b67f09SDavid van Moolenbroek 	ctxs_destroy(NULL, &context->actx, &context->taskmgr,
329*00b67f09SDavid van Moolenbroek 		     &context->socketmgr, &context->timermgr);
330*00b67f09SDavid van Moolenbroek 
331*00b67f09SDavid van Moolenbroek 	context->magic = 0;
332*00b67f09SDavid van Moolenbroek 
333*00b67f09SDavid van Moolenbroek 	isc_mem_putanddetach(&context->mctx, context, sizeof(*context));
334*00b67f09SDavid van Moolenbroek 
335*00b67f09SDavid van Moolenbroek 	*contextp = NULL;
336*00b67f09SDavid van Moolenbroek 
337*00b67f09SDavid van Moolenbroek #ifndef ISC_PLATFORM_USETHREADS
338*00b67f09SDavid van Moolenbroek 	irs_g_context = NULL;
339*00b67f09SDavid van Moolenbroek #else
340*00b67f09SDavid van Moolenbroek 	(void)isc_thread_key_setspecific(irs_context_key, NULL);
341*00b67f09SDavid van Moolenbroek #endif
342*00b67f09SDavid van Moolenbroek }
343*00b67f09SDavid van Moolenbroek 
344*00b67f09SDavid van Moolenbroek isc_mem_t *
irs_context_getmctx(irs_context_t * context)345*00b67f09SDavid van Moolenbroek irs_context_getmctx(irs_context_t *context) {
346*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
347*00b67f09SDavid van Moolenbroek 
348*00b67f09SDavid van Moolenbroek 	return (context->mctx);
349*00b67f09SDavid van Moolenbroek }
350*00b67f09SDavid van Moolenbroek 
351*00b67f09SDavid van Moolenbroek isc_appctx_t *
irs_context_getappctx(irs_context_t * context)352*00b67f09SDavid van Moolenbroek irs_context_getappctx(irs_context_t *context) {
353*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
354*00b67f09SDavid van Moolenbroek 
355*00b67f09SDavid van Moolenbroek 	return (context->actx);
356*00b67f09SDavid van Moolenbroek }
357*00b67f09SDavid van Moolenbroek 
358*00b67f09SDavid van Moolenbroek isc_taskmgr_t *
irs_context_gettaskmgr(irs_context_t * context)359*00b67f09SDavid van Moolenbroek irs_context_gettaskmgr(irs_context_t *context) {
360*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
361*00b67f09SDavid van Moolenbroek 
362*00b67f09SDavid van Moolenbroek 	return (context->taskmgr);
363*00b67f09SDavid van Moolenbroek }
364*00b67f09SDavid van Moolenbroek 
365*00b67f09SDavid van Moolenbroek isc_timermgr_t *
irs_context_gettimermgr(irs_context_t * context)366*00b67f09SDavid van Moolenbroek irs_context_gettimermgr(irs_context_t *context) {
367*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
368*00b67f09SDavid van Moolenbroek 
369*00b67f09SDavid van Moolenbroek 	return (context->timermgr);
370*00b67f09SDavid van Moolenbroek }
371*00b67f09SDavid van Moolenbroek 
372*00b67f09SDavid van Moolenbroek isc_task_t *
irs_context_gettask(irs_context_t * context)373*00b67f09SDavid van Moolenbroek irs_context_gettask(irs_context_t *context) {
374*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
375*00b67f09SDavid van Moolenbroek 
376*00b67f09SDavid van Moolenbroek 	return (context->task);
377*00b67f09SDavid van Moolenbroek }
378*00b67f09SDavid van Moolenbroek 
379*00b67f09SDavid van Moolenbroek dns_client_t *
irs_context_getdnsclient(irs_context_t * context)380*00b67f09SDavid van Moolenbroek irs_context_getdnsclient(irs_context_t *context) {
381*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
382*00b67f09SDavid van Moolenbroek 
383*00b67f09SDavid van Moolenbroek 	return (context->dnsclient);
384*00b67f09SDavid van Moolenbroek }
385*00b67f09SDavid van Moolenbroek 
386*00b67f09SDavid van Moolenbroek irs_resconf_t *
irs_context_getresconf(irs_context_t * context)387*00b67f09SDavid van Moolenbroek irs_context_getresconf(irs_context_t *context) {
388*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
389*00b67f09SDavid van Moolenbroek 
390*00b67f09SDavid van Moolenbroek 	return (context->resconf);
391*00b67f09SDavid van Moolenbroek }
392*00b67f09SDavid van Moolenbroek 
393*00b67f09SDavid van Moolenbroek irs_dnsconf_t *
irs_context_getdnsconf(irs_context_t * context)394*00b67f09SDavid van Moolenbroek irs_context_getdnsconf(irs_context_t *context) {
395*00b67f09SDavid van Moolenbroek 	REQUIRE(IRS_CONTEXT_VALID(context));
396*00b67f09SDavid van Moolenbroek 
397*00b67f09SDavid van Moolenbroek 	return (context->dnsconf);
398*00b67f09SDavid van Moolenbroek }
399