< prev index next >

src/java.base/share/classes/sun/net/util/IPAddressUtil.java

Print this page

        

*** 23,32 **** --- 23,41 ---- * questions. */ package sun.net.util; + import java.net.Inet6Address; + import java.net.InetAddress; + import java.net.NetworkInterface; + import java.net.SocketException; + import java.security.AccessController; + import java.security.PrivilegedAction; + import java.util.Map; + import java.util.concurrent.ConcurrentHashMap; + public class IPAddressUtil { private static final int INADDR4SZ = 4; private static final int INADDR16SZ = 16; private static final int INT16SZ = 2;
*** 285,290 **** --- 294,352 ---- (addr[11] == (byte)0xff)) { return true; } return false; } + + /** Returns a scopeId suitable for binding, or -1 if none */ + public static int bindingScopeId(InetAddress address) { + if (!(address instanceof Inet6Address)) + return -1; + + Inet6Address ia6 = (Inet6Address)address; + if (ia6.getScopeId() != 0) { // explicit scopeId + return ia6.getScopeId(); + } + + int scopeId = -1; + if (ia6.isLinkLocalAddress()) { + scopeId = IPAddressUtil.scopeFromLocalAddress(ia6); + } + + //TODO: if macOS default interface stuff + + return scopeId; + } + + private static Map<Inet6Address,Integer> localAddressScopeIdMap = new ConcurrentHashMap<>(); + + private static int scopeFromLocalAddress(Inet6Address addr) { + assert addr.isLinkLocalAddress() : addr; + + int scopeId = privilegedLookupScopeId(addr); + if (scopeId == -1) + return -1; + int cur = localAddressScopeIdMap.putIfAbsent(addr, scopeId); + assert cur == scopeId; + return scopeId; + } + + private static int privilegedLookupScopeId(Inet6Address ia6) { + PrivilegedAction<Integer> pa = () -> lookupScopeID(ia6); + return AccessController.doPrivileged(pa); + } + + private static int lookupScopeID(Inet6Address ia6) { + try { + return NetworkInterface.networkInterfaces() + .filter(nif -> nif.inetAddresses() + .filter(addr -> addr.equals(ia6)) + .findFirst().isPresent()) + .findFirst() + .map(NetworkInterface::getIndex) + .orElse(-1); + } catch (SocketException ignore) { + // ignore, handle as not found + } + return -1; + } }
< prev index next >