[Bug 193246] Bug in IPv6 multicast join(), uncovered by Jenkins
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 10 Aug 2026 21:14:09 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193246
Michael Osipov <michaelo@FreeBSD.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC|michael.osipov@innomotics.c |
|om |
--- Comment #33 from Michael Osipov <michaelo@FreeBSD.org> ---
(In reply to Adrian Chadd from comment #32)
Picked this up, updated to lastest from HEAD and OpenJDK 25, three-line Java
program. I don't have any IPv6 in use beyond ::1 on lo0.
Minimalist test:
import java.net.InetAddress; import java.net.MulticastSocket;
public class Join {
public static void main(String... args) throws Exception {
var g = InetAddress.getAllByName("228.5.6.7"); var z = new
MulticastSocket(6790);
z.joinGroup(g[0]);
}
}
Then had AI to generate the dtrace code. Output was:
# dtrace -s java-sockets.d -c 'java Join'
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=11
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
Exception in thread "main" java.net.SocketException: joinGroup failed
at
java.base/sun.nio.ch.DatagramSocketAdaptor.joinGroup(DatagramSocketAdaptor.java:423)
at
java.base/java.net.MulticastSocket.joinGroup(MulticastSocket.java:294)
at Join.main(Join.java:7)
Caused by: java.lang.IllegalArgumentException: IPv6 socket cannot join IPv4
multicast group
at
java.base/sun.nio.ch.DatagramChannelImpl.innerJoin(DatagramChannelImpl.java:1505)
at
java.base/sun.nio.ch.DatagramChannelImpl.join(DatagramChannelImpl.java:1586)
at
java.base/sun.nio.ch.DatagramSocketAdaptor.joinGroup(DatagramSocketAdaptor.java:469)
at
java.base/sun.nio.ch.DatagramSocketAdaptor.joinGroup(DatagramSocketAdaptor.java:420)
... 2 more
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=sh fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=3
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:17 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=1 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=28 type=1 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=28 type=1 proto=0
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=4 level=65535 opt=512
val=82b9faebc len=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=28 type=1 proto=6
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=5 level=6 opt=256
val=82b9fa9dc len=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=28 type=1 proto=6
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=5 level=6 opt=1024
val=82b9fa9dc len=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=28 type=1 proto=6
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=5 level=6 opt=512
val=82b9fa9dc len=4
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=5
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=28 type=2 proto=0
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=5 level=41 opt=27
val=82b9fb6b0 len=4
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=5 level=65535 opt=512
val=82b9fb680 len=4
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=5 level=65535 opt=4
val=82b9fb680 len=4
2026 Aug 10 22:49:18 setsockopt pid=51581 comm=java fd=5 level=65535 opt=32
val=82b9fb680 len=4
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=28 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
2026 Aug 10 22:49:18 socket pid=51581 comm=java domain=2 type=2 proto=0
2026 Aug 10 22:49:18 close pid=51581 comm=java fd=6
based on this it wrote a sample C program which mimics Java's behavior:
# cat mcast_repro.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
static void die(const char *msg) {
perror(msg);
exit(1);
}
static void usage(const char *prog) {
fprintf(stderr,
"usage: %s 4|6 [v6only 0|1]\n"
" 4 use PF_INET\n"
" 6 use PF_INET6\n"
" v6only only meaningful with PF_INET6 (default: 1)\n",
prog);
exit(2);
}
static void print_errno(const char *what) {
fprintf(stderr, "%s failed: %s (errno=%d)\n", what, strerror(errno),
errno);
}
int main(int argc, char **argv) {
int fd;
int family = 0;
int on = 1;
const char *group_str = "228.5.6.7";
if (argc < 2 || argc > 3)
usage(argv[0]);
if (strcmp(argv[1], "4") == 0)
family = PF_INET;
else if (strcmp(argv[1], "6") == 0)
family = PF_INET6;
else
usage(argv[0]);
if (argc == 3)
on = atoi(argv[2]) ? 1 : 0;
printf("mode: family=%s", family == PF_INET ? "PF_INET" : "PF_INET6");
if (family == PF_INET6)
printf(" v6only=%d", on);
printf("\n");
fd = socket(family, SOCK_DGRAM, 0);
if (fd < 0)
die("socket");
printf("socket() ok -> fd=%d\n", fd);
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
die("SO_REUSEADDR");
printf("setsockopt(SO_REUSEADDR) ok\n");
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
die("SO_REUSEPORT");
printf("setsockopt(SO_REUSEPORT) ok\n");
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
die("SO_BROADCAST");
printf("setsockopt(SO_BROADCAST) ok\n");
if (family == PF_INET6) {
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
die("IPV6_V6ONLY");
printf("setsockopt(IPV6_V6ONLY=%d) ok\n", on);
}
if (family == PF_INET) {
struct sockaddr_in sa4;
struct ip_mreq mreq4;
memset(&sa4, 0, sizeof(sa4));
sa4.sin_len = sizeof(sa4);
sa4.sin_family = AF_INET;
sa4.sin_port = htons(6790);
sa4.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(fd, (struct sockaddr *)&sa4, sizeof(sa4)) < 0) {
print_errno("bind(AF_INET)");
close(fd);
return 1;
}
printf("bind(AF_INET 0.0.0.0:6790) ok\n");
memset(&mreq4, 0, sizeof(mreq4));
if (inet_pton(AF_INET, group_str, &mreq4.imr_multiaddr) != 1)
die("inet_pton(AF_INET)");
mreq4.imr_interface.s_addr = htonl(INADDR_ANY);
printf("attempting IP_ADD_MEMBERSHIP for %s\n", group_str);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq4,
sizeof(mreq4)) < 0) {
print_errno("IP_ADD_MEMBERSHIP");
close(fd);
return 1;
}
printf("IP_ADD_MEMBERSHIP ok -> joined IPv4 multicast successfully on
PF_INET\n");
} else {
struct sockaddr_in6 sa6;
struct ip_mreq mreq4;
memset(&sa6, 0, sizeof(sa6));
sa6.sin6_len = sizeof(sa6);
sa6.sin6_family = AF_INET6;
sa6.sin6_port = htons(6790);
sa6.sin6_addr = in6addr_any;
if (bind(fd, (struct sockaddr *)&sa6, sizeof(sa6)) < 0) {
print_errno("bind(AF_INET6)");
close(fd);
return 1;
}
printf("bind(AF_INET6 :::6790) ok\n");
memset(&mreq4, 0, sizeof(mreq4));
if (inet_pton(AF_INET, group_str, &mreq4.imr_multiaddr) != 1)
die("inet_pton(AF_INET)");
mreq4.imr_interface.s_addr = htonl(INADDR_ANY);
printf("attempting IP_ADD_MEMBERSHIP for %s\n", group_str);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq4,
sizeof(mreq4)) < 0) {
print_errno("IP_ADD_MEMBERSHIP");
close(fd);
return 1;
}
printf("IP_ADD_MEMBERSHIP ok -> joined IPv4 multicast successfully on
PF_INET6\n");
}
close(fd);
return 0;
}
$ cc -Wall -Wextra -o mcast_repro mcast_repro.c
$ ./mcast_repro 4
mode: family=PF_INET
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
bind(AF_INET 0.0.0.0:6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP ok -> joined IPv4 multicast successfully on PF_INET
$ ./mcast_repro 6 0
mode: family=PF_INET6 v6only=0
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=0) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP failed: Invalid argument (errno=22)
$ ./mcast_repro 6 1
mode: family=PF_INET6 v6only=1
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=1) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP failed: Invalid argument (errno=22)
$ ./mcast_repro 6 0
mode: family=PF_INET6 v6only=0
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=0) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP failed: Invalid argument (errno=22)
Same program on HP-UX 11.31:
osipovmi@deblndw028v:~
$ ./mcast_repro 4
mode: family=PF_INET
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
bind(AF_INET 0.0.0.0:6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP ok -> joined IPv4 multicast successfully on PF_INET
osipovmi@deblndw028v:~
$ ./mcast_repro 6
mode: family=PF_INET6 v6only=1
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=1) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP failed: Operation not supported (errno=223)
osipovmi@deblndw028v:~
$ ./mcast_repro 6 0
mode: family=PF_INET6 v6only=0
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=0) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP failed: Operation not supported (errno=223)
osipovmi@deblndw028v:~
$ ./mcast_repro 6 1
mode: family=PF_INET6 v6only=1
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=1) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP failed: Operation not supported (errno=223)
and RHEL 8.x:
osipovmi@deblndw012x:~
$ ./mcast_repro 4
mode: family=PF_INET
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
bind(AF_INET 0.0.0.0:6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP ok -> joined IPv4 multicast successfully on PF_INET
osipovmi@deblndw012x:~
$ ./mcast_repro 6
mode: family=PF_INET6 v6only=1
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=1) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP ok -> joined IPv4 multicast successfully on PF_INET6
osipovmi@deblndw012x:~
$ ./mcast_repro 6 0
mode: family=PF_INET6 v6only=0
socket() ok -> fd=3
setsockopt(SO_REUSEADDR) ok
setsockopt(SO_REUSEPORT) ok
setsockopt(SO_BROADCAST) ok
setsockopt(IPV6_V6ONLY=0) ok
bind(AF_INET6 :::6790) ok
attempting IP_ADD_MEMBERSHIP for 228.5.6.7
IP_ADD_MEMBERSHIP ok -> joined IPv4 multicast successfully on PF_INET6
I am not an expert, let me know whether my approach is wrong and where to go
from here.
--
You are receiving this mail because:
You are on the CC list for the bug.