Mercurial > hg > dhcpcd
changeset 2469:5fc737832999 draft
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.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Sat, 03 May 2014 19:56:15 +0000 |
| parents | ec51834c005f |
| children | f8409fb98913 |
| files | dhcp.c dhcp.h |
| diffstat | 2 files changed, 45 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcp.c Sat May 03 19:53:22 2014 +0000 +++ b/dhcp.c Sat May 03 19:56:15 2014 +0000 @@ -1667,16 +1667,16 @@ 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 @@ } 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 @@ 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 @@ 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; @@ -2993,6 +2994,24 @@ } 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, const struct in_addr *net,
--- a/dhcp.h Sat May 03 19:53:22 2014 +0000 +++ b/dhcp.h Sat May 03 19:56:15 2014 +0000 @@ -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,
