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