1 /* $NetBSD: isclib.c,v 1.2 2014/07/12 12:09:37 spz Exp $ */
3 * Copyright(c) 2009-2010,2013-2014 by Internet Systems Consortium, Inc.("ISC")
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * Internet Systems Consortium, Inc.
19 * Redwood City, CA 94063
25 #include <sys/cdefs.h>
26 __RCSID("$NetBSD: isclib.c,v 1.2 2014/07/12 12:09:37 spz Exp $");
28 /*Trying to figure out what we need to define to get things to work.
29 It looks like we want/need the export library but need the fdwatchcommand
30 which may be a problem */
37 dhcp_context_t dhcp_gbl_ctx
;
38 int shutdown_signal
= 0;
40 #if defined (NSUPDATE)
42 /* This routine will open up the /etc/resolv.conf file and
43 * send any nameservers it finds to the DNS client code.
44 * It may be moved to be part of the dns client code instead
45 * of being in the DHCP code
48 dhcp_dns_client_setservers(void)
51 irs_resconf_t
*resconf
= NULL
;
52 isc_sockaddrlist_t
*nameservers
;
55 result
= irs_resconf_load(dhcp_gbl_ctx
.mctx
, _PATH_RESOLV_CONF
,
57 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_FILENOTFOUND
) {
58 log_error("irs_resconf_load failed: %d.", result
);
62 nameservers
= irs_resconf_getnameservers(resconf
);
64 /* Initialize port numbers */
65 for (sa
= ISC_LIST_HEAD(*nameservers
);
67 sa
= ISC_LIST_NEXT(sa
, link
)) {
68 switch (sa
->type
.sa
.sa_family
) {
70 sa
->type
.sin
.sin_port
= htons(NS_DEFAULTPORT
);
73 sa
->type
.sin6
.sin6_port
= htons(NS_DEFAULTPORT
);
80 result
= dns_client_setservers(dhcp_gbl_ctx
.dnsclient
,
83 if (result
!= ISC_R_SUCCESS
) {
84 log_error("dns_client_setservers failed: %d.",
94 #if defined (NSUPDATE)
95 if (dhcp_gbl_ctx
.dnsclient
!= NULL
)
96 dns_client_destroy((dns_client_t
**)&dhcp_gbl_ctx
.dnsclient
);
99 if (dhcp_gbl_ctx
.task
!= NULL
) {
100 isc_task_shutdown(dhcp_gbl_ctx
.task
);
101 isc_task_detach(&dhcp_gbl_ctx
.task
);
104 if (dhcp_gbl_ctx
.timermgr
!= NULL
)
105 isc_timermgr_destroy(&dhcp_gbl_ctx
.timermgr
);
107 if (dhcp_gbl_ctx
.socketmgr
!= NULL
)
108 isc_socketmgr_destroy(&dhcp_gbl_ctx
.socketmgr
);
110 if (dhcp_gbl_ctx
.taskmgr
!= NULL
)
111 isc_taskmgr_destroy(&dhcp_gbl_ctx
.taskmgr
);
113 if (dhcp_gbl_ctx
.actx_started
!= ISC_FALSE
) {
114 isc_app_ctxfinish(dhcp_gbl_ctx
.actx
);
115 dhcp_gbl_ctx
.actx_started
= ISC_FALSE
;
118 if (dhcp_gbl_ctx
.actx
!= NULL
)
119 isc_appctx_destroy(&dhcp_gbl_ctx
.actx
);
121 if (dhcp_gbl_ctx
.mctx
!= NULL
)
122 isc_mem_detach(&dhcp_gbl_ctx
.mctx
);
128 dhcp_context_create(int flags
,
129 struct in_addr
*local4
,
130 struct in6_addr
*local6
) {
133 if ((flags
& DHCP_CONTEXT_PRE_DB
) != 0) {
135 * Set up the error messages, this isn't the right place
136 * for this call but it is convienent for now.
138 result
= dhcp_result_register();
139 if (result
!= ISC_R_SUCCESS
) {
140 log_fatal("register_table() %s: %u", "failed", result
);
143 memset(&dhcp_gbl_ctx
, 0, sizeof (dhcp_gbl_ctx
));
147 /* get the current time for use as the random seed */
148 gettimeofday(&cur_tv
, (struct timezone
*)0);
149 isc_random_seed(cur_tv
.tv_sec
);
151 #if defined (NSUPDATE)
152 result
= dns_lib_init();
153 if (result
!= ISC_R_SUCCESS
)
156 /* The dst library is inited as part of dns_lib_init, we don't
157 * need it if NSUPDATE is enabled */
158 result
= dst_lib_init(dhcp_gbl_ctx
.mctx
, NULL
, 0);
159 if (result
!= ISC_R_SUCCESS
)
163 result
= isc_mem_create(0, 0, &dhcp_gbl_ctx
.mctx
);
164 if (result
!= ISC_R_SUCCESS
)
167 result
= isc_appctx_create(dhcp_gbl_ctx
.mctx
,
169 if (result
!= ISC_R_SUCCESS
)
172 result
= isc_app_ctxstart(dhcp_gbl_ctx
.actx
);
173 if (result
!= ISC_R_SUCCESS
)
175 dhcp_gbl_ctx
.actx_started
= ISC_TRUE
;
177 result
= isc_taskmgr_createinctx(dhcp_gbl_ctx
.mctx
,
180 &dhcp_gbl_ctx
.taskmgr
);
181 if (result
!= ISC_R_SUCCESS
)
184 result
= isc_socketmgr_createinctx(dhcp_gbl_ctx
.mctx
,
186 &dhcp_gbl_ctx
.socketmgr
);
187 if (result
!= ISC_R_SUCCESS
)
190 result
= isc_timermgr_createinctx(dhcp_gbl_ctx
.mctx
,
192 &dhcp_gbl_ctx
.timermgr
);
193 if (result
!= ISC_R_SUCCESS
)
196 result
= isc_task_create(dhcp_gbl_ctx
.taskmgr
, 0, &dhcp_gbl_ctx
.task
);
197 if (result
!= ISC_R_SUCCESS
)
201 #if defined (NSUPDATE)
202 if ((flags
& DHCP_CONTEXT_POST_DB
) != 0) {
203 isc_sockaddr_t localaddr4
, *localaddr4_ptr
= NULL
;
204 isc_sockaddr_t localaddr6
, *localaddr6_ptr
= NULL
;
205 if (local4
!= NULL
) {
206 isc_sockaddr_fromin(&localaddr4
, local4
, 0);
207 localaddr4_ptr
= &localaddr4
;
209 if (local6
!= NULL
) {
210 isc_sockaddr_fromin6(&localaddr6
, local6
, 0);
211 localaddr6_ptr
= &localaddr6
;
214 result
= dns_client_createx2(dhcp_gbl_ctx
.mctx
,
216 dhcp_gbl_ctx
.taskmgr
,
217 dhcp_gbl_ctx
.socketmgr
,
218 dhcp_gbl_ctx
.timermgr
,
220 &dhcp_gbl_ctx
.dnsclient
,
223 if (result
!= ISC_R_SUCCESS
)
226 result
= dhcp_dns_client_setservers();
227 if (result
!= ISC_R_SUCCESS
)
232 return(ISC_R_SUCCESS
);
236 * Currently we don't try and cleanup, just return an error
237 * expecting that our caller will log the error and exit.
244 * Convert a string name into the proper structure for the isc routines
246 * Previously we allowed names without a trailing '.' however the current
247 * dns and dst code requires the names to end in a period. If the
248 * name doesn't have a trailing period add one as part of creating
253 dhcp_isc_name(unsigned char *namestr
,
254 dns_fixedname_t
*namefix
,
261 namelen
= strlen((char *)namestr
);
262 isc_buffer_init(&b
, namestr
, namelen
);
263 isc_buffer_add(&b
, namelen
);
264 dns_fixedname_init(namefix
);
265 *name
= dns_fixedname_name(namefix
);
266 result
= dns_name_fromtext(*name
, &b
, dns_rootname
, 0, NULL
);
267 isc_buffer_invalidate(&b
);
272 isclib_make_dst_key(char *inname
,
274 unsigned char *secret
,
280 dns_fixedname_t name0
;
283 isc_buffer_init(&b
, secret
, length
);
284 isc_buffer_add(&b
, length
);
286 /* We only support HMAC_MD5 currently */
287 if (strcasecmp(algorithm
, DHCP_HMAC_MD5_NAME
) != 0) {
288 return(DHCP_R_INVALIDARG
);
291 result
= dhcp_isc_name((unsigned char *)inname
, &name0
, &name
);
292 if (result
!= ISC_R_SUCCESS
) {
296 return(dst_key_frombuffer(name
, DST_ALG_HMACMD5
, DNS_KEYOWNER_ENTITY
,
297 DNS_KEYPROTO_DNSSEC
, dns_rdataclass_in
,
298 &b
, dhcp_gbl_ctx
.mctx
, dstkey
));
302 * signal handler that initiates server shutdown
304 * @param signal signal code that we received
306 void dhcp_signal_handler(int signal
) {
307 isc_appctx_t
*ctx
= dhcp_gbl_ctx
.actx
;
308 int prev
= shutdown_signal
;
311 /* Already in shutdown. */
314 /* Possible race but does it matter? */
315 shutdown_signal
= signal
;
317 /* Use reload (aka suspend) for easier dispatch() reenter. */
318 if (ctx
&& ctx
->methods
&& ctx
->methods
->ctxsuspend
) {
319 (void) isc_app_ctxsuspend(ctx
);