]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Optimized if and when DNS client context and ports are initted
authorThomas Markwalder <tmark@isc.org>
Mon, 19 Jun 2017 18:44:29 +0000 (14:44 -0400)
committerThomas Markwalder <tmark@isc.org>
Mon, 19 Jun 2017 18:44:29 +0000 (14:44 -0400)
    Merges in rt45290.

RELNOTES
client/dhclient.8
client/dhclient.c
common/dns.c
includes/omapip/isclib.h
omapip/isclib.c
relay/dhcrelay.c
server/dhcpd.8
server/dhcpd.c

index 2a2465ed6cfcb6aedea378625b9eb6951386f577..acd341a666836db06b30f704027bdf4ac56522c1 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -144,6 +144,15 @@ by Eric Young (eay@cryptsoft.com).
   freebsd, linux, macos, netbsd, openbsd.
   [ISC-Bugs #36169]
 
+- Modified DDNS support initialization such DNS related ports will only be
+  opened by the server (dhcpd) at startup if ddns-update-style is not "none";
+  by dhclient only if and when the it first attempts an update; and never by
+  dhcrelay.  Prior to this all three always did the initialization at startup
+  which causes them to always open on and listen for traffic on two random
+  ports.
+  [ISC-Bugs #45290]
+  [ISC-Bugs #33377]
+
                        Changes since 4.3.0 (bug fixes)
 
 - Tidy up several small tickets.
index a00f1f77538f476d58b8483f3b3a4fa0fabf85a7..24f8f122b80c9cabdbcc6cf83d77edf97d7df8d6 100644 (file)
@@ -493,8 +493,9 @@ port will be used for the established connection.
 
 When DDNS is enabled at compile time (see includes/site.h)
 the client will open both a v4 and a v6 UDP socket on
-random ports.  These ports are opened even if DDNS is disabled
-in the configuration file.
+random ports.  These ports are not opened unless/until the
+client first attempts to do an update.  If the client is not
+configured to do updates, the ports will never be opened.
 .PP
 .SH CONFIGURATION
 The syntax of the \fBdhclient.conf(5)\fR file is discussed separately.
index 129aba7256edb8f938728d2f4e8161303343e087..40fd876a44e978964dcdfb5953e16736c98ca333 100644 (file)
@@ -315,8 +315,8 @@ main(int argc, char **argv) {
        }
 
        /* Set up the isc and dns library managers */
-       status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
-                                    NULL, NULL);
+       status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB
+                                    | DHCP_DNS_CLIENT_LAZY_INIT, NULL, NULL);
        if (status != ISC_R_SUCCESS)
                log_fatal("Can't initialize context: %s",
                          isc_result_totext(status));
index 0f8be80d964988da9bf26aab81e2d9902a4677af..2ca4ba8b42ea3bb68dab6c99bd3386891d02facc 100644 (file)
@@ -3,8 +3,7 @@
    Domain Name Service subroutines. */
 
 /*
- * Copyright (c) 2009-2015 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2001-2003 by Internet Software Consortium
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -2151,6 +2150,12 @@ ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
 
        isc_sockaddrlist_t *zlist = NULL;
 
+       /* Creates client context if we need to */
+       result = dns_client_init();
+       if (result != ISC_R_SUCCESS) {
+               return result;
+       }
+
        /* Get a pointer to the clientname to make things easier. */
        clientname = (unsigned char *)ddns_cb->fwd_name.data;
 
@@ -2359,6 +2364,12 @@ ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
        unsigned char buf[256];
        int buflen;
 
+       /* Creates client context if we need to */
+       result = dns_client_init();
+       if (result != ISC_R_SUCCESS) {
+               return result;
+       }
+
        /*
         * Try to lookup the zone in the zone cache.  As with the forward
         * case it's okay if we don't have one, the DNS code will try to
index caa388ad90c7cf6b8f9f3ca7bfeda97200ec55aa..e29630891c54feaa06e690d1ba68f4b8fdb39bcf 100644 (file)
@@ -3,7 +3,7 @@
    connections to the isc and dns libraries */
 
 /*
- * Copyright (c) 2009,2013,2014 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009-2017 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
@@ -98,6 +98,10 @@ typedef struct dhcp_context {
        isc_timermgr_t  *timermgr;
 #if defined (NSUPDATE)
        dns_client_t    *dnsclient;
+       int use_local4;
+       isc_sockaddr_t local4_sockaddr;
+       int use_local6;
+       isc_sockaddr_t local6_sockaddr;
 #endif
 } dhcp_context_t;
 
@@ -125,6 +129,7 @@ isclib_make_dst_key(char          *inname,
 
 #define DHCP_CONTEXT_PRE_DB  1
 #define DHCP_CONTEXT_POST_DB 2
+#define DHCP_DNS_CLIENT_LAZY_INIT 4
 isc_result_t dhcp_context_create(int              flags,
                                 struct in_addr  *local4,
                                 struct in6_addr *local6);
@@ -133,4 +138,6 @@ void isclib_cleanup(void);
 void dhcp_signal_handler(int signal);
 extern int shutdown_signal;
 
+isc_result_t dns_client_init();
+
 #endif /* ISCLIB_H */
index 781db848a6ba6b6232cd7d7147330f593c6e33c4..3c9c3590050cf77098db0f2a8ebfac7c5d024518 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2009-2010,2013-2014 by Internet Systems Consortium, Inc.("ISC")
+ * Copyright(c) 2009-2017 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
@@ -226,39 +226,24 @@ dhcp_context_create(int flags,
 
 #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
@@ -365,3 +350,40 @@ void dhcp_signal_handler(int signal) {
                (void) isc_app_ctxsuspend(ctx);
        }
 }
+
+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;
+}
index f4943879a3ebc1e96d1b5f5176acdbfd3a884b3b..3f1b3d04275b83d82262b7b19082d70687690179 100644 (file)
@@ -308,8 +308,7 @@ main(int argc, char **argv) {
 
 
        /* Set up the isc and dns library managers */
-       status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
-                                    NULL, NULL);
+       status = dhcp_context_create(DHCP_CONTEXT_PRE_DB, NULL, NULL);
        if (status != ISC_R_SUCCESS)
                log_fatal("Can't initialize context: %s",
                          isc_result_totext(status));
index 6ca794023f7fc668667b5ca01b90d7e099eec620..d27a1ea7f057820b9d46f9422a71b55832edac96 100644 (file)
@@ -1,6 +1,6 @@
 .\"    dhcpd.8
 .\"
-.\" Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
 .\" Copyright (c) 1996-2003 by Internet Software Consortium
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -369,8 +369,8 @@ port will be used for the established connection.
 
 When DDNS is enabled at compile time (see includes/site.h)
 the server will open both a v4 and a v6 UDP socket on
-random ports.  These ports are opened even if DDNS is disabled
-in the configuration file.
+random ports, unless DDNS updates are globally disabled by
+setting ddns-update-style to none in the configuration file.
 .PP
 .SH CONFIGURATION
 The syntax of the dhcpd.conf(5) file is discussed separately.  This
index 910f374f6ffc958898017e81e3f701de7a21ac0e..ce33587cebbb4143150202b5bca8fff47d42d391 100644 (file)
@@ -1253,10 +1253,16 @@ void postconf_initialization (int quiet)
                }
        }
 
-       if (dhcp_context_create(DHCP_CONTEXT_POST_DB, local4_ptr, local6_ptr)
-           != ISC_R_SUCCESS)
-               log_fatal("Unable to complete ddns initialization");
-
+       /* Don't init DNS client if update style is none. This avoids
+        * listening ports that aren't needed.  We don't use ddns-udpates
+        * as that has multiple levels of scope. */
+       if (ddns_update_style != DDNS_UPDATE_STYLE_NONE) {
+               if (dhcp_context_create(DHCP_CONTEXT_POST_DB,
+                                       local4_ptr, local6_ptr)
+                       != ISC_R_SUCCESS) {
+                       log_fatal("Unable to complete ddns initialization");
+               }
+       }
 #else
        /* If we don't have support for updates compiled in tell the user */
        if (ddns_update_style != DDNS_UPDATE_STYLE_NONE) {