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