diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index d27609655f..5064bf2b4f 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1661,10 +1661,37 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *message, siz return 0; } +static int client_enter_requesting_now(sd_dhcp_client *client) { + assert(client); + + client_set_state(client, DHCP_STATE_REQUESTING); + client->attempt = 0; + + return event_reset_time(client->event, &client->timeout_resend, + CLOCK_BOOTTIME, 0, 0, + client_timeout_resend, client, + client->event_priority, "dhcp4-resend-timer", + /* force_reset = */ true); +} + +static int client_enter_requesting_delayed(sd_event_source *s, uint64_t usec, void *userdata) { + sd_dhcp_client *client = ASSERT_PTR(userdata); + DHCP_CLIENT_DONT_DESTROY(client); + int r; + + r = client_enter_requesting_now(client); + if (r < 0) + client_stop(client, r); + + return 0; +} + static int client_enter_requesting(sd_dhcp_client *client) { assert(client); assert(client->lease); + (void) event_source_disable(client->timeout_resend); + if (client->lease->ipv6_only_preferred_usec > 0) { if (client->ipv6_acquired) { log_dhcp_client(client, @@ -1675,17 +1702,16 @@ static int client_enter_requesting(sd_dhcp_client *client) { log_dhcp_client(client, "Received an OFFER with IPv6-only preferred option, delaying to send REQUEST with %s.", FORMAT_TIMESPAN(client->lease->ipv6_only_preferred_usec, USEC_PER_SEC)); + + return event_reset_time_relative(client->event, &client->timeout_ipv6_only_mode, + CLOCK_BOOTTIME, + client->lease->ipv6_only_preferred_usec, 0, + client_enter_requesting_delayed, client, + client->event_priority, "dhcp4-ipv6-only-mode-timer", + /* force_reset = */ true); } - client_set_state(client, DHCP_STATE_REQUESTING); - client->attempt = 0; - - return event_reset_time_relative(client->event, &client->timeout_resend, - CLOCK_BOOTTIME, - client->lease->ipv6_only_preferred_usec, 0, - client_timeout_resend, client, - client->event_priority, "dhcp4-resend-timer", - /* force_reset = */ true); + return client_enter_requesting_now(client); } static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) { @@ -1887,7 +1913,7 @@ static int client_enter_bound_now(sd_dhcp_client *client, int notify_event) { return 0; } -static int client_timeout_ipv6_only_mode(sd_event_source *s, uint64_t usec, void *userdata) { +static int client_enter_bound_delayed(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp_client *client = ASSERT_PTR(userdata); DHCP_CLIENT_DONT_DESTROY(client); int r; @@ -1927,7 +1953,7 @@ static int client_enter_bound(sd_dhcp_client *client, int notify_event) { return event_reset_time_relative(client->event, &client->timeout_ipv6_only_mode, CLOCK_BOOTTIME, client->lease->ipv6_only_preferred_usec, 0, - client_timeout_ipv6_only_mode, client, + client_enter_bound_delayed, client, client->event_priority, "dhcp4-ipv6-only-mode", /* force_reset = */ true); }