From 781ca7a13feb01739a9aa8b629ff1ff7c51e74aa Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Wed, 9 Apr 2014 13:12:08 +0300 Subject: [PATCH] sd-dhcp-client: Add an explicit stop state for the DHCP client Add an explicit stop state for the DHCP client so that the library user can issue a stop at any time the callback has been called. When returning from the callback, check also the stop state and stop any further DHCP processing. --- src/libsystemd-network/dhcp-protocol.h | 1 + src/libsystemd-network/sd-dhcp-client.c | 38 +++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h index 400e953..539606c 100644 --- a/src/libsystemd-network/dhcp-protocol.h +++ b/src/libsystemd-network/dhcp-protocol.h @@ -76,6 +76,7 @@ enum DHCPState { DHCP_STATE_BOUND = 5, DHCP_STATE_RENEWING = 6, DHCP_STATE_REBINDING = 7, + DHCP_STATE_STOPPED = 8, }; typedef enum DHCPState DHCPState; diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 512bc93..afad776 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -96,7 +96,8 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { size_t i; assert_return(client, -EINVAL); - assert_return (client->state == DHCP_STATE_INIT, -EBUSY); + assert_return (IN_SET(client->state, DHCP_STATE_INIT, + DHCP_STATE_STOPPED), -EBUSY); switch(option) { case DHCP_OPTION_PAD: @@ -126,7 +127,8 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { int sd_dhcp_client_set_request_address(sd_dhcp_client *client, const struct in_addr *last_addr) { assert_return(client, -EINVAL); - assert_return(client->state == DHCP_STATE_INIT, -EBUSY); + assert_return (IN_SET(client->state, DHCP_STATE_INIT, + DHCP_STATE_STOPPED), -EBUSY); if (last_addr) client->last_addr = last_addr->s_addr; @@ -138,7 +140,8 @@ int sd_dhcp_client_set_request_address(sd_dhcp_client *client, int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) { assert_return(client, -EINVAL); - assert_return(client->state == DHCP_STATE_INIT, -EBUSY); + assert_return (IN_SET(client->state, DHCP_STATE_INIT, + DHCP_STATE_STOPPED), -EBUSY); assert_return(interface_index >= -1, -EINVAL); client->index = interface_index; @@ -156,7 +159,7 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0) return 0; - if (client->state != DHCP_STATE_INIT) { + if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { log_dhcp_client(client, "Changing MAC address on running DHCP " "client, restarting"); need_restart = true; @@ -169,7 +172,7 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, memcpy(&client->client_id.mac_addr, addr, ETH_ALEN); client->client_id.type = 0x01; - if (need_restart) + if (need_restart && client->state != DHCP_STATE_STOPPED) sd_dhcp_client_start(client); return 0; @@ -404,6 +407,9 @@ static int client_send_request(sd_dhcp_client *client) { case DHCP_STATE_REBINDING: break; + + case DHCP_STATE_STOPPED: + return -EINVAL; } r = dhcp_option_append(&opt, &optlen, DHCP_OPTION_END, 0, NULL); @@ -482,6 +488,10 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC; break; + + case DHCP_STATE_STOPPED: + r = -EINVAL; + goto error; } next_timeout += (random_u32() & 0x1fffff); @@ -540,6 +550,10 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, case DHCP_STATE_BOUND: break; + + case DHCP_STATE_STOPPED: + r = -EINVAL; + goto error; } return 0; @@ -630,8 +644,8 @@ static int client_timeout_expire(sd_event_source *s, uint64_t usec, client = client_notify(client, DHCP_EVENT_EXPIRED); - /* lease was lost, start over if not freed */ - if (client) { + /* lease was lost, start over if not freed or stopped in callback */ + if (client && client->state != DHCP_STATE_STOPPED) { client_initialize(client); client_start(client); } @@ -1046,7 +1060,8 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, if (notify_event) { client = client_notify(client, notify_event); - if (!client) + if (!client || + client->state == DHCP_STATE_STOPPED) return 0; } @@ -1064,6 +1079,10 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, case DHCP_STATE_BOUND: break; + + case DHCP_STATE_STOPPED: + r = -EINVAL; + goto error; } error: @@ -1177,7 +1196,8 @@ int sd_dhcp_client_start(sd_dhcp_client *client) { int sd_dhcp_client_stop(sd_dhcp_client *client) { assert_return(client, -EINVAL); - client_stop(client, DHCP_EVENT_STOP); + if (client_stop(client, DHCP_EVENT_STOP)) + client->state = DHCP_STATE_STOPPED; return 0; } -- 2.7.4