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