[systemd-devel] [PATCH 1/3] sd-dhcp6-client: Implement Elapsed Time option
Tom Gundersen
teg at jklm.no
Tue Sep 9 04:39:58 PDT 2014
Hi Patrik,
These all look good. Please push!
Cheers,
Tom
On Mon, Sep 1, 2014 at 12:21 PM, Patrik Flykt
<patrik.flykt at linux.intel.com> wrote:
> Implement Elapsed Time option as it is defined as MUST in RFC 3315,
> section 22.9. The elapsed time value is a 1/100th of a second with
> a max value of 0xffff, i.e. 655.35 seconds.
>
> As the main loop might not be running yet when sd_dhcp6_client_start() is
> called, fetch the monotonic time directly and not from the event loop
> while in state DHCP6_STATE_STOPPED.
> ---
> src/libsystemd-network/sd-dhcp6-client.c | 40 ++++++++++++++++++++++++--------
> 1 file changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
> index 6860c66..c190b56 100644
> --- a/src/libsystemd-network/sd-dhcp6-client.c
> +++ b/src/libsystemd-network/sd-dhcp6-client.c
> @@ -49,6 +49,7 @@ struct sd_dhcp6_client {
> struct ether_addr mac_addr;
> DHCP6IA ia_na;
> be32_t transaction_id;
> + usec_t transaction_start;
> struct sd_dhcp6_lease *lease;
> int fd;
> be16_t *req_opts;
> @@ -203,6 +204,7 @@ static int client_reset(sd_dhcp6_client *client) {
> client->fd = safe_close(client->fd);
>
> client->transaction_id = 0;
> + client->transaction_start = 0;
>
> client->ia_na.timeout_t1 =
> sd_event_source_unref(client->ia_na.timeout_t1);
> @@ -230,13 +232,15 @@ static void client_stop(sd_dhcp6_client *client, int error) {
> client_reset(client);
> }
>
> -static int client_send_message(sd_dhcp6_client *client) {
> +static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
> _cleanup_free_ DHCP6Message *message = NULL;
> struct in6_addr all_servers =
> IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
> size_t len, optlen = 512;
> uint8_t *opt;
> int r;
> + usec_t elapsed_usec;
> + be16_t elapsed_time;
>
> len = sizeof(DHCP6Message) + optlen;
>
> @@ -308,6 +312,17 @@ static int client_send_message(sd_dhcp6_client *client) {
> if (r < 0)
> return r;
>
> + elapsed_usec = time_now - client->transaction_start;
> + if (elapsed_usec < 0xffff * USEC_PER_MSEC * 10)
> + elapsed_time = htobe16(elapsed_usec / USEC_PER_MSEC / 10);
> + else
> + elapsed_time = 0xffff;
> +
> + r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ELAPSED_TIME,
> + sizeof(elapsed_time), &elapsed_time);
> + if (r < 0)
> + return r;
> +
> r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message,
> len - optlen);
> if (r < 0)
> @@ -455,15 +470,14 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
> return 0;
> }
>
> - r = client_send_message(client);
> - if (r >= 0)
> - client->retransmit_count++;
> -
> -
> r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
> if (r < 0)
> goto error;
>
> + r = client_send_message(client, time_now);
> + if (r >= 0)
> + client->retransmit_count++;
> +
> if (!client->retransmit_time) {
> client->retransmit_time =
> client_timeout_compute_random(init_retransmit_time);
> @@ -882,6 +896,15 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
> client->retransmit_time = 0;
> client->retransmit_count = 0;
>
> + if (client->state == DHCP6_STATE_STOPPED) {
> + time_now = now(clock_boottime_or_monotonic());
> + } else {
> + r = sd_event_now(client->event, clock_boottime_or_monotonic(),
> + &time_now);
> + if (r < 0)
> + return r;
> + }
> +
> switch (state) {
> case DHCP6_STATE_STOPPED:
> case DHCP6_STATE_SOLICITATION:
> @@ -926,10 +949,6 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
>
> case DHCP6_STATE_BOUND:
>
> - r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
> - if (r < 0)
> - return r;
> -
> if (client->lease->ia.lifetime_t1 == 0xffffffff ||
> client->lease->ia.lifetime_t2 == 0xffffffff) {
>
> @@ -996,6 +1015,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
> }
>
> client->transaction_id = random_u32() & htobe32(0x00ffffff);
> + client->transaction_start = time_now;
>
> r = sd_event_add_time(client->event, &client->timeout_resend,
> clock_boottime_or_monotonic(), 0, 0, client_timeout_resend,
> --
> 1.9.1
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
More information about the systemd-devel
mailing list