InetAddress.java revision 14176:8606d027b2c2
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
26package java.net;
27
28import java.util.NavigableSet;
29import java.util.Iterator;
30import java.util.List;
31import java.util.ArrayList;
32import java.util.Objects;
33import java.util.Scanner;
34import java.security.AccessController;
35import java.io.File;
36import java.io.FileNotFoundException;
37import java.io.ObjectStreamException;
38import java.io.ObjectStreamField;
39import java.io.IOException;
40import java.io.ObjectInputStream;
41import java.io.ObjectInputStream.GetField;
42import java.io.ObjectOutputStream;
43import java.io.ObjectOutputStream.PutField;
44import java.util.concurrent.ConcurrentHashMap;
45import java.util.concurrent.ConcurrentMap;
46import java.util.concurrent.ConcurrentSkipListSet;
47import java.util.concurrent.atomic.AtomicLong;
48
49import jdk.internal.misc.JavaNetInetAddressAccess;
50import jdk.internal.misc.SharedSecrets;
51import sun.security.action.*;
52import sun.net.InetAddressCachePolicy;
53import 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 */
194public
195class 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 transient 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         * Lookup a host mapping by name. Retrieve the IP addresses
867         * associated with a host
868         *
869         * @param host the specified hostname
870         * @return array of IP addresses for the requested host
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         * Lookup the host corresponding to the IP address provided
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    /**
890     * The default NameService implementation, which delegates to the underlying
891     * OS network libraries to resolve host address mappings.
892     *
893     * @since 9
894     */
895    private static final class PlatformNameService implements NameService {
896
897        public InetAddress[] lookupAllHostAddr(String host)
898            throws UnknownHostException
899        {
900            return impl.lookupAllHostAddr(host);
901        }
902
903        public String getHostByAddr(byte[] addr)
904            throws UnknownHostException
905        {
906            return impl.getHostByAddr(addr);
907        }
908    }
909
910    /**
911     * The HostsFileNameService provides host address mapping
912     * by reading the entries in a hosts file, which is specified by
913     * {@code jdk.net.hosts.file} system property
914     *
915     * <p>The file format is that which corresponds with the /etc/hosts file
916     * IP Address host alias list.
917     *
918     * <p>When the file lookup is enabled it replaces the default NameService
919     * implementation
920     *
921     * @since 9
922     */
923    private static final class HostsFileNameService implements NameService {
924
925        private final String hostsFile;
926
927        public HostsFileNameService (String hostsFileName) {
928            this.hostsFile = hostsFileName;
929        }
930
931        private  String addrToString(byte addr[]) {
932          String stringifiedAddress = null;
933
934            if (addr.length == Inet4Address.INADDRSZ) {
935                stringifiedAddress = Inet4Address.numericToTextFormat(addr);
936            } else { // treat as an IPV6 jobby
937                byte[] newAddr
938                    = IPAddressUtil.convertFromIPv4MappedAddress(addr);
939                if (newAddr != null) {
940                   stringifiedAddress = Inet4Address.numericToTextFormat(addr);
941                } else {
942                    stringifiedAddress = Inet6Address.numericToTextFormat(addr);
943                }
944            }
945            return stringifiedAddress;
946        }
947
948        /**
949         * Lookup the host name  corresponding to the IP address provided.
950         * Search the configured host file a host name corresponding to
951         * the specified IP address.
952         *
953         * @param addr byte array representing an IP address
954         * @return {@code String} representing the host name mapping
955         * @throws UnknownHostException
956         *             if no host found for the specified IP address
957         */
958        @Override
959        public String getHostByAddr(byte[] addr) throws UnknownHostException {
960            String hostEntry;
961            String host = null;
962
963            String addrString = addrToString(addr);
964            try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) {
965                while (hostsFileScanner.hasNextLine()) {
966                    hostEntry = hostsFileScanner.nextLine();
967                    if (!hostEntry.startsWith("#")) {
968                        hostEntry = removeComments(hostEntry);
969                        if (hostEntry.contains(addrString)) {
970                            host = extractHost(hostEntry, addrString);
971                            if (host != null) {
972                                break;
973                            }
974                        }
975                    }
976                }
977            } catch (FileNotFoundException e) {
978                throw new UnknownHostException("Unable to resolve address "
979                        + addrString + " as hosts file " + hostsFile
980                        + " not found ");
981            }
982
983            if ((host == null) || (host.equals("")) || (host.equals(" "))) {
984                throw new UnknownHostException("Requested address "
985                        + addrString
986                        + " resolves to an invalid entry in hosts file "
987                        + hostsFile);
988            }
989            return host;
990        }
991
992        /**
993         * <p>Lookup a host mapping by name. Retrieve the IP addresses
994         * associated with a host.
995         *
996         * <p>Search the configured hosts file for the addresses assocaited with
997         * with the specified host name.
998         *
999         * @param host the specified hostname
1000         * @return array of IP addresses for the requested host
1001         * @throws UnknownHostException
1002         *             if no IP address for the {@code host} could be found
1003         */
1004        public InetAddress[] lookupAllHostAddr(String host)
1005                throws UnknownHostException {
1006            String hostEntry;
1007            String addrStr = null;
1008            InetAddress[] res = null;
1009            byte addr[] = new byte[4];
1010            ArrayList<InetAddress> inetAddresses = null;
1011
1012            // lookup the file and create a list InetAddress for the specfied host
1013            try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) {
1014                while (hostsFileScanner.hasNextLine()) {
1015                    hostEntry = hostsFileScanner.nextLine();
1016                    if (!hostEntry.startsWith("#")) {
1017                        hostEntry = removeComments(hostEntry);
1018                        if (hostEntry.contains(host)) {
1019                            addrStr = extractHostAddr(hostEntry, host);
1020                            if ((addrStr != null) && (!addrStr.equals(""))) {
1021                                addr = createAddressByteArray(addrStr);
1022                                if (inetAddresses == null) {
1023                                    inetAddresses = new ArrayList<>(1);
1024                                }
1025                                if (addr != null) {
1026                                    inetAddresses.add(InetAddress.getByAddress(host, addr));
1027                                }
1028                            }
1029                        }
1030                    }
1031                }
1032            } catch (FileNotFoundException e) {
1033                throw new UnknownHostException("Unable to resolve host " + host
1034                        + " as hosts file " + hostsFile + " not found ");
1035            }
1036
1037            if (inetAddresses != null) {
1038                res = inetAddresses.toArray(new InetAddress[inetAddresses.size()]);
1039            } else {
1040                throw new UnknownHostException("Unable to resolve host " + host
1041                        + " in hosts file " + hostsFile);
1042            }
1043            return res;
1044        }
1045
1046        private String removeComments(String hostsEntry) {
1047            String filteredEntry = hostsEntry;
1048            int hashIndex;
1049
1050            if ((hashIndex = hostsEntry.indexOf("#")) != -1) {
1051                filteredEntry = hostsEntry.substring(0, hashIndex);
1052            }
1053            return filteredEntry;
1054        }
1055
1056        private byte [] createAddressByteArray(String addrStr) {
1057            byte[] addrArray;
1058            // check if IPV4 address - most likely
1059            addrArray = IPAddressUtil.textToNumericFormatV4(addrStr);
1060            if (addrArray == null) {
1061                addrArray = IPAddressUtil.textToNumericFormatV6(addrStr);
1062            }
1063            return addrArray;
1064        }
1065
1066        /** host to ip address mapping */
1067        private String extractHostAddr(String hostEntry, String host) {
1068            String[] mapping = hostEntry.split("\\s+");
1069            String hostAddr = null;
1070
1071            if (mapping.length >= 2) {
1072                // look at the host aliases
1073                for (int i = 1; i < mapping.length; i++) {
1074                    if (mapping[i].equalsIgnoreCase(host)) {
1075                        hostAddr = mapping[0];
1076                    }
1077                }
1078            }
1079            return hostAddr;
1080        }
1081
1082        /**
1083         * IP Address to host mapping
1084         * use first host alias in list
1085         */
1086        private String extractHost(String hostEntry, String addrString) {
1087            String[] mapping = hostEntry.split("\\s+");
1088            String host = null;
1089
1090            if (mapping.length >= 2) {
1091                if (mapping[0].equalsIgnoreCase(addrString)) {
1092                    host = mapping[1];
1093                }
1094            }
1095            return host;
1096        }
1097    }
1098
1099    static final InetAddressImpl  impl;
1100
1101    static {
1102        // create the impl
1103        impl = InetAddressImplFactory.create();
1104
1105        // create name service
1106        nameService = createNameService();
1107        }
1108
1109    /**
1110     * Create an instance of the NameService interface based on
1111     * the setting of the {@codejdk.net.hosts.file} system property.
1112     *
1113     * <p>The default NameService is the PlatformNameService, which typically
1114     * delegates name and address resolution calls to the underlying
1115     * OS network libraries.
1116     *
1117     * <p> A HostsFileNameService is created if the {@code jdk.net.hosts.file}
1118     * system property is set. If the specified file doesn't exist, the name or
1119     * address lookup will result in an UnknownHostException. Thus, non existent
1120     * hosts file is handled as if the file is empty.
1121     *
1122     * @return a NameService
1123     */
1124    private static NameService createNameService() {
1125
1126        String hostsFileName = AccessController
1127                .doPrivileged(new GetPropertyAction("jdk.net.hosts.file"));
1128        NameService theNameService;
1129        if (hostsFileName != null) {
1130            theNameService = new HostsFileNameService(hostsFileName);
1131        } else {
1132            theNameService = new PlatformNameService();
1133        }
1134        return theNameService;
1135    }
1136
1137    /**
1138     * Creates an InetAddress based on the provided host name and IP address.
1139     * No name service is checked for the validity of the address.
1140     *
1141     * <p> The host name can either be a machine name, such as
1142     * "{@code java.sun.com}", or a textual representation of its IP
1143     * address.
1144     * <p> No validity checking is done on the host name either.
1145     *
1146     * <p> If addr specifies an IPv4 address an instance of Inet4Address
1147     * will be returned; otherwise, an instance of Inet6Address
1148     * will be returned.
1149     *
1150     * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1151     * must be 16 bytes long
1152     *
1153     * @param host the specified host
1154     * @param addr the raw IP address in network byte order
1155     * @return  an InetAddress object created from the raw IP address.
1156     * @exception  UnknownHostException  if IP address is of illegal length
1157     * @since 1.4
1158     */
1159    public static InetAddress getByAddress(String host, byte[] addr)
1160        throws UnknownHostException {
1161        if (host != null && host.length() > 0 && host.charAt(0) == '[') {
1162            if (host.charAt(host.length()-1) == ']') {
1163                host = host.substring(1, host.length() -1);
1164            }
1165        }
1166        if (addr != null) {
1167            if (addr.length == Inet4Address.INADDRSZ) {
1168                return new Inet4Address(host, addr);
1169            } else if (addr.length == Inet6Address.INADDRSZ) {
1170                byte[] newAddr
1171                    = IPAddressUtil.convertFromIPv4MappedAddress(addr);
1172                if (newAddr != null) {
1173                    return new Inet4Address(host, newAddr);
1174                } else {
1175                    return new Inet6Address(host, addr);
1176                }
1177            }
1178        }
1179        throw new UnknownHostException("addr is of illegal length");
1180    }
1181
1182
1183    /**
1184     * Determines the IP address of a host, given the host's name.
1185     *
1186     * <p> The host name can either be a machine name, such as
1187     * "{@code java.sun.com}", or a textual representation of its
1188     * IP address. If a literal IP address is supplied, only the
1189     * validity of the address format is checked.
1190     *
1191     * <p> For {@code host} specified in literal IPv6 address,
1192     * either the form defined in RFC 2732 or the literal IPv6 address
1193     * format defined in RFC 2373 is accepted. IPv6 scoped addresses are also
1194     * supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
1195     * scoped addresses.
1196     *
1197     * <p> If the host is {@code null} then an {@code InetAddress}
1198     * representing an address of the loopback interface is returned.
1199     * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
1200     * section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
1201     * section&nbsp;2.5.3. </p>
1202     *
1203     * @param      host   the specified host, or {@code null}.
1204     * @return     an IP address for the given host name.
1205     * @exception  UnknownHostException  if no IP address for the
1206     *               {@code host} could be found, or if a scope_id was specified
1207     *               for a global IPv6 address.
1208     * @exception  SecurityException if a security manager exists
1209     *             and its checkConnect method doesn't allow the operation
1210     */
1211    public static InetAddress getByName(String host)
1212        throws UnknownHostException {
1213        return InetAddress.getAllByName(host)[0];
1214    }
1215
1216    // called from deployment cache manager
1217    private static InetAddress getByName(String host, InetAddress reqAddr)
1218        throws UnknownHostException {
1219        return InetAddress.getAllByName(host, reqAddr)[0];
1220    }
1221
1222    /**
1223     * Given the name of a host, returns an array of its IP addresses,
1224     * based on the configured name service on the system.
1225     *
1226     * <p> The host name can either be a machine name, such as
1227     * "{@code java.sun.com}", or a textual representation of its IP
1228     * address. If a literal IP address is supplied, only the
1229     * validity of the address format is checked.
1230     *
1231     * <p> For {@code host} specified in <i>literal IPv6 address</i>,
1232     * either the form defined in RFC 2732 or the literal IPv6 address
1233     * format defined in RFC 2373 is accepted. A literal IPv6 address may
1234     * also be qualified by appending a scoped zone identifier or scope_id.
1235     * The syntax and usage of scope_ids is described
1236     * <a href="Inet6Address.html#scoped">here</a>.
1237     * <p> If the host is {@code null} then an {@code InetAddress}
1238     * representing an address of the loopback interface is returned.
1239     * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
1240     * section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
1241     * section&nbsp;2.5.3. </p>
1242     *
1243     * <p> If there is a security manager and {@code host} is not
1244     * null and {@code host.length() } is not equal to zero, the
1245     * security manager's
1246     * {@code checkConnect} method is called
1247     * with the hostname and {@code -1}
1248     * as its arguments to see if the operation is allowed.
1249     *
1250     * @param      host   the name of the host, or {@code null}.
1251     * @return     an array of all the IP addresses for a given host name.
1252     *
1253     * @exception  UnknownHostException  if no IP address for the
1254     *               {@code host} could be found, or if a scope_id was specified
1255     *               for a global IPv6 address.
1256     * @exception  SecurityException  if a security manager exists and its
1257     *               {@code checkConnect} method doesn't allow the operation.
1258     *
1259     * @see SecurityManager#checkConnect
1260     */
1261    public static InetAddress[] getAllByName(String host)
1262        throws UnknownHostException {
1263        return getAllByName(host, null);
1264    }
1265
1266    private static InetAddress[] getAllByName(String host, InetAddress reqAddr)
1267        throws UnknownHostException {
1268
1269        if (host == null || host.length() == 0) {
1270            InetAddress[] ret = new InetAddress[1];
1271            ret[0] = impl.loopbackAddress();
1272            return ret;
1273        }
1274
1275        boolean ipv6Expected = false;
1276        if (host.charAt(0) == '[') {
1277            // This is supposed to be an IPv6 literal
1278            if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
1279                host = host.substring(1, host.length() -1);
1280                ipv6Expected = true;
1281            } else {
1282                // This was supposed to be a IPv6 address, but it's not!
1283                throw new UnknownHostException(host + ": invalid IPv6 address");
1284            }
1285        }
1286
1287        // if host is an IP address, we won't do further lookup
1288        if (Character.digit(host.charAt(0), 16) != -1
1289            || (host.charAt(0) == ':')) {
1290            byte[] addr = null;
1291            int numericZone = -1;
1292            String ifname = null;
1293            // see if it is IPv4 address
1294            addr = IPAddressUtil.textToNumericFormatV4(host);
1295            if (addr == null) {
1296                // This is supposed to be an IPv6 literal
1297                // Check if a numeric or string zone id is present
1298                int pos;
1299                if ((pos=host.indexOf ('%')) != -1) {
1300                    numericZone = checkNumericZone (host);
1301                    if (numericZone == -1) { /* remainder of string must be an ifname */
1302                        ifname = host.substring (pos+1);
1303                    }
1304                }
1305                if ((addr = IPAddressUtil.textToNumericFormatV6(host)) == null && host.contains(":")) {
1306                    throw new UnknownHostException(host + ": invalid IPv6 address");
1307                }
1308            } else if (ipv6Expected) {
1309                // Means an IPv4 litteral between brackets!
1310                throw new UnknownHostException("["+host+"]");
1311            }
1312            InetAddress[] ret = new InetAddress[1];
1313            if(addr != null) {
1314                if (addr.length == Inet4Address.INADDRSZ) {
1315                    ret[0] = new Inet4Address(null, addr);
1316                } else {
1317                    if (ifname != null) {
1318                        ret[0] = new Inet6Address(null, addr, ifname);
1319                    } else {
1320                        ret[0] = new Inet6Address(null, addr, numericZone);
1321                    }
1322                }
1323                return ret;
1324            }
1325        } else if (ipv6Expected) {
1326            // We were expecting an IPv6 Litteral, but got something else
1327            throw new UnknownHostException("["+host+"]");
1328        }
1329        return getAllByName0(host, reqAddr, true, true);
1330    }
1331
1332    /**
1333     * Returns the loopback address.
1334     * <p>
1335     * The InetAddress returned will represent the IPv4
1336     * loopback address, 127.0.0.1, or the IPv6 loopback
1337     * address, ::1. The IPv4 loopback address returned
1338     * is only one of many in the form 127.*.*.*
1339     *
1340     * @return  the InetAddress loopback instance.
1341     * @since 1.7
1342     */
1343    public static InetAddress getLoopbackAddress() {
1344        return impl.loopbackAddress();
1345    }
1346
1347
1348    /**
1349     * check if the literal address string has %nn appended
1350     * returns -1 if not, or the numeric value otherwise.
1351     *
1352     * %nn may also be a string that represents the displayName of
1353     * a currently available NetworkInterface.
1354     */
1355    private static int checkNumericZone (String s) throws UnknownHostException {
1356        int percent = s.indexOf ('%');
1357        int slen = s.length();
1358        int digit, zone=0;
1359        if (percent == -1) {
1360            return -1;
1361        }
1362        for (int i=percent+1; i<slen; i++) {
1363            char c = s.charAt(i);
1364            if (c == ']') {
1365                if (i == percent+1) {
1366                    /* empty per-cent field */
1367                    return -1;
1368                }
1369                break;
1370            }
1371            if ((digit = Character.digit (c, 10)) < 0) {
1372                return -1;
1373            }
1374            zone = (zone * 10) + digit;
1375        }
1376        return zone;
1377    }
1378
1379    private static InetAddress[] getAllByName0 (String host)
1380        throws UnknownHostException
1381    {
1382        return getAllByName0(host, true);
1383    }
1384
1385    /**
1386     * package private so SocketPermission can call it
1387     */
1388    static InetAddress[] getAllByName0 (String host, boolean check)
1389        throws UnknownHostException  {
1390        return getAllByName0 (host, null, check, true);
1391    }
1392
1393    /**
1394     * Designated lookup method.
1395     *
1396     * @param host host name to look up
1397     * @param reqAddr requested address to be the 1st in returned array
1398     * @param check perform security check
1399     * @param useCache use cached value if not expired else always
1400     *                 perform name service lookup (and cache the result)
1401     * @return array of InetAddress(es)
1402     * @throws UnknownHostException if host name is not found
1403     */
1404    private static InetAddress[] getAllByName0(String host,
1405                                               InetAddress reqAddr,
1406                                               boolean check,
1407                                               boolean useCache)
1408        throws UnknownHostException  {
1409
1410        /* If it gets here it is presumed to be a hostname */
1411
1412        /* make sure the connection to the host is allowed, before we
1413         * give out a hostname
1414         */
1415        if (check) {
1416            SecurityManager security = System.getSecurityManager();
1417            if (security != null) {
1418                security.checkConnect(host, -1);
1419            }
1420        }
1421
1422        // remove expired addresses from cache - expirySet keeps them ordered
1423        // by expiry time so we only need to iterate the prefix of the NavigableSet...
1424        long now = System.nanoTime();
1425        for (CachedAddresses caddrs : expirySet) {
1426            // compare difference of time instants rather than
1427            // time instants directly, to avoid possible overflow.
1428            // (see System.nanoTime() recommendations...)
1429            if ((caddrs.expiryTime - now) < 0L) {
1430                // ConcurrentSkipListSet uses weakly consistent iterator,
1431                // so removing while iterating is OK...
1432                if (expirySet.remove(caddrs)) {
1433                    // ... remove from cache
1434                    cache.remove(caddrs.host, caddrs);
1435                }
1436            } else {
1437                // we encountered 1st element that expires in future
1438                break;
1439            }
1440        }
1441
1442        // look-up or remove from cache
1443        Addresses addrs;
1444        if (useCache) {
1445            addrs = cache.get(host);
1446        } else {
1447            addrs = cache.remove(host);
1448            if (addrs != null) {
1449                if (addrs instanceof CachedAddresses) {
1450                    // try removing from expirySet too if CachedAddresses
1451                    expirySet.remove(addrs);
1452                }
1453                addrs = null;
1454            }
1455        }
1456
1457        if (addrs == null) {
1458            // create a NameServiceAddresses instance which will look up
1459            // the name service and install it within cache...
1460            Addresses oldAddrs = cache.putIfAbsent(
1461                host,
1462                addrs = new NameServiceAddresses(host, reqAddr)
1463            );
1464            if (oldAddrs != null) { // lost putIfAbsent race
1465                addrs = oldAddrs;
1466            }
1467        }
1468
1469        // ask Addresses to get an array of InetAddress(es) and clone it
1470        return addrs.get().clone();
1471    }
1472
1473    static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)
1474        throws UnknownHostException
1475    {
1476        InetAddress[] addresses = null;
1477        UnknownHostException ex = null;
1478
1479            try {
1480                addresses = nameService.lookupAllHostAddr(host);
1481            } catch (UnknownHostException uhe) {
1482                if (host.equalsIgnoreCase("localhost")) {
1483                    addresses = new InetAddress[] { impl.loopbackAddress() };
1484                }
1485                else {
1486                    ex = uhe;
1487                }
1488            }
1489
1490        if (addresses == null) {
1491            throw ex == null ? new UnknownHostException(host) : ex;
1492        }
1493
1494        // More to do?
1495        if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {
1496            // Find it?
1497            int i = 1;
1498            for (; i < addresses.length; i++) {
1499                if (addresses[i].equals(reqAddr)) {
1500                    break;
1501                }
1502            }
1503            // Rotate
1504            if (i < addresses.length) {
1505                InetAddress tmp, tmp2 = reqAddr;
1506                for (int j = 0; j < i; j++) {
1507                    tmp = addresses[j];
1508                    addresses[j] = tmp2;
1509                    tmp2 = tmp;
1510                }
1511                addresses[i] = tmp2;
1512            }
1513        }
1514
1515        return addresses;
1516    }
1517
1518    /**
1519     * Returns an {@code InetAddress} object given the raw IP address .
1520     * The argument is in network byte order: the highest order
1521     * byte of the address is in {@code getAddress()[0]}.
1522     *
1523     * <p> This method doesn't block, i.e. no reverse name service lookup
1524     * is performed.
1525     *
1526     * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1527     * must be 16 bytes long
1528     *
1529     * @param addr the raw IP address in network byte order
1530     * @return  an InetAddress object created from the raw IP address.
1531     * @exception  UnknownHostException  if IP address is of illegal length
1532     * @since 1.4
1533     */
1534    public static InetAddress getByAddress(byte[] addr)
1535        throws UnknownHostException {
1536        return getByAddress(null, addr);
1537    }
1538
1539    private static final class CachedLocalHost {
1540        final String host;
1541        final InetAddress addr;
1542        final long expiryTime = System.nanoTime() + 5000_000_000L; // now + 5s;
1543
1544        CachedLocalHost(String host, InetAddress addr) {
1545            this.host = host;
1546            this.addr = addr;
1547        }
1548    }
1549
1550    private static volatile CachedLocalHost cachedLocalHost;
1551
1552    /**
1553     * Returns the address of the local host. This is achieved by retrieving
1554     * the name of the host from the system, then resolving that name into
1555     * an {@code InetAddress}.
1556     *
1557     * <P>Note: The resolved address may be cached for a short period of time.
1558     * </P>
1559     *
1560     * <p>If there is a security manager, its
1561     * {@code checkConnect} method is called
1562     * with the local host name and {@code -1}
1563     * as its arguments to see if the operation is allowed.
1564     * If the operation is not allowed, an InetAddress representing
1565     * the loopback address is returned.
1566     *
1567     * @return     the address of the local host.
1568     *
1569     * @exception  UnknownHostException  if the local host name could not
1570     *             be resolved into an address.
1571     *
1572     * @see SecurityManager#checkConnect
1573     * @see java.net.InetAddress#getByName(java.lang.String)
1574     */
1575    public static InetAddress getLocalHost() throws UnknownHostException {
1576
1577        SecurityManager security = System.getSecurityManager();
1578        try {
1579            // is cached data still valid?
1580            CachedLocalHost clh = cachedLocalHost;
1581            if (clh != null && (clh.expiryTime - System.nanoTime()) >= 0L) {
1582                if (security != null) {
1583                    security.checkConnect(clh.host, -1);
1584                }
1585                return clh.addr;
1586            }
1587
1588            String local = impl.getLocalHostName();
1589
1590            if (security != null) {
1591                security.checkConnect(local, -1);
1592            }
1593
1594            InetAddress localAddr;
1595            if (local.equals("localhost")) {
1596                // shortcut for "localhost" host name
1597                localAddr = impl.loopbackAddress();
1598            } else {
1599                // call getAllByName0 without security checks and
1600                // without using cached data
1601                try {
1602                    localAddr = getAllByName0(local, null, false, false)[0];
1603                } catch (UnknownHostException uhe) {
1604                    // Rethrow with a more informative error message.
1605                    UnknownHostException uhe2 =
1606                        new UnknownHostException(local + ": " +
1607                                                 uhe.getMessage());
1608                    uhe2.initCause(uhe);
1609                    throw uhe2;
1610                }
1611            }
1612            cachedLocalHost = new CachedLocalHost(local, localAddr);
1613            return localAddr;
1614        } catch (java.lang.SecurityException e) {
1615            return impl.loopbackAddress();
1616        }
1617    }
1618
1619    /**
1620     * Perform class load-time initializations.
1621     */
1622    private static native void init();
1623
1624
1625    /*
1626     * Returns the InetAddress representing anyLocalAddress
1627     * (typically 0.0.0.0 or ::0)
1628     */
1629    static InetAddress anyLocalAddress() {
1630        return impl.anyLocalAddress();
1631    }
1632
1633    /*
1634     * Load and instantiate an underlying impl class
1635     */
1636    static InetAddressImpl loadImpl(String implName) {
1637        Object impl = null;
1638
1639        /*
1640         * Property "impl.prefix" will be prepended to the classname
1641         * of the implementation object we instantiate, to which we
1642         * delegate the real work (like native methods).  This
1643         * property can vary across implementations of the java.
1644         * classes.  The default is an empty String "".
1645         */
1646        String prefix = AccessController.doPrivileged(
1647                      new GetPropertyAction("impl.prefix", ""));
1648        try {
1649            impl = Class.forName("java.net." + prefix + implName).newInstance();
1650        } catch (ClassNotFoundException e) {
1651            System.err.println("Class not found: java.net." + prefix +
1652                               implName + ":\ncheck impl.prefix property " +
1653                               "in your properties file.");
1654        } catch (InstantiationException e) {
1655            System.err.println("Could not instantiate: java.net." + prefix +
1656                               implName + ":\ncheck impl.prefix property " +
1657                               "in your properties file.");
1658        } catch (IllegalAccessException e) {
1659            System.err.println("Cannot access class: java.net." + prefix +
1660                               implName + ":\ncheck impl.prefix property " +
1661                               "in your properties file.");
1662        }
1663
1664        if (impl == null) {
1665            try {
1666                impl = Class.forName(implName).newInstance();
1667            } catch (Exception e) {
1668                throw new Error("System property impl.prefix incorrect");
1669            }
1670        }
1671
1672        return (InetAddressImpl) impl;
1673    }
1674
1675    private void readObjectNoData (ObjectInputStream s) throws
1676                         IOException, ClassNotFoundException {
1677        if (getClass().getClassLoader() != null) {
1678            throw new SecurityException ("invalid address type");
1679        }
1680    }
1681
1682    private static final long FIELDS_OFFSET;
1683    private static final jdk.internal.misc.Unsafe UNSAFE;
1684
1685    static {
1686        try {
1687            jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
1688            FIELDS_OFFSET = unsafe.objectFieldOffset(
1689                InetAddress.class.getDeclaredField("holder")
1690            );
1691            UNSAFE = unsafe;
1692        } catch (ReflectiveOperationException e) {
1693            throw new Error(e);
1694        }
1695    }
1696
1697    private void readObject (ObjectInputStream s) throws
1698                         IOException, ClassNotFoundException {
1699        if (getClass().getClassLoader() != null) {
1700            throw new SecurityException ("invalid address type");
1701        }
1702        GetField gf = s.readFields();
1703        String host = (String)gf.get("hostName", null);
1704        int address= gf.get("address", 0);
1705        int family= gf.get("family", 0);
1706        InetAddressHolder h = new InetAddressHolder(host, address, family);
1707        UNSAFE.putObject(this, FIELDS_OFFSET, h);
1708    }
1709
1710    /* needed because the serializable fields no longer exist */
1711
1712    /**
1713     * @serialField hostName String
1714     * @serialField address int
1715     * @serialField family int
1716     */
1717    private static final ObjectStreamField[] serialPersistentFields = {
1718        new ObjectStreamField("hostName", String.class),
1719        new ObjectStreamField("address", int.class),
1720        new ObjectStreamField("family", int.class),
1721    };
1722
1723    private void writeObject (ObjectOutputStream s) throws
1724                        IOException {
1725        if (getClass().getClassLoader() != null) {
1726            throw new SecurityException ("invalid address type");
1727        }
1728        PutField pf = s.putFields();
1729        pf.put("hostName", holder().getHostName());
1730        pf.put("address", holder().getAddress());
1731        pf.put("family", holder().getFamily());
1732        s.writeFields();
1733    }
1734}
1735
1736/*
1737 * Simple factory to create the impl
1738 */
1739class InetAddressImplFactory {
1740
1741    static InetAddressImpl create() {
1742        return InetAddress.loadImpl(isIPv6Supported() ?
1743                                    "Inet6AddressImpl" : "Inet4AddressImpl");
1744    }
1745
1746    static native boolean isIPv6Supported();
1747}
1748