RFC2131 section 4.4.1 states the client SHOULD wait a random time between

one and ten seconds to desynchronize the use of DHCP at startup.
Instead we wait a random time between zero and one second to mirror
the more modern IPv6RS and DHCPv6 standards unless overridden by
defining RFC2131_STRICT.
This commit is contained in:
Roy Marples 2014-05-03 19:56:15 +00:00
parent 6e6e06af14
commit d56187a6dc
2 changed files with 45 additions and 16 deletions

51
dhcp.c
View File

@ -1667,16 +1667,16 @@ send_rebind(void *arg)
void
dhcp_discover(void *arg)
{
struct interface *iface = arg;
struct dhcp_state *state = D_STATE(iface);
struct if_options *ifo = iface->options;
struct interface *ifp = arg;
struct dhcp_state *state = D_STATE(ifp);
struct if_options *ifo = ifp->options;
time_t timeout = ifo->timeout;
/* If we're rebooting and we're not daemonised then we need
* to shorten the normal timeout to ensure we try correctly
* for a fallback or IPv4LL address. */
if (state->state == DHS_REBOOT &&
!(iface->ctx->options & DHCPCD_DAEMONISED))
!(ifp->ctx->options & DHCPCD_DAEMONISED))
{
if (ifo->reboot >= timeout)
timeout = 2;
@ -1685,25 +1685,25 @@ dhcp_discover(void *arg)
}
state->state = DHS_DISCOVER;
state->xid = dhcp_xid(iface);
eloop_timeout_delete(iface->ctx->eloop, NULL, iface);
state->xid = dhcp_xid(ifp);
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
if (ifo->fallback)
eloop_timeout_add_sec(iface->ctx->eloop,
timeout, dhcp_fallback, iface);
eloop_timeout_add_sec(ifp->ctx->eloop,
timeout, dhcp_fallback, ifp);
else if (ifo->options & DHCPCD_IPV4LL &&
!IN_LINKLOCAL(htonl(state->addr.s_addr)))
{
if (IN_LINKLOCAL(htonl(state->fail.s_addr)))
timeout = RATE_LIMIT_INTERVAL;
eloop_timeout_add_sec(iface->ctx->eloop,
timeout, ipv4ll_start, iface);
eloop_timeout_add_sec(ifp->ctx->eloop,
timeout, ipv4ll_start, ifp);
}
if (ifo->options & DHCPCD_REQUEST)
syslog(LOG_INFO, "%s: soliciting a DHCP lease (requesting %s)",
iface->name, inet_ntoa(ifo->req_addr));
ifp->name, inet_ntoa(ifo->req_addr));
else
syslog(LOG_INFO, "%s: soliciting a DHCP lease", iface->name);
send_discover(iface);
syslog(LOG_INFO, "%s: soliciting a DHCP lease", ifp->name);
send_discover(ifp);
}
static void
@ -2827,7 +2827,7 @@ dhcp_init(struct interface *ifp)
LEASEFILE, ifp->name);
ifo = ifp->options;
/* We need to drop the leasefile so that start_interface
/* We need to drop the leasefile so that dhcp_start
* doesn't load it. */
if (ifo->options & DHCPCD_REQUEST)
unlink(state->leasefile);
@ -2882,9 +2882,10 @@ eexit:
return -1;
}
void
dhcp_start(struct interface *ifp)
static void
dhcp_start1(void *arg)
{
struct interface *ifp = arg;
struct if_options *ifo = ifp->options;
struct dhcp_state *state;
struct stat st;
@ -2992,6 +2993,24 @@ dhcp_start(struct interface *ifp)
dhcp_reboot(ifp);
}
void
dhcp_start(struct interface *ifp)
{
struct timeval tv;
if (!(ifp->options->options & DHCPCD_IPV4))
return;
tv.tv_sec = DHCP_MIN_DELAY;
tv.tv_usec = (suseconds_t)(arc4random() %
((DHCP_MAX_DELAY - DHCP_MIN_DELAY) * 1000000));
timernorm(&tv);
syslog(LOG_DEBUG,
"%s: delaying DHCP for %0.1f seconds",
ifp->name, timeval_to_double(&tv));
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_start1, ifp);
}
void
dhcp_handleifa(int type, struct interface *ifp,
const struct in_addr *addr,

10
dhcp.h
View File

@ -77,6 +77,16 @@
#define PROBE_MIN_U PROBE_MIN * USECS_SECOND
#define PROBE_MAX_U PROBE_MAX * USECS_SECOND
#ifdef RFC2131_STRICT
/* Be strictly conformant for section 4.1.1 */
# define DHCP_MIN_DELAY 1
# define DHCP_MAX_DELAY 10
#else
/* or mirror the more modern IPv6RS and DHCPv6 delays */
# define DHCP_MIN_DELAY 0
# define DHCP_MAX_DELAY 1
#endif
/* DHCP options */
enum DHO {
DHO_PAD = 0,