[systemd-devel] [PATCH v2 19/26] dhcp: Add timeout and main loop support

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Mon Nov 25 20:32:20 PST 2013


On Mon, Nov 25, 2013 at 09:13:35AM +0200, Patrik Flykt wrote:
> Require a main loop to be set when creating a DHCP client. Set up
> a timer to resend DHCP Discover messages and add a 0-2 second
> delay to the timeout value. Move to state Selecting after successful
> sending of a Discover message.
> ---
> v2: - previous 20/28
>     - use usec_t
>     - adding monotonic event with timeout 0 seems to keep calling the
>       timeout function continuosly, use now() for the time being
> 
>  src/dhcp/client.c            |   74 ++++++++++++++++++++++++++++++++++++++++--
>  src/dhcp/test-dhcp-client.c  |   19 +++++++----
>  src/systemd/sd-dhcp-client.h |    4 ++-
>  3 files changed, 87 insertions(+), 10 deletions(-)
> 
> diff --git a/src/dhcp/client.c b/src/dhcp/client.c
> index 8735efe..7af0075 100644
> --- a/src/dhcp/client.c
> +++ b/src/dhcp/client.c
> @@ -34,12 +34,15 @@
>  
>  struct DHCPClient {
>          DHCPState state;
> +        sd_event *event;
> +        sd_event_source *timeout_resend;
>          int index;
>          uint8_t *req_opts;
>          size_t req_opts_size;
>          uint32_t last_addr;
>          struct ether_addr mac_addr;
>          uint32_t xid;
> +        usec_t start_time;
>  };
>  
>  static const uint8_t default_req_opts[] = {
> @@ -124,6 +127,8 @@ static int client_stop(DHCPClient *client, int error)
>          assert_return(client->state != DHCP_STATE_INIT &&
>                        client->state != DHCP_STATE_INIT_REBOOT, -EALREADY);
>  
> +        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
> +
>          switch (client->state) {
>  
>          case DHCP_STATE_INIT:
> @@ -277,8 +282,59 @@ static int client_send_discover(DHCPClient *client, uint16_t secs)
>          return 0;
>  }
>  
> +static int client_timeout_resend(sd_event_source *s, uint64_t usec,
> +                                 void *userdata)
> +{
> +        DHCPClient *client = userdata;
> +        usec_t next_timeout;
> +        uint16_t secs;
> +        int err = 0;
> +
> +        switch (client->state) {
> +        case DHCP_STATE_INIT:
> +        case DHCP_STATE_SELECTING:
> +
> +                if (!client->start_time)
> +                        client->start_time = usec;
> +
> +                secs = (usec - client->start_time) / USEC_PER_SEC;
> +
> +                next_timeout = usec + 2 * USEC_PER_SEC + (random() & 0x1fffff);
> +
> +                err = sd_event_add_monotonic(client->event, next_timeout,
> +                                             10 * USEC_PER_MSEC,
> +                                             client_timeout_resend, client,
> +                                             &client->timeout_resend);
> +                if (err < 0)
> +                        goto error;
> +
> +                if (client_send_discover(client, secs) >= 0)
> +                        client->state = DHCP_STATE_SELECTING;
> +
> +                break;
> +
> +        case DHCP_STATE_INIT_REBOOT:
> +        case DHCP_STATE_REBOOTING:
> +        case DHCP_STATE_REQUESTING:
> +        case DHCP_STATE_BOUND:
> +        case DHCP_STATE_RENEWING:
> +        case DHCP_STATE_REBINDING:
> +
> +                break;
> +        }
> +
> +        return 0;
> +
> +error:
> +        client_stop(client, err);
> +
> +        return 0;
Return err?

Zbyszek


More information about the systemd-devel mailing list