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