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