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