From: Roy Marples Date: Wed, 7 Nov 2007 10:43:35 +0000 (+0000) Subject: Implement an exponetial NAK backoff. X-Git-Tag: v3.2.3~166 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e60f94241b501d791955a8acb5e679aeafdc286;p=thirdparty%2Fdhcpcd.git Implement an exponetial NAK backoff. --- diff --git a/ChangeLog b/ChangeLog index 1c092e24..c1ed1cfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +Implement an exponential NAK backoff. Clear the signal_pipe fd from the fdset when all signals have been read. Don't release a link local address. diff --git a/client.c b/client.c index 4c3c7409..8d7b898f 100644 --- a/client.c +++ b/client.c @@ -94,6 +94,9 @@ #define STATE_RENEW_REQUESTED 6 #define STATE_RELEASED 7 +/* We should define a maximum for the NAK exponential backoff */ +#define NAKOFF_MAX 60 + #define SOCKET_CLOSED 0 #define SOCKET_OPEN 1 @@ -256,6 +259,7 @@ int dhcp_run (const options_t *options, int *pidfd) unsigned char *buffer = NULL; int buffer_len = 0; int buffer_pos = 0; + time_t nakoff = 1; if (! options || (iface = (read_interface (options->interface, options->metric))) == NULL) @@ -373,6 +377,9 @@ int dhcp_run (const options_t *options, int *pidfd) signal_setup (); while (1) { + /* Ensure our fd set is clear */ + FD_ZERO (&rset); + if (timeout > 0 || (options->timeout == 0 && (state != STATE_INIT || xid))) { @@ -710,9 +717,24 @@ int dhcp_run (const options_t *options, int *pidfd) xid = 0; free_dhcp (dhcp); memset (dhcp, 0, sizeof (dhcp_t)); + + /* If we constantly get NAKS then we should slowly back off */ + if (nakoff > 0) { + logger (LOG_DEBUG, "sleeping for %d seconds", nakoff); + tv.tv_sec = nakoff; + tv.tv_usec = 0; + nakoff *= 2; + if (nakoff > NAKOFF_MAX) + nakoff = NAKOFF_MAX; + select (0, NULL, NULL, NULL, &tv); + } + continue; } + /* No NAK, so reset the backoff */ + nakoff = 1; + switch (state) { case STATE_INIT: if (type == DHCP_OFFER) {