[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