InetAddress.java revision 048303b64df9c987ae2f57b6bf88ff5ac1b5cca0
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.net; 19 20import java.io.FileDescriptor; 21import java.io.IOException; 22import java.io.ObjectInputStream; 23import java.io.ObjectOutputStream; 24import java.io.ObjectStreamException; 25import java.io.ObjectStreamField; 26import java.io.Serializable; 27import java.security.AccessController; 28import java.util.Arrays; 29import java.util.ArrayList; 30import java.util.Comparator; 31import java.util.Enumeration; 32import java.util.StringTokenizer; 33 34import org.apache.harmony.luni.net.NetUtil; 35import org.apache.harmony.luni.platform.INetworkSystem; 36import org.apache.harmony.luni.platform.Platform; 37import org.apache.harmony.luni.util.Inet6Util; 38import org.apache.harmony.luni.util.Msg; 39import org.apache.harmony.luni.util.PriviAction; 40 41/** 42 * An Internet Protocol (IP) address. This can be either an IPv4 address or an IPv6 address, and 43 * in practice you'll have an instance of either {@code Inet4Address} or {@code Inet6Address} (this 44 * class cannot be instantiated directly). Most code does not need to distinguish between the two 45 * families, and should use {@code InetAddress}. 46 * <p> 47 * An {@code InetAddress} may have a hostname (accessible via {@code getHostName}), but may not, 48 * depending on how the {@code InetAddress} was created. 49 * <p> 50 * On Android, addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are 51 * cached for 10 seconds. The underlying C library or OS may cache for longer, but you can control 52 * the Java-level caching with the usual {@code "networkaddress.cache.ttl"} and 53 * {@code "networkaddress.cache.negative.ttl"} system properties. These are parsed as integer 54 * numbers of seconds, where the special value 0 means "don't cache" and -1 means "cache forever". 55 * <p> 56 * Note also that on Android – unlike the RI – the cache is not unbounded. The current 57 * implementation caches around 512 entries, removed on a least-recently-used basis. 58 * (Obviously, you should not rely on these details.) 59 * 60 * @see Inet4Address 61 * @see Inet6Address 62 */ 63public class InetAddress implements Serializable { 64 // BEGIN android-added: better DNS caching. 65 // Our Java-side DNS cache. 66 private static final AddressCache addressCache = new AddressCache(); 67 // END android-added 68 69 private final static INetworkSystem NETIMPL = Platform.getNetworkSystem(); 70 71 private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused"; //$NON-NLS-1$ 72 73 private static final long serialVersionUID = 3286316764910316507L; 74 75 String hostName; 76 77 private static class WaitReachable { 78 } 79 80 private transient Object waitReachable = new WaitReachable(); 81 82 private boolean reached; 83 84 private int addrCount; 85 86 int family = 0; 87 static final int AF_INET = 2; 88 static final int AF_INET6 = 10; 89 90 byte[] ipaddress; 91 92 // BEGIN android-removed 93 // // Fill in the JNI id caches 94 // private static native void oneTimeInitialization(boolean supportsIPv6); 95 // 96 // static { 97 // oneTimeInitialization(true); 98 // } 99 // END android-removed 100 101 /** 102 * Constructs an {@code InetAddress}. 103 * 104 * Note: this constructor should not be used. Creating an InetAddress 105 * without specifying whether it's an IPv4 or IPv6 address does not make 106 * sense, because subsequent code cannot know which of of the subclasses' 107 * methods need to be called to implement a given InetAddress method. The 108 * proper way to create an InetAddress is to call new Inet4Address or 109 * Inet6Address or to use one of the static methods that return 110 * InetAddresses (e.g., getByAddress). That is why the API does not have 111 * public constructors for any of these classes. 112 */ 113 InetAddress() { 114 super(); 115 } 116 117 // BEGIN android-removed 118 /** 119 * Constructs an {@code InetAddress}, representing the {@code address} and 120 * {@code hostName}. 121 * 122 * @param address 123 * the network address. 124 */ 125 // InetAddress(byte[] address) { 126 // super(); 127 // this.ipaddress = address; 128 // } 129 // END android-removed 130 131 // BEGIN android-removed 132 /** 133 * Constructs an {@code InetAddress}, representing the {@code address} and 134 * {@code hostName}. 135 * 136 * @param address 137 * the network address. 138 * 139 */ 140 // InetAddress(byte[] address, String hostName) { 141 // super(); 142 // this.ipaddress = address; 143 // this.hostName = hostName; 144 // } 145 // END android-removed 146 147 // BEGIN android-removed 148 // CacheElement cacheElement() { 149 // return new CacheElement(); 150 // } 151 // END android-removed 152 153 /** 154 * Compares this {@code InetAddress} instance against the specified address 155 * in {@code obj}. Two addresses are equal if their address byte arrays have 156 * the same length and if the bytes in the arrays are equal. 157 * 158 * @param obj 159 * the object to be tested for equality. 160 * @return {@code true} if both objects are equal, {@code false} otherwise. 161 */ 162 @Override 163 public boolean equals(Object obj) { 164 // BEGIN android-changed 165 if (!(obj instanceof InetAddress)) { 166 return false; 167 } 168 return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress); 169 // END android-changed 170 } 171 172 /** 173 * Returns the IP address represented by this {@code InetAddress} instance 174 * as a byte array. The elements are in network order (the highest order 175 * address byte is in the zeroth element). 176 * 177 * @return the address in form of a byte array. 178 */ 179 public byte[] getAddress() { 180 return ipaddress.clone(); 181 } 182 183 // BEGIN android-added 184 static final Comparator<byte[]> SHORTEST_FIRST = new Comparator<byte[]>() { 185 public int compare(byte[] a1, byte[] a2) { 186 return a1.length - a2.length; 187 } 188 }; 189 190 static final Comparator<byte[]> LONGEST_FIRST = new Comparator<byte[]>() { 191 public int compare(byte[] a1, byte[] a2) { 192 return a2.length - a1.length; 193 } 194 }; 195 196 /** 197 * Converts an array of byte arrays representing raw IP addresses of a host 198 * to an array of InetAddress objects, sorting to respect the value of the 199 * system preferIPv6Addresses preference. 200 * 201 * @param rawAddresses the raw addresses to convert. 202 * @param hostName the hostname corresponding to the IP address. 203 * @return the corresponding InetAddresses, appropriately sorted. 204 */ 205 static InetAddress[] bytesToInetAddresses(byte[][] rawAddresses, 206 String hostName) { 207 // Sort the raw byte arrays. 208 Comparator<byte[]> comparator = preferIPv6Addresses() 209 ? LONGEST_FIRST : SHORTEST_FIRST; 210 Arrays.sort(rawAddresses, comparator); 211 212 // Convert the byte arrays to InetAddresses. 213 InetAddress[] returnedAddresses = new InetAddress[rawAddresses.length]; 214 for (int i = 0; i < rawAddresses.length; i++) { 215 byte[] rawAddress = rawAddresses[i]; 216 if (rawAddress.length == 16) { 217 returnedAddresses[i] = new Inet6Address(rawAddress, hostName); 218 } else if (rawAddress.length == 4) { 219 returnedAddresses[i] = new Inet4Address(rawAddress, hostName); 220 } else { 221 // Cannot happen, because the underlying code only returns 222 // addresses that are 4 or 16 bytes long. 223 throw new AssertionError("Impossible address length " + 224 rawAddress.length); 225 } 226 } 227 return returnedAddresses; 228 } 229 // END android-added 230 231 /** 232 * Gets all IP addresses associated with the given {@code host} identified 233 * by name or literal IP address. The IP address is resolved by the 234 * configured name service. If the host name is empty or {@code null} an 235 * {@code UnknownHostException} is thrown. If the host name is a literal IP 236 * address string an array with the corresponding single {@code InetAddress} 237 * is returned. 238 * 239 * @param host the hostname or literal IP string to be resolved. 240 * @return the array of addresses associated with the specified host. 241 * @throws UnknownHostException if the address lookup fails. 242 */ 243 public static InetAddress[] getAllByName(String host) 244 throws UnknownHostException { 245 // BEGIN android-changed 246 return getAllByNameImpl(host, true); 247 // END android-changed 248 } 249 250 // BEGIN android-added 251 /** 252 * Implementation of getAllByName. 253 * 254 * @param host the hostname or literal IP string to be resolved. 255 * @param returnUnshared requests a result that is modifiable by the caller. 256 * @return the array of addresses associated with the specified host. 257 * @throws UnknownHostException if the address lookup fails. 258 */ 259 static InetAddress[] getAllByNameImpl(String host, boolean returnUnshared) 260 throws UnknownHostException { 261 if (host == null || 0 == host.length()) { 262 if (preferIPv6Addresses()) { 263 return new InetAddress[] { Inet6Address.LOOPBACK, 264 Inet4Address.LOOPBACK }; 265 } else { 266 return new InetAddress[] { Inet4Address.LOOPBACK, 267 Inet6Address.LOOPBACK }; 268 } 269 } 270 271 // Special-case "0" for legacy IPv4 applications. 272 if (host.equals("0")) { //$NON-NLS-1$ 273 return new InetAddress[] { Inet4Address.ANY }; 274 } 275 276 if (isHostName(host)) { 277 SecurityManager security = System.getSecurityManager(); 278 if (security != null) { 279 security.checkConnect(host, -1); 280 } 281 if (returnUnshared) { 282 return lookupHostByName(host).clone(); 283 } else { 284 return lookupHostByName(host); 285 } 286 } 287 288 byte[] hBytes = NETIMPL.ipStringToByteArray(host); 289 if (hBytes.length == 4) { 290 return (new InetAddress[] { new Inet4Address(hBytes) }); 291 } else if (hBytes.length == 16) { 292 return (new InetAddress[] { new Inet6Address(hBytes) }); 293 } else { 294 throw new UnknownHostException( 295 Msg.getString("K0339")); //$NON-NLS-1$ 296 } 297 } 298 // END android-added 299 300 /** 301 * Returns the address of a host according to the given host string name 302 * {@code host}. The host string may be either a machine name or a dotted 303 * string IP address. If the latter, the {@code hostName} field is 304 * determined upon demand. {@code host} can be {@code null} which means that 305 * an address of the loopback interface is returned. 306 * 307 * @param host 308 * the hostName to be resolved to an address or {@code null}. 309 * @return the {@code InetAddress} instance representing the host. 310 * @throws UnknownHostException 311 * if the address lookup fails. 312 */ 313 public static InetAddress getByName(String host) throws UnknownHostException { 314 return getAllByNameImpl(host, false)[0]; 315 } 316 317 // BEGIN android-added 318 /** 319 * Returns the numeric string form of the given IP address. 320 * 321 * @param ipAddress 322 * the byte array to convert; length 4 for IPv4, 16 for IPv6. 323 * @throws IllegalArgumentException 324 * if ipAddress is of length other than 4 or 16. 325 */ 326 private static String ipAddressToString(byte[] ipAddress) { 327 try { 328 return NETIMPL.byteArrayToIpString(ipAddress); 329 } catch (IOException ex) { 330 throw new IllegalArgumentException("byte[] neither 4 nor 16 bytes", ex); 331 } 332 } 333 // END android-added 334 335 /** 336 * Gets the textual representation of this IP address. 337 * 338 * @return the textual representation of host's IP address. 339 */ 340 public String getHostAddress() { 341 return ipAddressToString(ipaddress); 342 } 343 344 /** 345 * Gets the host name of this IP address. If the IP address could not be 346 * resolved, the textual representation in a dotted-quad-notation is 347 * returned. 348 * 349 * @return the corresponding string name of this IP address. 350 */ 351 public String getHostName() { 352 try { 353 if (hostName == null) { 354 int address = 0; 355 if (ipaddress.length == 4) { 356 address = bytesToInt(ipaddress, 0); 357 if (address == 0) { 358 return hostName = ipAddressToString(ipaddress); 359 } 360 } 361 hostName = getHostByAddrImpl(ipaddress).hostName; 362 if (hostName.equals("localhost") && ipaddress.length == 4 //$NON-NLS-1$ 363 && address != 0x7f000001) { 364 return hostName = ipAddressToString(ipaddress); 365 } 366 } 367 } catch (UnknownHostException e) { 368 return hostName = ipAddressToString(ipaddress); 369 } 370 SecurityManager security = System.getSecurityManager(); 371 try { 372 // Only check host names, not addresses 373 if (security != null && isHostName(hostName)) { 374 security.checkConnect(hostName, -1); 375 } 376 } catch (SecurityException e) { 377 return ipAddressToString(ipaddress); 378 } 379 return hostName; 380 } 381 382 /** 383 * Gets the fully qualified domain name for the host associated with this IP 384 * address. If a security manager is set, it is checked if the method caller 385 * is allowed to get the hostname. Otherwise, the textual representation in 386 * a dotted-quad-notation is returned. 387 * 388 * @return the fully qualified domain name of this IP address. 389 */ 390 public String getCanonicalHostName() { 391 String canonicalName; 392 try { 393 int address = 0; 394 if (ipaddress.length == 4) { 395 address = bytesToInt(ipaddress, 0); 396 if (address == 0) { 397 return ipAddressToString(ipaddress); 398 } 399 } 400 canonicalName = getHostByAddrImpl(ipaddress).hostName; 401 } catch (UnknownHostException e) { 402 return ipAddressToString(ipaddress); 403 } 404 SecurityManager security = System.getSecurityManager(); 405 try { 406 // Only check host names, not addresses 407 if (security != null && isHostName(canonicalName)) { 408 security.checkConnect(canonicalName, -1); 409 } 410 } catch (SecurityException e) { 411 return ipAddressToString(ipaddress); 412 } 413 return canonicalName; 414 } 415 416 /** 417 * Gets the local host address if the security policy allows this. 418 * Otherwise, gets the loopback address which allows this machine to be 419 * contacted. 420 * 421 * @return the {@code InetAddress} representing the local host. 422 * @throws UnknownHostException 423 * if the address lookup fails. 424 */ 425 public static InetAddress getLocalHost() throws UnknownHostException { 426 String host = gethostname(); 427 SecurityManager security = System.getSecurityManager(); 428 try { 429 if (security != null) { 430 security.checkConnect(host, -1); 431 } 432 } catch (SecurityException e) { 433 return Inet4Address.LOOPBACK; 434 } 435 return lookupHostByName(host)[0]; 436 } 437 private static native String gethostname(); 438 439 /** 440 * Gets the hashcode of the represented IP address. 441 * 442 * @return the appropriate hashcode value. 443 */ 444 @Override 445 public int hashCode() { 446 // BEGIN android-changed 447 return Arrays.hashCode(ipaddress); 448 // END android-changed 449 } 450 451 // BEGIN android-changed 452 /* 453 * Returns whether this address is an IP multicast address or not. This 454 * implementation returns always {@code false}. 455 * 456 * @return {@code true} if this address is in the multicast group, {@code 457 * false} otherwise. 458 */ 459 public boolean isMulticastAddress() { 460 return false; 461 } 462 // END android-changed 463 464 /** 465 * Resolves a hostname to its IP addresses using a cache. 466 * 467 * @param host the hostname to resolve. 468 * @return the IP addresses of the host. 469 */ 470 // BEGIN android-changed 471 private static InetAddress[] lookupHostByName(String host) throws UnknownHostException { 472 // Do we have a result cached? 473 InetAddress[] cachedResult = addressCache.get(host); 474 if (cachedResult != null) { 475 if (cachedResult.length > 0) { 476 // A cached positive result. 477 return cachedResult; 478 } else { 479 // A cached negative result. 480 throw new UnknownHostException(host); 481 } 482 } 483 try { 484 InetAddress[] addresses = bytesToInetAddresses(getaddrinfo(host), host); 485 addressCache.put(host, addresses); 486 return addresses; 487 } catch (UnknownHostException e) { 488 addressCache.putUnknownHost(host); 489 throw new UnknownHostException(host); 490 } 491 } 492 private static native byte[][] getaddrinfo(String name) throws UnknownHostException; 493 // END android-changed 494 495 // BEGIN android-deleted 496 // static native InetAddress[] getAliasesByNameImpl(String name) 497 // throws UnknownHostException; 498 // END android-deleted 499 500 /** 501 * Query the IP stack for the host address. The host is in address form. 502 * 503 * @param addr 504 * the host address to lookup. 505 * @throws UnknownHostException 506 * if an error occurs during lookup. 507 */ 508 // BEGIN android-changed 509 // static native InetAddress getHostByAddrImpl(byte[] addr) 510 // throws UnknownHostException; 511 static InetAddress getHostByAddrImpl(byte[] addr) 512 throws UnknownHostException { 513 if (addr.length == 4) { 514 return new Inet4Address(addr, getnameinfo(addr)); 515 } else if (addr.length == 16) { 516 return new Inet6Address(addr, getnameinfo(addr)); 517 } else { 518 throw new UnknownHostException(Msg.getString( 519 "K0339")); //$NON-NLS-1$ 520 } 521 } 522 523 /** 524 * Resolves an IP address to a hostname. Thread safe. 525 */ 526 private static native String getnameinfo(byte[] addr); 527 // END android-changed 528 529 // BEGIN android-removed 530 // static int inetAddr(String host) throws UnknownHostException 531 // END android-removed 532 533 /** 534 * Convert a string containing an IPv4 Internet Protocol dotted address into 535 * a binary address. Note, the special case of '255.255.255.255' throws an 536 * exception, so this value should not be used as an argument. See also 537 * inetAddr(String). 538 */ 539 // BEGIN android-removed 540 // static native int inetAddrImpl(String host) throws UnknownHostException; 541 // END android-removed 542 543 /** 544 * Convert a binary address into a string containing an Ipv4 Internet 545 * Protocol dotted address. 546 */ 547 // BEGIN android-removed 548 // static native String inetNtoaImpl(int hipAddr); 549 // END android-removed 550 551 // BEGIN android-removed 552 /** 553 * Query the IP stack for the host address. The host is in string name form. 554 * 555 * @param name 556 * the host name to lookup 557 * @param preferIPv6Address 558 * address preference if underlying platform is V4/V6 559 * @return InetAddress the host address 560 * @throws UnknownHostException 561 * if an error occurs during lookup 562 */ 563 // static native InetAddress getHostByNameImpl(String name, 564 // boolean preferIPv6Address) throws UnknownHostException; 565 // END android-removed 566 567 static String getHostNameInternal(String host, boolean isCheck) throws UnknownHostException { 568 if (host == null || 0 == host.length()) { 569 return Inet4Address.LOOPBACK.getHostAddress(); 570 } 571 if (isHostName(host)) { 572 if (isCheck) { 573 SecurityManager sm = System.getSecurityManager(); 574 if (sm != null) { 575 sm.checkConnect(host, -1); 576 } 577 } 578 return lookupHostByName(host)[0].getHostAddress(); 579 } 580 return host; 581 } 582 583 /** 584 * Returns a string containing a concise, human-readable description of this 585 * IP address. 586 * 587 * @return the description, as host/address. 588 */ 589 @Override 590 public String toString() { 591 return (hostName == null ? "" : hostName) + "/" + getHostAddress(); //$NON-NLS-1$ //$NON-NLS-2$ 592 } 593 594 /** 595 * Returns true if the string is a host name, false if it is an IP Address. 596 */ 597 private static boolean isHostName(String value) { 598 try { 599 NETIMPL.ipStringToByteArray(value); 600 return false; 601 } catch (UnknownHostException e) { 602 return true; 603 } 604 } 605 606 /** 607 * Returns whether this address is a loopback address or not. This 608 * implementation returns always {@code false}. Valid IPv4 loopback 609 * addresses are 127.d.d.d The only valid IPv6 loopback address is ::1. 610 * 611 * @return {@code true} if this instance represents a loopback address, 612 * {@code false} otherwise. 613 */ 614 public boolean isLoopbackAddress() { 615 return false; 616 } 617 618 /** 619 * Returns whether this address is a link-local address or not. This 620 * implementation returns always {@code false}. 621 * <p> 622 * Valid IPv6 link-local addresses are FE80::0 through to 623 * FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF. 624 * <p> 625 * There are no valid IPv4 link-local addresses. 626 * 627 * @return {@code true} if this instance represents a link-local address, 628 * {@code false} otherwise. 629 */ 630 public boolean isLinkLocalAddress() { 631 return false; 632 } 633 634 /** 635 * Returns whether this address is a site-local address or not. This 636 * implementation returns always {@code false}. 637 * <p> 638 * Valid IPv6 site-local addresses are FEC0::0 through to 639 * FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF. 640 * <p> 641 * There are no valid IPv4 site-local addresses. 642 * 643 * @return {@code true} if this instance represents a site-local address, 644 * {@code false} otherwise. 645 */ 646 public boolean isSiteLocalAddress() { 647 return false; 648 } 649 650 /** 651 * Returns whether this address is a global multicast address or not. This 652 * implementation returns always {@code false}. 653 * <p> 654 * Valid IPv6 link-global multicast addresses are FFxE:/112 where x is a set 655 * of flags, and the additional 112 bits make up the global multicast 656 * address space. 657 * <p> 658 * Valid IPv4 global multicast addresses are between: 224.0.1.0 to 659 * 238.255.255.255. 660 * 661 * @return {@code true} if this instance represents a global multicast 662 * address, {@code false} otherwise. 663 */ 664 public boolean isMCGlobal() { 665 return false; 666 } 667 668 /** 669 * Returns whether this address is a node-local multicast address or not. 670 * This implementation returns always {@code false}. 671 * <p> 672 * Valid IPv6 node-local multicast addresses are FFx1:/112 where x is a set 673 * of flags, and the additional 112 bits make up the node-local multicast 674 * address space. 675 * <p> 676 * There are no valid IPv4 node-local multicast addresses. 677 * 678 * @return {@code true} if this instance represents a node-local multicast 679 * address, {@code false} otherwise. 680 */ 681 public boolean isMCNodeLocal() { 682 return false; 683 } 684 685 /** 686 * Returns whether this address is a link-local multicast address or not. 687 * This implementation returns always {@code false}. 688 * <p> 689 * Valid IPv6 link-local multicast addresses are FFx2:/112 where x is a set 690 * of flags, and the additional 112 bits make up the link-local multicast 691 * address space. 692 * <p> 693 * Valid IPv4 link-local addresses are between: 224.0.0.0 to 224.0.0.255 694 * 695 * @return {@code true} if this instance represents a link-local multicast 696 * address, {@code false} otherwise. 697 */ 698 public boolean isMCLinkLocal() { 699 return false; 700 } 701 702 /** 703 * Returns whether this address is a site-local multicast address or not. 704 * This implementation returns always {@code false}. 705 * <p> 706 * Valid IPv6 site-local multicast addresses are FFx5:/112 where x is a set 707 * of flags, and the additional 112 bits make up the site-local multicast 708 * address space. 709 * <p> 710 * Valid IPv4 site-local addresses are between: 239.252.0.0 to 711 * 239.255.255.255 712 * 713 * @return {@code true} if this instance represents a site-local multicast 714 * address, {@code false} otherwise. 715 */ 716 public boolean isMCSiteLocal() { 717 return false; 718 } 719 720 /** 721 * Returns whether this address is a organization-local multicast address or 722 * not. This implementation returns always {@code false}. 723 * <p> 724 * Valid IPv6 organization-local multicast addresses are FFx8:/112 where x 725 * is a set of flags, and the additional 112 bits make up the 726 * organization-local multicast address space. 727 * <p> 728 * Valid IPv4 organization-local addresses are between: 239.192.0.0 to 729 * 239.251.255.255 730 * 731 * @return {@code true} if this instance represents a organization-local 732 * multicast address, {@code false} otherwise. 733 */ 734 public boolean isMCOrgLocal() { 735 return false; 736 } 737 738 /** 739 * Returns whether this is a wildcard address or not. This implementation 740 * returns always {@code false}. 741 * 742 * @return {@code true} if this instance represents a wildcard address, 743 * {@code false} otherwise. 744 */ 745 public boolean isAnyLocalAddress() { 746 return false; 747 } 748 749 /** 750 * Tries to reach this {@code InetAddress}. This method first tries to use 751 * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection 752 * on port 7 (Echo) of the remote host is established. 753 * 754 * @param timeout 755 * timeout in milliseconds before the test fails if no connection 756 * could be established. 757 * @return {@code true} if this address is reachable, {@code false} 758 * otherwise. 759 * @throws IOException 760 * if an error occurs during an I/O operation. 761 * @throws IllegalArgumentException 762 * if timeout is less than zero. 763 */ 764 public boolean isReachable(int timeout) throws IOException { 765 return isReachable(null, 0, timeout); 766 } 767 768 /** 769 * Tries to reach this {@code InetAddress}. This method first tries to use 770 * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection 771 * on port 7 (Echo) of the remote host is established. 772 * 773 * @param netif 774 * the network interface on which to connection should be 775 * established. 776 * @param ttl 777 * the maximum count of hops (time-to-live). 778 * @param timeout 779 * timeout in milliseconds before the test fails if no connection 780 * could be established. 781 * @return {@code true} if this address is reachable, {@code false} 782 * otherwise. 783 * @throws IOException 784 * if an error occurs during an I/O operation. 785 * @throws IllegalArgumentException 786 * if ttl or timeout is less than zero. 787 */ 788 public boolean isReachable(NetworkInterface netif, final int ttl, 789 final int timeout) throws IOException { 790 if (0 > ttl || 0 > timeout) { 791 throw new IllegalArgumentException(Msg.getString("K0051")); //$NON-NLS-1$ 792 } 793 boolean reachable = false; 794 if (null == netif) { 795 // network interface is null, binds to no address 796 // BEGIN android-changed 797 // reachable = NETIMPL.isReachableByICMP(this, null, ttl, timeout); 798 // if (!reachable) { 799 reachable = isReachableByTCP(this, null, timeout); 800 // } 801 // END android-changed 802 } else { 803 // Not Bind to any address 804 if (null == netif.addresses) { 805 return false; 806 } 807 // binds to all address on this NetworkInterface, tries ICMP ping 808 // first 809 // BEGIN android-changed 810 // reachable = isReachableByICMPUseMultiThread(netif, ttl, timeout); 811 // if (!reachable) { 812 // tries TCP echo if ICMP ping fails 813 reachable = isReachableByMultiThread(netif, ttl, timeout); 814 // } 815 // END adnroid-changed 816 } 817 return reachable; 818 } 819 820 /* 821 * Uses multi-Thread to try if isReachable, returns true if any of threads 822 * returns in time 823 */ 824 // BEGIN android-changed 825 private boolean isReachableByMultiThread(NetworkInterface netif, 826 final int ttl, final int timeout) 827 // END android-changed 828 throws IOException { 829 if (null == netif.addresses) { 830 return false; 831 } 832 Enumeration<InetAddress> addresses = netif.getInetAddresses(); 833 reached = false; 834 addrCount = netif.addresses.length; 835 boolean needWait = false; 836 while (addresses.hasMoreElements()) { 837 final InetAddress addr = addresses.nextElement(); 838 839 // loopback interface can only reach to local addresses 840 if (addr.isLoopbackAddress()) { 841 Enumeration<NetworkInterface> NetworkInterfaces = NetworkInterface 842 .getNetworkInterfaces(); 843 while (NetworkInterfaces.hasMoreElements()) { 844 NetworkInterface networkInterface = NetworkInterfaces 845 .nextElement(); 846 Enumeration<InetAddress> localAddresses = networkInterface 847 .getInetAddresses(); 848 while (localAddresses.hasMoreElements()) { 849 if (InetAddress.this.equals(localAddresses 850 .nextElement())) { 851 return true; 852 } 853 } 854 } 855 856 synchronized (waitReachable) { 857 addrCount--; 858 859 if (addrCount == 0) { 860 // if count equals zero, all thread 861 // expired,notifies main thread 862 waitReachable.notifyAll(); 863 } 864 } 865 continue; 866 } 867 868 needWait = true; 869 new Thread() { 870 @Override 871 public void run() { 872 boolean threadReached = false; 873 // BEGIN android-changed 874 // if isICMP, tries ICMP ping, else TCP echo 875 // if (isICMP) { 876 // threadReached = NETIMPL.isReachableByICMP( 877 // InetAddress.this, addr, ttl, timeout); 878 // } else { 879 try { 880 threadReached = isReachableByTCP(addr, 881 InetAddress.this, timeout); 882 } catch (IOException e) { 883 // do nothing 884 } 885 // } 886 // END android-changed 887 888 synchronized (waitReachable) { 889 if (threadReached) { 890 // if thread reached this address, sets reached to 891 // true and notifies main thread 892 reached = true; 893 waitReachable.notifyAll(); 894 } else { 895 addrCount--; 896 if (0 == addrCount) { 897 // if count equals zero, all thread 898 // expired,notifies main thread 899 waitReachable.notifyAll(); 900 } 901 } 902 } 903 } 904 }.start(); 905 } 906 907 if (needWait) { 908 synchronized (waitReachable) { 909 try { 910 while (!reached && (addrCount != 0)) { 911 // wait for notification 912 waitReachable.wait(1000); 913 } 914 } catch (InterruptedException e) { 915 // do nothing 916 } 917 return reached; 918 } 919 } 920 921 return false; 922 } 923 924 // BEGIN android-removed 925 // private boolean isReachableByICMPUseMultiThread(NetworkInterface netif, 926 // int ttl, int timeout) throws IOException { 927 // return isReachableByMultiThread(netif, ttl, timeout, true); 928 // } 929 // 930 // private boolean isReachableByTCPUseMultiThread(NetworkInterface netif, 931 // int ttl, int timeout) throws IOException { 932 // return isReachableByMultiThread(netif, ttl, timeout, false); 933 // } 934 // END android-removed 935 936 private boolean isReachableByTCP(InetAddress dest, InetAddress source, 937 int timeout) throws IOException { 938 FileDescriptor fd = new FileDescriptor(); 939 // define traffic only for parameter 940 int traffic = 0; 941 boolean reached = false; 942 NETIMPL.createStreamSocket(fd, NetUtil.preferIPv4Stack()); 943 try { 944 if (null != source) { 945 NETIMPL.bind(fd, source, 0); 946 } 947 NETIMPL.connectStreamWithTimeoutSocket(fd, 7, timeout, traffic, 948 dest); 949 reached = true; 950 } catch (IOException e) { 951 if (ERRMSG_CONNECTION_REFUSED.equals(e.getMessage())) { 952 // Connection refused means the IP is reachable 953 reached = true; 954 } 955 } 956 957 NETIMPL.socketClose(fd); 958 959 return reached; 960 } 961 962 /** 963 * Returns the {@code InetAddress} corresponding to the array of bytes. In 964 * the case of an IPv4 address there must be exactly 4 bytes and for IPv6 965 * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown. 966 * <p> 967 * The IP address is not validated by a name service. 968 * <p> 969 * The high order byte is {@code ipAddress[0]}. 970 * 971 * @param ipAddress 972 * is either a 4 (IPv4) or 16 (IPv6) byte long array. 973 * @return an {@code InetAddress} instance representing the given IP address 974 * {@code ipAddress}. 975 * @throws UnknownHostException 976 * if the given byte array has no valid length. 977 */ 978 public static InetAddress getByAddress(byte[] ipAddress) 979 throws UnknownHostException { 980 // simply call the method by the same name specifying the default scope 981 // id of 0 982 return getByAddressInternal(null, ipAddress, 0); 983 } 984 985 /** 986 * Returns the {@code InetAddress} corresponding to the array of bytes. In 987 * the case of an IPv4 address there must be exactly 4 bytes and for IPv6 988 * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown. The 989 * IP address is not validated by a name service. The high order byte is 990 * {@code ipAddress[0]}. 991 * 992 * @param ipAddress 993 * either a 4 (IPv4) or 16 (IPv6) byte array. 994 * @param scope_id 995 * the scope id for an IPV6 scoped address. If not a scoped 996 * address just pass in 0. 997 * @return the InetAddress 998 * @throws UnknownHostException 999 */ 1000 static InetAddress getByAddress(byte[] ipAddress, int scope_id) 1001 throws UnknownHostException { 1002 return getByAddressInternal(null, ipAddress, scope_id); 1003 } 1004 1005 private static boolean isIPv4MappedAddress(byte ipAddress[]) { 1006 // Check if the address matches ::FFFF:d.d.d.d 1007 // The first 10 bytes are 0. The next to are -1 (FF). 1008 // The last 4 bytes are varied. 1009 if (ipAddress == null || ipAddress.length != 16) { 1010 return false; 1011 } 1012 for (int i = 0; i < 10; i++) { 1013 if (ipAddress[i] != 0) { 1014 return false; 1015 } 1016 } 1017 if (ipAddress[10] != -1 || ipAddress[11] != -1) { 1018 return false; 1019 } 1020 return true; 1021 } 1022 1023 private static byte[] ipv4MappedToIPv4(byte[] mappedAddress) { 1024 byte[] ipv4Address = new byte[4]; 1025 for(int i = 0; i < 4; i++) { 1026 ipv4Address[i] = mappedAddress[12 + i]; 1027 } 1028 return ipv4Address; 1029 } 1030 1031 /** 1032 * Returns the {@code InetAddress} corresponding to the array of bytes, and 1033 * the given hostname. In the case of an IPv4 address there must be exactly 1034 * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code 1035 * UnknownHostException} will be thrown. 1036 * <p> 1037 * The host name and IP address are not validated. 1038 * <p> 1039 * The hostname either be a machine alias or a valid IPv6 or IPv4 address 1040 * format. 1041 * <p> 1042 * The high order byte is {@code ipAddress[0]}. 1043 * 1044 * @param hostName 1045 * the string representation of hostname or IP address. 1046 * @param ipAddress 1047 * either a 4 (IPv4) or 16 (IPv6) byte long array. 1048 * @return an {@code InetAddress} instance representing the given IP address 1049 * and hostname. 1050 * @throws UnknownHostException 1051 * if the given byte array has no valid length. 1052 */ 1053 public static InetAddress getByAddress(String hostName, byte[] ipAddress) 1054 throws UnknownHostException { 1055 // just call the method by the same name passing in a default scope id 1056 // of 0 1057 return getByAddressInternal(hostName, ipAddress, 0); 1058 } 1059 1060 /** 1061 * Returns the {@code InetAddress} corresponding to the array of bytes, and 1062 * the given hostname. In the case of an IPv4 address there must be exactly 1063 * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code 1064 * UnknownHostException} is thrown. The host name and IP address are not 1065 * validated. The hostname either be a machine alias or a valid IPv6 or IPv4 1066 * address format. The high order byte is {@code ipAddress[0]}. 1067 * 1068 * @param hostName 1069 * string representation of hostname or IP address. 1070 * @param ipAddress 1071 * either a 4 (IPv4) or 16 (IPv6) byte array. 1072 * @param scope_id 1073 * the scope id for a scoped address. If not a scoped address 1074 * just pass in 0. 1075 * @return the InetAddress 1076 * @throws UnknownHostException 1077 */ 1078 static InetAddress getByAddressInternal(String hostName, byte[] ipAddress, 1079 int scope_id) throws UnknownHostException { 1080 if (ipAddress == null) { 1081 // We don't throw NullPointerException here for RI compatibility, 1082 // but we do say "address is null" (K0331), instead of "addr is of 1083 // illegal length". 1084 throw new UnknownHostException( 1085 Msg.getString("K0331", hostName)); //$NON-NLS-1$ 1086 } 1087 switch (ipAddress.length) { 1088 case 4: 1089 return new Inet4Address(ipAddress.clone()); 1090 case 16: 1091 // First check to see if the address is an IPv6-mapped 1092 // IPv4 address. If it is, then we can make it a IPv4 1093 // address, otherwise, we'll create an IPv6 address. 1094 if (isIPv4MappedAddress(ipAddress)) { 1095 return new Inet4Address(ipv4MappedToIPv4(ipAddress)); 1096 } else { 1097 return new Inet6Address(ipAddress.clone(), scope_id); 1098 } 1099 default: 1100 if (hostName != null) { 1101 // "Invalid IP Address is neither 4 or 16 bytes: <hostName>" 1102 throw new UnknownHostException( 1103 Msg.getString("K0332", hostName)); //$NON-NLS-1$ 1104 } else { 1105 // "Invalid IP Address is neither 4 or 16 bytes" 1106 throw new UnknownHostException( 1107 Msg.getString("K0339")); //$NON-NLS-1$ 1108 } 1109 } 1110 } 1111 1112 /** 1113 * Takes the integer and chops it into 4 bytes, putting it into the byte 1114 * array starting with the high order byte at the index start. This method 1115 * makes no checks on the validity of the parameters. 1116 */ 1117 static void intToBytes(int value, byte bytes[], int start) { 1118 // Shift the int so the current byte is right-most 1119 // Use a byte mask of 255 to single out the last byte. 1120 bytes[start] = (byte) ((value >> 24) & 255); 1121 bytes[start + 1] = (byte) ((value >> 16) & 255); 1122 bytes[start + 2] = (byte) ((value >> 8) & 255); 1123 bytes[start + 3] = (byte) (value & 255); 1124 } 1125 1126 /** 1127 * Takes the byte array and creates an integer out of four bytes starting at 1128 * start as the high-order byte. This method makes no checks on the validity 1129 * of the parameters. 1130 */ 1131 static int bytesToInt(byte bytes[], int start) { 1132 // First mask the byte with 255, as when a negative 1133 // signed byte converts to an integer, it has bits 1134 // on in the first 3 bytes, we are only concerned 1135 // about the right-most 8 bits. 1136 // Then shift the rightmost byte to align with its 1137 // position in the integer. 1138 int value = ((bytes[start + 3] & 255)) 1139 | ((bytes[start + 2] & 255) << 8) 1140 | ((bytes[start + 1] & 255) << 16) 1141 | ((bytes[start] & 255) << 24); 1142 return value; 1143 } 1144 1145 static boolean preferIPv6Addresses() { 1146 String result = AccessController.doPrivileged(new PriviAction<String>( 1147 "java.net.preferIPv6Addresses")); //$NON-NLS-1$ 1148 return "true".equals(result); //$NON-NLS-1$ 1149 } 1150 1151 private static final ObjectStreamField[] serialPersistentFields = { 1152 new ObjectStreamField("address", Integer.TYPE), //$NON-NLS-1$ 1153 new ObjectStreamField("family", Integer.TYPE), //$NON-NLS-1$ 1154 new ObjectStreamField("hostName", String.class) }; //$NON-NLS-1$ 1155 1156 private void writeObject(ObjectOutputStream stream) throws IOException { 1157 ObjectOutputStream.PutField fields = stream.putFields(); 1158 if (ipaddress == null) { 1159 fields.put("address", 0); //$NON-NLS-1$ 1160 } else { 1161 fields.put("address", bytesToInt(ipaddress, 0)); //$NON-NLS-1$ 1162 } 1163 fields.put("family", family); //$NON-NLS-1$ 1164 fields.put("hostName", hostName); //$NON-NLS-1$ 1165 1166 stream.writeFields(); 1167 } 1168 1169 private void readObject(ObjectInputStream stream) throws IOException, 1170 ClassNotFoundException { 1171 ObjectInputStream.GetField fields = stream.readFields(); 1172 int addr = fields.get("address", 0); //$NON-NLS-1$ 1173 ipaddress = new byte[4]; 1174 intToBytes(addr, ipaddress, 0); 1175 hostName = (String) fields.get("hostName", null); //$NON-NLS-1$ 1176 family = fields.get("family", 2); //$NON-NLS-1$ 1177 } 1178 1179 /* 1180 * The spec requires that if we encounter a generic InetAddress in 1181 * serialized form then we should interpret it as an Inet4 address. 1182 */ 1183 private Object readResolve() throws ObjectStreamException { 1184 return new Inet4Address(ipaddress, hostName); 1185 } 1186} 1187