8178161: Default multicast interface on Mac
authorchegar
Fri, 07 Apr 2017 10:39:46 +0100
changeset 44544 fd2a9f5c6ff0
parent 44543 a8e05f640131
child 44547 a76fff35c8db
8178161: Default multicast interface on Mac Reviewed-by: michaelm, bpb
jdk/src/java.base/macosx/classes/java/net/DefaultInterface.java
--- a/jdk/src/java.base/macosx/classes/java/net/DefaultInterface.java	Thu Apr 06 18:00:47 2017 -0700
+++ b/jdk/src/java.base/macosx/classes/java/net/DefaultInterface.java	Fri Apr 07 10:39:46 2017 +0100
@@ -50,10 +50,11 @@
     }
 
     /**
-     * Choose a default interface. This method returns an interface that is
-     * both "up" and supports multicast. This method choses an interface in
+     * Choose a default interface. This method returns the first interface that
+     * is both "up" and supports multicast. This method chooses an interface in
      * order of preference:
      * 1. neither loopback nor point to point
+     *    ( prefer interfaces with dual IP support )
      * 2. point to point
      * 3. loopback
      *
@@ -66,32 +67,56 @@
         try {
            nifs = NetworkInterface.getNetworkInterfaces();
         } catch (IOException ignore) {
-            // unable to enumate network interfaces
+            // unable to enumerate network interfaces
             return null;
         }
 
+        NetworkInterface preferred = null;
         NetworkInterface ppp = null;
         NetworkInterface loopback = null;
 
         while (nifs.hasMoreElements()) {
             NetworkInterface ni = nifs.nextElement();
             try {
-                if (ni.isUp() && ni.supportsMulticast()) {
-                    boolean isLoopback = ni.isLoopback();
-                    boolean isPPP = ni.isPointToPoint();
-                    if (!isLoopback && !isPPP) {
-                        // found an interface that is not the loopback or a
-                        // point-to-point interface
+                if (!ni.isUp() || !ni.supportsMulticast())
+                    continue;
+
+                boolean ip4 = false, ip6 = false;
+                Enumeration<InetAddress> addrs = ni.getInetAddresses();
+                while (addrs.hasMoreElements()) {
+                    InetAddress addr = addrs.nextElement();
+                    if (!addr.isAnyLocalAddress()) {
+                        if (addr instanceof Inet4Address) {
+                            ip4 = true;
+                        } else if (addr instanceof Inet6Address) {
+                            ip6 = true;
+                        }
+                    }
+                }
+
+                boolean isLoopback = ni.isLoopback();
+                boolean isPPP = ni.isPointToPoint();
+                if (!isLoopback && !isPPP) {
+                    // found an interface that is not the loopback or a
+                    // point-to-point interface
+                    if (preferred == null) {
+                        preferred = ni;
+                    } else if (ip4 && ip6){
                         return ni;
                     }
-                    if (ppp == null && isPPP)
-                        ppp = ni;
-                    if (loopback == null && isLoopback)
-                        loopback = ni;
                 }
+                if (ppp == null && isPPP)
+                    ppp = ni;
+                if (loopback == null && isLoopback)
+                    loopback = ni;
+
             } catch (IOException skip) { }
         }
 
-        return (ppp != null) ? ppp : loopback;
+        if (preferred != null) {
+            return preferred;
+        } else {
+            return (ppp != null) ? ppp : loopback;
+        }
     }
 }