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.
This commit is contained in:
Patrik Flykt
2018-01-23 12:34:31 +02:00
committed by Lennart Poettering
parent 2b0c59baa2
commit 10a0f27bfd

View File

@@ -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);