/*
- * Copyright(c) 2009-2010,2013-2014 by Internet Systems Consortium, Inc.("ISC")
+ * Copyright(C) 2009-2022 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.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
+ * PO Box 360
+ * Newmarket, NH 03857 USA
* <info@isc.org>
* http://www.isc.org/
*
* It may be moved to be part of the dns client code instead
* of being in the DHCP code
*/
-isc_result_t
+isc_result_t
dhcp_dns_client_setservers(void)
{
isc_result_t result;
}
return (result);
}
-#endif
+#endif /* defined NSUPDATE */
void
isclib_cleanup(void)
#if defined (NSUPDATE)
if (dhcp_gbl_ctx.dnsclient != NULL)
dns_client_destroy((dns_client_t **)&dhcp_gbl_ctx.dnsclient);
-#endif
+#endif /* defined NSUPDATE */
if (dhcp_gbl_ctx.task != NULL) {
isc_task_shutdown(dhcp_gbl_ctx.task);
}
}
+/* Callback passed to isc_app_ctxonrun
+ *
+ * BIND9 context code will invoke this handler once the context has
+ * entered the running state. We use it to set a global marker so that
+ * we can tell if the context is running. Several of the isc_app_
+ * calls REQUIRE that the context is running and we need a way to
+ * know that.
+ *
+ * We also check to see if we received a shutdown signal prior to
+ * the context entering the run state. If we did, then we can just
+ * simply shut the context down now. This closes the relatively
+ * small window between start up and entering run via the call
+ * to dispatch().
+ *
+ */
+static void
+set_ctx_running(isc_task_t *task, isc_event_t *event) {
+ IGNORE_UNUSED(task);
+ dhcp_gbl_ctx.actx_running = ISC_TRUE;
+
+ if (shutdown_signal) {
+ // We got signaled shutdown before we entered running state.
+ // Now that we've reached running state, shut'er down.
+ isc_app_ctxsuspend(dhcp_gbl_ctx.actx);
+ }
+
+ isc_event_free(&event);
+}
+
isc_result_t
dhcp_context_create(int flags,
struct in_addr *local4,
isc_result_t result;
if ((flags & DHCP_CONTEXT_PRE_DB) != 0) {
+ dhcp_gbl_ctx.actx_started = ISC_FALSE;
+ dhcp_gbl_ctx.actx_running = ISC_FALSE;
+
/*
* Set up the error messages, this isn't the right place
* for this call but it is convienent for now.
}
memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx));
-
+
isc_lib_register();
/* get the current time for use as the random seed */
result = dns_lib_init();
if (result != ISC_R_SUCCESS)
goto cleanup;
-#else
+#else /* defined NSUPDATE */
/* 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
+#endif /* defined NSUPDATE */
result = isc_appctx_create(dhcp_gbl_ctx.mctx,
&dhcp_gbl_ctx.actx);
if (result != ISC_R_SUCCESS)
goto cleanup;
- result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task);
+ result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0,
+ &dhcp_gbl_ctx.task);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = isc_app_ctxstart(dhcp_gbl_ctx.actx);
if (result != ISC_R_SUCCESS)
- return (result);
+ goto cleanup;
+
dhcp_gbl_ctx.actx_started = ISC_TRUE;
+ // Install the onrun callback.
+ result = isc_app_ctxonrun(dhcp_gbl_ctx.actx, dhcp_gbl_ctx.mctx,
+ dhcp_gbl_ctx.task, set_ctx_running,
+ dhcp_gbl_ctx.actx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
/* 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 */
#if defined (NSUPDATE)
if ((flags & DHCP_CONTEXT_POST_DB) != 0) {
- isc_sockaddr_t localaddr4, *localaddr4_ptr = NULL;
- isc_sockaddr_t localaddr6, *localaddr6_ptr = NULL;
+ /* Setting addresses only.
+ * All real work will be done later on if needed to avoid
+ * listening on ddns port if client/server was compiled with
+ * ddns support but not using it. */
if (local4 != NULL) {
- isc_sockaddr_fromin(&localaddr4, local4, 0);
- localaddr4_ptr = &localaddr4;
+ dhcp_gbl_ctx.use_local4 = 1;
+ isc_sockaddr_fromin(&dhcp_gbl_ctx.local4_sockaddr,
+ local4, 0);
}
+
if (local6 != NULL) {
- isc_sockaddr_fromin6(&localaddr6, local6, 0);
- localaddr6_ptr = &localaddr6;
+ dhcp_gbl_ctx.use_local6 = 1;
+ isc_sockaddr_fromin6(&dhcp_gbl_ctx.local6_sockaddr,
+ local6, 0);
}
- result = dns_client_createx2(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,
- localaddr4_ptr,
- localaddr6_ptr);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /*
- * If we can't set up the servers we may not be able to
- * do DDNS but we should continue to try and perform
- * our basic functions and let the user sort it out.
- */
- result = dhcp_dns_client_setservers();
- if (result != ISC_R_SUCCESS) {
- log_error("Unable to set resolver from resolv.conf; "
- "startup continuing but DDNS support "
- "may be affected");
+ if (!(flags & DHCP_DNS_CLIENT_LAZY_INIT)) {
+ result = dns_client_init();
}
}
-#endif
+#endif /* defined NSUPDATE */
return(ISC_R_SUCCESS);
isc_buffer_t b;
isc_result_t result;
- namelen = strlen((char *)namestr);
+ namelen = strlen((char *)namestr);
isc_buffer_init(&b, namestr, namelen);
isc_buffer_add(&b, namelen);
dns_fixedname_init(namefix);
* @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) {
+ if (shutdown_signal != 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);
+ /* If the application context is running tell it to shut down */
+ if (dhcp_gbl_ctx.actx_running == ISC_TRUE) {
+ (void) isc_app_ctxsuspend(dhcp_gbl_ctx.actx);
+ }
+}
+
+#if defined (NSUPDATE)
+isc_result_t dns_client_init() {
+ isc_result_t result;
+ if (dhcp_gbl_ctx.dnsclient == NULL) {
+ result = dns_client_createx2(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,
+ (dhcp_gbl_ctx.use_local4 ?
+ &dhcp_gbl_ctx.local4_sockaddr
+ : NULL),
+ (dhcp_gbl_ctx.use_local6 ?
+ &dhcp_gbl_ctx.local6_sockaddr
+ : NULL));
+
+ if (result != ISC_R_SUCCESS) {
+ log_error("Unable to create DNS client context:"
+ " result: %d", result);
+ return result;
+ }
+
+ /* If we can't set up the servers we may not be able to
+ * do DDNS but we should continue to try and perform
+ * our basic functions and let the user sort it out. */
+ result = dhcp_dns_client_setservers();
+ if (result != ISC_R_SUCCESS) {
+ log_error("Unable to set resolver from resolv.conf; "
+ "startup continuing but DDNS support "
+ "may be affected: result %d", result);
+ }
}
+
+ return ISC_R_SUCCESS;
}
+#endif /* defined (NSUPDATE) */