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