diff options
-rw-r--r-- | src/n-dhcp4/src/n-dhcp4-c-probe.c | 15 | ||||
-rw-r--r-- | src/n-dhcp4/src/n-dhcp4-private.h | 1 |
2 files changed, 14 insertions, 2 deletions
diff --git a/src/n-dhcp4/src/n-dhcp4-c-probe.c b/src/n-dhcp4/src/n-dhcp4-c-probe.c index dcd51c6f3e..284aa428e9 100644 --- a/src/n-dhcp4/src/n-dhcp4-c-probe.c +++ b/src/n-dhcp4/src/n-dhcp4-c-probe.c @@ -1089,6 +1089,7 @@ int n_dhcp4_client_probe_transition_accept(NDhcp4ClientProbe *probe, NDhcp4Incom return r; probe->state = N_DHCP4_CLIENT_PROBE_STATE_BOUND; + probe->ns_decline_restart_delay = 0; n_dhcp4_client_lease_unlink(probe->current_lease); n_dhcp4_client_arm_timer(probe->client); @@ -1128,11 +1129,21 @@ int n_dhcp4_client_probe_transition_decline(NDhcp4ClientProbe *probe, NDhcp4Inco else request = NULL; /* consumed */ - /* XXX: what state to transition to? */ - n_dhcp4_client_lease_unlink(probe->current_lease); probe->current_lease = n_dhcp4_client_lease_unref(probe->current_lease); + probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT; + + /* RFC2131, 3.1, 5.) The client SHOULD wait a minimum of ten seconds before restarting + * the configuration process to avoid excessive network traffic in case of looping. + * + * Let's go beyond that, and use an exponential backoff. */ + probe->ns_decline_restart_delay = C_CLAMP(probe->ns_decline_restart_delay * 2u, + UINT64_C(10) * UINT64_C(1000000000), + UINT64_C(300) * UINT64_C(1000000000)); + probe->ns_deferred = n_dhcp4_gettime(CLOCK_BOOTTIME) + probe->ns_decline_restart_delay; + + n_dhcp4_client_arm_timer(probe->client); return 0; case N_DHCP4_CLIENT_PROBE_STATE_INIT: diff --git a/src/n-dhcp4/src/n-dhcp4-private.h b/src/n-dhcp4/src/n-dhcp4-private.h index 858c3d3ab0..6b366884be 100644 --- a/src/n-dhcp4/src/n-dhcp4-private.h +++ b/src/n-dhcp4/src/n-dhcp4-private.h @@ -378,6 +378,7 @@ struct NDhcp4ClientProbe { uint64_t ns_deferred; /* timeout for deferred action */ uint64_t ns_reinit; uint64_t ns_nak_restart_delay; /* restart delay after a nak */ + uint64_t ns_decline_restart_delay; /* restart delay after a decline */ NDhcp4ClientLease *current_lease; /* current lease */ NDhcp4CConnection connection; /* client connection wrapper */ |