From 10a0f27bfdd22ec1fe7d9fc2af15c3a2bf221a97 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Tue, 23 Jan 2018 12:34:31 +0200 Subject: [PATCH] sd-dhcp6-client: Fix DHCPv6 client file descriptor handling The DHCPv6 client will set its state to DHCP6_STATE_STOPPED if an error occurs or when receiving an Information Reply DHCPv6 message. Once in DHCP6_STATE_STOPPED, the DHCPv6 client needs to be restarted by calling sd_dhcp6_client_start(). As of pull request #7796 client_reset() no longer closes the network socket, thus a call to sd_dhcp6_client_start() needs to check whether the file descriptor already exists in order not to create a new one. Likewise, a call to sd_dhcp6_client_unref() must now close the network socket as client_reset() is not closing it. Reported by asavah and Yu Watanabe. --- src/libsystemd-network/sd-dhcp6-client.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index a8ad8eb..ec34843 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1353,17 +1353,19 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { if (r < 0) return r; - r = dhcp6_network_bind_udp_socket(client->ifindex, &client->local_address); - if (r < 0) { - _cleanup_free_ char *p = NULL; + if (client->fd < 0) { + r = dhcp6_network_bind_udp_socket(client->ifindex, &client->local_address); + if (r < 0) { + _cleanup_free_ char *p = NULL; + + (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &client->local_address, &p); + return log_dhcp6_client_errno(client, r, + "Failed to bind to UDP socket at address %s: %m", strna(p)); + } - (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &client->local_address, &p); - return log_dhcp6_client_errno(client, r, - "Failed to bind to UDP socket at address %s: %m", strna(p)); + client->fd = r; } - client->fd = r; - if (client->information_request) state = DHCP6_STATE_INFORMATION_REQUEST; @@ -1431,6 +1433,8 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { client_reset(client); + client->fd = safe_close(client->fd); + sd_dhcp6_client_detach_event(client); free(client->req_opts); -- 2.7.4