dhcp: Cancel old renewal timeout prior to adding a new one
authorGrant Erickson <marathon96@gmail.com>
Thu, 2 Jun 2011 04:16:13 +0000 (21:16 -0700)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 14 Jun 2011 09:26:27 +0000 (11:26 +0200)
Given the following reproduction steps:

    1) Set up an access point with a Class B IP address, say
       10.2.40.254.
    2) Set up the access point to provide DHCP leases over a range
       10.2.40.2 through 10.2.40.253.
    3) Set up a short lease renewal period of 5-10 minutes.
    4) Allow the device to associate, connect and receive an IP
       address.
    5) Midway through the lease interval, change the access point to a
       different IP address, say, 10.2.41.254.
    6) Change the access point to issue DHCP leases over a new range,
       10.2.41.2 through 10.2.41.253.
    7) Watch as the access point resets, the connection is lost, the
       connection is regained and as connman tries to get a new DHCP
       lease.

Prior to commit 39825846, connman could receive a new but different
DHCP lease but connman would not program the confirmed lease to the
interface.

However, following that commit, it now programs the new, changed DHCP
lease to the interface but still believes the old lease is valid and
attempts to keep servicing the old renewal timeout for the prior but
now stale lease.

This patch cancels any existing, pending DHCP lease renewal timeout
following a DHCP lease configuration change.

gdhcp/client.c

index 4a873bf..0cf39cd 100644 (file)
@@ -944,6 +944,9 @@ static gboolean start_renew_timeout(gpointer user_data)
        else {
                send_renew(dhcp_client);
 
+               if (dhcp_client->timeout > 0)
+                       g_source_remove(dhcp_client->timeout);
+
                dhcp_client->timeout =
                                g_timeout_add_seconds_full(G_PRIORITY_HIGH,
                                                dhcp_client->lease_seconds >> 1,
@@ -961,6 +964,9 @@ static void start_bound(GDHCPClient *dhcp_client)
 
        dhcp_client->state = BOUND;
 
+       if (dhcp_client->timeout > 0)
+               g_source_remove(dhcp_client->timeout);
+
        dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
                                        dhcp_client->lease_seconds >> 1,
                                        start_renew_timeout, dhcp_client,