summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/sd-dhcp-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-network/sd-dhcp-client.c')
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 2d3af2f187..792e4af9c6 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -178,7 +178,7 @@ static int client_notify(sd_dhcp_client *client, int event) {
return 0;
}
-static int client_stop(sd_dhcp_client *client, int error) {
+static int client_initialize(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
client->receive_message =
@@ -194,15 +194,24 @@ static int client_stop(sd_dhcp_client *client, int error) {
client->attempt = 1;
- client_notify(client, error);
-
client->start_time = 0;
client->secs = 0;
client->state = DHCP_STATE_INIT;
+ client->xid = 0;
if (client->lease)
client->lease = sd_dhcp_lease_unref(client->lease);
+ return 0;
+}
+
+static int client_stop(sd_dhcp_client *client, int error) {
+ assert_return(client, -EINVAL);
+
+ client_notify(client, error);
+
+ client_initialize(client);
+
log_dhcp_client(client, "STOPPED");
return 0;
@@ -529,13 +538,46 @@ error:
}
+static int client_start(sd_dhcp_client *client) {
+ int r;
+
+ assert_return(client, -EINVAL);
+ assert_return(client->event, -EINVAL);
+ assert_return(client->index > 0, -EINVAL);
+ assert_return(client->fd < 0, -EBUSY);
+ assert_return(client->xid == 0, -EINVAL);
+ assert_return(client->state == DHCP_STATE_INIT ||
+ client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
+
+ client->xid = random_u32();
+
+ r = dhcp_network_bind_raw_socket(client->index, &client->link);
+
+ if (r < 0) {
+ client_stop(client, r);
+ return r;
+ }
+
+ client->fd = r;
+ client->start_time = now(CLOCK_MONOTONIC);
+ client->secs = 0;
+
+ log_dhcp_client(client, "STARTED");
+
+ return client_initialize_events(client, client_receive_message_raw);
+}
+
static int client_timeout_expire(sd_event_source *s, uint64_t usec,
void *userdata) {
sd_dhcp_client *client = userdata;
log_dhcp_client(client, "EXPIRED");
- client_stop(client, DHCP_EVENT_EXPIRED);
+ client_notify(client, DHCP_EVENT_EXPIRED);
+
+ /* start over as the lease was lost */
+ client_initialize(client);
+ client_start(client);
return 0;
}
@@ -961,27 +1003,15 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
int r;
assert_return(client, -EINVAL);
- assert_return(client->event, -EINVAL);
- assert_return(client->index > 0, -EINVAL);
- assert_return(client->state == DHCP_STATE_INIT ||
- client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
- client->xid = random_u32();
-
- r = dhcp_network_bind_raw_socket(client->index, &client->link);
-
- if (r < 0) {
- client_stop(client, r);
+ r = client_initialize(client);
+ if (r < 0)
return r;
- }
- client->fd = r;
- client->start_time = now(CLOCK_MONOTONIC);
- client->secs = 0;
+ if (client->last_addr)
+ client->state = DHCP_STATE_INIT_REBOOT;
- log_dhcp_client(client, "STARTED");
-
- return client_initialize_events(client, client_receive_message_raw);
+ return client_start(client);
}
int sd_dhcp_client_stop(sd_dhcp_client *client) {