[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