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