]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Implement an exponetial NAK backoff.
authorRoy Marples <roy@marples.name>
Wed, 7 Nov 2007 10:43:35 +0000 (10:43 +0000)
committerRoy Marples <roy@marples.name>
Wed, 7 Nov 2007 10:43:35 +0000 (10:43 +0000)
ChangeLog
client.c

index 1c092e245fdd738fbe5b6108c5422e3a604242d7..c1ed1cfb0e2abc17c3b268c95c11645d3930b6dc 100644 (file)
--- 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.
index 4c3c7409171af229eabed09e2ab10329b4a6020f..8d7b898fa74ca184556f3d82aa2deb7ca31e9e77 100644 (file)
--- 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) {