diff options
-rw-r--r-- | RELNOTES | 49 | ||||
-rw-r--r-- | client/dhc6.c | 12 | ||||
-rw-r--r-- | client/dhclient.8 | 20 | ||||
-rw-r--r-- | client/dhclient.c | 34 | ||||
-rwxr-xr-x | client/scripts/freebsd | 36 | ||||
-rwxr-xr-x | client/scripts/linux | 35 | ||||
-rwxr-xr-x | client/scripts/macos | 35 | ||||
-rwxr-xr-x | client/scripts/netbsd | 35 | ||||
-rw-r--r-- | client/scripts/openbsd | 35 | ||||
-rw-r--r-- | common/discover.c | 9 | ||||
-rw-r--r-- | common/dns.c | 15 | ||||
-rwxr-xr-x | configure | 16 | ||||
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | configure.ac+lt | 7 | ||||
-rw-r--r-- | configure.ac-base | 7 | ||||
-rw-r--r-- | configure.ac-lt | 7 | ||||
-rw-r--r-- | includes/config.h.in | 3 | ||||
-rw-r--r-- | includes/omapip/isclib.h | 9 | ||||
-rw-r--r-- | omapip/isclib.c | 80 | ||||
-rw-r--r-- | relay/dhcrelay.c | 3 | ||||
-rw-r--r-- | server/confpars.c | 11 | ||||
-rw-r--r-- | server/dhcpd.8 | 6 | ||||
-rw-r--r-- | server/dhcpd.c | 14 | ||||
-rw-r--r-- | server/dhcpv6.c | 18 |
24 files changed, 432 insertions, 71 deletions
@@ -129,6 +129,40 @@ by Eric Young (eay@cryptsoft.com). includes/site.h. This flag is undefined by default. [ISC-Bugs #43927] +- Added new compile time option --with-srv-conf-file which specifies a + default location of the server configuration file. + [ISC-Bugs #44765] + +- Added --dad-wait-time parameter to dhclient. It specifies the maximum time, + in seconds, that the client process should wait for the duplicate address + detection to complete before initiating DHCP requests. This value is + propagated to the dhclient script and the script is responsible for waiting + the specified amount of time or until DAD has completed. If the script does + not support it, specifying this parameter has no effect. The default value + is 0 which specifies that the script should not wait for DAD. With this + change the following scripts have been modified to support the new parameter: + freebsd, linux, macos, netbsd, openbsd. + [ISC-Bugs #36169] + +- Modified DDNS support initialization such that 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. Thanks to Rodney Beede for reporting the issue. + [ISC-Bugs #45290] + [ISC-Bugs #33377] + +- Added error logging to two memory allocation failure checks. Thanks to Bill + Parker (wp02855 at gmail dot com) for reporting the issue. + [ISC-Bugs #41185] + +- Corrected a dhclient -6 issue that caused the client to crash with an + "Impossible condition" error after de-preferencing its only IA binding. + The crash occurred when server configuration changes rendered the existing + binding out-of-range and no other leases were available to offer. + [ISC-Bugs #44373] + - Client now calls the script with reason set to FAIL when run with -1 (one try) and there are no server responses. Thanks for a patch by Martin Pitt which got to us via Andrew Pollock. @@ -1050,9 +1084,22 @@ by Eric Young (eay@cryptsoft.com). OS systems when using -1 or large values for default-lease-time. Rollover values will be replaced with 0x7FFFFFFF - 1. This alleviates unintentionally short expiration times being handed out when infinite lease times (-1) in - conjuction with failover. + conjuction with failover. Our thanks to Alessandro Gherardi for bringing + the issue to our attention. [ISC-Bugs #41976] +- The server nows checks both the address and length of a prefix delegation + when attempting to match it to a prefix pool. This ensures the server + responds properly when pool configurations change such that once valid, + "in-pool" delegations are now treated as being invalid. During lease + file loading at startup, the server will discard any PD leases that + are deemed "out-of-pool" either by address or mis-matched prefix length. + Clients seeking to renew or rebind such leases will get a response of + No Binding in the case of the former, and the prefix delegation with + lifetimes set to zero in the case of the latter. Thanks to Mark Nejedlo + at TDS Telecom for reporting this issue. + [ISC-Bugs #35378] + Changes since 4.2.0 (new features) - If a client renews before 'dhcp-cache-threshold' percent of its lease diff --git a/client/dhc6.c b/client/dhc6.c index f7cc90fe..683bbab9 100644 --- a/client/dhc6.c +++ b/client/dhc6.c @@ -1,7 +1,7 @@ /* dhc6.c - DHCPv6 client routines. */ /* - * Copyright (c) 2012-2016 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2012-2017 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2006-2010 by Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any @@ -4364,6 +4364,7 @@ dhc6_check_times(struct client_state *client) TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME, lo_expire=MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp; int has_addrs = ISC_FALSE; + int has_preferred_addrs = ISC_FALSE; struct timeval tv; lease = client->active_lease; @@ -4392,6 +4393,10 @@ dhc6_check_times(struct client_state *client) if (tmp < depref) depref = tmp; + + if (!(addr->flags & DHC6_ADDR_EXPIRED)) { + has_preferred_addrs = ISC_TRUE; + } } if (!(addr->flags & DHC6_ADDR_EXPIRED)) { @@ -4550,7 +4555,10 @@ dhc6_check_times(struct client_state *client) break; default: - log_fatal("Impossible condition at %s:%d.", MDL); + if (has_preferred_addrs) { + log_fatal("Impossible condition, state %d at %s:%d.", + client->state, MDL); + } } /* Separately, set a time at which we will depref and expire diff --git a/client/dhclient.8 b/client/dhclient.8 index cf073b4a..24f8f122 100644 --- a/client/dhclient.8 +++ b/client/dhclient.8 @@ -1,6 +1,6 @@ .\" $Id: dhclient.8,v 1.36 2011/04/15 21:58:12 sar Exp $ .\" -.\" 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 @@ -134,6 +134,10 @@ dhclient - Dynamic Host Configuration Protocol Client .B -w ] [ +.B --dad-wait-time +.I seconds +] +[ .B -v ] [ @@ -409,6 +413,15 @@ overrides these default, with a value of either \fILL\fR or \fILLT\fR. Restore normal address query for IPv6. This implies \fB-6\fR. It is used to restore normal operation after using \fB-T\fR or \fB-P\fR. Multiple addresses can be requested with multiple \fB\-N\fR flags. +.TP +.BI \--dad-wait-time \ seconds +Specify maximum time (in seconds) that the client should wait for the +duplicate address detection (DAD) to complete on an interface. This +value is propagated to the dhclient script in a dad_wait_time environment +variable. If any of the IPv6 addresses on the interface are tentative +(DAD is in progress), the script will wait for the specified number of +seconds for DAD to complete. If the script ignores this variable the +parameter has no effect. .PP .I Modifying default file locations: The following options can be used to modify the locations a client uses @@ -480,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. diff --git a/client/dhclient.c b/client/dhclient.c index 1f07d20c..98422f02 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -72,7 +72,7 @@ int std_dhcid = 0; #define ASSERT_STATE(state_is, state_shouldbe) {} #ifndef UNIT_TEST -static const char copyright[] = "Copyright 2004-2016 Internet Systems Consortium."; +static const char copyright[] = "Copyright 2004-2017 Internet Systems Consortium."; static const char arr [] = "All rights reserved."; static const char message [] = "Internet Systems Consortium DHCP Client"; static const char url [] = "For info, please visit https://www.isc.org/software/dhcp/"; @@ -97,6 +97,7 @@ int wanted_ia_pd = 0; int require_all_ias = 0; /* If the user requires all of the IAs to be available before accepting a lease 0 = no, 1 = requries */ +int dad_wait_time = 0; char *mockup_relay = NULL; char *progname = NULL; @@ -153,11 +154,12 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s"; #ifdef DHCPv6 #ifdef DHCP4o6 #define DHCLIENT_USAGE0 \ -"[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>]\n" \ -" [-p <port>] [-D LL|LLT] \n" +"[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>]\n" \ +" [-D LL|LLT] [--dad-wait-time seconds]\n" #else /* DHCP4o6 */ #define DHCLIENT_USAGE0 \ -"[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n" +"[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT]\n" \ +" [--dad-wait-time seconds]\n" #endif #else /* DHCPv6 */ #define DHCLIENT_USAGE0 \ @@ -313,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)); @@ -478,6 +480,15 @@ main(int argc, char **argv) { local_family_set = 1; local_family = AF_INET6; require_all_ias = 1; + } else if (!strcmp(argv[i], "--dad-wait-time")) { + if (++i == argc) { + usage(use_noarg, argv[i-1]); + } + dad_wait_time = (int)strtol(argv[i], &s, 10); + if (errno || (*s != '\0') || (dad_wait_time < 0)) { + usage("Invalid value for --dad-wait-time: %s", argv[i]); + } + #endif /* DHCPv6 */ } else if (!strcmp(argv[i], "-D")) { duid_v4 = 1; @@ -3940,6 +3951,8 @@ void script_init (client, reason, medium) client_envadd (client, "", "reason", "%s", reason); client_envadd (client, "", "pid", "%ld", (long int)getpid ()); + client_envadd (client, "", "dad_wait_time", "%ld", + (long int)dad_wait_time); } } @@ -4221,8 +4234,11 @@ void client_envadd (struct client_state *client, val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ + len + sizeof *val, MDL); - if (!val) + if (!val) { + log_error ("client_envadd: cannot allocate space for variable"); return; + } + s = val -> string; strcpy (s, prefix); strcat (s, name); @@ -4232,8 +4248,10 @@ void client_envadd (struct client_state *client, va_start (list, fmt); vsnprintf (s, len + 1, fmt, list); va_end (list); - } else + } else { strcpy (s, spbuf); + } + val -> next = client -> env; client -> env = val; client -> envc++; diff --git a/client/scripts/freebsd b/client/scripts/freebsd index 6485cc75..8f3e2a23 100755 --- a/client/scripts/freebsd +++ b/client/scripts/freebsd @@ -335,6 +335,42 @@ if [ ${reason} = PREINIT6 ] ; then # XXX: Remove any stale addresses from aborted clients. + # We need to give the kernel some time to active interface + interface_up_wait_time=5 + for i in $(seq 0 ${interface_up_wait_time}) + do + ifconfig ${interface} | grep inactive >/dev/null 2>&1 + if [ $? -ne 0 ]; then + break; + fi + sleep 1 + done + + # Wait for duplicate address detection for this interface if the + # --dad-wait-time parameter has been specified and is greater than + # zero. + if [ ${dad_wait_time} -gt 0 ]; then + # Check if any IPv6 address on this interface is marked as + # tentative. + ifconfig ${interface} | grep inet6 | grep tentative \ + >/dev/null 2>&1 + if [ $? -eq 0 ]; then + # Wait for duplicate address detection to complete or for + # the timeout specified as --dad-wait-time. + for i in $(seq 0 $dad_wait_time) + do + # We're going to poll for the tentative flag every second. + sleep 1 + ifconfig ${interface} | grep inet6 | grep tentative \ + >/dev/null 2>&1 + if [ $? -ne 0 ]; then + break; + fi + done + fi + fi + + exit_with_hooks 0 fi diff --git a/client/scripts/linux b/client/scripts/linux index e6792c67..7d77fd39 100755 --- a/client/scripts/linux +++ b/client/scripts/linux @@ -248,9 +248,44 @@ if [ x$reason = xPREINIT6 ] ; then # Ensure interface is up. ${ip} link set ${interface} up + # We need to give the kernel some time to active interface + interface_up_wait_time=5 + for i in $(seq 0 ${interface_up_wait_time}) + do + ifconfig ${interface} | grep RUNNING >/dev/null 2>&1 + if [ $? -eq 0 ]; then + break; + fi + sleep 1 + done + # Remove any stale addresses from aborted clients. ${ip} -f inet6 addr flush dev ${interface} scope global permanent + # Wait for duplicate address detection for this interface if the + # --dad-wait-time parameter has been specified and is greater than + # zero. + if [ ${dad_wait_time} -gt 0 ]; then + # Check if any IPv6 address on this interface is marked as + # tentative. + ${ip} addr show ${interface} | grep inet6 | grep tentative \ + &> /dev/null + if [ $? -eq 0 ]; then + # Wait for duplicate address detection to complete or for + # the timeout specified as --dad-wait-time. + for i in $(seq 0 $dad_wait_time) + do + # We're going to poll for the tentative flag every second. + sleep 1 + ${ip} addr show ${interface} | grep inet6 | grep tentative \ + &> /dev/null + if [ $? -ne 0 ]; then + break; + fi + done + fi + fi + exit_with_hooks 0 fi diff --git a/client/scripts/macos b/client/scripts/macos index cb661921..a896b1e9 100755 --- a/client/scripts/macos +++ b/client/scripts/macos @@ -144,8 +144,43 @@ if [ x$reason = xPREINIT6 ]; then # Ensure interface is up. ifconfig ${interface} up + # We need to give the kernel some time to active interface + interface_up_wait_time=5 + for i in $(seq 0 ${interface_up_wait_time}) + do + ifconfig ${interface} | grep inactive &> /dev/null + if [ $? -ne 0 ]; then + break; + fi + sleep 1 + done + # XXX: Remove any stale addresses from aborted clients. + # Wait for duplicate address detection for this interface if the + # --dad-wait-time parameter has been specified and is greater than + # zero. + if [ ${dad_wait_time} -gt 0 ]; then + # Check if any IPv6 address on this interface is marked as + # tentative. + ifconfig ${interface} | grep inet6 | grep tentative \ + &> /dev/null + if [ $? -eq 0 ]; then + # Wait for duplicate address detection to complete or for + # the timeout specified as --dad-wait-time. + for i in $(seq 0 $dad_wait_time) + do + # We're going to poll for the tentative flag every second. + sleep 1 + ifconfig ${interface} | grep inet6 | grep tentative \ + &> /dev/null + if [ $? -ne 0 ]; then + break; + fi + done + fi + fi + exit_with_hooks 0 fi diff --git a/client/scripts/netbsd b/client/scripts/netbsd index 8a5007e7..6a41edf4 100755 --- a/client/scripts/netbsd +++ b/client/scripts/netbsd @@ -265,6 +265,41 @@ if [ ${reason} = PREINIT6 ] ; then # XXX: Remove any stale addresses from aborted clients. + # We need to give the kernel some time to active interface + interface_up_wait_time=5 + for i in $(seq 0 ${interface_up_wait_time}) + do + ifconfig ${interface} | grep inactive >/dev/null 2>&1 + if [ $? -ne 0 ]; then + break; + fi + sleep 1 + done + + # Wait for duplicate address detection for this interface if the + # --dad-wait-time parameter has been specified and is greater than + # zero. + if [ ${dad_wait_time} -gt 0 ]; then + # Check if any IPv6 address on this interface is marked as + # tentative. + ifconfig ${interface} | grep inet6 | grep tentative \ + >/dev/null 2>&1 + if [ $? -eq 0 ]; then + # Wait for duplicate address detection to complete or for + # the timeout specified as --dad-wait-time. + for i in $(seq 0 $dad_wait_time) + do + # We're going to poll for the tentative flag every second. + sleep 1 + ifconfig ${interface} | grep inet6 | grep tentative \ + >/dev/null 2>&1 + if [ $? -ne 0 ]; then + break; + fi + done + fi + fi + exit_with_hooks 0 fi diff --git a/client/scripts/openbsd b/client/scripts/openbsd index f20d0ff6..151b50aa 100644 --- a/client/scripts/openbsd +++ b/client/scripts/openbsd @@ -259,6 +259,41 @@ if [ ${reason} = PREINIT6 ] ; then # XXX: Remove any stale addresses from aborted clients. + # We need to give the kernel some time to active interface + interface_up_wait_time=5 + for i in $(seq 0 ${interface_up_wait_time}) + do + ifconfig ${interface} | grep inactive >/dev/null 2>&1 + if [ $? -ne 0 ]; then + break; + fi + sleep 1 + done + + # Wait for duplicate address detection for this interface if the + # --dad-wait-time parameter has been specified and is greater than + # zero. + if [ ${dad_wait_time} -gt 0 ]; then + # Check if any IPv6 address on this interface is marked as + # tentative. + ifconfig ${interface} | grep inet6 | grep tentative \ + >/dev/null 2>&1 + if [ $? -eq 0 ]; then + # Wait for duplicate address detection to complete or for + # the timeout specified as --dad-wait-time. + for i in $(seq 0 $dad_wait_time) + do + # We're going to poll for the tentative flag every second. + sleep 1 + ifconfig ${interface} | grep inet6 | grep tentative \ + >/dev/null 2>&1 + if [ $? -ne 0 ]; then + break; + fi + done + fi + fi + exit_with_hooks 0 fi diff --git a/common/discover.c b/common/discover.c index 6824ec4b..57fd1b66 100644 --- a/common/discover.c +++ b/common/discover.c @@ -3,7 +3,7 @@ Find and identify the network interfaces. */ /* - * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -1491,8 +1491,11 @@ void interface_stash (struct interface_info *tptr) delta = tptr -> index - interface_max + 10; vec = dmalloc ((interface_max + delta) * sizeof (struct interface_info *), MDL); - if (!vec) + if (!vec) { + log_error ("interface_stash: allocation failed "); return; + } + memset (&vec [interface_max], 0, (sizeof (struct interface_info *)) * delta); interface_max += delta; @@ -1502,8 +1505,10 @@ void interface_stash (struct interface_info *tptr) sizeof (struct interface_info *))); dfree (interface_vector, MDL); } + interface_vector = vec; } + interface_reference (&interface_vector [tptr -> index], tptr, MDL); if (tptr -> index >= interface_count) interface_count = tptr -> index + 1; diff --git a/common/dns.c b/common/dns.c index 0f8be80d..2ca4ba8b 100644 --- a/common/dns.c +++ b/common/dns.c @@ -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 @@ -776,6 +776,7 @@ enable_secs_byteorder enable_log_pid enable_binary_leases with_atf +with_srv_conf_file with_srv_lease_file with_srv6_lease_file with_cli_lease_file @@ -1468,6 +1469,9 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-atf=PATH specify location where atf was installed (or "bind") + --with-srv-conf-file=PATH + Default file containing dhcpd configuration (default + is typically /etc/dhcpd.conf) --with-srv-lease-file=PATH File for dhcpd leases (default is LOCALSTATEDIR/db/dhcpd.leases) @@ -5826,6 +5830,18 @@ case "$localstatedir" in ;; esac +# Default server configuration file. + +# Check whether --with-srv-conf-file was given. +if test "${with_srv_conf_file+set}" = set; then : + withval=$with_srv_conf_file; +cat >>confdefs.h <<_ACEOF +#define _PATH_DHCPD_CONF "$withval" +_ACEOF + +fi + + # Allow specification of alternate state files # Check whether --with-srv-lease-file was given. diff --git a/configure.ac b/configure.ac index b4d5bc3f..6162d261 100644 --- a/configure.ac +++ b/configure.ac @@ -340,6 +340,13 @@ case "$localstatedir" in ;; esac +# Default server configuration file. +AC_ARG_WITH(srv-conf-file, + AS_HELP_STRING([--with-srv-conf-file=PATH],[Default file containing dhcpd configuration + (default is typically /etc/dhcpd.conf)]), + AC_DEFINE_UNQUOTED([_PATH_DHCPD_CONF], ["$withval"], + [Default file containing dhcpd configuration.])) + # Allow specification of alternate state files AC_ARG_WITH(srv-lease-file, AS_HELP_STRING([--with-srv-lease-file=PATH],[File for dhcpd leases diff --git a/configure.ac+lt b/configure.ac+lt index b1edb6da..742207a1 100644 --- a/configure.ac+lt +++ b/configure.ac+lt @@ -341,6 +341,13 @@ case "$localstatedir" in ;; esac +# Default server configuration file. +AC_ARG_WITH(srv-conf-file, + AS_HELP_STRING([--with-srv-conf-file=PATH],[Default file containing dhcpd configuration + (default is typically /etc/dhcpd.conf)]), + AC_DEFINE_UNQUOTED([_PATH_DHCPD_CONF], ["$withval"], + [Default file containing dhcpd configuration.])) + # Allow specification of alternate state files AC_ARG_WITH(srv-lease-file, AS_HELP_STRING([--with-srv-lease-file=PATH],[File for dhcpd leases diff --git a/configure.ac-base b/configure.ac-base index 6bd236ce..284011e6 100644 --- a/configure.ac-base +++ b/configure.ac-base @@ -346,6 +346,13 @@ case "$localstatedir" in ;; esac +# Default server configuration file. +AC_ARG_WITH(srv-conf-file, + AS_HELP_STRING([--with-srv-conf-file=PATH],[Default file containing dhcpd configuration + (default is typically /etc/dhcpd.conf)]), + AC_DEFINE_UNQUOTED([_PATH_DHCPD_CONF], ["$withval"], + [Default file containing dhcpd configuration.])) + # Allow specification of alternate state files AC_ARG_WITH(srv-lease-file, AS_HELP_STRING([--with-srv-lease-file=PATH],[File for dhcpd leases diff --git a/configure.ac-lt b/configure.ac-lt index 302271de..ba0a8920 100644 --- a/configure.ac-lt +++ b/configure.ac-lt @@ -340,6 +340,13 @@ case "$localstatedir" in ;; esac +# Default server configuration file. +AC_ARG_WITH(srv-conf-file, + AS_HELP_STRING([--with-srv-conf-file=PATH],[Default file containing dhcpd configuration + (default is typically /etc/dhcpd.conf)]), + AC_DEFINE_UNQUOTED([_PATH_DHCPD_CONF], ["$withval"], + [Default file containing dhcpd configuration.])) + # Allow specification of alternate state files AC_ARG_WITH(srv-lease-file, AS_HELP_STRING([--with-srv-lease-file=PATH],[File for dhcpd leases diff --git a/includes/config.h.in b/includes/config.h.in index 02f5dbcf..4a3330d8 100644 --- a/includes/config.h.in +++ b/includes/config.h.in @@ -242,6 +242,9 @@ /* File for dhcpd6 process information. */ #undef _PATH_DHCPD6_PID +/* Default file containing dhcpd configuration. */ +#undef _PATH_DHCPD_CONF + /* File for dhcpd leases. */ #undef _PATH_DHCPD_DB diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h index caa388ad..e2963089 100644 --- a/includes/omapip/isclib.h +++ b/includes/omapip/isclib.h @@ -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 */ diff --git a/omapip/isclib.c b/omapip/isclib.c index 781db848..3c9c3590 100644 --- a/omapip/isclib.c +++ b/omapip/isclib.c @@ -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; +} diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index f4943879..3f1b3d04 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -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)); diff --git a/server/confpars.c b/server/confpars.c index d2714516..97e2990a 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -5974,13 +5974,16 @@ parse_ia_pd_declaration(struct parse *cfile) { executable_statement_dereference (&on_star[i], MDL); } - /* find the pool this address is in */ + /* Find the pool this address is in. We need to check prefix + * lengths too in case the pool has been reconfigured. */ pool = NULL; - if (find_ipv6_pool(&pool, D6O_IA_PD, - &iapref->addr) != ISC_R_SUCCESS) { + if ((find_ipv6_pool(&pool, D6O_IA_PD, + &iapref->addr) != ISC_R_SUCCESS) || + (pool->units != iapref->plen)) { inet_ntop(AF_INET6, &iapref->addr, addr_buf, sizeof(addr_buf)); - log_error("No pool found for prefix %s", addr_buf); + log_error("No pool found for prefix %s/%d", addr_buf, + iapref->plen); iasubopt_dereference(&iapref, MDL); continue; } diff --git a/server/dhcpd.8 b/server/dhcpd.8 index 6ca79402..d27a1ea7 100644 --- a/server/dhcpd.8 +++ b/server/dhcpd.8 @@ -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 diff --git a/server/dhcpd.c b/server/dhcpd.c index 910f374f..ce33587c 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -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) { diff --git a/server/dhcpv6.c b/server/dhcpv6.c index a8bae63c..2ecc23b6 100644 --- a/server/dhcpv6.c +++ b/server/dhcpv6.c @@ -1437,22 +1437,25 @@ try_client_v6_prefix(struct iasubopt **pref, if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) { return DHCP_R_INVALIDARG; } + tmp_plen = (int) requested_pref->data[0]; - if ((tmp_plen < 3) || (tmp_plen > 128) || - ((int)tmp_plen != pool->units)) { + if ((tmp_plen < 3) || (tmp_plen > 128)) { return ISC_R_FAILURE; } + memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref)); if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) { return ISC_R_FAILURE; } + ia.len = 16; memcpy(&ia.iabuf, &tmp_pref, 16); if (!is_cidr_mask_valid(&ia, (int) tmp_plen)) { return ISC_R_FAILURE; } - if (!ipv6_in_pool(&tmp_pref, pool)) { + if (!ipv6_in_pool(&tmp_pref, pool) || + ((int)tmp_plen != pool->units)) { return ISC_R_ADDRNOTAVAIL; } @@ -1464,6 +1467,7 @@ try_client_v6_prefix(struct iasubopt **pref, if (result != ISC_R_SUCCESS) { return result; } + (*pref)->addr = tmp_pref; (*pref)->plen = tmp_plen; @@ -1472,6 +1476,7 @@ try_client_v6_prefix(struct iasubopt **pref, if (result != ISC_R_SUCCESS) { iasubopt_dereference(pref, MDL); } + return result; } @@ -1688,13 +1693,6 @@ eval_prefix_mode(int len, int preflen, int prefix_mode) { break; } -#if defined (DEBUG) - log_debug("eval_prefix_mode: " - "len %d, preflen %d, mode %s, use_it %d", - len, preflen, - prefix_length_modes.values[prefix_mode].name, use_it); -#endif - return (use_it); } |