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