Inet6AddressImpl.java revision 48e205e5e0bc55b5c7b11df445da39c5be890623
151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 37f4b1b8935a58d3f44351083cf5ef19045761de3Yi Kong * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net; 27c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport android.system.ErrnoException; 28c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport android.system.GaiException; 29c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport android.system.StructAddrinfo; 3048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport android.system.StructIcmpHdr; 3148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 32c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport dalvik.system.BlockGuard; 332be229c284db4293a86200fa800886fed137e567Yi Kong 342be229c284db4293a86200fa800886fed137e567Yi Kongimport libcore.io.IoBridge; 35c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport libcore.io.Libcore; 36c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 372be229c284db4293a86200fa800886fed137e567Yi Kongimport java.io.FileDescriptor; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.AF_INET; 4148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.AF_INET6; 42c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport static android.system.OsConstants.AF_UNSPEC; 43c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport static android.system.OsConstants.AI_ADDRCONFIG; 44c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport static android.system.OsConstants.EACCES; 452be229c284db4293a86200fa800886fed137e567Yi Kongimport static android.system.OsConstants.ECONNREFUSED; 46b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kongimport static android.system.OsConstants.NI_NAMEREQD; 4748e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.ICMP6_ECHO_REPLY; 4848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.ICMP_ECHOREPLY; 4948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.IPPROTO_ICMP; 5048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.IPPROTO_ICMPV6; 5148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.IPPROTO_IPV6; 5248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.IPV6_UNICAST_HOPS; 5348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kongimport static android.system.OsConstants.SOCK_DGRAM; 54c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamathimport static android.system.OsConstants.SOCK_STREAM; 55c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Package private implementation of InetAddressImpl for dual 58c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath * IPv4/IPv6 stack. {@code #anyLocalAddress()} will always return an IPv6 address. 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass Inet6AddressImpl implements InetAddressImpl { 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 655427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // @GuardedBy(Inet6AddressImpl.class) 665427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath private static InetAddress anyLocalAddress; 675427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // @GuardedBy(Inet6AddressImpl.class) 685427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath private static InetAddress[] loopbackAddresses; 69c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 70c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath private static final AddressCache addressCache = new AddressCache(); 71c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 72c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath @Override 73c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath public InetAddress[] lookupAllHostAddr(String host, int netId) throws UnknownHostException { 74c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath if (host == null || host.isEmpty()) { 75c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // Android-changed : Return both the Inet4 and Inet6 loopback addresses 76c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // when host == null or empty. 77c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath return loopbackAddresses(); 78c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 79c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 80c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // Is it a numeric address? 81c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath InetAddress result = InetAddress.parseNumericAddressNoThrow(host); 82c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath if (result != null) { 83c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath result = InetAddress.disallowDeprecatedFormats(host, result); 84c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath if (result == null) { 85c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath throw new UnknownHostException("Deprecated IPv4 address format: " + host); 86c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 87c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath return new InetAddress[] { result }; 88c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 89c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 90d960ef32a57a91e4ea0976a2bbd97b8ec0fd2cf0Narayan Kamath return lookupHostByName(host, netId); 91c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 92c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 93c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath /** 94c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath * Resolves a hostname to its IP addresses using a cache. 95c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath * 96c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath * @param host the hostname to resolve. 97c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath * @param netId the network to perform resolution upon. 98c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath * @return the IP addresses of the host. 99c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath */ 100c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath private static InetAddress[] lookupHostByName(String host, int netId) 101c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath throws UnknownHostException { 102c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath BlockGuard.getThreadPolicy().onNetwork(); 103c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // Do we have a result cached? 104c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath Object cachedResult = addressCache.get(host, netId); 105c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath if (cachedResult != null) { 106c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath if (cachedResult instanceof InetAddress[]) { 107c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // A cached positive result. 108c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath return (InetAddress[]) cachedResult; 109c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } else { 110c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // A cached negative result. 111c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath throw new UnknownHostException((String) cachedResult); 112c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 113c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 114c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath try { 115c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath StructAddrinfo hints = new StructAddrinfo(); 116c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath hints.ai_flags = AI_ADDRCONFIG; 117c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath hints.ai_family = AF_UNSPEC; 118c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // If we don't specify a socket type, every address will appear twice, once 119c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // for SOCK_STREAM and one for SOCK_DGRAM. Since we do not return the family 120c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // anyway, just pick one. 121c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath hints.ai_socktype = SOCK_STREAM; 122c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath InetAddress[] addresses = Libcore.os.android_getaddrinfo(host, hints, netId); 123c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // TODO: should getaddrinfo set the hostname of the InetAddresses it returns? 124c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath for (InetAddress address : addresses) { 125c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath address.holder().hostName = host; 126c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 127c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath addressCache.put(host, netId, addresses); 128c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath return addresses; 129c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } catch (GaiException gaiException) { 130c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // If the failure appears to have been a lack of INTERNET permission, throw a clear 131c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // SecurityException to aid in debugging this common mistake. 132c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // http://code.google.com/p/android/issues/detail?id=15722 133c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath if (gaiException.getCause() instanceof ErrnoException) { 134c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath if (((ErrnoException) gaiException.getCause()).errno == EACCES) { 135c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath throw new SecurityException("Permission denied (missing INTERNET permission?)", gaiException); 136c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 137c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 138c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath // Otherwise, throw an UnknownHostException. 139c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error); 140c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath addressCache.putUnknownHost(host, netId, detailMessage); 141c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath throw gaiException.rethrowAsUnknownHostException(detailMessage); 142c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 143c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 144c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 145c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath @Override 146c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath public String getHostByAddr(byte[] addr) throws UnknownHostException { 147c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath BlockGuard.getThreadPolicy().onNetwork(); 148c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 149c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath return getHostByAddr0(addr); 150c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 151c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 152c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath @Override 153c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath public void clearAddressCache() { 154c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath addressCache.clear(); 155c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath } 156c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 157c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath @Override 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif, int ttl) throws IOException { 1592be229c284db4293a86200fa800886fed137e567Yi Kong // Android-changed: rewritten on the top of IoBridge and Libcore.os 1602be229c284db4293a86200fa800886fed137e567Yi Kong InetAddress sourceAddr = null; 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (netif != null) { 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Let's make sure we bind to an address of the proper family. 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Which means same family as addr because at this point it could 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be either an IPv6 address or an IPv4 address (case of a dual 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stack system). 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 1683a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong java.util.Enumeration<InetAddress> it = netif.getInetAddresses(); 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress inetaddr = null; 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (it.hasMoreElements()) { 1713a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong inetaddr = it.nextElement(); 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inetaddr.getClass().isInstance(addr)) { 1732be229c284db4293a86200fa800886fed137e567Yi Kong sourceAddr = inetaddr; 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1772be229c284db4293a86200fa800886fed137e567Yi Kong 1782be229c284db4293a86200fa800886fed137e567Yi Kong if (sourceAddr == null) { 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Interface doesn't support the address family of 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the destination 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 184c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath 18548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong // Try ICMP first 18648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong if (icmpEcho(addr, timeout, sourceAddr, ttl)) { 18748e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong return true; 18848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 18948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 19048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong // No good, let's fall back to TCP 19148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong return tcpEcho(addr, timeout, sourceAddr, ttl); 19248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 19348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 19448e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong private boolean tcpEcho(InetAddress addr, int timeout, InetAddress sourceAddr, int ttl) 19548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong throws IOException { 19648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong FileDescriptor fd = null; 197838dc8ab4b456d91e56b46f7deb76a8f97145563Narayan Kamath try { 19848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong fd = IoBridge.socket(AF_INET6, SOCK_STREAM, 0); 19948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong if (ttl > 0) { 20048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong IoBridge.setSocketOption(fd, IoBridge.JAVA_IP_TTL, ttl); 20148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 2022be229c284db4293a86200fa800886fed137e567Yi Kong if (sourceAddr != null) { 2032be229c284db4293a86200fa800886fed137e567Yi Kong IoBridge.bind(fd, sourceAddr, 0); 2042be229c284db4293a86200fa800886fed137e567Yi Kong } 2052be229c284db4293a86200fa800886fed137e567Yi Kong IoBridge.connect(fd, addr, 7 /* Echo-protocol port */, timeout); 2062be229c284db4293a86200fa800886fed137e567Yi Kong return true; 2072be229c284db4293a86200fa800886fed137e567Yi Kong } catch (IOException e) { 2082be229c284db4293a86200fa800886fed137e567Yi Kong // Connection refused by remote (ECONNREFUSED) implies reachable. Otherwise silently 2092be229c284db4293a86200fa800886fed137e567Yi Kong // ignore the exception and return false. 2102be229c284db4293a86200fa800886fed137e567Yi Kong Throwable cause = e.getCause(); 2112be229c284db4293a86200fa800886fed137e567Yi Kong return cause instanceof ErrnoException 2122be229c284db4293a86200fa800886fed137e567Yi Kong && ((ErrnoException) cause).errno == ECONNREFUSED; 2132be229c284db4293a86200fa800886fed137e567Yi Kong } finally { 2142be229c284db4293a86200fa800886fed137e567Yi Kong IoBridge.closeAndSignalBlockedThreads(fd); 215838dc8ab4b456d91e56b46f7deb76a8f97145563Narayan Kamath } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong protected boolean icmpEcho(InetAddress addr, int timeout, InetAddress sourceAddr, int ttl) 21948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong throws IOException { 22048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 22148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong FileDescriptor fd = null; 22248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong try { 22348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong boolean isIPv4 = addr instanceof Inet4Address; 22448e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong int domain = isIPv4 ? AF_INET : AF_INET6; 22548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong int icmpProto = isIPv4 ? IPPROTO_ICMP : IPPROTO_ICMPV6; 22648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong fd = IoBridge.socket(domain, SOCK_DGRAM, icmpProto); 22748e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 22848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong if (ttl > 0) { 22948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong IoBridge.setSocketOption(fd, IoBridge.JAVA_IP_TTL, ttl); 23048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 23148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong if (sourceAddr != null) { 23248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong IoBridge.bind(fd, sourceAddr, 0); 23348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 23448e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 23548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong byte[] packet; 23648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 23748e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong // ICMP is unreliable, try sending requests every second until timeout. 23848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong for (int to = timeout, seq = 0; to > 0; ++seq) { 23948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong int sockTo = to >= 1000 ? 1000 : to; 24048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 24148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong IoBridge.setSocketOption(fd, SocketOptions.SO_TIMEOUT, sockTo); 24248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 24348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong packet = StructIcmpHdr.IcmpEchoHdr(isIPv4, seq).getBytes(); 24448e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong IoBridge.sendto(fd, packet, 0, packet.length, 0, addr, 0); 24548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong final int icmpId = IoBridge.getSocketLocalPort(fd); 24648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 24748e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong byte[] received = new byte[packet.length]; 24848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong DatagramPacket receivedPacket = new DatagramPacket(received, packet.length); 24948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong int size = IoBridge 25048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong .recvfrom(true, fd, received, 0, received.length, 0, receivedPacket, false); 25148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong if (size == packet.length) { 25248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong byte expectedType = isIPv4 ? (byte) ICMP_ECHOREPLY 25348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong : (byte) ICMP6_ECHO_REPLY; 25448e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong if (receivedPacket.getAddress().equals(addr) 25548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong && received[0] == expectedType 25648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong && received[4] == (byte) (icmpId >> 8) 25748e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong && received[5] == (byte) icmpId 25848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong && received[6] == (byte) (seq >> 8) 25948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong && received[7] == (byte) seq) { 26048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong // This is the packet we're expecting. 26148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong return true; 26248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 26348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 26448e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong to -= sockTo; 26548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 26648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } catch (IOException e) { 26748e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong // Silently ignore and fall back. 26848e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } finally { 26948e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong try { 27048e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong Libcore.os.close(fd); 27148e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } catch (ErrnoException e) { } 27248e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 27348e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 27448e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong return false; 27548e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong } 27648e205e5e0bc55b5c7b11df445da39c5be890623Yi Kong 277c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath @Override 278c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath public InetAddress anyLocalAddress() { 2795427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath synchronized (Inet6AddressImpl.class) { 2805427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // We avoid initializing anyLocalAddress during <clinit> to avoid issues 2815427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // caused by the dependency chains of these classes. InetAddress depends on 2825427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // InetAddressImpl, but Inet6Address & Inet4Address are its subclasses. 2835427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // Also see {@code loopbackAddresses). 2845427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath if (anyLocalAddress == null) { 2855427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath Inet6Address anyAddress = new Inet6Address(); 2865427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath anyAddress.holder().hostName = "::"; 2875427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath anyLocalAddress = anyAddress; 2885427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath } 2895427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath 2905427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath return anyLocalAddress; 2915427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath } 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 294c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath @Override 295c2614bb1297234d89f1a428a8b589bb1373a68ddNarayan Kamath public InetAddress[] loopbackAddresses() { 2965427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath synchronized (Inet6AddressImpl.class) { 2975427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // We avoid initializing anyLocalAddress during <clinit> to avoid issues 2985427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // caused by the dependency chains of these classes. InetAddress depends on 2995427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // InetAddressImpl, but Inet6Address & Inet4Address are its subclasses. 3005427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath // Also see {@code anyLocalAddress). 3015427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath if (loopbackAddresses == null) { 3025427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath loopbackAddresses = new InetAddress[]{Inet6Address.LOOPBACK, Inet4Address.LOOPBACK}; 3035427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath } 3045427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath 3055427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath return loopbackAddresses; 3065427c8d283752ae3c41fb0bb083d562060c5be08Narayan Kamath } 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 309b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong private String getHostByAddr0(byte[] addr) throws UnknownHostException { 310b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong // Android-changed: Rewritten on the top of Libcore.os 311b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong InetAddress hostaddr = InetAddress.getByAddress(addr); 312b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong try { 313b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong return Libcore.os.getnameinfo(hostaddr, NI_NAMEREQD); 314b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong } catch (GaiException e) { 315b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong UnknownHostException uhe = new UnknownHostException(hostaddr.toString()); 316b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong uhe.initCause(e); 317b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong throw uhe; 318b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong } 319b11d8b52b4ea85ab56a033fc76b21bf3b50a1b3eYi Kong } 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 321