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