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