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