Path: blob/master/src/java.base/macosx/classes/java/net/DefaultInterface.java
41133 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.net;2627/**28* Choose a network interface to be the default for29* outgoing IPv6 traffic that does not specify a scope_id (and which needs one).30* We choose the first interface that is up and is (in order of preference):31* 1. neither loopback nor point to point32* 2. point to point33* 3. loopback34* 4. none.35* Platforms that do not require a default interface implement a dummy36* that returns null.37*/3839import java.security.AccessController;40import java.security.PrivilegedAction;41import java.util.Enumeration;42import java.io.IOException;4344class DefaultInterface {4546private static final NetworkInterface defaultInterface =47chooseDefaultInterface();4849static NetworkInterface getDefault() {50return defaultInterface;51}5253/**54* Choose a default interface. This method returns the first interface that55* is both "up" and supports multicast. This method chooses an interface in56* order of preference, using the following algorithm:57*58* <pre>59* Interfaces that are down, or don't support multicasting, are skipped.60* In steps 1-4 below, PPP and loopback interfaces are skipped.61*62* 1. The first interface that has at least an IPv4 address, and an IPv6 address,63* and a non link-local IP address, is picked.64*65* 2. If none is found, then the first interface that has at least an66* IPv4 address, and an IPv6 address is picked.67*68* 3. If none is found, then the first interface that has at least a69* non link local IP address is picked.70*71* 4. If none is found, then the first non loopback and non PPP interface72* is picked.73*74* 5. If none is found then first PPP interface is picked.75*76* 6. If none is found, then the first loopback interface is picked.77*78* 7. If none is found, then null is returned.79* </pre>80*81* @return the chosen interface or {@code null} if there isn't a suitable82* default83*/84private static NetworkInterface chooseDefaultInterface() {85Enumeration<NetworkInterface> nifs;8687try {88nifs = NetworkInterface.getNetworkInterfaces();89} catch (IOException ignore) {90// unable to enumerate network interfaces91return null;92}9394NetworkInterface preferred = null;95NetworkInterface dual = null;96NetworkInterface nonLinkLocal = null;97NetworkInterface ppp = null;98NetworkInterface loopback = null;99100while (nifs.hasMoreElements()) {101NetworkInterface ni = nifs.nextElement();102try {103if (!ni.isUp() || !ni.supportsMulticast())104continue;105106boolean ip4 = false, ip6 = false, isNonLinkLocal = false;107PrivilegedAction<Enumeration<InetAddress>> pa = ni::getInetAddresses;108@SuppressWarnings("removal")109Enumeration<InetAddress> addrs = AccessController.doPrivileged(pa);110while (addrs.hasMoreElements()) {111InetAddress addr = addrs.nextElement();112if (!addr.isAnyLocalAddress()) {113if (addr instanceof Inet4Address) {114ip4 = true;115} else if (addr instanceof Inet6Address) {116ip6 = true;117}118if (!addr.isLinkLocalAddress()) {119isNonLinkLocal = true;120}121}122}123124boolean isLoopback = ni.isLoopback();125boolean isPPP = ni.isPointToPoint();126if (!isLoopback && !isPPP) {127// found an interface that is not the loopback or a128// point-to-point interface129if (preferred == null) {130preferred = ni;131}132if (ip4 && ip6) {133if (isNonLinkLocal) return ni;134if (dual == null) dual = ni;135}136if (nonLinkLocal == null) {137if (isNonLinkLocal) nonLinkLocal = ni;138}139}140if (ppp == null && isPPP)141ppp = ni;142if (loopback == null && isLoopback)143loopback = ni;144145} catch (IOException skip) { }146}147148if (dual != null) {149return dual;150} else if (nonLinkLocal != null) {151return nonLinkLocal;152} else if (preferred != null) {153return preferred;154} else {155return (ppp != null) ? ppp : loopback;156}157}158}159160161