The MulticastSocket implementation on Windows uses the two stacks implementation. The two stacks implementation creates a socket on the IPv4 stack and another on the IPv6 stack. Operations are then performed on both sockets as appropriate. If the socket is bound to a specific address, then the IP version of the socket that matches that address is retained, and the other closed.
This is a complicated implementation, which will hopefully be replaced soon, but in the meantime there is a serious bug with handling the IP_MULTICAST_IF[2] socket option. The code does not correctly cater for the fact that one of the file descriptors may be closed, leading to SocketExceptions with a message of: "An operation was attempted on something that is not a socket (Error setting socket option)"
The following demonstrates the issue:
---
$ cat SupportMulticastIF.java
import java.net.*;
import java.util.*;
import static java.lang.System.out;
import static java.net.StandardSocketOptions.IP_MULTICAST_IF;
import static java.util.stream.Collectors.toList;
public class SupportMulticastIF {
public static void main(String[] args) throws Exception {
List<NetworkInterface> netInterfaces = NetworkInterface.networkInterfaces().collect(toList());
// for all the available interfaces set and get
for (NetworkInterface nif : netInterfaces) {
if (nif.getInetAddresses().hasMoreElements() && nif.isUp() && nif.supportsMulticast()) {
out.println("The nif name - "+nif.getName());
InetAddress localHost = InetAddress.getLocalHost();
out.println("localhost ipaddress: " + localHost.getHostAddress());
InetSocketAddress addr = new InetSocketAddress(localHost, 0);
try (MulticastSocket ms = new MulticastSocket(addr)) { // bound ms
ms.setOption(IP_MULTICAST_IF, nif);
NetworkInterface actualNif = ms.getOption(IP_MULTICAST_IF);
}
}
}
}
}
$ ~/binaries/jdk-11.0.5/bin/java -version
java version "11.0.5" 2019-10-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.5+10-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.5+10-LTS, mixed mode)
$ ~/binaries/jdk-11.0.5/bin/javac SupportMulticastIF.java
$ ~/binaries/jdk-11.0.5/bin/java SupportMulticastIF
The nif name - lo
localhost ipaddress: 1yy.2x.6x.1
The nif name - eth0
localhost ipaddress: 1yy.2x.x4.1
Exception in thread "main" java.net.SocketException: An operation was attempted on something that is not a socket (Error setting socket option)
at java.base/java.net.TwoStacksPlainDatagramSocketImpl.socketNativeSetOption(Native Method)
at java.base/java.net.TwoStacksPlainDatagramSocketImpl.socketSetOption(TwoStacksPlainDatagramSocketImpl.java:161)
at java.base/java.net.AbstractPlainDatagramSocketImpl.setOption(AbstractPlainDatagramSocketImpl.java:352)
at java.base/java.net.DatagramSocketImpl.setOption(DatagramSocketImpl.java:295)
at java.base/java.net.DatagramSocket.setOption(DatagramSocket.java:1346)
at SupportMulticastIF.main(SupportMulticastIF.java:20)