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