(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);
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;
}
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);
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;
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;
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);
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:
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;
}
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;
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);
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;
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)
*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;
}