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