summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/sd-dhcp6-client.c
diff options
context:
space:
mode:
authorPatrik Flykt <patrik.flykt@linux.intel.com>2014-06-19 15:39:49 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2014-06-19 15:44:44 +0300
commitc3e2adeaba8e043caed0ef139eeaea016bd152d0 (patch)
tree422cee20fcb021aa23c983e153c6cd3be09073f8 /src/libsystemd-network/sd-dhcp6-client.c
parent859cca44f834ab1cc3e41fa6b94744f1856ab027 (diff)
sd-dhcp6-client: Update start function to take a state
Update the start function so that the client state can be conveniently changed with the previous message resend timers cleared. On initial startup also create and bind to the UDP socket.
Diffstat (limited to 'src/libsystemd-network/sd-dhcp6-client.c')
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 65679b7301..1a59cc2861 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -95,6 +95,8 @@ const char * dhcp6_message_status_table[_DHCP6_STATUS_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
+static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
+
int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
sd_dhcp6_client_cb_t cb, void *userdata)
{
@@ -161,7 +163,7 @@ static int client_initialize(sd_dhcp6_client *client)
if (client->fd > 0)
client->fd = safe_close(client->fd);
- client->transaction_id = random_u32() & 0x00ffffff;
+ client->transaction_id = 0;
client->ia_na.timeout_t1 =
sd_event_source_unref(client->ia_na.timeout_t1);
@@ -609,36 +611,53 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
return 0;
}
-static int client_start(sd_dhcp6_client *client)
+static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
{
int r;
assert_return(client, -EINVAL);
assert_return(client->event, -EINVAL);
assert_return(client->index > 0, -EINVAL);
+ assert_return(client->state != state, -EINVAL);
- r = client_ensure_iaid(client);
- if (r < 0)
- return r;
+ client->timeout_resend_expire =
+ sd_event_source_unref(client->timeout_resend_expire);
+ client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+ client->retransmit_time = 0;
+ client->retransmit_count = 0;
- r = dhcp6_network_bind_udp_socket(client->index, NULL);
- if (r < 0)
- return r;
+ switch (state) {
+ case DHCP6_STATE_STOPPED:
+ case DHCP6_STATE_RS:
+ case DHCP6_STATE_SOLICITATION:
- client->fd = r;
+ r = client_ensure_iaid(client);
+ if (r < 0)
+ return r;
- r = sd_event_add_io(client->event, &client->receive_message,
- client->fd, EPOLLIN, client_receive_message,
- client);
- if (r < 0)
- return r;
+ r = dhcp6_network_bind_udp_socket(client->index, NULL);
+ if (r < 0)
+ return r;
- r = sd_event_source_set_priority(client->receive_message,
- client->event_priority);
- if (r < 0)
- return r;
+ client->fd = r;
+
+ r = sd_event_add_io(client->event, &client->receive_message,
+ client->fd, EPOLLIN, client_receive_message,
+ client);
+ if (r < 0)
+ return r;
+
+ r = sd_event_source_set_priority(client->receive_message,
+ client->event_priority);
+ if (r < 0)
+ return r;
+
+ client->state = DHCP6_STATE_SOLICITATION;
+
+ break;
+ }
- client->state = DHCP6_STATE_SOLICITATION;
+ client->transaction_id = random_u32() & htobe32(0x00ffffff);
r = sd_event_add_time(client->event, &client->timeout_resend,
CLOCK_MONOTONIC, 0, 0, client_timeout_resend,
@@ -673,7 +692,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client)
if (r < 0)
return r;
- return client_start(client);
+ return client_start(client, DHCP6_STATE_SOLICITATION);
}
int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,