udhcpd: keep expired leases at startup
authorChristian Lindeberg <christian.lindeberg@axis.com>
Tue, 1 Mar 2016 18:23:22 +0000 (19:23 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 1 Mar 2016 18:23:22 +0000 (19:23 +0100)
Let udhcpd retain the information about expired leases when restarting
so that the leases are reserved until they possibly become the oldest
expired lease.

This reduces the frequency of IP address changes for example when the
DHCP server and a group of clients, who do not store and request their
previously offered IP address across restarts, are collectively restarted
and the startup order of the clients are not guaranteed.

Signed-off-by: Christian Lindeberg <christian.lindeberg@axis.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
networking/udhcp/files.c
networking/udhcp/leases.c

index 1c8808c0f1fcc911c54ec093421eb535a820c48d..5b90e26d28fd113dac2c165edccdece93010dd93 100644 (file)
@@ -195,7 +195,11 @@ void FAST_FUNC read_leases(const char *file)
                        uint32_t static_nip;
 
                        if (expires <= 0)
-                               continue;
+                               /* We keep expired leases: add_lease() will add
+                                * a lease with 0 seconds remaining.
+                                * Fewer IP address changes this way for mass reboot scenario.
+                                */
+                               expires = 0;
 
                        /* Check if there is a different static lease for this IP or MAC */
                        static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac);
index 844bb60b17f77558300c9baa9747dd5412e92f8d..411b74962fb8186967ba2cded5eb07aedfaea521 100644 (file)
@@ -17,7 +17,9 @@ static struct dyn_lease *oldest_expired_lease(void)
        /* Unexpired leases have g_leases[i].expires >= current time
         * and therefore can't ever match */
        for (i = 0; i < server_config.max_leases; i++) {
-               if (g_leases[i].expires < oldest_time) {
+               if (g_leases[i].expires == 0 /* empty entry */
+                || g_leases[i].expires < oldest_time
+               ) {
                        oldest_time = g_leases[i].expires;
                        oldest_lease = &g_leases[i];
                }