diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-03-02 19:04:49 +0000 |
---|---|---|
committer | <> | 2015-05-08 15:30:59 +0000 |
commit | f800382616186a5d30e28d8b2c51e97a9a8360f2 (patch) | |
tree | 0d5270190548a37223d14b54383ce8a3d3af5302 /omapip/isclib.c | |
download | isc-dhcp-tarball-master.tar.gz |
Imported from /home/lorry/working-area/delta_isc-dhcp-tarball/dhcp-4.2.8.tar.gz.HEADdhcp-4.2.8master
Diffstat (limited to 'omapip/isclib.c')
-rw-r--r-- | omapip/isclib.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/omapip/isclib.c b/omapip/isclib.c new file mode 100644 index 0000000..ce42e45 --- /dev/null +++ b/omapip/isclib.c @@ -0,0 +1,276 @@ +/* + * Copyright(c) 2009-2010,2013-2014 by Internet Systems Consortium, Inc.("ISC") + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * <info@isc.org> + * http://www.isc.org/ + * + */ + +/*Trying to figure out what we need to define to get things to work. + It looks like we want/need the export library but need the fdwatchcommand + which may be a problem */ + +#include "dhcpd.h" + +#include <sys/time.h> +#include <signal.h> + +dhcp_context_t dhcp_gbl_ctx; +int shutdown_signal = 0; + +void +isclib_cleanup(void) +{ +#if defined (NSUPDATE) + if (dhcp_gbl_ctx.dnsclient != NULL) + dns_client_destroy((dns_client_t **)&dhcp_gbl_ctx.dnsclient); +#endif + + if (dhcp_gbl_ctx.task != NULL) { + isc_task_shutdown(dhcp_gbl_ctx.task); + isc_task_detach(&dhcp_gbl_ctx.task); + } + + if (dhcp_gbl_ctx.timermgr != NULL) + isc_timermgr_destroy(&dhcp_gbl_ctx.timermgr); + + if (dhcp_gbl_ctx.socketmgr != NULL) + isc_socketmgr_destroy(&dhcp_gbl_ctx.socketmgr); + + if (dhcp_gbl_ctx.taskmgr != NULL) + isc_taskmgr_destroy(&dhcp_gbl_ctx.taskmgr); + + if (dhcp_gbl_ctx.actx_started != ISC_FALSE) { + isc_app_ctxfinish(dhcp_gbl_ctx.actx); + dhcp_gbl_ctx.actx_started = ISC_FALSE; + } + + if (dhcp_gbl_ctx.actx != NULL) + isc_appctx_destroy(&dhcp_gbl_ctx.actx); + + if (dhcp_gbl_ctx.mctx != NULL) + isc_mem_detach(&dhcp_gbl_ctx.mctx); + + return; +} + +/* Installs a handler for a signal using sigaction */ +static void +handle_signal(int sig, void (*handler)(int)) { + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler; + sigfillset(&sa.sa_mask); + if (sigaction(sig, &sa, NULL) != 0) { + log_debug("handle_signal() failed for signal %d error: %s", + sig, strerror(errno)); + } +} + +isc_result_t +dhcp_context_create(void) { + isc_result_t result; + + /* + * Set up the error messages, this isn't the right place + * for this call but it is convienent for now. + */ + result = dhcp_result_register(); + if (result != ISC_R_SUCCESS) { + log_fatal("register_table() %s: %u", "failed", result); + } + + memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx)); + + isc_lib_register(); + + /* get the current time for use as the random seed */ + gettimeofday(&cur_tv, (struct timezone *)0); + isc_random_seed(cur_tv.tv_sec); + + /* we need to create the memory context before + * the lib inits in case we aren't doing NSUPDATE + * in which case dst needs a memory context + */ + result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx); + if (result != ISC_R_SUCCESS) + goto cleanup; + +#if defined (NSUPDATE) + result = dns_lib_init(); + if (result != ISC_R_SUCCESS) + goto cleanup; +#else + /* The dst library is inited as part of dns_lib_init, we don't + * need it if NSUPDATE is enabled */ + result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0); + if (result != ISC_R_SUCCESS) + goto cleanup; +#endif + + result = isc_appctx_create(dhcp_gbl_ctx.mctx, &dhcp_gbl_ctx.actx); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_app_ctxstart(dhcp_gbl_ctx.actx); + if (result != ISC_R_SUCCESS) + return (result); + dhcp_gbl_ctx.actx_started = ISC_TRUE; + + /* Not all OSs support suppressing SIGPIPE through socket + * options, so set the sigal action to be ignore. This allows + * broken connections to fail gracefully with EPIPE on writes */ + handle_signal(SIGPIPE, SIG_IGN); + + result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + 1, 0, + &dhcp_gbl_ctx.taskmgr); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + &dhcp_gbl_ctx.socketmgr); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + &dhcp_gbl_ctx.timermgr); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task); + if (result != ISC_R_SUCCESS) + goto cleanup; + +#if defined (NSUPDATE) + result = dns_client_createx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + dhcp_gbl_ctx.taskmgr, + dhcp_gbl_ctx.socketmgr, + dhcp_gbl_ctx.timermgr, + 0, + &dhcp_gbl_ctx.dnsclient); + if (result != ISC_R_SUCCESS) + goto cleanup; +#endif + return(ISC_R_SUCCESS); + + cleanup: + /* + * Currently we don't try and cleanup, just return an error + * expecting that our caller will log the error and exit. + */ + + return(result); +} + +/* + * Convert a string name into the proper structure for the isc routines + * + * Previously we allowed names without a trailing '.' however the current + * dns and dst code requires the names to end in a period. If the + * name doesn't have a trailing period add one as part of creating + * the dns name. + */ + +isc_result_t +dhcp_isc_name(unsigned char *namestr, + dns_fixedname_t *namefix, + dns_name_t **name) +{ + size_t namelen; + isc_buffer_t b; + isc_result_t result; + + namelen = strlen((char *)namestr); + isc_buffer_init(&b, namestr, namelen); + isc_buffer_add(&b, namelen); + dns_fixedname_init(namefix); + *name = dns_fixedname_name(namefix); + result = dns_name_fromtext(*name, &b, dns_rootname, 0, NULL); + isc_buffer_invalidate(&b); + return(result); +} + +isc_result_t +isclib_make_dst_key(char *inname, + char *algorithm, + unsigned char *secret, + int length, + dst_key_t **dstkey) +{ + isc_result_t result; + dns_name_t *name; + dns_fixedname_t name0; + isc_buffer_t b; + unsigned int algorithm_code; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + + if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) == 0) { + algorithm_code = DST_ALG_HMACMD5; + } else if (strcasecmp(algorithm, DHCP_HMAC_SHA1_NAME) == 0) { + algorithm_code = DST_ALG_HMACSHA1; + } else if (strcasecmp(algorithm, DHCP_HMAC_SHA224_NAME) == 0) { + algorithm_code = DST_ALG_HMACSHA224; + } else if (strcasecmp(algorithm, DHCP_HMAC_SHA256_NAME) == 0) { + algorithm_code = DST_ALG_HMACSHA256; + } else if (strcasecmp(algorithm, DHCP_HMAC_SHA384_NAME) == 0) { + algorithm_code = DST_ALG_HMACSHA384; + } else if (strcasecmp(algorithm, DHCP_HMAC_SHA512_NAME) == 0) { + algorithm_code = DST_ALG_HMACSHA512; + } else { + return(DHCP_R_INVALIDARG); + } + + result = dhcp_isc_name((unsigned char *)inname, &name0, &name); + if (result != ISC_R_SUCCESS) { + return(result); + } + + return(dst_key_frombuffer(name, algorithm_code, DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, + &b, dhcp_gbl_ctx.mctx, dstkey)); +} + +/** + * signal handler that initiates server shutdown + * + * @param signal signal code that we received + */ +void dhcp_signal_handler(int signal) { + isc_appctx_t *ctx = dhcp_gbl_ctx.actx; + int prev = shutdown_signal; + + if (prev != 0) { + /* Already in shutdown. */ + return; + } + /* Possible race but does it matter? */ + shutdown_signal = signal; + + /* Use reload (aka suspend) for easier dispatch() reenter. */ + if (ctx && ctx->methods && ctx->methods->ctxsuspend) { + (void) isc_app_ctxsuspend(ctx); + } +} |