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