sd-dhcp6-client: set lease expiration timer in client_enter_bound_state()
The timer must be active until the client get re-enter bound state, and the timeout must be determined by the lease acquired when entering the bound state.
This commit is contained in:
@@ -98,8 +98,6 @@ typedef struct sd_dhcp6_client {
|
||||
uint16_t arp_type;
|
||||
DHCP6IA ia_na;
|
||||
DHCP6IA ia_pd;
|
||||
sd_event_source *timeout_t1;
|
||||
sd_event_source *timeout_t2;
|
||||
DHCP6RequestIA request_ia;
|
||||
be32_t transaction_id;
|
||||
usec_t transaction_start;
|
||||
@@ -117,7 +115,9 @@ typedef struct sd_dhcp6_client {
|
||||
usec_t retransmit_time;
|
||||
uint8_t retransmit_count;
|
||||
sd_event_source *timeout_resend;
|
||||
sd_event_source *timeout_resend_expire;
|
||||
sd_event_source *timeout_expire;
|
||||
sd_event_source *timeout_t1;
|
||||
sd_event_source *timeout_t2;
|
||||
sd_dhcp6_client_callback_t callback;
|
||||
void *userdata;
|
||||
struct duid duid;
|
||||
|
||||
@@ -25,7 +25,7 @@ struct sd_dhcp6_lease {
|
||||
triple_timestamp timestamp;
|
||||
usec_t lifetime_t1;
|
||||
usec_t lifetime_t2;
|
||||
usec_t max_retransmit_duration;
|
||||
usec_t lifetime_valid;
|
||||
struct in6_addr server_address;
|
||||
|
||||
DHCP6IA *ia_na;
|
||||
@@ -49,8 +49,7 @@ void dhcp6_ia_clear_addresses(DHCP6IA *ia);
|
||||
DHCP6IA *dhcp6_ia_free(DHCP6IA *ia);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DHCP6IA*, dhcp6_ia_free);
|
||||
|
||||
int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2);
|
||||
int dhcp6_lease_get_max_retransmit_duration(sd_dhcp6_lease *lease, usec_t *ret);
|
||||
int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2, usec_t *ret_valid);
|
||||
|
||||
int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len);
|
||||
int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len);
|
||||
|
||||
@@ -597,7 +597,7 @@ static void client_reset(sd_dhcp6_client *client) {
|
||||
|
||||
(void) event_source_disable(client->receive_message);
|
||||
(void) event_source_disable(client->timeout_resend);
|
||||
(void) event_source_disable(client->timeout_resend_expire);
|
||||
(void) event_source_disable(client->timeout_expire);
|
||||
(void) event_source_disable(client->timeout_t1);
|
||||
(void) event_source_disable(client->timeout_t2);
|
||||
|
||||
@@ -811,6 +811,31 @@ static usec_t client_timeout_compute_random(usec_t val) {
|
||||
return usec_sub_unsigned(val, random_u64_range(val / 10));
|
||||
}
|
||||
|
||||
static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
sd_dhcp6_client *client = userdata;
|
||||
DHCP6_CLIENT_DONT_DESTROY(client);
|
||||
DHCP6State state;
|
||||
|
||||
assert(s);
|
||||
assert(client);
|
||||
assert(client->event);
|
||||
|
||||
(void) event_source_disable(client->timeout_expire);
|
||||
(void) event_source_disable(client->timeout_t2);
|
||||
(void) event_source_disable(client->timeout_t1);
|
||||
|
||||
state = client->state;
|
||||
|
||||
client_stop(client, SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE);
|
||||
|
||||
/* RFC 3315, section 18.1.4., says that "...the client may choose to
|
||||
use a Solicit message to locate a new DHCP server..." */
|
||||
if (state == DHCP6_STATE_REBIND)
|
||||
client_set_state(client, DHCP6_STATE_SOLICITATION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
sd_dhcp6_client *client = userdata;
|
||||
|
||||
@@ -845,7 +870,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
|
||||
}
|
||||
|
||||
static int client_enter_bound_state(sd_dhcp6_client *client) {
|
||||
usec_t lifetime_t1, lifetime_t2;
|
||||
usec_t lifetime_t1, lifetime_t2, lifetime_valid;
|
||||
int r;
|
||||
|
||||
assert(client);
|
||||
@@ -856,10 +881,9 @@ static int client_enter_bound_state(sd_dhcp6_client *client) {
|
||||
DHCP6_STATE_RENEW,
|
||||
DHCP6_STATE_REBIND));
|
||||
|
||||
(void) event_source_disable(client->timeout_resend_expire);
|
||||
(void) event_source_disable(client->timeout_resend);
|
||||
|
||||
r = dhcp6_lease_get_lifetime(client->lease, &lifetime_t1, &lifetime_t2);
|
||||
r = dhcp6_lease_get_lifetime(client->lease, &lifetime_t1, &lifetime_t2, &lifetime_valid);
|
||||
if (r < 0)
|
||||
goto error;
|
||||
|
||||
@@ -894,6 +918,21 @@ static int client_enter_bound_state(sd_dhcp6_client *client) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (lifetime_valid == USEC_INFINITY) {
|
||||
log_dhcp6_client(client, "Infinite valid lifetime");
|
||||
event_source_disable(client->timeout_expire);
|
||||
} else {
|
||||
log_dhcp6_client(client, "Valid lifetime expires in %s", FORMAT_TIMESPAN(lifetime_valid, USEC_PER_SEC));
|
||||
|
||||
r = event_reset_time_relative(client->event, &client->timeout_expire,
|
||||
clock_boottime_or_monotonic(),
|
||||
lifetime_valid, USEC_PER_SEC,
|
||||
client_timeout_expire, client,
|
||||
client->event_priority, "dhcp6-lease-expire", true);
|
||||
if (r < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
client->state = DHCP6_STATE_BOUND;
|
||||
client_notify(client, SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE);
|
||||
return 0;
|
||||
@@ -903,36 +942,13 @@ error:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
sd_dhcp6_client *client = userdata;
|
||||
DHCP6_CLIENT_DONT_DESTROY(client);
|
||||
DHCP6State state;
|
||||
|
||||
assert(s);
|
||||
assert(client);
|
||||
assert(client->event);
|
||||
|
||||
state = client->state;
|
||||
|
||||
client_stop(client, SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE);
|
||||
|
||||
/* RFC 3315, section 18.1.4., says that "...the client may choose to
|
||||
use a Solicit message to locate a new DHCP server..." */
|
||||
if (state == DHCP6_STATE_REBIND)
|
||||
client_set_state(client, DHCP6_STATE_SOLICITATION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
int r = 0;
|
||||
sd_dhcp6_client *client = userdata;
|
||||
sd_dhcp6_client *client = ASSERT_PTR(userdata);
|
||||
usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0;
|
||||
usec_t max_retransmit_duration = 0;
|
||||
uint8_t max_retransmit_count = 0;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
assert(client);
|
||||
assert(client->event);
|
||||
|
||||
(void) event_source_disable(client->timeout_resend);
|
||||
@@ -977,14 +993,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
|
||||
init_retransmit_time = DHCP6_REB_TIMEOUT;
|
||||
max_retransmit_time = DHCP6_REB_MAX_RT;
|
||||
|
||||
if (event_source_is_enabled(client->timeout_resend_expire) <= 0) {
|
||||
r = dhcp6_lease_get_max_retransmit_duration(client->lease, &max_retransmit_duration);
|
||||
if (r < 0) {
|
||||
client_stop(client, r);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Also, instead of setting MRD, the expire timer is already set in client_enter_bound_state(). */
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_STOPPED:
|
||||
@@ -1034,24 +1043,10 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
|
||||
if (r < 0)
|
||||
goto error;
|
||||
|
||||
if (max_retransmit_duration > 0 && event_source_is_enabled(client->timeout_resend_expire) <= 0) {
|
||||
|
||||
log_dhcp6_client(client, "Max retransmission duration %"PRIu64" secs",
|
||||
max_retransmit_duration / USEC_PER_SEC);
|
||||
|
||||
r = event_reset_time(client->event, &client->timeout_resend_expire,
|
||||
clock_boottime_or_monotonic(),
|
||||
time_now + max_retransmit_duration, USEC_PER_SEC,
|
||||
client_timeout_resend_expire, client,
|
||||
client->event_priority, "dhcp6-resend-expire-timer", true);
|
||||
if (r < 0)
|
||||
goto error;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (r < 0)
|
||||
client_stop(client, r);
|
||||
|
||||
client_stop(client, r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1347,7 +1342,6 @@ static int client_set_state(sd_dhcp6_client *client, DHCP6State state) {
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
(void) event_source_disable(client->timeout_resend_expire);
|
||||
(void) event_source_disable(client->timeout_resend);
|
||||
client->retransmit_time = 0;
|
||||
client->retransmit_count = 0;
|
||||
@@ -1508,7 +1502,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
|
||||
|
||||
sd_event_source_disable_unref(client->receive_message);
|
||||
sd_event_source_disable_unref(client->timeout_resend);
|
||||
sd_event_source_disable_unref(client->timeout_resend_expire);
|
||||
sd_event_source_disable_unref(client->timeout_expire);
|
||||
sd_event_source_disable_unref(client->timeout_t1);
|
||||
sd_event_source_disable_unref(client->timeout_t2);
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static usec_t sec2usec(uint32_t sec) {
|
||||
return sec == UINT32_MAX ? USEC_INFINITY : sec * USEC_PER_SEC;
|
||||
}
|
||||
|
||||
static void dhcp6_lease_set_lifetime(sd_dhcp6_lease *lease) {
|
||||
uint32_t t1 = UINT32_MAX, t2 = UINT32_MAX, min_valid_lt = UINT32_MAX;
|
||||
DHCP6Address *a;
|
||||
@@ -66,14 +70,12 @@ static void dhcp6_lease_set_lifetime(sd_dhcp6_lease *lease) {
|
||||
t2 = min_valid_lt / 10 * 8;
|
||||
}
|
||||
|
||||
assert(t2 <= min_valid_lt);
|
||||
lease->max_retransmit_duration = (min_valid_lt - t2) * USEC_PER_SEC;
|
||||
|
||||
lease->lifetime_t1 = t1 == UINT32_MAX ? USEC_INFINITY : t1 * USEC_PER_SEC;
|
||||
lease->lifetime_t2 = t2 == UINT32_MAX ? USEC_INFINITY : t2 * USEC_PER_SEC;
|
||||
lease->lifetime_valid = sec2usec(min_valid_lt);
|
||||
lease->lifetime_t1 = sec2usec(t1);
|
||||
lease->lifetime_t2 = sec2usec(t2);
|
||||
}
|
||||
|
||||
int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2) {
|
||||
int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2, usec_t *ret_valid) {
|
||||
assert(lease);
|
||||
|
||||
if (!lease->ia_na && !lease->ia_pd)
|
||||
@@ -83,17 +85,8 @@ int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_
|
||||
*ret_t1 = lease->lifetime_t1;
|
||||
if (ret_t2)
|
||||
*ret_t2 = lease->lifetime_t2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_lease_get_max_retransmit_duration(sd_dhcp6_lease *lease, usec_t *ret) {
|
||||
assert(lease);
|
||||
|
||||
if (!lease->ia_na && !lease->ia_pd)
|
||||
return -ENODATA;
|
||||
|
||||
if (ret)
|
||||
*ret = lease->max_retransmit_duration;
|
||||
if (ret_valid)
|
||||
*ret_valid = lease->lifetime_valid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user