summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELNOTES49
-rw-r--r--client/dhc6.c12
-rw-r--r--client/dhclient.820
-rw-r--r--client/dhclient.c34
-rwxr-xr-xclient/scripts/freebsd36
-rwxr-xr-xclient/scripts/linux35
-rwxr-xr-xclient/scripts/macos35
-rwxr-xr-xclient/scripts/netbsd35
-rw-r--r--client/scripts/openbsd35
-rw-r--r--common/discover.c9
-rw-r--r--common/dns.c15
-rwxr-xr-xconfigure16
-rw-r--r--configure.ac7
-rw-r--r--configure.ac+lt7
-rw-r--r--configure.ac-base7
-rw-r--r--configure.ac-lt7
-rw-r--r--includes/config.h.in3
-rw-r--r--includes/omapip/isclib.h9
-rw-r--r--omapip/isclib.c80
-rw-r--r--relay/dhcrelay.c3
-rw-r--r--server/confpars.c11
-rw-r--r--server/dhcpd.86
-rw-r--r--server/dhcpd.c14
-rw-r--r--server/dhcpv6.c18
24 files changed, 432 insertions, 71 deletions
diff --git a/RELNOTES b/RELNOTES
index dbc4d250..07b35ee4 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -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
diff --git a/configure b/configure
index eff92d16..9620b1ac 100755
--- a/configure
+++ b/configure
@@ -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);
}