Both renew and rebind now consist of two parts: start_<> and
<>_request_timeout. During the start segment, we send the actual message
and schedule a timeout for REQUEST_TIMEOUT to call <>_request_timeout.
This function then divides the applicable timer by two (T2 in renew and
expire in rebind) and schedules another renew message for that time if
appropriate
---
gdhcp/client.c | 103 ++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 66 insertions(+), 37 deletions(-)
diff --git a/gdhcp/client.c b/gdhcp/client.c
index b24d19d..7d103ce 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -1646,6 +1646,7 @@ static void restart_dhcp(GDHCPClient *dhcp_client, int
retry_times)
g_dhcp_client_start(dhcp_client, dhcp_client->last_address);
}
+static gboolean start_rebound(gpointer dhcp_client);
static gboolean start_rebound_timeout(gpointer user_data)
{
GDHCPClient *dhcp_client = user_data;
@@ -1654,10 +1655,10 @@ static gboolean start_rebound_timeout(gpointer
user_data)
switch_listening_mode(dhcp_client, L2);
- dhcp_client->lease_seconds >>= 1;
+ dhcp_client->expire >>= 1;
/* We need to have enough time to receive ACK package*/
- if (dhcp_client->lease_seconds <= 6) {
+ if (dhcp_client->expire <= 60) {
/* ip need to be cleared */
if (dhcp_client->lease_lost_cb)
@@ -1666,46 +1667,69 @@ static gboolean start_rebound_timeout(gpointer
user_data)
restart_dhcp(dhcp_client, 0);
} else {
- send_rebound(dhcp_client);
-
dhcp_client->timeout =
g_timeout_add_seconds_full(G_PRIORITY_HIGH,
- dhcp_client->lease_seconds >> 1,
- start_rebound_timeout,
- dhcp_client,
- NULL);
+ dhcp_client->expire,
+ start_rebound,
+ dhcp_client,
+ NULL);
}
- return FALSE;
+ return false;
}
-static void start_rebound(GDHCPClient *dhcp_client)
+static gboolean start_rebound(gpointer user_data)
{
+ GDHCPClient *dhcp_client = user_data;
debug(dhcp_client, "start rebound");
dhcp_client->state = REBINDING;
+ if (dhcp_client->timeout > 0){
+ g_source_remove(dhcp_client->timeout);
+ }
+
+ dhcp_client->expire -= REQUEST_TIMEOUT;
+ send_rebound(dhcp_client);
dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
- dhcp_client->lease_seconds >> 1,
- start_rebound_timeout,
- dhcp_client,
- NULL);
+ REQUEST_TIMEOUT,
+ start_rebound_timeout,
+ dhcp_client,
+ NULL);
+
+ return FALSE;
}
+static gboolean start_renew(gpointer user_data);
static gboolean start_renew_request_timeout(gpointer user_data)
{
GDHCPClient *dhcp_client = user_data;
- debug(dhcp_client, "renew request timeout");
- if (dhcp_client->no_lease_cb)
+ dhcp_client->T2>>=1;
+
+ if (dhcp_client->T2 <= 60)
+ {
+ debug(dhcp_client, "renew request timeout");
+ if (dhcp_client->no_lease_cb)
dhcp_client->no_lease_cb(dhcp_client,
- dhcp_client->no_lease_data);
+ dhcp_client->no_lease_data);
+
+ start_rebound(dhcp_client);
+ } else {
+
+ /*reschedule the renew for 1/2 the renew time remaining*/
+ dhcp_client->timeout =
g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+ dhcp_client->T2,
+ start_renew,
+ dhcp_client,
+ NULL);
+ }
return false;
}
-static gboolean start_renew_timeout(gpointer user_data)
+static gboolean start_renew(gpointer user_data)
{
GDHCPClient *dhcp_client = user_data;
@@ -1713,24 +1737,20 @@ static gboolean start_renew_timeout(gpointer user_data)
dhcp_client->state = RENEWING;
- dhcp_client->lease_seconds >>= 1;
-
switch_listening_mode(dhcp_client, L3);
- if (dhcp_client->lease_seconds <= 60)
- start_rebound(dhcp_client);
- else {
- send_renew(dhcp_client);
- if (dhcp_client->timeout > 0)
- g_source_remove(dhcp_client->timeout);
+ if (dhcp_client->timeout > 0)
+ g_source_remove(dhcp_client->timeout);
- dhcp_client->timeout =
- g_timeout_add_seconds_full(G_PRIORITY_HIGH,
- REQUEST_TIMEOUT,
- start_renew_request_timeout,
- dhcp_client,
- NULL);
- }
+ send_renew(dhcp_client);
+
+ dhcp_client->T2 -= REQUEST_TIMEOUT;
+ dhcp_client->timeout =
+ g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+ REQUEST_TIMEOUT,
+ start_renew_request_timeout,
+ dhcp_client,
+ NULL);
return FALSE;
}
@@ -1744,9 +1764,18 @@ static void start_bound(GDHCPClient *dhcp_client)
if (dhcp_client->timeout > 0)
g_source_remove(dhcp_client->timeout);
+ /* TODO: T1 and T2 should be set through options instead of
+ * defaults as they are here, also note that the actual value
+ * of T2 is T1+T2. Because we don't start the T2 timer until
+ * T1 is elapsed we subtract it now while we know the original T1*/
+
+ dhcp_client->T1 = dhcp_client->lease_seconds >> 1;
+ dhcp_client->T2 = dhcp_client->lease_seconds * 0.875 - dhcp_client->T1;
+ dhcp_client->expire = dhcp_client->lease_seconds - dhcp_client->T1 -
dhcp_client->T2;
+
dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
- dhcp_client->lease_seconds >> 1,
- start_renew_timeout, dhcp_client,
+ dhcp_client->T1,
+ start_renew, dhcp_client,
NULL);
}
@@ -2583,7 +2612,7 @@ static gboolean ipv4ll_announce_timeout(gpointer
dhcp_data)
uint32_t ip;
debug(dhcp_client, "request timeout (retries %d)",
- dhcp_client->retry_times);
+ dhcp_client->retry_times);
if (dhcp_client->retry_times != ANNOUNCE_NUM) {
dhcp_client->retry_times++;
@@ -2610,7 +2639,7 @@ static gboolean ipv4ll_probe_timeout(gpointer dhcp_data)
GDHCPClient *dhcp_client = dhcp_data;
debug(dhcp_client, "IPV4LL probe timeout (retries %d)",
- dhcp_client->retry_times);
+ dhcp_client->retry_times);
if (dhcp_client->retry_times == PROBE_NUM) {
dhcp_client->state = IPV4LL_ANNOUNCE;
--
1.7.9.5
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman