From: Dan Streetman Date: Tue, 8 Dec 2020 20:40:10 +0000 (-0500) Subject: sd-dhcp-client: correct dhcpv4 renew/rebind retransmit timeouts X-Git-Tag: v248-rc1~501^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c24288d21ee94856f5c60473191d41c77b71da91;p=thirdparty%2Fsystemd.git sd-dhcp-client: correct dhcpv4 renew/rebind retransmit timeouts Use the request timeout algorithm specified in RFC2131 section 4.4.5 for handling timed out RENEW and REBIND requests. This changes behavior, as previously only 2 RENEW and 2 REBIND requests were sent, no matter how long the lease lifetime. Now, requests are send according to the RFC, which results in starting with a timeout of 1/2 the t1 or t2 period, and halving the timeout for each retry down to a minimum of 60 seconds. Fixes: #17909 --- diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 8c6affac81c..4a693ba7060 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1227,7 +1227,6 @@ static int client_timeout_resend( DHCP_CLIENT_DONT_DESTROY(client); usec_t next_timeout; uint64_t time_now; - uint32_t time_left; int r; assert(s); @@ -1241,19 +1240,11 @@ static int client_timeout_resend( switch (client->state) { case DHCP_STATE_RENEWING: - time_left = (client->lease->t2 - client->lease->t1) / 2; - if (time_left < 60) - time_left = 60; - - next_timeout = time_now + time_left * USEC_PER_SEC; + next_timeout = client_compute_reacquisition_timeout(time_now, client->t2_time); break; case DHCP_STATE_REBINDING: - time_left = (client->lease->lifetime - client->lease->t2) / 2; - if (time_left < 60) - time_left = 60; - - next_timeout = time_now + time_left * USEC_PER_SEC; + next_timeout = client_compute_reacquisition_timeout(time_now, client->expire_time); break; case DHCP_STATE_REBOOTING: @@ -1279,6 +1270,7 @@ static int client_timeout_resend( client->attempt++; next_timeout = time_now + ((UINT64_C(1) << MIN(client->attempt, (uint64_t) 6)) - 1) * USEC_PER_SEC; + next_timeout += (random_u32() & 0x1fffff); break; case DHCP_STATE_STOPPED: @@ -1286,8 +1278,6 @@ static int client_timeout_resend( goto error; } - next_timeout += (random_u32() & 0x1fffff); - r = event_reset_time(client->event, &client->timeout_resend, clock_boottime_or_monotonic(), next_timeout, 10 * USEC_PER_MSEC,