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