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