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