< 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 >