Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package java.net;
     28 
     29 import java.io.ObjectStreamException;
     30 import java.io.ObjectStreamField;
     31 import java.io.IOException;
     32 import java.io.ObjectInputStream;
     33 import java.io.ObjectInputStream.GetField;
     34 import java.io.ObjectOutputStream;
     35 import java.io.ObjectOutputStream.PutField;
     36 import sun.net.util.IPAddressUtil;
     37 import sun.net.spi.nameservice.*;
     38 import android.system.GaiException;
     39 import android.system.StructAddrinfo;
     40 import libcore.io.Libcore;
     41 import static android.system.OsConstants.*;
     42 
     43 /**
     44  * This class represents an Internet Protocol (IP) address.
     45  *
     46  * <p> An IP address is either a 32-bit or 128-bit unsigned number
     47  * used by IP, a lower-level protocol on which protocols like UDP and
     48  * TCP are built. The IP address architecture is defined by <a
     49  * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC&nbsp;790:
     50  * Assigned Numbers</i></a>, <a
     51  * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC&nbsp;1918:
     52  * Address Allocation for Private Internets</i></a>, <a
     53  * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC&nbsp;2365:
     54  * Administratively Scoped IP Multicast</i></a>, and <a
     55  * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IP
     56  * Version 6 Addressing Architecture</i></a>. An instance of an
     57  * InetAddress consists of an IP address and possibly its
     58  * corresponding host name (depending on whether it is constructed
     59  * with a host name or whether it has already done reverse host name
     60  * resolution).
     61  *
     62  * <h3> Address types </h3>
     63  *
     64  * <blockquote><table cellspacing=2 summary="Description of unicast and multicast address types">
     65  *   <tr><th valign=top><i>unicast</i></th>
     66  *       <td>An identifier for a single interface. A packet sent to
     67  *         a unicast address is delivered to the interface identified by
     68  *         that address.
     69  *
     70  *         <p> The Unspecified Address -- Also called anylocal or wildcard
     71  *         address. It must never be assigned to any node. It indicates the
     72  *         absence of an address. One example of its use is as the target of
     73  *         bind, which allows a server to accept a client connection on any
     74  *         interface, in case the server host has multiple interfaces.
     75  *
     76  *         <p> The <i>unspecified</i> address must not be used as
     77  *         the destination address of an IP packet.
     78  *
     79  *         <p> The <i>Loopback</i> Addresses -- This is the address
     80  *         assigned to the loopback interface. Anything sent to this
     81  *         IP address loops around and becomes IP input on the local
     82  *         host. This address is often used when testing a
     83  *         client.</td></tr>
     84  *   <tr><th valign=top><i>multicast</i></th>
     85  *       <td>An identifier for a set of interfaces (typically belonging
     86  *         to different nodes). A packet sent to a multicast address is
     87  *         delivered to all interfaces identified by that address.</td></tr>
     88  * </table></blockquote>
     89  *
     90  * <h4> IP address scope </h4>
     91  *
     92  * <p> <i>Link-local</i> addresses are designed to be used for addressing
     93  * on a single link for purposes such as auto-address configuration,
     94  * neighbor discovery, or when no routers are present.
     95  *
     96  * <p> <i>Site-local</i> addresses are designed to be used for addressing
     97  * inside of a site without the need for a global prefix.
     98  *
     99  * <p> <i>Global</i> addresses are unique across the internet.
    100  *
    101  * <h4> Textual representation of IP addresses </h4>
    102  *
    103  * The textual representation of an IP address is address family specific.
    104  *
    105  * <p>
    106  *
    107  * For IPv4 address format, please refer to <A
    108  * HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6
    109  * address format, please refer to <A
    110  * HREF="Inet6Address.html#format">Inet6Address#format</A>.
    111  *
    112  * <P>There is a <a href="doc-files/net-properties.html#Ipv4IPv6">couple of
    113  * System Properties</a> affecting how IPv4 and IPv6 addresses are used.</P>
    114  *
    115  * <h4> Host Name Resolution </h4>
    116  *
    117  * Host name-to-IP address <i>resolution</i> is accomplished through
    118  * the use of a combination of local machine configuration information
    119  * and network naming services such as the Domain Name System (DNS)
    120  * and Network Information Service(NIS). The particular naming
    121  * services(s) being used is by default the local machine configured
    122  * one. For any host name, its corresponding IP address is returned.
    123  *
    124  * <p> <i>Reverse name resolution</i> means that for any IP address,
    125  * the host associated with the IP address is returned.
    126  *
    127  * <p> The InetAddress class provides methods to resolve host names to
    128  * their IP addresses and vice versa.
    129  *
    130  * <h4> InetAddress Caching </h4>
    131  *
    132  * The InetAddress class has a cache to store successful as well as
    133  * unsuccessful host name resolutions.
    134  *
    135  * <p> By default, when a security manager is installed, in order to
    136  * protect against DNS spoofing attacks,
    137  * the result of positive host name resolutions are
    138  * cached forever. When a security manager is not installed, the default
    139  * behavior is to cache entries for a finite (implementation dependent)
    140  * period of time. The result of unsuccessful host
    141  * name resolution is cached for a very short period of time (10
    142  * seconds) to improve performance.
    143  *
    144  * <p> If the default behavior is not desired, then a Java security property
    145  * can be set to a different Time-to-live (TTL) value for positive
    146  * caching. Likewise, a system admin can configure a different
    147  * negative caching TTL value when needed.
    148  *
    149  * <p> Two Java security properties control the TTL values used for
    150  *  positive and negative host name resolution caching:
    151  *
    152  * <blockquote>
    153  * <dl>
    154  * <dt><b>networkaddress.cache.ttl</b></dt>
    155  * <dd>Indicates the caching policy for successful name lookups from
    156  * the name service. The value is specified as as integer to indicate
    157  * the number of seconds to cache the successful lookup. The default
    158  * setting is to cache for an implementation specific period of time.
    159  * <p>
    160  * A value of -1 indicates "cache forever".
    161  * </dd>
    162  * <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
    163  * <dd>Indicates the caching policy for un-successful name lookups
    164  * from the name service. The value is specified as as integer to
    165  * indicate the number of seconds to cache the failure for
    166  * un-successful lookups.
    167  * <p>
    168  * A value of 0 indicates "never cache".
    169  * A value of -1 indicates "cache forever".
    170  * </dd>
    171  * </dl>
    172  * </blockquote>
    173  *
    174  * @author  Chris Warth
    175  * @see     java.net.InetAddress#getByAddress(byte[])
    176  * @see     java.net.InetAddress#getByAddress(java.lang.String, byte[])
    177  * @see     java.net.InetAddress#getAllByName(java.lang.String)
    178  * @see     java.net.InetAddress#getByName(java.lang.String)
    179  * @see     java.net.InetAddress#getLocalHost()
    180  * @since JDK1.0
    181  */
    182 public
    183 class InetAddress implements java.io.Serializable {
    184     // BEGIN Android-removed: Android uses linux-based OsConstants.
    185     /*
    186      * Specify the address family: Internet Protocol, Version 4
    187      * @since 1.4
    188      *
    189     static final int IPv4 = 1;
    190 
    191     /**
    192      * Specify the address family: Internet Protocol, Version 6
    193      * @since 1.4
    194      *
    195     static final int IPv6 = 2;
    196     */
    197     // END Android-removed: Android uses linux-based OsConstants.
    198 
    199     // Android-removed: Android doesn't support the preference.
    200     // /* Specify address family preference */
    201     //static transient boolean preferIPv6Address = false;
    202 
    203     static class InetAddressHolder {
    204         /**
    205          * Reserve the original application specified hostname.
    206          *
    207          * The original hostname is useful for domain-based endpoint
    208          * identification (see RFC 2818 and RFC 6125).  If an address
    209          * was created with a raw IP address, a reverse name lookup
    210          * may introduce endpoint identification security issue via
    211          * DNS forging.
    212          *
    213          * Oracle JSSE provider is using this original hostname, via
    214          * sun.misc.JavaNetAccess, for SSL/TLS endpoint identification.
    215          *
    216          * Note: May define a new public method in the future if necessary.
    217          */
    218         String originalHostName;
    219 
    220         InetAddressHolder() {}
    221 
    222         InetAddressHolder(String hostName, int address, int family) {
    223             this.originalHostName = hostName;
    224             this.hostName = hostName;
    225             this.address = address;
    226             this.family = family;
    227         }
    228 
    229         void init(String hostName, int family) {
    230             this.originalHostName = hostName;
    231             this.hostName = hostName;
    232             if (family != -1) {
    233                 this.family = family;
    234             }
    235         }
    236 
    237         String hostName;
    238 
    239         String getHostName() {
    240             return hostName;
    241         }
    242 
    243         String getOriginalHostName() {
    244             return originalHostName;
    245         }
    246 
    247         /**
    248          * Holds a 32-bit IPv4 address.
    249          */
    250         int address;
    251 
    252         int getAddress() {
    253             return address;
    254         }
    255 
    256         // Android-changed: Documentation: use Linux-based OsConstants.
    257         /**
    258          * Specifies the address family type, for instance, AF_INET for IPv4
    259          * addresses, and AF_INET6 for IPv6 addresses.
    260          */
    261         int family;
    262 
    263         int getFamily() {
    264             return family;
    265         }
    266     }
    267 
    268     transient InetAddressHolder holder;
    269 
    270     InetAddressHolder holder() {
    271         return holder;
    272     }
    273 
    274     /* The implementation is always dual stack IPv6/IPv4 on android */
    275     static final InetAddressImpl impl = new Inet6AddressImpl();
    276 
    277     /* Used to store the name service provider */
    278     // Android-changed: Android has only one name service.
    279     // Android doesn't allow user to provide custom name services.
    280     // private static List<NameService> nameServices = null;
    281     private static final NameService nameService = new NameService() {
    282         public InetAddress[] lookupAllHostAddr(String host, int netId)
    283                 throws UnknownHostException {
    284             return impl.lookupAllHostAddr(host, netId);
    285         }
    286         public String getHostByAddr(byte[] addr)
    287                 throws UnknownHostException {
    288             return impl.getHostByAddr(addr);
    289         }
    290     };
    291 
    292     /* Used to store the best available hostname */
    293     private transient String canonicalHostName = null;
    294 
    295     /** use serialVersionUID from JDK 1.0.2 for interoperability */
    296     private static final long serialVersionUID = 3286316764910316507L;
    297 
    298 
    299     // BEGIN Android-removed: Android doesn't need to load native library.
    300     /*
    301      * Load net library into runtime, and perform initializations.
    302      *
    303     static {
    304         preferIPv6Address = java.security.AccessController.doPrivileged(
    305             new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue();
    306         AccessController.doPrivileged(
    307             new java.security.PrivilegedAction<Void>() {
    308                 public Void run() {
    309                     System.loadLibrary("net");
    310                     return null;
    311                 }
    312             });
    313         init();
    314     }
    315     */
    316     // END Android-removed: Android doesn't need to load native library.
    317 
    318     /**
    319      * Constructor for the Socket.accept() method.
    320      * This creates an empty InetAddress, which is filled in by
    321      * the accept() method.  This InetAddress, however, is not
    322      * put in the address cache, since it is not created by name.
    323      */
    324     InetAddress() {
    325         holder = new InetAddressHolder();
    326     }
    327 
    328     /**
    329      * Replaces the de-serialized object with an Inet4Address object.
    330      *
    331      * @return the alternate object to the de-serialized object.
    332      *
    333      * @throws ObjectStreamException if a new object replacing this
    334      * object could not be created
    335      */
    336     private Object readResolve() throws ObjectStreamException {
    337         // will replace the deserialized 'this' object
    338         return new Inet4Address(holder().getHostName(), holder().getAddress());
    339     }
    340 
    341     /**
    342      * Utility routine to check if the InetAddress is an
    343      * IP multicast address.
    344      * @return a {@code boolean} indicating if the InetAddress is
    345      * an IP multicast address
    346      * @since   JDK1.1
    347      */
    348     public boolean isMulticastAddress() {
    349         return false;
    350     }
    351 
    352     /**
    353      * Utility routine to check if the InetAddress in a wildcard address.
    354      * @return a {@code boolean} indicating if the Inetaddress is
    355      *         a wildcard address.
    356      * @since 1.4
    357      */
    358     public boolean isAnyLocalAddress() {
    359         return false;
    360     }
    361 
    362     /**
    363      * Utility routine to check if the InetAddress is a loopback address.
    364      *
    365      * @return a {@code boolean} indicating if the InetAddress is
    366      * a loopback address; or false otherwise.
    367      * @since 1.4
    368      */
    369     public boolean isLoopbackAddress() {
    370         return false;
    371     }
    372 
    373     /**
    374      * Utility routine to check if the InetAddress is an link local address.
    375      *
    376      * @return a {@code boolean} indicating if the InetAddress is
    377      * a link local address; or false if address is not a link local unicast address.
    378      * @since 1.4
    379      */
    380     public boolean isLinkLocalAddress() {
    381         return false;
    382     }
    383 
    384     /**
    385      * Utility routine to check if the InetAddress is a site local address.
    386      *
    387      * @return a {@code boolean} indicating if the InetAddress is
    388      * a site local address; or false if address is not a site local unicast address.
    389      * @since 1.4
    390      */
    391     public boolean isSiteLocalAddress() {
    392         return false;
    393     }
    394 
    395     /**
    396      * Utility routine to check if the multicast address has global scope.
    397      *
    398      * @return a {@code boolean} indicating if the address has
    399      *         is a multicast address of global scope, false if it is not
    400      *         of global scope or it is not a multicast address
    401      * @since 1.4
    402      */
    403     public boolean isMCGlobal() {
    404         return false;
    405     }
    406 
    407     /**
    408      * Utility routine to check if the multicast address has node scope.
    409      *
    410      * @return a {@code boolean} indicating if the address has
    411      *         is a multicast address of node-local scope, false if it is not
    412      *         of node-local scope or it is not a multicast address
    413      * @since 1.4
    414      */
    415     public boolean isMCNodeLocal() {
    416         return false;
    417     }
    418 
    419     /**
    420      * Utility routine to check if the multicast address has link scope.
    421      *
    422      * @return a {@code boolean} indicating if the address has
    423      *         is a multicast address of link-local scope, false if it is not
    424      *         of link-local scope or it is not a multicast address
    425      * @since 1.4
    426      */
    427     public boolean isMCLinkLocal() {
    428         return false;
    429     }
    430 
    431     /**
    432      * Utility routine to check if the multicast address has site scope.
    433      *
    434      * @return a {@code boolean} indicating if the address has
    435      *         is a multicast address of site-local scope, false if it is not
    436      *         of site-local scope or it is not a multicast address
    437      * @since 1.4
    438      */
    439     public boolean isMCSiteLocal() {
    440         return false;
    441     }
    442 
    443     /**
    444      * Utility routine to check if the multicast address has organization scope.
    445      *
    446      * @return a {@code boolean} indicating if the address has
    447      *         is a multicast address of organization-local scope,
    448      *         false if it is not of organization-local scope
    449      *         or it is not a multicast address
    450      * @since 1.4
    451      */
    452     public boolean isMCOrgLocal() {
    453         return false;
    454     }
    455 
    456 
    457     // Android-changed: Document that impl tries ICMP ECHO REQUESTs first.
    458     // The sole implementation, Inet6AddressImpl.isReachable(), tries ICMP ECHO REQUESTs before
    459     // TCP ECHO REQUESTs on Android. On Android, these are both possible without root access.
    460     /**
    461      * Test whether that address is reachable. Best effort is made by the
    462      * implementation to try to reach the host, but firewalls and server
    463      * configuration may block requests resulting in a unreachable status
    464      * while some specific ports may be accessible.
    465      * <p>
    466      * Android implementation attempts ICMP ECHO REQUESTs first, on failure it
    467      * will fall back to TCP ECHO REQUESTs. Success on either protocol will
    468      * return true.
    469      * <p>
    470      * The timeout value, in milliseconds, indicates the maximum amount of time
    471      * the try should take. If the operation times out before getting an
    472      * answer, the host is deemed unreachable. A negative value will result
    473      * in an IllegalArgumentException being thrown.
    474      *
    475      * @param   timeout the time, in milliseconds, before the call aborts
    476      * @return a {@code boolean} indicating if the address is reachable.
    477      * @throws IOException if a network error occurs
    478      * @throws  IllegalArgumentException if {@code timeout} is negative.
    479      * @since 1.5
    480      */
    481     public boolean isReachable(int timeout) throws IOException {
    482         return isReachable(null, 0 , timeout);
    483     }
    484 
    485     // Android-changed: Document that impl tries ICMP ECHO REQUESTs first.
    486     // The sole implementation, Inet6AddressImpl.isReachable(), tries ICMP ECHO REQUESTs before
    487     // TCP ECHO REQUESTs on Android. On Android, these are both possible without root access.
    488     /**
    489      * Test whether that address is reachable. Best effort is made by the
    490      * implementation to try to reach the host, but firewalls and server
    491      * configuration may block requests resulting in a unreachable status
    492      * while some specific ports may be accessible.
    493      * <p>
    494      * Android implementation attempts ICMP ECHO REQUESTs first, on failure it
    495      * will fall back to TCP ECHO REQUESTs. Success on either protocol will
    496      * return true.
    497      * <p>
    498      * The {@code network interface} and {@code ttl} parameters
    499      * let the caller specify which network interface the test will go through
    500      * and the maximum number of hops the packets should go through.
    501      * A negative value for the {@code ttl} will result in an
    502      * IllegalArgumentException being thrown.
    503      * <p>
    504      * The timeout value, in milliseconds, indicates the maximum amount of time
    505      * the try should take. If the operation times out before getting an
    506      * answer, the host is deemed unreachable. A negative value will result
    507      * in an IllegalArgumentException being thrown.
    508      *
    509      * @param   netif   the NetworkInterface through which the
    510      *                    test will be done, or null for any interface
    511      * @param   ttl     the maximum numbers of hops to try or 0 for the
    512      *                  default
    513      * @param   timeout the time, in milliseconds, before the call aborts
    514      * @throws  IllegalArgumentException if either {@code timeout}
    515      *                          or {@code ttl} are negative.
    516      * @return a {@code boolean}indicating if the address is reachable.
    517      * @throws IOException if a network error occurs
    518      * @since 1.5
    519      */
    520     public boolean isReachable(NetworkInterface netif, int ttl,
    521                                int timeout) throws IOException {
    522         if (ttl < 0)
    523             throw new IllegalArgumentException("ttl can't be negative");
    524         if (timeout < 0)
    525             throw new IllegalArgumentException("timeout can't be negative");
    526 
    527         return impl.isReachable(this, timeout, netif, ttl);
    528     }
    529 
    530     // BEGIN Android-added: isReachableByICMP(timeout).
    531     /**
    532      * @hide For testing only
    533      */
    534     public boolean isReachableByICMP(int timeout) throws IOException {
    535         return ((Inet6AddressImpl) impl).icmpEcho(this, timeout, null, 0);
    536     }
    537     // END Android-added: isReachableByICMP(timeout).
    538 
    539     /**
    540      * Gets the host name for this IP address.
    541      *
    542      * <p>If this InetAddress was created with a host name,
    543      * this host name will be remembered and returned;
    544      * otherwise, a reverse name lookup will be performed
    545      * and the result will be returned based on the system
    546      * configured name lookup service. If a lookup of the name service
    547      * is required, call
    548      * {@link #getCanonicalHostName() getCanonicalHostName}.
    549      *
    550      * <p>If there is a security manager, its
    551      * {@code checkConnect} method is first called
    552      * with the hostname and {@code -1}
    553      * as its arguments to see if the operation is allowed.
    554      * If the operation is not allowed, it will return
    555      * the textual representation of the IP address.
    556      *
    557      * @return  the host name for this IP address, or if the operation
    558      *    is not allowed by the security check, the textual
    559      *    representation of the IP address.
    560      *
    561      * @see InetAddress#getCanonicalHostName
    562      * @see SecurityManager#checkConnect
    563      */
    564     public String getHostName() {
    565         // Android-changed: Remove SecurityManager check.
    566         if (holder().getHostName() == null) {
    567             holder().hostName = InetAddress.getHostFromNameService(this);
    568         }
    569         return holder().getHostName();
    570     }
    571 
    572     // BEGIN Android-removed: Android doesn't support SecurityManager.
    573     /*
    574      * Returns the hostname for this address.
    575      * If the host is equal to null, then this address refers to any
    576      * of the local machine's available network addresses.
    577      * this is package private so SocketPermission can make calls into
    578      * here without a security check.
    579      *
    580      * <p>If there is a security manager, this method first
    581      * calls its {@code checkConnect} method
    582      * with the hostname and {@code -1}
    583      * as its arguments to see if the calling code is allowed to know
    584      * the hostname for this IP address, i.e., to connect to the host.
    585      * If the operation is not allowed, it will return
    586      * the textual representation of the IP address.
    587      *
    588      * @return  the host name for this IP address, or if the operation
    589      *    is not allowed by the security check, the textual
    590      *    representation of the IP address.
    591      *
    592      * @param check make security check if true
    593      *
    594      * @see SecurityManager#checkConnect
    595      *
    596     String getHostName(boolean check) {
    597         if (holder().getHostName() == null) {
    598             holder().hostName = InetAddress.getHostFromNameService(this, check);
    599         }
    600         return holder().getHostName();
    601     }
    602     */
    603     // END Android-removed: Android doesn't support SecurityManager.
    604 
    605     /**
    606      * Gets the fully qualified domain name for this IP address.
    607      * Best effort method, meaning we may not be able to return
    608      * the FQDN depending on the underlying system configuration.
    609      *
    610      * <p>If there is a security manager, this method first
    611      * calls its {@code checkConnect} method
    612      * with the hostname and {@code -1}
    613      * as its arguments to see if the calling code is allowed to know
    614      * the hostname for this IP address, i.e., to connect to the host.
    615      * If the operation is not allowed, it will return
    616      * the textual representation of the IP address.
    617      *
    618      * @return  the fully qualified domain name for this IP address,
    619      *    or if the operation is not allowed by the security check,
    620      *    the textual representation of the IP address.
    621      *
    622      * @see SecurityManager#checkConnect
    623      *
    624      * @since 1.4
    625      */
    626     public String getCanonicalHostName() {
    627         // Android-changed: Remove SecurityManager check.
    628         if (canonicalHostName == null) {
    629             canonicalHostName = InetAddress.getHostFromNameService(this);
    630         }
    631         return canonicalHostName;
    632     }
    633 
    634     // Android-changed: Remove SecurityManager check.
    635     // * @param check make security check if true
    636     /**
    637      * Returns the hostname for this address.
    638      *
    639      * <p>If there is a security manager, this method first
    640      * calls its {@code checkConnect} method
    641      * with the hostname and {@code -1}
    642      * as its arguments to see if the calling code is allowed to know
    643      * the hostname for this IP address, i.e., to connect to the host.
    644      * If the operation is not allowed, it will return
    645      * the textual representation of the IP address.
    646      *
    647      * @return  the host name for this IP address, or if the operation
    648      *    is not allowed by the security check, the textual
    649      *    representation of the IP address.
    650      *
    651      * @see SecurityManager#checkConnect
    652      */
    653     private static String getHostFromNameService(InetAddress addr) {
    654         String host = null;
    655         try {
    656             // first lookup the hostname
    657             // Android-changed: Android has only one name service.
    658             host = nameService.getHostByAddr(addr.getAddress());
    659 
    660                 /* now get all the IP addresses for this hostname,
    661                  * and make sure one of them matches the original IP
    662                  * address. We do this to try and prevent spoofing.
    663                  */
    664             InetAddress[] arr = nameService.lookupAllHostAddr(host, NETID_UNSET);
    665             boolean ok = false;
    666 
    667             if (arr != null) {
    668                 for(int i = 0; !ok && i < arr.length; i++) {
    669                     ok = addr.equals(arr[i]);
    670                 }
    671             }
    672 
    673             //XXX: if it looks a spoof just return the address?
    674             if (!ok) {
    675                 host = addr.getHostAddress();
    676                 return host;
    677             }
    678         } catch (UnknownHostException e) {
    679             host = addr.getHostAddress();
    680         }
    681 
    682         return host;
    683     }
    684 
    685     /**
    686      * Returns the raw IP address of this {@code InetAddress}
    687      * object. The result is in network byte order: the highest order
    688      * byte of the address is in {@code getAddress()[0]}.
    689      *
    690      * @return  the raw IP address of this object.
    691      */
    692     public byte[] getAddress() {
    693         return null;
    694     }
    695 
    696     /**
    697      * Returns the IP address string in textual presentation.
    698      *
    699      * @return  the raw IP address in a string format.
    700      * @since   JDK1.0.2
    701      */
    702     public String getHostAddress() {
    703         return null;
    704      }
    705 
    706     /**
    707      * Returns a hashcode for this IP address.
    708      *
    709      * @return  a hash code value for this IP address.
    710      */
    711     public int hashCode() {
    712         return -1;
    713     }
    714 
    715     /**
    716      * Compares this object against the specified object.
    717      * The result is {@code true} if and only if the argument is
    718      * not {@code null} and it represents the same IP address as
    719      * this object.
    720      * <p>
    721      * Two instances of {@code InetAddress} represent the same IP
    722      * address if the length of the byte arrays returned by
    723      * {@code getAddress} is the same for both, and each of the
    724      * array components is the same for the byte arrays.
    725      *
    726      * @param   obj   the object to compare against.
    727      * @return  {@code true} if the objects are the same;
    728      *          {@code false} otherwise.
    729      * @see     java.net.InetAddress#getAddress()
    730      */
    731     public boolean equals(Object obj) {
    732         return false;
    733     }
    734 
    735     /**
    736      * Converts this IP address to a {@code String}. The
    737      * string returned is of the form: hostname / literal IP
    738      * address.
    739      *
    740      * If the host name is unresolved, no reverse name service lookup
    741      * is performed. The hostname part will be represented by an empty string.
    742      *
    743      * @return  a string representation of this IP address.
    744      */
    745     public String toString() {
    746         String hostName = holder().getHostName();
    747         return ((hostName != null) ? hostName : "")
    748             + "/" + getHostAddress();
    749     }
    750 
    751     // BEGIN Android-removed: Resolves a hostname using Libcore.os.
    752     /*
    753      * Cached addresses - our own litle nis, not!
    754      *
    755     private static Cache addressCache = new Cache(Cache.Type.Positive);
    756 
    757     private static Cache negativeCache = new Cache(Cache.Type.Negative);
    758 
    759     private static boolean addressCacheInit = false;
    760 
    761     static InetAddress[]    unknown_array; // put THIS in cache
    762 
    763     static InetAddressImpl  impl;
    764 
    765     private static final HashMap<String, Void> lookupTable = new HashMap<>();
    766 
    767     /**
    768      * Represents a cache entry
    769      *
    770     static final class CacheEntry {
    771 
    772         CacheEntry(InetAddress[] addresses, long expiration) {
    773             this.addresses = addresses;
    774             this.expiration = expiration;
    775         }
    776 
    777         InetAddress[] addresses;
    778         long expiration;
    779     }
    780 
    781     /**
    782      * A cache that manages entries based on a policy specified
    783      * at creation time.
    784      *
    785     static final class Cache {
    786         private LinkedHashMap<String, CacheEntry> cache;
    787         private Type type;
    788 
    789         enum Type {Positive, Negative};
    790 
    791         /**
    792          * Create cache
    793          *
    794         public Cache(Type type) {
    795             this.type = type;
    796             cache = new LinkedHashMap<String, CacheEntry>();
    797         }
    798 
    799         private int getPolicy() {
    800             if (type == Type.Positive) {
    801                 return InetAddressCachePolicy.get();
    802             } else {
    803                 return InetAddressCachePolicy.getNegative();
    804             }
    805         }
    806 
    807         /**
    808          * Add an entry to the cache. If there's already an
    809          * entry then for this host then the entry will be
    810          * replaced.
    811          *
    812         public Cache put(String host, InetAddress[] addresses) {
    813             int policy = getPolicy();
    814             if (policy == InetAddressCachePolicy.NEVER) {
    815                 return this;
    816             }
    817 
    818             // purge any expired entries
    819 
    820             if (policy != InetAddressCachePolicy.FOREVER) {
    821 
    822                 // As we iterate in insertion order we can
    823                 // terminate when a non-expired entry is found.
    824                 LinkedList<String> expired = new LinkedList<>();
    825                 long now = System.currentTimeMillis();
    826                 for (String key : cache.keySet()) {
    827                     CacheEntry entry = cache.get(key);
    828 
    829                     if (entry.expiration >= 0 && entry.expiration < now) {
    830                         expired.add(key);
    831                     } else {
    832                         break;
    833                     }
    834                 }
    835 
    836                 for (String key : expired) {
    837                     cache.remove(key);
    838                 }
    839             }
    840 
    841             // create new entry and add it to the cache
    842             // -- as a HashMap replaces existing entries we
    843             //    don't need to explicitly check if there is
    844             //    already an entry for this host.
    845             long expiration;
    846             if (policy == InetAddressCachePolicy.FOREVER) {
    847                 expiration = -1;
    848             } else {
    849                 expiration = System.currentTimeMillis() + (policy * 1000);
    850             }
    851             CacheEntry entry = new CacheEntry(addresses, expiration);
    852             cache.put(host, entry);
    853             return this;
    854         }
    855 
    856         /**
    857          * Query the cache for the specific host. If found then
    858          * return its CacheEntry, or null if not found.
    859          *
    860         public CacheEntry get(String host) {
    861             int policy = getPolicy();
    862             if (policy == InetAddressCachePolicy.NEVER) {
    863                 return null;
    864             }
    865             CacheEntry entry = cache.get(host);
    866 
    867             // check if entry has expired
    868             if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
    869                 if (entry.expiration >= 0 &&
    870                         entry.expiration < System.currentTimeMillis()) {
    871                     cache.remove(host);
    872                     entry = null;
    873                 }
    874             }
    875 
    876             return entry;
    877         }
    878     }
    879 
    880     /*
    881      * Initialize cache and insert anyLocalAddress into the
    882      * unknown array with no expiry.
    883      *
    884     private static void cacheInitIfNeeded() {
    885         assert Thread.holdsLock(addressCache);
    886         if (addressCacheInit) {
    887             return;
    888         }
    889         unknown_array = new InetAddress[1];
    890         unknown_array[0] = impl.anyLocalAddress();
    891 
    892         addressCache.put(impl.anyLocalAddress().getHostName(),
    893                          unknown_array);
    894 
    895         addressCacheInit = true;
    896     }
    897 
    898     /*
    899      * Cache the given hostname and addresses.
    900      *
    901     private static void cacheAddresses(String hostname,
    902                                        InetAddress[] addresses,
    903                                        boolean success) {
    904         hostname = hostname.toLowerCase();
    905         synchronized (addressCache) {
    906             cacheInitIfNeeded();
    907             if (success) {
    908                 addressCache.put(hostname, addresses);
    909             } else {
    910                 negativeCache.put(hostname, addresses);
    911             }
    912         }
    913     }
    914 
    915     /*
    916      * Lookup hostname in cache (positive & negative cache). If
    917      * found return addresses, null if not found.
    918      *
    919     private static InetAddress[] getCachedAddresses(String hostname) {
    920         hostname = hostname.toLowerCase();
    921 
    922         // search both positive & negative caches
    923 
    924         synchronized (addressCache) {
    925             cacheInitIfNeeded();
    926 
    927             CacheEntry entry = addressCache.get(hostname);
    928             if (entry == null) {
    929                 entry = negativeCache.get(hostname);
    930             }
    931 
    932             if (entry != null) {
    933                 return entry.addresses;
    934             }
    935         }
    936 
    937         // not found
    938         return null;
    939     }
    940 
    941     private static NameService createNSProvider(String provider) {
    942         if (provider == null)
    943             return null;
    944 
    945         NameService nameService = null;
    946         if (provider.equals("default")) {
    947             // initialize the default name service
    948             nameService = new NameService() {
    949                 public InetAddress[] lookupAllHostAddr(String host)
    950                     throws UnknownHostException {
    951                     return impl.lookupAllHostAddr(host);
    952                 }
    953                 public String getHostByAddr(byte[] addr)
    954                     throws UnknownHostException {
    955                     return impl.getHostByAddr(addr);
    956                 }
    957             };
    958         } else {
    959             final String providerName = provider;
    960             try {
    961                 nameService = java.security.AccessController.doPrivileged(
    962                     new java.security.PrivilegedExceptionAction<NameService>() {
    963                         public NameService run() {
    964                             Iterator<NameServiceDescriptor> itr =
    965                                 ServiceLoader.load(NameServiceDescriptor.class)
    966                                     .iterator();
    967                             while (itr.hasNext()) {
    968                                 NameServiceDescriptor nsd = itr.next();
    969                                 if (providerName.
    970                                     equalsIgnoreCase(nsd.getType()+","
    971                                         +nsd.getProviderName())) {
    972                                     try {
    973                                         return nsd.createNameService();
    974                                     } catch (Exception e) {
    975                                         e.printStackTrace();
    976                                         System.err.println(
    977                                             "Cannot create name service:"
    978                                              +providerName+": " + e);
    979                                     }
    980                                 }
    981                             }
    982 
    983                             return null;
    984                         }
    985                     }
    986                 );
    987             } catch (java.security.PrivilegedActionException e) {
    988             }
    989         }
    990 
    991         return nameService;
    992     }
    993 
    994     static {
    995         // create the impl
    996         impl = InetAddressImplFactory.create();
    997 
    998         // get name service if provided and requested
    999         String provider = null;;
   1000         String propPrefix = "sun.net.spi.nameservice.provider.";
   1001         int n = 1;
   1002         nameServices = new ArrayList<NameService>();
   1003         provider = AccessController.doPrivileged(
   1004                 new GetPropertyAction(propPrefix + n));
   1005         while (provider != null) {
   1006             NameService ns = createNSProvider(provider);
   1007             if (ns != null)
   1008                 nameServices.add(ns);
   1009 
   1010             n++;
   1011             provider = AccessController.doPrivileged(
   1012                     new GetPropertyAction(propPrefix + n));
   1013         }
   1014 
   1015         // if not designate any name services provider,
   1016         // create a default one
   1017         if (nameServices.size() == 0) {
   1018             NameService ns = createNSProvider("default");
   1019             nameServices.add(ns);
   1020         }
   1021     }
   1022     */
   1023     // END Android-removed: Resolves a hostname using Libcore.os.
   1024 
   1025     /**
   1026      * Creates an InetAddress based on the provided host name and IP address.
   1027      * No name service is checked for the validity of the address.
   1028      *
   1029      * <p> The host name can either be a machine name, such as
   1030      * "{@code java.sun.com}", or a textual representation of its IP
   1031      * address.
   1032      * <p> No validity checking is done on the host name either.
   1033      *
   1034      * <p> If addr specifies an IPv4 address an instance of Inet4Address
   1035      * will be returned; otherwise, an instance of Inet6Address
   1036      * will be returned.
   1037      *
   1038      * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
   1039      * must be 16 bytes long
   1040      *
   1041      * @param host the specified host
   1042      * @param addr the raw IP address in network byte order
   1043      * @return  an InetAddress object created from the raw IP address.
   1044      * @exception  UnknownHostException  if IP address is of illegal length
   1045      * @since 1.4
   1046      */
   1047     public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException {
   1048         return getByAddress(host, addr, -1 /* scopeId */);
   1049     }
   1050 
   1051     // Android-added: Called by native code in Libcore.io.
   1052     // Do not delete. Called from native code.
   1053     private static InetAddress getByAddress(String host, byte[] addr, int scopeId)
   1054         throws UnknownHostException {
   1055         if (host != null && host.length() > 0 && host.charAt(0) == '[') {
   1056             if (host.charAt(host.length()-1) == ']') {
   1057                 host = host.substring(1, host.length() -1);
   1058             }
   1059         }
   1060         if (addr != null) {
   1061             if (addr.length == Inet4Address.INADDRSZ) {
   1062                 return new Inet4Address(host, addr);
   1063             } else if (addr.length == Inet6Address.INADDRSZ) {
   1064                 byte[] newAddr
   1065                     = IPAddressUtil.convertFromIPv4MappedAddress(addr);
   1066                 if (newAddr != null) {
   1067                     return new Inet4Address(host, newAddr);
   1068                 } else {
   1069                     return new Inet6Address(host, addr, scopeId);
   1070                 }
   1071             }
   1072         }
   1073         throw new UnknownHostException("addr is of illegal length");
   1074     }
   1075 
   1076 
   1077     /**
   1078      * Determines the IP address of a host, given the host's name.
   1079      *
   1080      * <p> The host name can either be a machine name, such as
   1081      * "{@code java.sun.com}", or a textual representation of its
   1082      * IP address. If a literal IP address is supplied, only the
   1083      * validity of the address format is checked.
   1084      *
   1085      * <p> For {@code host} specified in literal IPv6 address,
   1086      * either the form defined in RFC 2732 or the literal IPv6 address
   1087      * format defined in RFC 2373 is accepted. IPv6 scoped addresses are also
   1088      * supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
   1089      * scoped addresses.
   1090      *
   1091      * <p> If the host is {@code null} then an {@code InetAddress}
   1092      * representing an address of the loopback interface is returned.
   1093      * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
   1094      * section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
   1095      * section&nbsp;2.5.3. </p>
   1096      *
   1097      * @param      host   the specified host, or {@code null}.
   1098      * @return     an IP address for the given host name.
   1099      * @exception  UnknownHostException  if no IP address for the
   1100      *               {@code host} could be found, or if a scope_id was specified
   1101      *               for a global IPv6 address.
   1102      * @exception  SecurityException if a security manager exists
   1103      *             and its checkConnect method doesn't allow the operation
   1104      */
   1105     public static InetAddress getByName(String host)
   1106         throws UnknownHostException {
   1107         // Android-changed: Rewritten on the top of Libcore.os.
   1108         return impl.lookupAllHostAddr(host, NETID_UNSET)[0];
   1109     }
   1110 
   1111     /**
   1112      * Given the name of a host, returns an array of its IP addresses,
   1113      * based on the configured name service on the system.
   1114      *
   1115      * <p> The host name can either be a machine name, such as
   1116      * "{@code java.sun.com}", or a textual representation of its IP
   1117      * address. If a literal IP address is supplied, only the
   1118      * validity of the address format is checked.
   1119      *
   1120      * <p> For {@code host} specified in <i>literal IPv6 address</i>,
   1121      * either the form defined in RFC 2732 or the literal IPv6 address
   1122      * format defined in RFC 2373 is accepted. A literal IPv6 address may
   1123      * also be qualified by appending a scoped zone identifier or scope_id.
   1124      * The syntax and usage of scope_ids is described
   1125      * <a href="Inet6Address.html#scoped">here</a>.
   1126      * <p> If the host is {@code null} then an {@code InetAddress}
   1127      * representing an address of the loopback interface is returned.
   1128      * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
   1129      * section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
   1130      * section&nbsp;2.5.3. </p>
   1131      *
   1132      * <p> If there is a security manager and {@code host} is not
   1133      * null and {@code host.length() } is not equal to zero, the
   1134      * security manager's
   1135      * {@code checkConnect} method is called
   1136      * with the hostname and {@code -1}
   1137      * as its arguments to see if the operation is allowed.
   1138      *
   1139      * @param      host   the name of the host, or {@code null}.
   1140      * @return     an array of all the IP addresses for a given host name.
   1141      *
   1142      * @exception  UnknownHostException  if no IP address for the
   1143      *               {@code host} could be found, or if a scope_id was specified
   1144      *               for a global IPv6 address.
   1145      * @exception  SecurityException  if a security manager exists and its
   1146      *               {@code checkConnect} method doesn't allow the operation.
   1147      *
   1148      * @see SecurityManager#checkConnect
   1149      */
   1150     public static InetAddress[] getAllByName(String host)
   1151         throws UnknownHostException {
   1152         // Android-changed: Resolves a hostname using Libcore.os.
   1153         // Also, returns both the Inet4 and Inet6 loopback for null/empty host
   1154         return impl.lookupAllHostAddr(host, NETID_UNSET).clone();
   1155     }
   1156 
   1157     /**
   1158      * Returns the loopback address.
   1159      * <p>
   1160      * The InetAddress returned will represent the IPv4
   1161      * loopback address, 127.0.0.1, or the IPv6 loopback
   1162      * address, ::1. The IPv4 loopback address returned
   1163      * is only one of many in the form 127.*.*.*
   1164      *
   1165      * @return  the InetAddress loopback instance.
   1166      * @since 1.7
   1167      */
   1168     public static InetAddress getLoopbackAddress() {
   1169         // Android-changed: Always returns IPv6 loopback address in Android.
   1170         return impl.loopbackAddresses()[0];
   1171     }
   1172 
   1173     // BEGIN Android-removed: Resolves a hostname using Libcore.os.
   1174     /*
   1175      * check if the literal address string has %nn appended
   1176      * returns -1 if not, or the numeric value otherwise.
   1177      *
   1178      * %nn may also be a string that represents the displayName of
   1179      * a currently available NetworkInterface.
   1180      *
   1181     private static int checkNumericZone (String s) throws UnknownHostException {
   1182         int percent = s.indexOf ('%');
   1183         int slen = s.length();
   1184         int digit, zone=0;
   1185         if (percent == -1) {
   1186             return -1;
   1187         }
   1188         for (int i=percent+1; i<slen; i++) {
   1189             char c = s.charAt(i);
   1190             if (c == ']') {
   1191                 if (i == percent+1) {
   1192                     /* empty per-cent field *
   1193                     return -1;
   1194                 }
   1195                 break;
   1196             }
   1197             if ((digit = Character.digit (c, 10)) < 0) {
   1198                 return -1;
   1199             }
   1200             zone = (zone * 10) + digit;
   1201         }
   1202         return zone;
   1203     }
   1204 
   1205     private static InetAddress[] getAllByName0 (String host)
   1206         throws UnknownHostException
   1207     {
   1208         return getAllByName0(host, true);
   1209     }
   1210 
   1211     /**
   1212      * package private so SocketPermission can call it
   1213      *
   1214     static InetAddress[] getAllByName0 (String host, boolean check)
   1215         throws UnknownHostException  {
   1216         return getAllByName0 (host, null, check);
   1217     }
   1218 
   1219     private static InetAddress[] getAllByName0 (String host, InetAddress reqAddr, boolean check)
   1220         throws UnknownHostException  {
   1221 
   1222         /* If it gets here it is presumed to be a hostname */
   1223         /* Cache.get can return: null, unknownAddress, or InetAddress[] */
   1224 
   1225         /* make sure the connection to the host is allowed, before we
   1226          * give out a hostname
   1227          *
   1228         if (check) {
   1229             SecurityManager security = System.getSecurityManager();
   1230             if (security != null) {
   1231                 security.checkConnect(host, -1);
   1232             }
   1233         }
   1234 
   1235         InetAddress[] addresses = getCachedAddresses(host);
   1236 
   1237         /* If no entry in cache, then do the host lookup *
   1238         if (addresses == null) {
   1239             addresses = getAddressesFromNameService(host, reqAddr);
   1240         }
   1241 
   1242         if (addresses == unknown_array)
   1243             throw new UnknownHostException(host);
   1244 
   1245         return addresses.clone();
   1246     }
   1247 
   1248     private static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)
   1249         throws UnknownHostException
   1250     {
   1251         InetAddress[] addresses = null;
   1252         boolean success = false;
   1253         UnknownHostException ex = null;
   1254 
   1255         // Check whether the host is in the lookupTable.
   1256         // 1) If the host isn't in the lookupTable when
   1257         //    checkLookupTable() is called, checkLookupTable()
   1258         //    would add the host in the lookupTable and
   1259         //    return null. So we will do the lookup.
   1260         // 2) If the host is in the lookupTable when
   1261         //    checkLookupTable() is called, the current thread
   1262         //    would be blocked until the host is removed
   1263         //    from the lookupTable. Then this thread
   1264         //    should try to look up the addressCache.
   1265         //     i) if it found the addresses in the
   1266         //        addressCache, checkLookupTable()  would
   1267         //        return the addresses.
   1268         //     ii) if it didn't find the addresses in the
   1269         //         addressCache for any reason,
   1270         //         it should add the host in the
   1271         //         lookupTable and return null so the
   1272         //         following code would do  a lookup itself.
   1273         if ((addresses = checkLookupTable(host)) == null) {
   1274             try {
   1275                 // This is the first thread which looks up the addresses
   1276                 // this host or the cache entry for this host has been
   1277                 // expired so this thread should do the lookup.
   1278                 for (NameService nameService : nameServices) {
   1279                     try {
   1280                         /*
   1281                          * Do not put the call to lookup() inside the
   1282                          * constructor.  if you do you will still be
   1283                          * allocating space when the lookup fails.
   1284                          *
   1285 
   1286                         addresses = nameService.lookupAllHostAddr(host);
   1287                         success = true;
   1288                         break;
   1289                     } catch (UnknownHostException uhe) {
   1290                         if (host.equalsIgnoreCase("localhost")) {
   1291                             InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
   1292                             addresses = local;
   1293                             success = true;
   1294                             break;
   1295                         }
   1296                         else {
   1297                             addresses = unknown_array;
   1298                             success = false;
   1299                             ex = uhe;
   1300                         }
   1301                     }
   1302                 }
   1303 
   1304                 // More to do?
   1305                 if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {
   1306                     // Find it?
   1307                     int i = 1;
   1308                     for (; i < addresses.length; i++) {
   1309                         if (addresses[i].equals(reqAddr)) {
   1310                             break;
   1311                         }
   1312                     }
   1313                     // Rotate
   1314                     if (i < addresses.length) {
   1315                         InetAddress tmp, tmp2 = reqAddr;
   1316                         for (int j = 0; j < i; j++) {
   1317                             tmp = addresses[j];
   1318                             addresses[j] = tmp2;
   1319                             tmp2 = tmp;
   1320                         }
   1321                         addresses[i] = tmp2;
   1322                     }
   1323                 }
   1324                 // Cache the address.
   1325                 cacheAddresses(host, addresses, success);
   1326 
   1327                 if (!success && ex != null)
   1328                     throw ex;
   1329 
   1330             } finally {
   1331                 // Delete host from the lookupTable and notify
   1332                 // all threads waiting on the lookupTable monitor.
   1333                 updateLookupTable(host);
   1334             }
   1335         }
   1336 
   1337         return addresses;
   1338     }
   1339 
   1340 
   1341     private static InetAddress[] checkLookupTable(String host) {
   1342         synchronized (lookupTable) {
   1343             // If the host isn't in the lookupTable, add it in the
   1344             // lookuptable and return null. The caller should do
   1345             // the lookup.
   1346             if (lookupTable.containsKey(host) == false) {
   1347                 lookupTable.put(host, null);
   1348                 return null;
   1349             }
   1350 
   1351             // If the host is in the lookupTable, it means that another
   1352             // thread is trying to look up the addresses of this host.
   1353             // This thread should wait.
   1354             while (lookupTable.containsKey(host)) {
   1355                 try {
   1356                     lookupTable.wait();
   1357                 } catch (InterruptedException e) {
   1358                 }
   1359             }
   1360         }
   1361 
   1362         // The other thread has finished looking up the addresses of
   1363         // the host. This thread should retry to get the addresses
   1364         // from the addressCache. If it doesn't get the addresses from
   1365         // the cache, it will try to look up the addresses itself.
   1366         InetAddress[] addresses = getCachedAddresses(host);
   1367         if (addresses == null) {
   1368             synchronized (lookupTable) {
   1369                 lookupTable.put(host, null);
   1370                 return null;
   1371             }
   1372         }
   1373 
   1374         return addresses;
   1375     }
   1376 
   1377     private static void updateLookupTable(String host) {
   1378         synchronized (lookupTable) {
   1379             lookupTable.remove(host);
   1380             lookupTable.notifyAll();
   1381         }
   1382     }
   1383     */
   1384     // END Android-removed: Resolves a hostname using Libcore.os.
   1385 
   1386     /**
   1387      * Returns an {@code InetAddress} object given the raw IP address .
   1388      * The argument is in network byte order: the highest order
   1389      * byte of the address is in {@code getAddress()[0]}.
   1390      *
   1391      * <p> This method doesn't block, i.e. no reverse name service lookup
   1392      * is performed.
   1393      *
   1394      * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
   1395      * must be 16 bytes long
   1396      *
   1397      * @param addr the raw IP address in network byte order
   1398      * @return  an InetAddress object created from the raw IP address.
   1399      * @exception  UnknownHostException  if IP address is of illegal length
   1400      * @since 1.4
   1401      */
   1402     public static InetAddress getByAddress(byte[] addr)
   1403         throws UnknownHostException {
   1404         return getByAddress(null, addr);
   1405     }
   1406 
   1407     // BEGIN Android-removed: Resolves a hostname using Libcore.os.
   1408     /*
   1409     private static InetAddress cachedLocalHost = null;
   1410     private static long cacheTime = 0;
   1411     private static final long maxCacheTime = 5000L;
   1412     private static final Object cacheLock = new Object();
   1413     */
   1414     // END Android-removed: Resolves a hostname using Libcore.os.
   1415 
   1416     /**
   1417      * Returns the address of the local host. This is achieved by retrieving
   1418      * the name of the host from the system, then resolving that name into
   1419      * an {@code InetAddress}.
   1420      *
   1421      * <P>Note: The resolved address may be cached for a short period of time.
   1422      * </P>
   1423      *
   1424      * <p>If there is a security manager, its
   1425      * {@code checkConnect} method is called
   1426      * with the local host name and {@code -1}
   1427      * as its arguments to see if the operation is allowed.
   1428      * If the operation is not allowed, an InetAddress representing
   1429      * the loopback address is returned.
   1430      *
   1431      * @return     the address of the local host.
   1432      *
   1433      * @exception  UnknownHostException  if the local host name could not
   1434      *             be resolved into an address.
   1435      *
   1436      * @see SecurityManager#checkConnect
   1437      * @see java.net.InetAddress#getByName(java.lang.String)
   1438      */
   1439     public static InetAddress getLocalHost() throws UnknownHostException {
   1440         // BEGIN Android-changed: Resolves a hostname using Libcore.os.
   1441         /*
   1442         SecurityManager security = System.getSecurityManager();
   1443         try {
   1444             String local = impl.getLocalHostName();
   1445 
   1446             if (security != null) {
   1447                 security.checkConnect(local, -1);
   1448             }
   1449 
   1450             if (local.equals("localhost")) {
   1451                 return impl.loopbackAddress();
   1452             }
   1453 
   1454             InetAddress ret = null;
   1455             synchronized (cacheLock) {
   1456                 long now = System.currentTimeMillis();
   1457                 if (cachedLocalHost != null) {
   1458                     if ((now - cacheTime) < maxCacheTime) // Less than 5s old?
   1459                         ret = cachedLocalHost;
   1460                     else
   1461                         cachedLocalHost = null;
   1462                 }
   1463 
   1464                 // we are calling getAddressesFromNameService directly
   1465                 // to avoid getting localHost from cache
   1466                 if (ret == null) {
   1467                     InetAddress[] localAddrs;
   1468                     try {
   1469                         localAddrs =
   1470                             InetAddress.getAddressesFromNameService(local, null);
   1471                     } catch (UnknownHostException uhe) {
   1472                         // Rethrow with a more informative error message.
   1473                         UnknownHostException uhe2 =
   1474                             new UnknownHostException(local + ": " +
   1475                                                      uhe.getMessage());
   1476                         uhe2.initCause(uhe);
   1477                         throw uhe2;
   1478                     }
   1479                     cachedLocalHost = localAddrs[0];
   1480                     cacheTime = now;
   1481                     ret = localAddrs[0];
   1482                 }
   1483             }
   1484             return ret;
   1485         } catch (java.lang.SecurityException e) {
   1486             return impl.loopbackAddress();
   1487         }
   1488         */
   1489         String local = Libcore.os.uname().nodename;
   1490         return impl.lookupAllHostAddr(local, NETID_UNSET)[0];
   1491         // END Android-changed: Resolves a hostname using Libcore.os.
   1492     }
   1493 
   1494     // BEGIN Android-removed: Android doesn't need to call native init.
   1495     /**
   1496      * Perform class load-time initializations.
   1497      *
   1498     private static native void init();
   1499     */
   1500     // END Android-removed: Android doesn't need to call native init.
   1501 
   1502     /*
   1503      * Returns the InetAddress representing anyLocalAddress
   1504      * (typically 0.0.0.0 or ::0)
   1505      */
   1506     static InetAddress anyLocalAddress() {
   1507         return impl.anyLocalAddress();
   1508     }
   1509 
   1510     // BEGIN Android-removed: Android doesn't load user-provided implementation.
   1511     /*
   1512      * Load and instantiate an underlying impl class
   1513      *
   1514     static InetAddressImpl loadImpl(String implName) {
   1515         Object impl = null;
   1516 
   1517         /*
   1518          * Property "impl.prefix" will be prepended to the classname
   1519          * of the implementation object we instantiate, to which we
   1520          * delegate the real work (like native methods).  This
   1521          * property can vary across implementations of the java.
   1522          * classes.  The default is an empty String "".
   1523          *
   1524         String prefix = AccessController.doPrivileged(
   1525                       new GetPropertyAction("impl.prefix", ""));
   1526         try {
   1527             impl = Class.forName("java.net." + prefix + implName).newInstance();
   1528         } catch (ClassNotFoundException e) {
   1529             System.err.println("Class not found: java.net." + prefix +
   1530                                implName + ":\ncheck impl.prefix property " +
   1531                                "in your properties file.");
   1532         } catch (InstantiationException e) {
   1533             System.err.println("Could not instantiate: java.net." + prefix +
   1534                                implName + ":\ncheck impl.prefix property " +
   1535                                "in your properties file.");
   1536         } catch (IllegalAccessException e) {
   1537             System.err.println("Cannot access class: java.net." + prefix +
   1538                                implName + ":\ncheck impl.prefix property " +
   1539                                "in your properties file.");
   1540         }
   1541 
   1542         if (impl == null) {
   1543             try {
   1544                 impl = Class.forName(implName).newInstance();
   1545             } catch (Exception e) {
   1546                 throw new Error("System property impl.prefix incorrect");
   1547             }
   1548         }
   1549 
   1550         return (InetAddressImpl) impl;
   1551     }
   1552     */
   1553     // END Android-removed: Android doesn't load user-provided implementation.
   1554 
   1555     private void readObjectNoData (ObjectInputStream s) throws
   1556                          IOException, ClassNotFoundException {
   1557         // Android-changed: Don't use null to mean the boot classloader.
   1558         if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
   1559             throw new SecurityException ("invalid address type");
   1560         }
   1561     }
   1562 
   1563     // Android-changed: Don't use null to mean the boot classloader.
   1564     private static final ClassLoader BOOT_CLASSLOADER = Object.class.getClassLoader();
   1565 
   1566     private void readObject (ObjectInputStream s) throws
   1567                          IOException, ClassNotFoundException {
   1568         // Android-changed: Don't use null to mean the boot classloader.
   1569         if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
   1570             throw new SecurityException ("invalid address type");
   1571         }
   1572         GetField gf = s.readFields();
   1573         String host = (String)gf.get("hostName", null);
   1574         int address= gf.get("address", 0);
   1575         int family= gf.get("family", 0);
   1576         holder = new InetAddressHolder(host, address, family);
   1577     }
   1578 
   1579     /* needed because the serializable fields no longer exist */
   1580 
   1581     /**
   1582      * @serialField hostName String
   1583      * @serialField address int
   1584      * @serialField family int
   1585      */
   1586     private static final ObjectStreamField[] serialPersistentFields = {
   1587         new ObjectStreamField("hostName", String.class),
   1588         new ObjectStreamField("address", int.class),
   1589         new ObjectStreamField("family", int.class),
   1590     };
   1591 
   1592     private void writeObject (ObjectOutputStream s) throws
   1593                         IOException {
   1594         // Android-changed: Don't use null to mean the boot classloader.
   1595         if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
   1596             throw new SecurityException ("invalid address type");
   1597         }
   1598         PutField pf = s.putFields();
   1599         pf.put("hostName", holder().hostName);
   1600         pf.put("address", holder().address);
   1601         pf.put("family", holder().family);
   1602         s.writeFields();
   1603         s.flush();
   1604     }
   1605 
   1606     static final int NETID_UNSET = 0;
   1607 
   1608     // BEGIN Android-added: Add methods required by frameworks/base.
   1609     // Particularly those required to deal with net-ids and scope ids.
   1610     /**
   1611      * Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1").
   1612      * This copes with all forms of address that Java supports, detailed in the {@link InetAddress}
   1613      * class documentation.
   1614      *
   1615      * @hide used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup.
   1616      */
   1617     public static boolean isNumeric(String address) {
   1618         InetAddress inetAddress = parseNumericAddressNoThrow(address);
   1619         return inetAddress != null && disallowDeprecatedFormats(address, inetAddress) != null;
   1620     }
   1621 
   1622     static InetAddress parseNumericAddressNoThrow(String address) {
   1623         // Accept IPv6 addresses (only) in square brackets for compatibility.
   1624         if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
   1625             address = address.substring(1, address.length() - 1);
   1626         }
   1627         StructAddrinfo hints = new StructAddrinfo();
   1628         hints.ai_flags = AI_NUMERICHOST;
   1629         InetAddress[] addresses = null;
   1630         try {
   1631             addresses = Libcore.os.android_getaddrinfo(address, hints, NETID_UNSET);
   1632         } catch (GaiException ignored) {
   1633         }
   1634         return (addresses != null) ? addresses[0] : null;
   1635     }
   1636 
   1637     static InetAddress disallowDeprecatedFormats(String address, InetAddress inetAddress) {
   1638         // Only IPv4 addresses are problematic.
   1639         if (!(inetAddress instanceof Inet4Address) || address.indexOf(':') != -1) {
   1640             return inetAddress;
   1641         }
   1642         // If inet_pton(3) can't parse it, it must have been a deprecated format.
   1643         // We need to return inet_pton(3)'s result to ensure that numbers assumed to be octal
   1644         // by getaddrinfo(3) are reinterpreted by inet_pton(3) as decimal.
   1645         return Libcore.os.inet_pton(AF_INET, address);
   1646     }
   1647 
   1648     /**
   1649      * Returns an InetAddress corresponding to the given numeric address (such
   1650      * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
   1651      * This method will never do a DNS lookup. Non-numeric addresses are errors.
   1652      *
   1653      * @hide used by frameworks/base's NetworkUtils.numericToInetAddress
   1654      * @throws IllegalArgumentException if {@code numericAddress} is not a numeric address
   1655      */
   1656     public static InetAddress parseNumericAddress(String numericAddress) {
   1657         if (numericAddress == null || numericAddress.isEmpty()) {
   1658             return Inet6Address.LOOPBACK;
   1659         }
   1660         InetAddress result = parseNumericAddressNoThrow(numericAddress);
   1661         result = disallowDeprecatedFormats(numericAddress, result);
   1662         if (result == null) {
   1663             throw new IllegalArgumentException("Not a numeric address: " + numericAddress);
   1664         }
   1665         return result;
   1666     }
   1667 
   1668     /**
   1669      * Removes all entries from the VM's DNS cache. This does not affect the C library's DNS
   1670      * cache, nor any caching DNS servers between you and the canonical server.
   1671      * @hide
   1672      */
   1673     public static void clearDnsCache() {
   1674         impl.clearAddressCache();
   1675     }
   1676 
   1677     /**
   1678      * Operates identically to {@code getByName} except host resolution is
   1679      * performed on the network designated by {@code netId}.
   1680      *
   1681      * @param host
   1682      *            the hostName to be resolved to an address or {@code null}.
   1683      * @param netId the network to use for host resolution.
   1684      * @return the {@code InetAddress} instance representing the host.
   1685      * @throws UnknownHostException if the address lookup fails.
   1686      * @hide internal use only
   1687      */
   1688     public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException {
   1689         return impl.lookupAllHostAddr(host, netId)[0];
   1690     }
   1691 
   1692     /**
   1693      * Operates identically to {@code getAllByName} except host resolution is
   1694      * performed on the network designated by {@code netId}.
   1695      *
   1696      * @param host the hostname or literal IP string to be resolved.
   1697      * @param netId the network to use for host resolution.
   1698      * @return the array of addresses associated with the specified host.
   1699      * @throws UnknownHostException if the address lookup fails.
   1700      * @hide internal use only
   1701      */
   1702     public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
   1703         return impl.lookupAllHostAddr(host, netId).clone();
   1704     }
   1705     // END Android-added: Add methods required by frameworks/base.
   1706 
   1707     // Only called by java.net.SocketPermission.
   1708     static InetAddress[] getAllByName0(String authHost, boolean check) throws UnknownHostException {
   1709         throw new UnsupportedOperationException();
   1710     }
   1711 
   1712     // Only called by java.net.SocketPermission.
   1713     String getHostName(boolean check) {
   1714         throw new UnsupportedOperationException();
   1715     }
   1716 }
   1717 // BEGIN Android-removed: Android doesn't load user-provided implementation.
   1718 /*
   1719  * Simple factory to create the impl
   1720  *
   1721 class InetAddressImplFactory {
   1722 
   1723     static InetAddressImpl create() {
   1724         return InetAddress.loadImpl(isIPv6Supported() ?
   1725                                     "Inet6AddressImpl" : "Inet4AddressImpl");
   1726     }
   1727 
   1728     static native boolean isIPv6Supported();
   1729 }
   1730 */
   1731 // END Android-removed: Android doesn't load user-provided implementation.
   1732