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