omapip/isclib.c

Go to the documentation of this file.
00001 /*
00002  * Copyright(c) 2009-2010,2013-2014 by Internet Systems Consortium, Inc.("ISC")
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00014  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  *
00016  *   Internet Systems Consortium, Inc.
00017  *   950 Charter Street
00018  *   Redwood City, CA 94063
00019  *   <info@isc.org>
00020  *   http://www.isc.org/
00021  *
00022  */
00023 
00024 /*Trying to figure out what we need to define to get things to work.
00025   It looks like we want/need the export library but need the fdwatchcommand
00026   which may be a problem */
00027 
00028 #include "dhcpd.h"
00029 
00030 #include <sys/time.h>
00031 #include <signal.h>
00032 
00033 dhcp_context_t dhcp_gbl_ctx;
00034 int shutdown_signal = 0;
00035 
00036 #if defined (NSUPDATE)
00037 
00038 /* This routine will open up the /etc/resolv.conf file and
00039  * send any nameservers it finds to the DNS client code.
00040  * It may be moved to be part of the dns client code instead
00041  * of being in the DHCP code
00042  */
00043 isc_result_t 
00044 dhcp_dns_client_setservers(void)
00045 {
00046         isc_result_t result;
00047         irs_resconf_t *resconf = NULL;
00048         isc_sockaddrlist_t *nameservers;
00049         isc_sockaddr_t *sa;
00050 
00051         result = irs_resconf_load(dhcp_gbl_ctx.mctx, _PATH_RESOLV_CONF,
00052                                   &resconf);
00053         if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
00054                 log_error("irs_resconf_load failed: %d.", result);
00055                 return (result);
00056         }
00057 
00058         nameservers = irs_resconf_getnameservers(resconf);
00059 
00060         /* Initialize port numbers */
00061         for (sa = ISC_LIST_HEAD(*nameservers);
00062              sa != NULL;
00063              sa = ISC_LIST_NEXT(sa, link)) {
00064                 switch (sa->type.sa.sa_family) {
00065                 case AF_INET:
00066                         sa->type.sin.sin_port = htons(NS_DEFAULTPORT);
00067                         break;
00068                 case AF_INET6:
00069                         sa->type.sin6.sin6_port = htons(NS_DEFAULTPORT);
00070                         break;
00071                 default:
00072                         break;
00073                 }
00074         }
00075 
00076         result = dns_client_setservers(dhcp_gbl_ctx.dnsclient,
00077                                        dns_rdataclass_in,
00078                                        NULL, nameservers);
00079         if (result != ISC_R_SUCCESS) {
00080                 log_error("dns_client_setservers failed: %d.",
00081                           result);
00082         }
00083         return (result);
00084 }
00085 #endif
00086 
00087 void
00088 isclib_cleanup(void)
00089 {
00090 #if defined (NSUPDATE)
00091         if (dhcp_gbl_ctx.dnsclient != NULL)
00092                 dns_client_destroy((dns_client_t **)&dhcp_gbl_ctx.dnsclient);
00093 #endif
00094 
00095         if (dhcp_gbl_ctx.task != NULL) {
00096                 isc_task_shutdown(dhcp_gbl_ctx.task);
00097                 isc_task_detach(&dhcp_gbl_ctx.task);
00098         }
00099 
00100         if (dhcp_gbl_ctx.timermgr != NULL)
00101                 isc_timermgr_destroy(&dhcp_gbl_ctx.timermgr);
00102 
00103         if (dhcp_gbl_ctx.socketmgr != NULL)
00104                 isc_socketmgr_destroy(&dhcp_gbl_ctx.socketmgr);
00105 
00106         if (dhcp_gbl_ctx.taskmgr != NULL)
00107                 isc_taskmgr_destroy(&dhcp_gbl_ctx.taskmgr);
00108 
00109         if (dhcp_gbl_ctx.actx_started != ISC_FALSE) {
00110                 isc_app_ctxfinish(dhcp_gbl_ctx.actx);
00111                 dhcp_gbl_ctx.actx_started = ISC_FALSE;
00112         }
00113 
00114         if (dhcp_gbl_ctx.actx != NULL)
00115                 isc_appctx_destroy(&dhcp_gbl_ctx.actx);
00116 
00117         if (dhcp_gbl_ctx.mctx != NULL)
00118                 isc_mem_detach(&dhcp_gbl_ctx.mctx);
00119 
00120         return;
00121 }
00122 
00123 isc_result_t
00124 dhcp_context_create(int flags,
00125                     struct in_addr  *local4,
00126                     struct in6_addr *local6) {
00127         isc_result_t result;
00128 
00129         if ((flags & DHCP_CONTEXT_PRE_DB) != 0) {
00130                 /*
00131                  * Set up the error messages, this isn't the right place
00132                  * for this call but it is convienent for now.
00133                  */
00134                 result = dhcp_result_register();
00135                 if (result != ISC_R_SUCCESS) {
00136                         log_fatal("register_table() %s: %u", "failed", result);
00137                 }
00138 
00139                 memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx));
00140         
00141                 isc_lib_register();
00142 
00143                 /* get the current time for use as the random seed */
00144                 gettimeofday(&cur_tv, (struct timezone *)0);
00145                 isc_random_seed(cur_tv.tv_sec);
00146 
00147 #if defined (NSUPDATE)
00148                 result = dns_lib_init();
00149                 if (result != ISC_R_SUCCESS)
00150                         goto cleanup;
00151 #else
00152                 /* The dst library is inited as part of dns_lib_init, we don't
00153                  * need it if NSUPDATE is enabled */
00154                 result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0);
00155                 if (result != ISC_R_SUCCESS)
00156                         goto cleanup;
00157 
00158 #endif
00159                 result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx);
00160                 if (result != ISC_R_SUCCESS)
00161                         goto cleanup;
00162 
00163                 result = isc_appctx_create(dhcp_gbl_ctx.mctx,
00164                                            &dhcp_gbl_ctx.actx);
00165                 if (result != ISC_R_SUCCESS)
00166                         goto cleanup;
00167 
00168                 result = isc_app_ctxstart(dhcp_gbl_ctx.actx);
00169                 if (result != ISC_R_SUCCESS)
00170                         return (result);
00171                 dhcp_gbl_ctx.actx_started = ISC_TRUE;
00172 
00173                 result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx,
00174                                                  dhcp_gbl_ctx.actx,
00175                                                  1, 0,
00176                                                  &dhcp_gbl_ctx.taskmgr);
00177                 if (result != ISC_R_SUCCESS)
00178                         goto cleanup;
00179 
00180                 result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx,
00181                                                    dhcp_gbl_ctx.actx,
00182                                                    &dhcp_gbl_ctx.socketmgr);
00183                 if (result != ISC_R_SUCCESS)
00184                         goto cleanup;
00185 
00186                 result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx,
00187                                                   dhcp_gbl_ctx.actx,
00188                                                   &dhcp_gbl_ctx.timermgr);
00189                 if (result != ISC_R_SUCCESS)
00190                         goto cleanup;
00191 
00192                 result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task);
00193                 if (result != ISC_R_SUCCESS)
00194                         goto cleanup;
00195         }
00196 
00197 #if defined (NSUPDATE)
00198         if ((flags & DHCP_CONTEXT_POST_DB) != 0) {
00199                 isc_sockaddr_t localaddr4, *localaddr4_ptr = NULL;
00200                 isc_sockaddr_t localaddr6, *localaddr6_ptr = NULL;
00201                 if (local4 != NULL) {
00202                         isc_sockaddr_fromin(&localaddr4, local4, 0);
00203                         localaddr4_ptr = &localaddr4;
00204                 }
00205                 if (local6 != NULL) {
00206                         isc_sockaddr_fromin6(&localaddr6, local6, 0);
00207                         localaddr6_ptr = &localaddr6;
00208                 }
00209 
00210                 result = dns_client_createx2(dhcp_gbl_ctx.mctx,
00211                                              dhcp_gbl_ctx.actx,
00212                                              dhcp_gbl_ctx.taskmgr,
00213                                              dhcp_gbl_ctx.socketmgr,
00214                                              dhcp_gbl_ctx.timermgr,
00215                                              0,
00216                                              &dhcp_gbl_ctx.dnsclient,
00217                                              localaddr4_ptr,
00218                                              localaddr6_ptr);
00219                 if (result != ISC_R_SUCCESS)
00220                         goto cleanup;
00221 
00222                 result = dhcp_dns_client_setservers();
00223                 if (result != ISC_R_SUCCESS)
00224                         goto cleanup;
00225         }
00226 #endif
00227 
00228         return(ISC_R_SUCCESS);
00229 
00230  cleanup:
00231         /*
00232          * Currently we don't try and cleanup, just return an error
00233          * expecting that our caller will log the error and exit.
00234          */
00235 
00236         return(result);
00237 }
00238 
00239 /*
00240  * Convert a string name into the proper structure for the isc routines
00241  *
00242  * Previously we allowed names without a trailing '.' however the current
00243  * dns and dst code requires the names to end in a period.  If the
00244  * name doesn't have a trailing period add one as part of creating
00245  * the dns name.
00246  */
00247 
00248 isc_result_t
00249 dhcp_isc_name(unsigned char   *namestr,
00250               dns_fixedname_t *namefix,
00251               dns_name_t     **name)
00252 {
00253         size_t namelen;
00254         isc_buffer_t b;
00255         isc_result_t result;
00256 
00257         namelen = strlen((char *)namestr); 
00258         isc_buffer_init(&b, namestr, namelen);
00259         isc_buffer_add(&b, namelen);
00260         dns_fixedname_init(namefix);
00261         *name = dns_fixedname_name(namefix);
00262         result = dns_name_fromtext(*name, &b, dns_rootname, 0, NULL);
00263         isc_buffer_invalidate(&b);
00264         return(result);
00265 }
00266 
00267 isc_result_t
00268 isclib_make_dst_key(char          *inname,
00269                     char          *algorithm,
00270                     unsigned char *secret,
00271                     int            length,
00272                     dst_key_t    **dstkey)
00273 {
00274         isc_result_t result;
00275         dns_name_t *name;
00276         dns_fixedname_t name0;
00277         isc_buffer_t b;
00278 
00279         isc_buffer_init(&b, secret, length);
00280         isc_buffer_add(&b, length);
00281 
00282         /* We only support HMAC_MD5 currently */
00283         if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) != 0) {
00284                 return(DHCP_R_INVALIDARG);
00285         }
00286 
00287         result = dhcp_isc_name((unsigned char *)inname, &name0, &name);
00288         if (result != ISC_R_SUCCESS) {
00289                 return(result);
00290         }
00291 
00292         return(dst_key_frombuffer(name, DST_ALG_HMACMD5, DNS_KEYOWNER_ENTITY,
00293                                   DNS_KEYPROTO_DNSSEC, dns_rdataclass_in,
00294                                   &b, dhcp_gbl_ctx.mctx, dstkey));
00295 }
00296 
00302 void dhcp_signal_handler(int signal) {
00303         isc_appctx_t *ctx = dhcp_gbl_ctx.actx;
00304         int prev = shutdown_signal;
00305 
00306         if (prev != 0) {
00307                 /* Already in shutdown. */
00308                 return;
00309         }
00310         /* Possible race but does it matter? */
00311         shutdown_signal = signal;
00312 
00313         /* Use reload (aka suspend) for easier dispatch() reenter. */
00314         if (ctx && ctx->methods && ctx->methods->ctxsuspend) {
00315                 (void) isc_app_ctxsuspend(ctx);
00316         }
00317 }

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1