1 /* 2 * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.net; 26 27 import java.io.IOException; 28 import java.net.spi.InetAddressResolver.LookupPolicy; 29 30 import static java.net.InetAddress.PLATFORM_LOOKUP_POLICY; 31 32 /* 33 * Package private implementation of InetAddressImpl for dual 34 * IPv4/IPv6 stack. 35 * <p> 36 * If InetAddress.preferIPv6Address is true then anyLocalAddress() 37 * and localHost() will return IPv6 addresses, otherwise IPv4 addresses. 38 * 39 * loopbackAddress() will return the first valid loopback address in 40 * [IPv6 loopback, IPv4 loopback] if InetAddress.preferIPv6Address is true, 41 * else [IPv4 loopback, IPv6 loopback]. 42 * If neither are valid it will fallback to the first address tried. 43 * 44 * @since 1.4 45 */ 46 final class Inet6AddressImpl implements InetAddressImpl { 47 48 public native String getLocalHostName() throws UnknownHostException; 49 50 public InetAddress[] lookupAllHostAddr(String hostname, LookupPolicy lookupPolicy) 51 throws UnknownHostException { 52 return lookupAllHostAddr(hostname, lookupPolicy.characteristics()); 53 } 54 55 private native InetAddress[] lookupAllHostAddr(String hostname, int characteristics) 56 throws UnknownHostException; 57 58 public native String getHostByAddr(byte[] addr) throws UnknownHostException; 59 60 private native boolean isReachable0(byte[] addr, int scope, int timeout, 61 byte[] inf, int ttl, int if_scope) 62 throws IOException; 63 64 public boolean isReachable(InetAddress addr, int timeout, 65 NetworkInterface netif, int ttl) 66 throws IOException 67 { 68 byte[] ifaddr = null; 69 int scope = -1; 70 int netif_scope = -1; 71 if (netif != null) { 72 /* 73 * Let's make sure we bind to an address of the proper family. 74 * Which means same family as addr because at this point it could 75 * be either an IPv6 address or an IPv4 address (case of a dual 76 * stack system). 77 */ 78 java.util.Enumeration<InetAddress> it = netif.getInetAddresses(); 79 InetAddress inetaddr; 80 while (it.hasMoreElements()) { 81 inetaddr = it.nextElement(); 82 if (inetaddr.getClass().isInstance(addr)) { 83 ifaddr = inetaddr.getAddress(); 84 if (inetaddr instanceof Inet6Address) { 85 netif_scope = ((Inet6Address) inetaddr).getScopeId(); 86 } 87 break; 88 } 89 } 90 if (ifaddr == null) { 91 // Interface doesn't support the address family of 92 // the destination 93 return false; 94 } 95 } 96 if (addr instanceof Inet6Address) 97 scope = ((Inet6Address) addr).getScopeId(); 98 return isReachable0(addr.getAddress(), scope, timeout, ifaddr, ttl, netif_scope); 99 } 100 101 public synchronized InetAddress anyLocalAddress() { 102 if (anyLocalAddress == null) { 103 int flags = PLATFORM_LOOKUP_POLICY.characteristics(); 104 if (InetAddress.ipv6AddressesFirst(flags) || 105 InetAddress.systemAddressesOrder(flags)) { 106 anyLocalAddress = new Inet6Address(); 107 anyLocalAddress.holder().hostName = "::"; 108 } else { 109 anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress(); 110 } 111 } 112 return anyLocalAddress; 113 } 114 115 public synchronized InetAddress loopbackAddress() { 116 if (loopbackAddress == null) { 117 int flags = PLATFORM_LOOKUP_POLICY.characteristics(); 118 boolean preferIPv6Address = InetAddress.ipv6AddressesFirst(flags) || 119 InetAddress.systemAddressesOrder(flags); 120 121 for (int i = 0; i < 2; i++) { 122 InetAddress address; 123 // Order the candidate addresses by preference. 124 if (i == (preferIPv6Address ? 0 : 1)) { 125 address = new Inet6Address("localhost", 126 new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}); 128 } else { 129 address = new Inet4Address("localhost", new byte[]{ 0x7f,0x00,0x00,0x01 }); 130 } 131 if (i == 0) { 132 // In case of failure, default to the preferred address. 133 loopbackAddress = address; 134 } 135 try { 136 if (!NetworkInterface.isBoundInetAddress(address)) { 137 continue; 138 } 139 } catch (SocketException e) { 140 continue; 141 } 142 loopbackAddress = address; 143 break; 144 } 145 } 146 return loopbackAddress; 147 } 148 149 private InetAddress anyLocalAddress; 150 private InetAddress loopbackAddress; 151 } --- EOF ---