Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8236441

Bound MulticastSocket fails when setting outbound interface on Windows

    XMLWordPrintable

Details

    • b30
    • Verified

    Backports

      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)

        Attachments

          Issue Links

            Activity

              People

                chegar Chris Hegarty
                chegar Chris Hegarty
                Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: