JDK-8236441 : Bound MulticastSocket fails when setting outbound interface on Windows
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 11.0.5,14
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2019-12-20
  • Updated: 2020-02-11
  • Resolved: 2019-12-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 14 JDK 15
14 b30Fixed 15Fixed
Related Reports
Relates :  
Description
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)


Comments
This issue is partly related to the changes for JDK-6458027 - some of the fallback code does not correctly check that the file descriptor is still valid.
23-12-2019

URL: https://hg.openjdk.java.net/jdk/jdk14/rev/97744abc4fde User: chegar Date: 2019-12-23 09:18:15 +0000
23-12-2019