From 70ff9183e5533d6f0bfccf20bb67ac18d0bbb493 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 7 Feb 2017 18:02:12 +0100 Subject: socket: ignore EADDRINUSE when joining multicast group If an interface is configured with multiple addresses, llmnrd tries to join the LLMNR multicast group for each address instead of once per interface. Ideally llmnrd should track whether the group is already joined but since the kernel tells us that the group is already joined, just omit the error message on EADDRINUSE. This fixes the following error case: $ ip address add 2001:db8:1::/48 dev eth0 $ ./llmnrd -6 Starting llmnrd on port 5355, hostname foobar Added IPv4 address 127.0.0.1 on interface lo Added IPv4 address 10.42.0.42 on interface eth0 Added IPv6 address ::1 on interface lo Added IPv6 address 2001:db8:1:: on interface eth1 Error: Failed to join IPv6 multicast group on interface eth1: Address already in use Added IPv6 address fe80::xxxx:xxxx:xxxx:xxxx on interface eth0 Reference: #21 Signed-off-by: Tobias Klauser --- socket.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/socket.c b/socket.c index 1103779..73713eb 100644 --- a/socket.c +++ b/socket.c @@ -209,9 +209,14 @@ int socket_mcast_group_ipv4(int sock, unsigned int ifindex, bool join) if (setsockopt(sock, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { - log_err("Failed to join IPv4 multicast group on interface %s: %s\n", - if_indextoname(ifindex, ifname), strerror(errno)); - return -1; + /* ignore error if we attempt to join a group the interface is + * already part of */ + if (!join || errno != EADDRINUSE) { + log_err("Failed to %s IPv4 multicast group membership on interface %s: %s\n", + join ? "add" : "drop", if_indextoname(ifindex, ifname), + strerror(errno)); + return -1; + } } return 0; @@ -232,9 +237,14 @@ int socket_mcast_group_ipv6(int sock, unsigned int ifindex, bool join) if (setsockopt(sock, IPPROTO_IPV6, join ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { - log_err("Failed to join IPv6 multicast group on interface %s: %s\n", - if_indextoname(ifindex, ifname), strerror(errno)); - return -1; + /* ignore error if we attempt to join a group the interface is + * already part of */ + if (!join || errno != EADDRINUSE) { + log_err("Failed to %s IPv6 multicast group membership on interface %s: %s\n", + join ? "add" : "drop", if_indextoname(ifindex, ifname), + strerror(errno)); + return -1; + } } return 0; -- cgit v1.2.3-54-g00ecf