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 &&	\

Reply via email to