diff options
author | Patrik Flykt <patrik.flykt@linux.intel.com> | 2018-01-04 12:02:52 +0200 |
---|---|---|
committer | Mike Gilbert <floppym@gentoo.org> | 2018-01-13 12:19:21 -0500 |
commit | d8289559b884ea3323d6c4932c347295d4f6a8c6 (patch) | |
tree | ad883ab9ad5f58ffaf3f1af09a4f8b448822dc66 | |
parent | README: EXT4_POSIX_ACL -> EXT4_FS_POSIX_ACL (#7799) (diff) | |
download | systemd-d8289559b884ea3323d6c4932c347295d4f6a8c6.tar.gz systemd-d8289559b884ea3323d6c4932c347295d4f6a8c6.tar.bz2 systemd-d8289559b884ea3323d6c4932c347295d4f6a8c6.zip |
dhcp6: Fix DHCPv6 client file descriptor and event handling (#7796)
Close DHCPv6 client socket file descriptor when
sd_dhcp6_client_stop() is called and not when client_reset() is
called. If left in client_reset(), any internal temporary stopping
of the DHCPv6 client with client_stop() will call client_reset()
after which the DHCPv6 client will not be able to receive any further
DHCPv6 messages.
Similarly, client_start() needs to enable events for the DHCPv6
socket file descriptor since a call to client_stop() will call
client_reset() which will remove it from the main loop. Events should
be turned off when no DHCPv6 messages are expected.
(cherry picked from commit 7ac6c26a22294b3276953c635ac1e91b5d03db18)
-rw-r--r-- | src/libsystemd-network/sd-dhcp6-client.c | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 1c12e5430..074a409cb 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -336,8 +336,6 @@ static int client_reset(sd_dhcp6_client *client) { client->receive_message = sd_event_source_unref(client->receive_message); - client->fd = safe_close(client->fd); - client->transaction_id = 0; client->transaction_start = 0; @@ -1092,6 +1090,24 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { if (r < 0) return r; + if (!client->receive_message) { + r = sd_event_add_io(client->event, &client->receive_message, + client->fd, EPOLLIN, client_receive_message, + client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->receive_message, + client->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(client->receive_message, + "dhcp6-receive-message"); + if (r < 0) + goto error; + } + switch (state) { case DHCP6_STATE_STOPPED: if (client->state == DHCP6_STATE_INFORMATION_REQUEST) { @@ -1138,16 +1154,16 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { 10 * USEC_PER_SEC, client_timeout_t1, client); if (r < 0) - return r; + goto error; r = sd_event_source_set_priority(client->lease->ia.timeout_t1, client->event_priority); if (r < 0) - return r; + goto error; r = sd_event_source_set_description(client->lease->ia.timeout_t1, "dhcp6-t1-timeout"); if (r < 0) - return r; + goto error; timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t2) * USEC_PER_SEC); @@ -1160,16 +1176,16 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { 10 * USEC_PER_SEC, client_timeout_t2, client); if (r < 0) - return r; + goto error; r = sd_event_source_set_priority(client->lease->ia.timeout_t2, client->event_priority); if (r < 0) - return r; + goto error; r = sd_event_source_set_description(client->lease->ia.timeout_t2, "dhcp6-t2-timeout"); if (r < 0) - return r; + goto error; client->state = state; @@ -1183,18 +1199,22 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { clock_boottime_or_monotonic(), 0, 0, client_timeout_resend, client); if (r < 0) - return r; + goto error; r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); if (r < 0) - return r; + goto error; r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout"); if (r < 0) - return r; + goto error; return 0; + + error: + client_reset(client); + return r; } int sd_dhcp6_client_stop(sd_dhcp6_client *client) { @@ -1202,6 +1222,8 @@ int sd_dhcp6_client_stop(sd_dhcp6_client *client) { client_stop(client, SD_DHCP6_CLIENT_EVENT_STOP); + client->fd = safe_close(client->fd); + return 0; } @@ -1246,22 +1268,6 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { client->fd = r; - r = sd_event_add_io(client->event, &client->receive_message, - client->fd, EPOLLIN, client_receive_message, - client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->receive_message, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->receive_message, - "dhcp6-receive-message"); - if (r < 0) - goto error; - if (client->information_request) state = DHCP6_STATE_INFORMATION_REQUEST; @@ -1270,10 +1276,6 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { "Managed"); return client_start(client, state); - -error: - client_reset(client); - return r; } int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64_t priority) { |