Skip to content

Commit 4c510fd

Browse files
committed
Fix multicast check for loopback interface
This corrects the interface addresses used when checking whether multicast is supported on IPv4 even when the interface doesn't have the IFF_MULTICAST flag set as introduced in 3b66431. On Ubuntu it worked fine the way it was (at least for what I have seen), but not on Fedora 40. This appears to work fine on both. Signed-off-by: Erik Boasson <[email protected]>
1 parent ceeb739 commit 4c510fd

File tree

1 file changed

+18
-15
lines changed

1 file changed

+18
-15
lines changed

src/ddsrt/src/ifaddrs/posix/ifaddrs.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -161,33 +161,36 @@ static bool is_the_kernel_likely_lying_about_multicast (const ddsrt_ifaddrs_t *i
161161
struct sockaddr gen;
162162
struct sockaddr_in ipv4;
163163
struct sockaddr_in6 ipv6;
164-
} addr, mcaddr;
165-
memset (&addr, 0, sizeof (addr));
164+
} ifaddr, bindaddr, mcaddr;
165+
memset (&ifaddr, 0, sizeof (ifaddr));
166+
memset (&bindaddr, 0, sizeof (bindaddr));
166167
memset (&mcaddr, 0, sizeof (mcaddr));
167168
// Multicast address: abuse DDSI's default address because we need to pick something
168169
if (ipv6) {
169-
addr.ipv6 = *((struct sockaddr_in6 *) ifa->addr);
170-
addr.ipv6.sin6_port = 0;
171-
mcaddr = addr;
170+
ifaddr.ipv6 = *((struct sockaddr_in6 *) ifa->addr);
171+
ifaddr.ipv6.sin6_port = 0;
172+
bindaddr = ifaddr;
173+
mcaddr = ifaddr;
172174
if (inet_pton (mcaddr.gen.sa_family, "ff02::ffff:239.255.0.1", &mcaddr.ipv6.sin6_addr) != 1)
173175
goto out;
174176
} else {
175-
addr.ipv4 = *((struct sockaddr_in *) ifa->addr);
176-
addr.ipv4.sin_addr.s_addr = htonl (INADDR_ANY); // because we can't receive multicasts otherwise
177-
addr.ipv4.sin_port = 0;
178-
mcaddr = addr;
177+
ifaddr.ipv4 = *((struct sockaddr_in *) ifa->addr);
178+
ifaddr.ipv4.sin_port = 0;
179+
bindaddr = ifaddr;
180+
bindaddr.ipv4.sin_addr.s_addr = htonl (INADDR_ANY); // because we can't receive multicasts otherwise
181+
mcaddr = ifaddr;
179182
if (inet_pton (mcaddr.gen.sa_family, "239.255.0.1", &mcaddr.ipv4.sin_addr) != 1)
180183
goto out;
181184
}
182-
if (bind (sock, &addr.gen, addrsz) < 0)
185+
if (bind (sock, &bindaddr.gen, addrsz) < 0)
183186
goto out;
184-
if (getsockname (sock, &addr.gen, &addrsz) < 0)
187+
if (getsockname (sock, &bindaddr.gen, &addrsz) < 0)
185188
goto out;
186189
if (ipv6)
187190
{
188191
const unsigned hops = 0;
189192
struct ipv6_mreq ipv6mreq;
190-
mcaddr.ipv6.sin6_port = addr.ipv6.sin6_port;
193+
mcaddr.ipv6.sin6_port = bindaddr.ipv6.sin6_port;
191194
memset (&ipv6mreq, 0, sizeof (ipv6mreq));
192195
ipv6mreq.ipv6mr_multiaddr = mcaddr.ipv6.sin6_addr;
193196
ipv6mreq.ipv6mr_interface = ifa->index;
@@ -200,11 +203,11 @@ static bool is_the_kernel_likely_lying_about_multicast (const ddsrt_ifaddrs_t *i
200203
{
201204
const unsigned char ttl = 0;
202205
struct ip_mreq mreq;
203-
mcaddr.ipv4.sin_port = addr.ipv4.sin_port;
206+
mcaddr.ipv4.sin_port = bindaddr.ipv4.sin_port;
204207
mreq.imr_multiaddr = mcaddr.ipv4.sin_addr;
205-
mreq.imr_interface = addr.ipv4.sin_addr;
208+
mreq.imr_interface = ifaddr.ipv4.sin_addr;
206209
if (setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)) != 0 ||
207-
setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, &addr.ipv4.sin_addr, sizeof (addr.ipv4.sin_addr)) != 0 ||
210+
setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr.ipv4.sin_addr, sizeof (ifaddr.ipv4.sin_addr)) != 0 ||
208211
setsockopt (sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof (ttl)) != 0)
209212
goto out;
210213
}

0 commit comments

Comments
 (0)