Package: dhcp3-client
Version: 3.1.1-6
Followup-For: Bug #509089
The attached patch adds both of Michel's patches to dhcp3 as dpatches in
debian/patches, and makes the suggested change to dhclient-script. I
can confirm that these changes, together with setting
initial-random-delay to 0 in dhclient.conf, significantly reduce the
time needed to negotiate a DHCP lease.
Please consider applying the attached patch.
Please also consider changing the default dhclient.conf to set
initial-random-delay to 0, initial-interval to 1, and backoff-cutoff to
1.
- Josh Triplett
-- System Information:
Debian Release: squeeze/sid
APT prefers unstable
APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.28-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages dhcp3-client depends on:
ii debconf [debconf-2.0] 1.5.26 Debian configuration management sy
ii debianutils 2.31 Miscellaneous utilities specific t
ii dhcp3-common 3.1.1-6 common files used by all the dhcp3
ii libc6 2.9-4 GNU C Library: Shared libraries
dhcp3-client recommends no packages.
Versions of packages dhcp3-client suggests:
pn avahi-autoipd <none> (no description available)
pn resolvconf <none> (no description available)
-- debconf information excluded
diff -Naur dhcp3-3.1.1.orig/debian/dhclient-script.linux dhcp3-3.1.1/debian/dhclient-script.linux
--- dhcp3-3.1.1.orig/debian/dhclient-script.linux 2009-03-05 11:54:00.000000000 -0800
+++ dhcp3-3.1.1/debian/dhclient-script.linux 2009-03-05 11:49:24.000000000 -0800
@@ -9,6 +9,7 @@
# Andrew Pollock, February 2005
# Modified to work on point-to-point links. Andrew Pollock, June 2005
# Modified to support passing the parameters called with to the hooks. Andrew Pollock, November 2005
+# Modified to remove delay in PREINIT. Josh Triplett, suggested by Michel Lespinasse, March 2009
# The alias handling in here probably still sucks. -mdz
@@ -150,9 +151,6 @@
ifconfig $interface:0- inet 0
fi
ifconfig $interface inet 0 up
-
- # We need to give the kernel some time to get the interface up.
- sleep 1
;;
BOUND|RENEW|REBIND|REBOOT)
diff -Naur dhcp3-3.1.1.orig/debian/dhclient-script.udeb dhcp3-3.1.1/debian/dhclient-script.udeb
--- dhcp3-3.1.1.orig/debian/dhclient-script.udeb 2009-03-05 11:54:00.000000000 -0800
+++ dhcp3-3.1.1/debian/dhclient-script.udeb 2009-03-05 11:50:03.000000000 -0800
@@ -9,6 +9,7 @@
# dhclient-script for Linux. Dan Halbert, March, 1997.
# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.
# Modified for Debian. Matt Zimmerman and Eloy Paris, December 2003
+# Modified to remove delay in PREINIT. Josh Triplett, suggested by Michel Lespinasse, March 2009
make_resolv_conf() {
if [ -n "$new_domain_name" ] || [ -n "$new_domain_name_servers" ]; then
@@ -52,9 +53,6 @@
;;
PREINIT)
ip link set $interface up
-
- # We need to give the kernel some time to get the interface up.
- sleep 1
;;
BOUND|RENEW|REBIND|REBOOT)
diff -Naur dhcp3-3.1.1.orig/debian/patches/00list dhcp3-3.1.1/debian/patches/00list
--- dhcp3-3.1.1.orig/debian/patches/00list 2009-03-05 11:54:00.000000000 -0800
+++ dhcp3-3.1.1/debian/patches/00list 2009-03-05 12:07:03.000000000 -0800
@@ -20,6 +20,9 @@
kfreebsd
# emailed upstream (ISC-Bugs #18174)
dhclient-pretty_print-off-by-one
+# not emailed upstream (http://bugs.debian.org/509089)
+dhclient-fix-backoff
+dhclient-initial-random-delay-option
#ldap backend for dhcp3 server (docs and code)
dhcp-3.1.0-ldap-docs
dhcp-3.1.0-ldap-code
diff -Naur dhcp3-3.1.1.orig/debian/patches/dhclient-fix-backoff.dpatch dhcp3-3.1.1/debian/patches/dhclient-fix-backoff.dpatch
--- dhcp3-3.1.1.orig/debian/patches/dhclient-fix-backoff.dpatch 1969-12-31 16:00:00.000000000 -0800
+++ dhcp3-3.1.1/debian/patches/dhclient-fix-backoff.dpatch 2009-03-05 11:44:25.000000000 -0800
@@ -0,0 +1,101 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## dhclient-fix-backoff.dpatch by Michel Lespinasse <[email protected]>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Patch from http://bugs.debian.org/509089:
+## DP:
+## DP: dhcp3-client-1.diff fixes the delays between consecutive requests
+## DP: (the backoff algorithm). This algorithm is best explained in the
+## DP: following code comment:
+## DP: /* If we're supposed to increase the interval, do so. If it's
+## DP: currently zero (i.e., we haven't sent any packets yet), set
+## DP: it to initial_interval; otherwise, add to it a random number
+## DP: between zero and two times itself. On average, this means
+## DP: that it will double with every transmission. */
+## DP: However contrary to what the comment indicates, client->interval has
+## DP: been initialised, before the first request is sent, to the initial_interval
+## DP: value rather than to 0. Because of that, the delay between the first two
+## DP: requests is, on average, double of the initial_interval value, instead of
+## DP: being equal to the initial_interval value. I'm proposing to change the
+## DP: initialization value to zero, in order to match the programmers expectations
+## DP: as documented in that comment, and to have the initial-interval option
+## DP: in dhclient.conf work as per the documented behavior.
+## DP:
+## DP: Additionally, I'm proposing to enforce that the delay between consecutive
+## DP: requests is always at least one second - this was already the case when
+## DP: using the default values, but could be messed with if setting an
+## DP: initial-interval of 0 or a backoff-cutoff of 1. Some people
+## DP: (see for example http://syn.theti.ca/ ) have been suggesting to use
+## DP: a backoff-cutoff of 1, so such configurations do exist in the wild.
+
+...@dpatch@
+diff -ru dhcp3-3.1.1.orig/client/dhclient.c dhcp3-3.1.1/client/dhclient.c
+--- dhcp3-3.1.1.orig/client/dhclient.c 2008-12-16 22:06:57.000000000 -0800
++++ dhcp3-3.1.1/client/dhclient.c 2008-12-16 23:44:39.000000000 -0800
+@@ -578,7 +579,7 @@
+ make_request (client, client -> active);
+ client -> destination = iaddr_broadcast;
+ client -> first_sending = cur_time;
+- client -> interval = client -> config -> initial_interval;
++ client -> interval = 0;
+
+ /* Zap the medium list... */
+ client -> medium = (struct string_list *)0;
+@@ -604,7 +605,7 @@
+ client -> destination = iaddr_broadcast;
+ client -> state = S_SELECTING;
+ client -> first_sending = cur_time;
+- client -> interval = client -> config -> initial_interval;
++ client -> interval = 0;
+
+ /* Add an immediate timeout to cause the first DHCPDISCOVER packet
+ to go out. */
+@@ -676,7 +677,7 @@
+ client -> destination = iaddr_broadcast;
+ client -> state = S_REQUESTING;
+ client -> first_sending = cur_time;
+- client -> interval = client -> config -> initial_interval;
++ client -> interval = 0;
+
+ /* Make a DHCPREQUEST packet from the lease we picked. */
+ make_request (client, picked);
+@@ -947,7 +948,7 @@
+ client -> destination = iaddr_broadcast;
+
+ client -> first_sending = cur_time;
+- client -> interval = client -> config -> initial_interval;
++ client -> interval = 0;
+ client -> state = S_RENEWING;
+
+ /* Send the first packet immediately. */
+@@ -1487,6 +1488,10 @@
+ (client -> first_sending +
+ client -> config -> timeout) - cur_time + 1;
+
++ /* Make sure the computed interval is at least one second. */
++ if (!client->interval)
++ client->interval = 1;
++
+ /* Record the number of seconds since we started sending. */
+ if (interval < 65536)
+ client -> packet.secs = htons (interval);
+@@ -1714,6 +1719,10 @@
+ client -> interval =
+ client -> active -> expiry - cur_time + 1;
+
++ /* Make sure the computed interval is at least one second. */
++ if (!client->interval)
++ client->interval = 1;
++
+ /* If the lease T2 time has elapsed, or if we're not yet bound,
+ broadcast the DHCPREQUEST rather than unicasting. */
+ if (client -> state == S_REQUESTING ||
+@@ -2882,7 +2891,7 @@
+ } else
+ client -> destination = iaddr_broadcast;
+ client -> first_sending = cur_time;
+- client -> interval = client -> config -> initial_interval;
++ client -> interval = 0;
+
+ /* Zap the medium list... */
+ client -> medium = (struct string_list *)0;
diff -Naur dhcp3-3.1.1.orig/debian/patches/dhclient-initial-random-delay-option.dpatch dhcp3-3.1.1/debian/patches/dhclient-initial-random-delay-option.dpatch
--- dhcp3-3.1.1.orig/debian/patches/dhclient-initial-random-delay-option.dpatch 1969-12-31 16:00:00.000000000 -0800
+++ dhcp3-3.1.1/debian/patches/dhclient-initial-random-delay-option.dpatch 2009-03-05 11:44:11.000000000 -0800
@@ -0,0 +1,104 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## dhclient-initial-random-delay-option.dpatch by Michel Lespinasse <[email protected]>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Patch from http://bugs.debian.org/509089:
+## DP:
+## DP: dhcp3-client-2.diff fixes a separate issue: the dhcp client was waiting
+## DP: a random delay, between 0 and 4 seconds, before sending the first dhcp
+## DP: request. The maximum delay was hardcoded and this behavior was not documented
+## DP: anywhere, but my guess is that this may have been intended to reduce dhcp
+## DP: floods when a large number of machines boot at the same time, following
+## DP: a power failure for example. It seems to me however, that such a delay is
+## DP: not necessary in many common situations, such as when running on a laptop
+## DP: with its own battery... I don't feel bold enough to just remove that random
+## DP: delay, but I think adding a new dhclient.conf option named
+## DP: initial-random-delay, which would default to 4 but be user-settable to
+## DP: any desired maximum random delay value, including 0 for no delay,
+## DP: is a reasonable proposal. Laptop users could then be encouraged to use
+## DP: initial-random-delay = 0.
+
+...@dpatch@
+diff -ru dhcp3-3.1.1.orig/client/clparse.c dhcp3-3.1.1/client/clparse.c
+--- dhcp3-3.1.1.orig/client/clparse.c 2008-12-16 22:06:57.000000000 -0800
++++ dhcp3-3.1.1/client/clparse.c 2008-12-16 23:21:38.000000000 -0800
+@@ -78,6 +78,7 @@
+ top_level_config.reboot_timeout = 10;
+ top_level_config.retry_interval = 300;
+ top_level_config.backoff_cutoff = 15;
++ top_level_config.initial_random_delay = 4;
+ top_level_config.initial_interval = 3;
+ top_level_config.bootp_policy = P_ACCEPT;
+ top_level_config.script_name = path_dhclient_script;
+@@ -477,6 +478,11 @@
+ parse_lease_time (cfile, &config -> backoff_cutoff);
+ return;
+
++ case INITIAL_RANDOM_DELAY:
++ token = next_token (&val, (unsigned *)0, cfile);
++ parse_lease_time (cfile, &config -> initial_random_delay);
++ return;
++
+ case INITIAL_INTERVAL:
+ token = next_token (&val, (unsigned *)0, cfile);
+ parse_lease_time (cfile, &config -> initial_interval);
+diff -ru dhcp3-3.1.1.orig/client/dhclient.c dhcp3-3.1.1/client/dhclient.c
+--- dhcp3-3.1.1.orig/client/dhclient.c 2008-12-16 22:06:57.000000000 -0800
++++ dhcp3-3.1.1/client/dhclient.c 2008-12-16 23:44:39.000000000 -0800
+@@ -424,7 +424,8 @@
+ client -> state = S_INIT;
+ /* Set up a timeout to start the initialization
+ process. */
+- add_timeout (cur_time + random () % 5,
++ add_timeout (cur_time + random () %
++ (client->config->initial_random_delay+1),
+ state_reboot, client, 0, 0);
+ }
+ }
+@@ -3004,7 +3013,8 @@
+ client -> state = S_INIT;
+ /* Set up a timeout to start the initialization
+ process. */
+- add_timeout (cur_time + random () % 5,
++ add_timeout (cur_time + random () %
++ (client->config->initial_random_delay+1),
+ state_reboot, client, 0, 0);
+ }
+ }
+diff -ru dhcp3-3.1.1.orig/common/conflex.c dhcp3-3.1.1/common/conflex.c
+--- dhcp3-3.1.1.orig/common/conflex.c 2008-12-16 22:06:57.000000000 -0800
++++ dhcp3-3.1.1/common/conflex.c 2008-12-16 23:20:19.000000000 -0800
+@@ -804,6 +804,8 @@
+ return IS;
+ if (!strcasecmp (atom + 1, "gnore"))
+ return IGNORE;
++ if (!strcasecmp (atom + 1, "nitial-random-delay"))
++ return INITIAL_RANDOM_DELAY;
+ break;
+ case 'k':
+ if (!strncasecmp (atom + 1, "nown", 4)) {
+diff -ru dhcp3-3.1.1.orig/includes/dhcpd.h dhcp3-3.1.1/includes/dhcpd.h
+--- dhcp3-3.1.1.orig/includes/dhcpd.h 2008-12-16 22:06:59.000000000 -0800
++++ dhcp3-3.1.1/includes/dhcpd.h 2008-12-16 23:18:05.000000000 -0800
+@@ -839,6 +839,8 @@
+ TIME timeout; /* Start to panic if we don't get a
+ lease in this time period when
+ SELECTING. */
++ TIME initial_random_delay; /* Maximum random delay before sending
++ first request. */
+ TIME initial_interval; /* All exponential backoff intervals
+ start here. */
+ TIME retry_interval; /* If the protocol failed to produce
+diff -ru dhcp3-3.1.1.orig/includes/dhctoken.h dhcp3-3.1.1/includes/dhctoken.h
+--- dhcp3-3.1.1.orig/includes/dhctoken.h 2008-12-16 22:06:59.000000000 -0800
++++ dhcp3-3.1.1/includes/dhctoken.h 2008-12-16 23:19:25.000000000 -0800
+@@ -325,7 +325,8 @@
+ MIN_BALANCE = 629,
+ DOMAIN_LIST = 630,
+ LEASEQUERY = 631,
+- EXECUTE = 632
++ EXECUTE = 632,
++ INITIAL_RANDOM_DELAY = 633
+ };
+
+ #define is_identifier(x) ((x) >= FIRST_TOKEN && \