]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp-client: rework discover/request_attempts counter
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 14 Mar 2026 07:45:53 +0000 (16:45 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Apr 2026 22:40:08 +0000 (07:40 +0900)
discover_attempts should be reset only when
- the client is stopped, to make the counter starts from zero on
  the next invocation.
- we acquire a bound lease, to make the counter starts from zero
  when the lease is expired.

request_attempts should be reset only when the client enter a new state
that sends DHCPREQUEST, that is, when enter one of the REBOOTING,
REQUESTING, RENEWING, and REBINDING state.

This moves resetting counter to client_set_state() as it should happen
only when the state transition.

src/libsystemd-network/sd-dhcp-client.c

index 6ff6329ccf138a454f08ccee231a1443017f9705..ad7714d596d09103937d3a824da4087cd44f444b 100644 (file)
@@ -607,6 +607,28 @@ static void client_set_state(sd_dhcp_client *client, DHCPState state) {
 
         client->state = state;
 
+        switch (state) {
+        case DHCP_STATE_STOPPED:
+        case DHCP_STATE_BOUND:
+                /* In these cases, the next DHCPDISCOVER message will be sent in a new cycle.
+                 * Hence, clear the counter for DHCPDISCOVER messages. */
+                client->discover_attempt = 0;
+                break;
+
+        case DHCP_STATE_REBOOTING:
+        case DHCP_STATE_REQUESTING:
+        case DHCP_STATE_RENEWING:
+        case DHCP_STATE_REBINDING:
+                /* In these cases, the next DHCPREQUEST message will be the first message in this new state.
+                 * Hence, clear the counter for DHCPREQUEST messages. */
+                client->request_attempt = 0;
+                break;
+
+        default:
+                /* otherwise, do not reset the counters. */
+                ;
+        }
+
         if (client->state_callback)
                 client->state_callback(client, state, client->state_userdata);
 }
@@ -642,9 +664,6 @@ static void client_initialize(sd_dhcp_client *client) {
 
         client_disable_event_sources(client);
 
-        client->discover_attempt = 0;
-        client->request_attempt = 0;
-
         client_set_state(client, DHCP_STATE_STOPPED);
         client->xid = 0;
 
@@ -1385,8 +1404,6 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
         client->receive_message = sd_event_source_disable_unref(client->receive_message);
 
         client_set_state(client, DHCP_STATE_REBINDING);
-        client->discover_attempt = 0;
-        client->request_attempt = 0;
 
         return client_timeout_resend(s, usec, userdata);
 }
@@ -1396,8 +1413,6 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
         DHCP_CLIENT_DONT_DESTROY(client);
 
         client_set_state(client, DHCP_STATE_RENEWING);
-        client->discover_attempt = 0;
-        client->request_attempt = 0;
 
         return client_timeout_resend(s, usec, userdata);
 }
@@ -1598,8 +1613,6 @@ static int client_enter_requesting(sd_dhcp_client *client) {
         client_disable_event_sources(client);
 
         client_set_state(client, DHCP_STATE_REQUESTING);
-        client->discover_attempt = 0;
-        client->request_attempt = 0;
 
         if (sd_dhcp_client_is_waiting_for_ipv6_connectivity(client)) {
                 if (client->ipv6_acquired) {
@@ -1790,8 +1803,6 @@ static int client_enter_bound(sd_dhcp_client *client, int notify_event) {
         client->start_delay = 0;
 
         client_set_state(client, DHCP_STATE_BOUND);
-        client->discover_attempt = 0;
-        client->request_attempt = 0;
 
         client->last_addr = client->lease->address;
 
@@ -2030,11 +2041,9 @@ int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
         if (!sd_dhcp_client_is_running(client) || client->state != DHCP_STATE_BOUND || client->bootp)
                 return 0; /* do nothing */
 
-        client->start_delay = 0;
-        client->discover_attempt = 1;
-        client->request_attempt = 1;
         client_set_state(client, DHCP_STATE_RENEWING);
 
+        client->start_delay = 0;
         return client_initialize_time_events(client);
 }