InetAddress.java revision b46dab348e2007bc08abaf7ecae34d89a2474e50
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 207983be972905950b4a4e7d66df908f083c81ee29Brad Fitzpatrickimport dalvik.system.BlockGuard; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileDescriptor; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectStreamException; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectStreamField; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable; 280eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughesimport java.nio.ByteOrder; 290917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughesimport java.security.AccessController; 30ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colittiimport java.util.Arrays; 31d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.Collections; 32ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colittiimport java.util.Comparator; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration; 34d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.List; 350eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughesimport org.apache.harmony.luni.platform.OSMemory; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.Platform; 370917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughesimport org.apache.harmony.luni.util.PriviAction; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 40048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * An Internet Protocol (IP) address. This can be either an IPv4 address or an IPv6 address, and 41048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * in practice you'll have an instance of either {@code Inet4Address} or {@code Inet6Address} (this 42048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * class cannot be instantiated directly). Most code does not need to distinguish between the two 43048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * families, and should use {@code InetAddress}. 444adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 454adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>An {@code InetAddress} may have a hostname (accessible via {@code getHostName}), but may not, 46048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * depending on how the {@code InetAddress} was created. 474adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 484adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <h4>IPv4 numeric address formats</h4> 494adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>The {@code getAllByName} method accepts IPv4 addresses in the following forms: 504adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <ul> 514adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "1.2.3.4"} - 1.2.3.4 524adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "1.2.3"} - 1.2.0.3 534adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "1.2"} - 1.0.0.2 544adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "16909060"} - 1.2.3.4 554adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </ul> 564adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>In the first three cases, each number is treated as an 8-bit value between 0 and 255. 574adff24306c86433ce4f771da8489a574e63318eElliott Hughes * In the fourth case, the single number is treated as a 32-bit value representing the entire 584adff24306c86433ce4f771da8489a574e63318eElliott Hughes * address. 594adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Note that each numeric part can be expressed in decimal (as above) or hex. For example, 604adff24306c86433ce4f771da8489a574e63318eElliott Hughes * {@code "0x01020304"} is equivalent to 1.2.3.4 and {@code "0xa.0xb.0xc.0xd"} is equivalent 614adff24306c86433ce4f771da8489a574e63318eElliott Hughes * to 10.11.12.13. 624adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 634adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Typically, only the four-dot decimal form ({@code "1.2.3.4"}) is ever used. Any method that 644adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <i>returns</i> a textual numeric address will use four-dot decimal form. 654adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 664adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <h4>IPv6 numeric address formats</h4> 674adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>The {@code getAllByName} method accepts IPv6 addresses in the following forms (this text 684adff24306c86433ce4f771da8489a574e63318eElliott Hughes * comes from <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>, which you should consult 694adff24306c86433ce4f771da8489a574e63318eElliott Hughes * for full details of IPv6 addressing): 704adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <ul> 714adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li><p>The preferred form is {@code x:x:x:x:x:x:x:x}, where the 'x's are the 724adff24306c86433ce4f771da8489a574e63318eElliott Hughes * hexadecimal values of the eight 16-bit pieces of the address. 734adff24306c86433ce4f771da8489a574e63318eElliott Hughes * Note that it is not necessary to write the leading zeros in an 744adff24306c86433ce4f771da8489a574e63318eElliott Hughes * individual field, but there must be at least one numeral in every 754adff24306c86433ce4f771da8489a574e63318eElliott Hughes * field (except for the case described in the next bullet). 764adff24306c86433ce4f771da8489a574e63318eElliott Hughes * Examples: 774adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre> 784adff24306c86433ce4f771da8489a574e63318eElliott Hughes * FEDC:BA98:7654:3210:FEDC:BA98:7654:3210 794adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 1080:0:0:0:8:800:200C:417A</pre> 804adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </li> 814adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>Due to some methods of allocating certain styles of IPv6 824adff24306c86433ce4f771da8489a574e63318eElliott Hughes * addresses, it will be common for addresses to contain long strings 834adff24306c86433ce4f771da8489a574e63318eElliott Hughes * of zero bits. In order to make writing addresses containing zero 844adff24306c86433ce4f771da8489a574e63318eElliott Hughes * bits easier a special syntax is available to compress the zeros. 854adff24306c86433ce4f771da8489a574e63318eElliott Hughes * The use of "::" indicates multiple groups of 16-bits of zeros. 864adff24306c86433ce4f771da8489a574e63318eElliott Hughes * The "::" can only appear once in an address. The "::" can also be 874adff24306c86433ce4f771da8489a574e63318eElliott Hughes * used to compress the leading and/or trailing zeros in an address. 884adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 894adff24306c86433ce4f771da8489a574e63318eElliott Hughes * For example the following addresses: 904adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre> 914adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 1080:0:0:0:8:800:200C:417A a unicast address 924adff24306c86433ce4f771da8489a574e63318eElliott Hughes * FF01:0:0:0:0:0:0:101 a multicast address 934adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 0:0:0:0:0:0:0:1 the loopback address 944adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 0:0:0:0:0:0:0:0 the unspecified addresses</pre> 954adff24306c86433ce4f771da8489a574e63318eElliott Hughes * may be represented as: 964adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre> 974adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 1080::8:800:200C:417A a unicast address 984adff24306c86433ce4f771da8489a574e63318eElliott Hughes * FF01::101 a multicast address 994adff24306c86433ce4f771da8489a574e63318eElliott Hughes * ::1 the loopback address 1004adff24306c86433ce4f771da8489a574e63318eElliott Hughes * :: the unspecified addresses</pre> 1014adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </li> 1024adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li><p>An alternative form that is sometimes more convenient when dealing 1034adff24306c86433ce4f771da8489a574e63318eElliott Hughes * with a mixed environment of IPv4 and IPv6 nodes is 1044adff24306c86433ce4f771da8489a574e63318eElliott Hughes * {@code x:x:x:x:x:x:d.d.d.d}, where the 'x's are the hexadecimal values of 1054adff24306c86433ce4f771da8489a574e63318eElliott Hughes * the six high-order 16-bit pieces of the address, and the 'd's are 1064adff24306c86433ce4f771da8489a574e63318eElliott Hughes * the decimal values of the four low-order 8-bit pieces of the 1074adff24306c86433ce4f771da8489a574e63318eElliott Hughes * address (standard IPv4 representation). Examples: 1084adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre> 1094adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 0:0:0:0:0:0:13.1.68.3 1104adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 0:0:0:0:0:FFFF:129.144.52.38</pre> 1114adff24306c86433ce4f771da8489a574e63318eElliott Hughes * or in compressed form: 1124adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre> 1134adff24306c86433ce4f771da8489a574e63318eElliott Hughes * ::13.1.68.3 1144adff24306c86433ce4f771da8489a574e63318eElliott Hughes * ::FFFF:129.144.52.38</pre> 1154adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </li> 1164adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </ul> 1174adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Scopes are given using a trailing {@code %} followed by the scope id, as in 1184adff24306c86433ce4f771da8489a574e63318eElliott Hughes * {@code 1080::8:800:200C:417A%2} or {@code 1080::8:800:200C:417A%en0}. 1194adff24306c86433ce4f771da8489a574e63318eElliott Hughes * See <a href="https://www.ietf.org/rfc/rfc4007.txt">RFC 4007</a> for more on IPv6's scoped 1204adff24306c86433ce4f771da8489a574e63318eElliott Hughes * address architecture. 1214adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 1220d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * <p>Additionally, for backwards compatibility, IPv6 addresses may be surrounded by square 1230d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * brackets. 1240d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * 1254adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <h4>DNS caching</h4> 1264adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>On Android, addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are 127048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * cached for 10 seconds. The underlying C library or OS may cache for longer, but you can control 128048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * the Java-level caching with the usual {@code "networkaddress.cache.ttl"} and 129048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * {@code "networkaddress.cache.negative.ttl"} system properties. These are parsed as integer 130048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * numbers of seconds, where the special value 0 means "don't cache" and -1 means "cache forever". 1314adff24306c86433ce4f771da8489a574e63318eElliott Hughes * 1324adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Note also that on Android – unlike the RI – the cache is not unbounded. The 1334adff24306c86433ce4f771da8489a574e63318eElliott Hughes * current implementation caches around 512 entries, removed on a least-recently-used basis. 134048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * (Obviously, you should not rely on these details.) 135f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 136048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * @see Inet4Address 137048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * @see Inet6Address 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 139048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughespublic class InetAddress implements Serializable { 14038607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson /** Our Java-side DNS cache. */ 141048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes private static final AddressCache addressCache = new AddressCache(); 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 14338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused"; 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti private static final long serialVersionUID = 3286316764910316507L; 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String hostName; 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class WaitReachable { 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient Object waitReachable = new WaitReachable(); 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean reached; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int addrCount; 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 158051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti int family = 0; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] ipaddress; 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 163051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * Constructs an {@code InetAddress}. 164051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * 165051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * Note: this constructor should not be used. Creating an InetAddress 166051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * without specifying whether it's an IPv4 or IPv6 address does not make 167051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * sense, because subsequent code cannot know which of of the subclasses' 168051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * methods need to be called to implement a given InetAddress method. The 169051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * proper way to create an InetAddress is to call new Inet4Address or 170051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * Inet6Address or to use one of the static methods that return 171051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * InetAddresses (e.g., getByAddress). That is why the API does not have 172051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * public constructors for any of these classes. 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson InetAddress() {} 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares this {@code InetAddress} instance against the specified address 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in {@code obj}. Two addresses are equal if their address byte arrays have 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the same length and if the bytes in the arrays are equal. 180f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object to be tested for equality. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if both objects are equal, {@code false} otherwise. 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object obj) { 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(obj instanceof InetAddress)) { 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 190051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress); 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the IP address represented by this {@code InetAddress} instance 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as a byte array. The elements are in network order (the highest order 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address byte is in the zeroth element). 197f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the address in form of a byte array. 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getAddress() { 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ipaddress.clone(); 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 204ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti static final Comparator<byte[]> SHORTEST_FIRST = new Comparator<byte[]>() { 205ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti public int compare(byte[] a1, byte[] a2) { 206ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti return a1.length - a2.length; 207ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } 208ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti }; 209ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti 210ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti /** 211ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * Converts an array of byte arrays representing raw IP addresses of a host 212ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * to an array of InetAddress objects, sorting to respect the value of the 2134c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes * system property {@code "java.net.preferIPv6Addresses"}. 214ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * 215ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * @param rawAddresses the raw addresses to convert. 216ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * @param hostName the hostname corresponding to the IP address. 217ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * @return the corresponding InetAddresses, appropriately sorted. 218ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti */ 219fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes static InetAddress[] bytesToInetAddresses(byte[][] rawAddresses, String hostName) 220fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes throws UnknownHostException { 221fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes // If we prefer IPv4, ignore the RFC3484 ordering we get from getaddrinfo(3) 222a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson // and always put IPv4 addresses first. Arrays.sort() is stable, so the 223a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson // internal ordering will not be changed. 2240917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes if (!preferIPv6Addresses()) { 225a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson Arrays.sort(rawAddresses, SHORTEST_FIRST); 226a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson } 227ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti 228ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti // Convert the byte arrays to InetAddresses. 229ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti InetAddress[] returnedAddresses = new InetAddress[rawAddresses.length]; 230ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti for (int i = 0; i < rawAddresses.length; i++) { 231fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes returnedAddresses[i] = makeInetAddress(rawAddresses[i], hostName); 232ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } 233ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti return returnedAddresses; 234ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } 235ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets all IP addresses associated with the given {@code host} identified 238ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * by name or literal IP address. The IP address is resolved by the 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * configured name service. If the host name is empty or {@code null} an 240ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * {@code UnknownHostException} is thrown. If the host name is a literal IP 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address string an array with the corresponding single {@code InetAddress} 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is returned. 243f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 244ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * @param host the hostname or literal IP string to be resolved. 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of addresses associated with the specified host. 246ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * @throws UnknownHostException if the address lookup fails. 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 24838607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson public static InetAddress[] getAllByName(String host) throws UnknownHostException { 24938607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson return getAllByNameImpl(host).clone(); 250ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } 251ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti 252ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti /** 25338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson * Returns the InetAddresses for {@code host}. The returned array is shared 25438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson * and must be cloned before it is returned to application code. 255ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti */ 25638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson static InetAddress[] getAllByNameImpl(String host) throws UnknownHostException { 25738607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson if (host == null || host.isEmpty()) { 2580917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes if (preferIPv6Addresses()) { 2594fe378672d700aaae3a50db956b693b3ed599c7dElliott Hughes return new InetAddress[] { Inet6Address.LOOPBACK, Inet4Address.LOOPBACK }; 260ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } else { 2614fe378672d700aaae3a50db956b693b3ed599c7dElliott Hughes return new InetAddress[] { Inet4Address.LOOPBACK, Inet6Address.LOOPBACK }; 262ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } 263ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } 264ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti 265ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti // Special-case "0" for legacy IPv4 applications. 26638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson if (host.equals("0")) { 267051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti return new InetAddress[] { Inet4Address.ANY }; 268ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti } 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2700d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes // Is it a numeric address? 2710d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes byte[] bytes = ipStringToByteArray(host); 2720d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes if (bytes != null) { 2730d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes return new InetAddress[] { makeInetAddress(bytes, null) }; 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 27638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson SecurityManager security = System.getSecurityManager(); 27738607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson if (security != null) { 27838607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson security.checkConnect(host, -1); 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 28038607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson 28138607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson return lookupHostByName(host); 28238607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson } 28338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson 284fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes private static InetAddress makeInetAddress(byte[] bytes, String hostname) throws UnknownHostException { 285fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes if (bytes.length == 4) { 286fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes return new Inet4Address(bytes, hostname); 287fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } else if (bytes.length == 16) { 288fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes return new Inet6Address(bytes, hostname, 0); 289fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } else { 290fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes throw badAddressLength(bytes); 291fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } 292fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } 293fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes 294753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes private static native String byteArrayToIpString(byte[] address); 295753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes 2960d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes static native byte[] ipStringToByteArray(String address); 297753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes 2980917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes static boolean preferIPv6Addresses() { 2990917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes String propertyName = "java.net.preferIPv6Addresses"; 3000917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes String propertyValue = AccessController.doPrivileged(new PriviAction<String>(propertyName)); 30195c82c8a020e48793dd5db33ba1a20f9ef01737aElliott Hughes return Boolean.parseBoolean(propertyValue); 3020917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes } 3030917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the address of a host according to the given host string name 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code host}. The host string may be either a machine name or a dotted 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * string IP address. If the latter, the {@code hostName} field is 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * determined upon demand. {@code host} can be {@code null} which means that 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an address of the loopback interface is returned. 310f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param host 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the hostName to be resolved to an address or {@code null}. 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code InetAddress} instance representing the host. 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the address lookup fails. 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 317ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti public static InetAddress getByName(String host) throws UnknownHostException { 31838607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson return getAllByNameImpl(host)[0]; 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 321e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti /** 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the textual representation of this IP address. 323f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 324511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti * @return the textual representation of host's IP address. 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getHostAddress() { 327753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return byteArrayToIpString(ipaddress); 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the host name of this IP address. If the IP address could not be 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * resolved, the textual representation in a dotted-quad-notation is 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned. 334f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the corresponding string name of this IP address. 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getHostName() { 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (hostName == null) { 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int address = 0; 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ipaddress.length == 4) { 3420eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes address = OSMemory.peekInt(ipaddress, 0, ByteOrder.BIG_ENDIAN); 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (address == 0) { 344753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return hostName = byteArrayToIpString(ipaddress); 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project hostName = getHostByAddrImpl(ipaddress).hostName; 34838607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson if (hostName.equals("localhost") && ipaddress.length == 4 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && address != 0x7f000001) { 350753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return hostName = byteArrayToIpString(ipaddress); 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (UnknownHostException e) { 354753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return hostName = byteArrayToIpString(ipaddress); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only check host names, not addresses 3590d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes if (security != null && !isNumeric(hostName)) { 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkConnect(hostName, -1); 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SecurityException e) { 363753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return byteArrayToIpString(ipaddress); 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return hostName; 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the fully qualified domain name for the host associated with this IP 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address. If a security manager is set, it is checked if the method caller 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is allowed to get the hostname. Otherwise, the textual representation in 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a dotted-quad-notation is returned. 373f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the fully qualified domain name of this IP address. 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getCanonicalHostName() { 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String canonicalName; 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int address = 0; 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ipaddress.length == 4) { 3810eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes address = OSMemory.peekInt(ipaddress, 0, ByteOrder.BIG_ENDIAN); 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (address == 0) { 383753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return byteArrayToIpString(ipaddress); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project canonicalName = getHostByAddrImpl(ipaddress).hostName; 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (UnknownHostException e) { 388753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return byteArrayToIpString(ipaddress); 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only check host names, not addresses 3930d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes if (security != null && !isNumeric(canonicalName)) { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkConnect(canonicalName, -1); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SecurityException e) { 397753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes return byteArrayToIpString(ipaddress); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return canonicalName; 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 403ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * Returns an {@code InetAddress} for the local host if possible, or the 404ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * loopback address otherwise. This method works by getting the hostname, 405ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * performing a DNS lookup, and then taking the first returned address. 406ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * For devices with multiple network interfaces and/or multiple addresses 407ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * per interface, this does not necessarily return the {@code InetAddress} 408ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * you want. 409f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 410ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * <p>Multiple interface/address configurations were relatively rare 411ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * when this API was designed, but multiple interfaces are the default for 412ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * modern mobile devices (with separate wifi and radio interfaces), and 413ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * the need to support both IPv4 and IPv6 has made multiple addresses 414ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * commonplace. New code should thus avoid this method except where it's 415ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * basically being used to get a loopback address or equivalent. 416ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * 417ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * <p>There are two main ways to get a more specific answer: 418ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * <ul> 419ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * <li>If you have a connected socket, you should probably use 420ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * {@link Socket#getLocalAddress} instead: that will give you the address 421ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * that's actually in use for that connection. (It's not possible to ask 422ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * the question "what local address would a connection to a given remote 423ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * address use?"; you have to actually make the connection and see.)</li> 424ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * <li>For other use cases, see {@link NetworkInterface}, which lets you 425ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * enumerate all available network interfaces and their addresses.</li> 426ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * </ul> 427ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * 428ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * <p>Note that if the host doesn't have a hostname set – as 429ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * Android devices typically don't – this method will 430ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * effectively return the loopback address, albeit by getting the name 431ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * {@code localhost} and then doing a lookup to translate that to 432ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * {@code 127.0.0.1}. 433ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * 434ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * @return an {@code InetAddress} representing the local host, or the 435ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes * loopback address. 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the address lookup fails. 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static InetAddress getLocalHost() throws UnknownHostException { 440048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes String host = gethostname(); 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkConnect(host, -1); 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SecurityException e) { 447051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti return Inet4Address.LOOPBACK; 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 449ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti return lookupHostByName(host)[0]; 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 451048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes private static native String gethostname(); 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the hashcode of the represented IP address. 455f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the appropriate hashcode value. 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int hashCode() { 460051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti return Arrays.hashCode(ipaddress); 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 463051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti /* 464051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * Returns whether this address is an IP multicast address or not. This 465051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti * implementation returns always {@code false}. 466f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this address is in the multicast group, {@code 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * false} otherwise. 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isMulticastAddress() { 471051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti return false; 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 473051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti 474ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti /** 475048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * Resolves a hostname to its IP addresses using a cache. 476ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * 477ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * @param host the hostname to resolve. 478ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti * @return the IP addresses of the host. 479ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti */ 480048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes private static InetAddress[] lookupHostByName(String host) throws UnknownHostException { 4817983be972905950b4a4e7d66df908f083c81ee29Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 482048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes // Do we have a result cached? 483fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes Object cachedResult = addressCache.get(host); 484048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes if (cachedResult != null) { 485fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes if (cachedResult instanceof InetAddress[]) { 486048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes // A cached positive result. 487fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes return (InetAddress[]) cachedResult; 488048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes } else { 489048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes // A cached negative result. 490fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes throw new UnknownHostException((String) cachedResult); 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 494048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes InetAddress[] addresses = bytesToInetAddresses(getaddrinfo(host), host); 495048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes addressCache.put(host, addresses); 496048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes return addresses; 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (UnknownHostException e) { 498fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes String detailMessage = e.getMessage(); 499fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes addressCache.putUnknownHost(host, detailMessage); 500fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes throw new UnknownHostException(detailMessage); 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 503048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes private static native byte[][] getaddrinfo(String name) throws UnknownHostException; 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 506b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes * Removes all entries from the VM's DNS cache. This does not affect the C library's DNS 507b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes * cache, nor any caching DNS servers between you and the canonical server. 508b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes * @hide 509b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes */ 510b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes public static void clearDnsCache() { 511b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes addressCache.clear(); 512b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes } 513b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes 514b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes /** 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Query the IP stack for the host address. The host is in address form. 516f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param addr 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the host address to lookup. 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs during lookup. 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 522b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes static InetAddress getHostByAddrImpl(byte[] addr) throws UnknownHostException { 5237983be972905950b4a4e7d66df908f083c81ee29Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 524fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes return makeInetAddress(addr, getnameinfo(addr)); 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Resolves an IP address to a hostname. Thread safe. 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 530048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes private static native String getnameinfo(byte[] addr); 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 53255392539fea537abfb6581b474918f9d611fba27Jesse Wilson static String getHostNameInternal(String host, boolean isCheck) throws UnknownHostException { 533b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (host == null || host.isEmpty()) { 534051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti return Inet4Address.LOOPBACK.getHostAddress(); 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 5360d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes if (!isNumeric(host)) { 53755392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (isCheck) { 53855392539fea537abfb6581b474918f9d611fba27Jesse Wilson SecurityManager sm = System.getSecurityManager(); 53955392539fea537abfb6581b474918f9d611fba27Jesse Wilson if (sm != null) { 54055392539fea537abfb6581b474918f9d611fba27Jesse Wilson sm.checkConnect(host, -1); 54155392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 54255392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 543ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti return lookupHostByName(host)[0].getHostAddress(); 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return host; 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of this 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * IP address. 551f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the description, as host/address. 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 55638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson return (hostName == null ? "" : hostName) + "/" + getHostAddress(); 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 5600d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1"). 5610d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * This copes with all forms of address that Java supports, detailed in the {@link InetAddress} 5620d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * class documentation. 5630d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * 5640d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * @hide - used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup. 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 5660d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes public static boolean isNumeric(String address) { 5670d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes return ipStringToByteArray(address) != null; 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a loopback address or not. This 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation returns always {@code false}. Valid IPv4 loopback 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * addresses are 127.d.d.d The only valid IPv6 loopback address is ::1. 574f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a loopback address, 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isLoopbackAddress() { 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a link-local address or not. This 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation returns always {@code false}. 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv6 link-local addresses are FE80::0 through to 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF. 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * There are no valid IPv4 link-local addresses. 590f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a link-local address, 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isLinkLocalAddress() { 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a site-local address or not. This 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation returns always {@code false}. 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv6 site-local addresses are FEC0::0 through to 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF. 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * There are no valid IPv4 site-local addresses. 606f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a site-local address, 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isSiteLocalAddress() { 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a global multicast address or not. This 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation returns always {@code false}. 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv6 link-global multicast addresses are FFxE:/112 where x is a set 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of flags, and the additional 112 bits make up the global multicast 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address space. 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv4 global multicast addresses are between: 224.0.1.0 to 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 238.255.255.255. 624f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a global multicast 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address, {@code false} otherwise. 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isMCGlobal() { 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a node-local multicast address or not. 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This implementation returns always {@code false}. 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv6 node-local multicast addresses are FFx1:/112 where x is a set 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of flags, and the additional 112 bits make up the node-local multicast 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address space. 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * There are no valid IPv4 node-local multicast addresses. 641f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a node-local multicast 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address, {@code false} otherwise. 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isMCNodeLocal() { 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a link-local multicast address or not. 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This implementation returns always {@code false}. 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv6 link-local multicast addresses are FFx2:/112 where x is a set 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of flags, and the additional 112 bits make up the link-local multicast 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address space. 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv4 link-local addresses are between: 224.0.0.0 to 224.0.0.255 658f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a link-local multicast 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address, {@code false} otherwise. 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isMCLinkLocal() { 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a site-local multicast address or not. 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This implementation returns always {@code false}. 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv6 site-local multicast addresses are FFx5:/112 where x is a set 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of flags, and the additional 112 bits make up the site-local multicast 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address space. 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv4 site-local addresses are between: 239.252.0.0 to 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 239.255.255.255 676f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a site-local multicast 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address, {@code false} otherwise. 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isMCSiteLocal() { 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this address is a organization-local multicast address or 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not. This implementation returns always {@code false}. 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv6 organization-local multicast addresses are FFx8:/112 where x 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is a set of flags, and the additional 112 bits make up the 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * organization-local multicast address space. 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Valid IPv4 organization-local addresses are between: 239.192.0.0 to 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 239.251.255.255 694f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a organization-local 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * multicast address, {@code false} otherwise. 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isMCOrgLocal() { 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this is a wildcard address or not. This implementation 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returns always {@code false}. 705f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this instance represents a wildcard address, 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isAnyLocalAddress() { 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tries to reach this {@code InetAddress}. This method first tries to use 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on port 7 (Echo) of the remote host is established. 717f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * timeout in milliseconds before the test fails if no connection 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * could be established. 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this address is reachable, {@code false} 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs during an I/O operation. 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if timeout is less than zero. 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isReachable(int timeout) throws IOException { 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isReachable(null, 0, timeout); 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tries to reach this {@code InetAddress}. This method first tries to use 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on port 7 (Echo) of the remote host is established. 736f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 737d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @param networkInterface 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the network interface on which to connection should be 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * established. 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param ttl 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the maximum count of hops (time-to-live). 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * timeout in milliseconds before the test fails if no connection 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * could be established. 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this address is reachable, {@code false} 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs during an I/O operation. 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if ttl or timeout is less than zero. 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 752d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public boolean isReachable(NetworkInterface networkInterface, final int ttl, 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final int timeout) throws IOException { 754d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes if (ttl < 0 || timeout < 0) { 75538607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson throw new IllegalArgumentException("ttl < 0 || timeout < 0"); 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 757d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes if (networkInterface == null) { 758d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return isReachableByTCP(this, null, timeout); 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 760d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return isReachableByMultiThread(networkInterface, ttl, timeout); 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Uses multi-Thread to try if isReachable, returns true if any of threads 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returns in time 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isReachableByMultiThread(NetworkInterface netif, 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final int ttl, final int timeout) 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 771d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes List<InetAddress> addresses = Collections.list(netif.getInetAddresses()); 772d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes if (addresses.isEmpty()) { 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reached = false; 776d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes addrCount = addresses.size(); 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean needWait = false; 778d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes for (final InetAddress addr : addresses) { 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // loopback interface can only reach to local addresses 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (addr.isLoopbackAddress()) { 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Enumeration<NetworkInterface> NetworkInterfaces = NetworkInterface 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getNetworkInterfaces(); 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (NetworkInterfaces.hasMoreElements()) { 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NetworkInterface networkInterface = NetworkInterfaces 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .nextElement(); 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Enumeration<InetAddress> localAddresses = networkInterface 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getInetAddresses(); 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (localAddresses.hasMoreElements()) { 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (InetAddress.this.equals(localAddresses 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .nextElement())) { 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (waitReachable) { 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addrCount--; 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (addrCount == 0) { 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if count equals zero, all thread 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // expired,notifies main thread 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project waitReachable.notifyAll(); 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project needWait = true; 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new Thread() { 81038607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson @Override public void run() { 81138607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson /* 81238607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson * Spec violation! This implementation doesn't attempt an 81338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson * ICMP; it skips right to TCP echo. 81438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson */ 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean threadReached = false; 81638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson try { 81738607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson threadReached = isReachableByTCP(addr, InetAddress.this, timeout); 81838607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson } catch (IOException e) { 81938607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson } 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (waitReachable) { 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (threadReached) { 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if thread reached this address, sets reached to 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // true and notifies main thread 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reached = true; 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project waitReachable.notifyAll(); 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addrCount--; 829b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (addrCount == 0) { 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if count equals zero, all thread 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // expired,notifies main thread 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project waitReachable.notifyAll(); 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }.start(); 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (needWait) { 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (waitReachable) { 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (!reached && (addrCount != 0)) { 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // wait for notification 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project waitReachable.wait(1000); 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedException e) { 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // do nothing 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return reached; 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 8572cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes private boolean isReachableByTCP(InetAddress destination, InetAddress source, int timeout) 8582cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes throws IOException { 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project FileDescriptor fd = new FileDescriptor(); 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean reached = false; 8613db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes Platform.NETWORK.socket(fd, true); 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 863b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (source != null) { 8643db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes Platform.NETWORK.bind(fd, source, 0); 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 8663db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes Platform.NETWORK.connect(fd, destination, 7, timeout); 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reached = true; 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ERRMSG_CONNECTION_REFUSED.equals(e.getMessage())) { 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Connection refused means the IP is reachable 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reached = true; 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 8753db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes Platform.NETWORK.close(fd); 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return reached; 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the {@code InetAddress} corresponding to the array of bytes. In 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the case of an IPv4 address there must be exactly 4 bytes and for IPv6 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown. 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The IP address is not validated by a name service. 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The high order byte is {@code ipAddress[0]}. 888f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param ipAddress 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is either a 4 (IPv4) or 16 (IPv6) byte long array. 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an {@code InetAddress} instance representing the given IP address 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code ipAddress}. 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given byte array has no valid length. 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static InetAddress getByAddress(byte[] ipAddress) 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws UnknownHostException { 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // simply call the method by the same name specifying the default scope 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // id of 0 90055b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti return getByAddressInternal(null, ipAddress, 0); 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the {@code InetAddress} corresponding to the array of bytes. In 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the case of an IPv4 address there must be exactly 4 bytes and for IPv6 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown. The 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * IP address is not validated by a name service. The high order byte is 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code ipAddress[0]}. 909f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param ipAddress 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * either a 4 (IPv4) or 16 (IPv6) byte array. 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param scope_id 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the scope id for an IPV6 scoped address. If not a scoped 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address just pass in 0. 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the InetAddress 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static InetAddress getByAddress(byte[] ipAddress, int scope_id) 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws UnknownHostException { 92055b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti return getByAddressInternal(null, ipAddress, scope_id); 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 923171dc20afe5071d5cbfad7103903bfa2c1f8d00fElliott Hughes private static boolean isIPv4MappedAddress(byte[] ipAddress) { 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Check if the address matches ::FFFF:d.d.d.d 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The first 10 bytes are 0. The next to are -1 (FF). 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The last 4 bytes are varied. 92755b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti if (ipAddress == null || ipAddress.length != 16) { 92855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti return false; 92955b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti } 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < 10; i++) { 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ipAddress[i] != 0) { 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ipAddress[10] != -1 || ipAddress[11] != -1) { 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 94155b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti private static byte[] ipv4MappedToIPv4(byte[] mappedAddress) { 94255b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti byte[] ipv4Address = new byte[4]; 94355b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti for(int i = 0; i < 4; i++) { 94455b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti ipv4Address[i] = mappedAddress[12 + i]; 94555b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti } 94655b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti return ipv4Address; 94755b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti } 94855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the {@code InetAddress} corresponding to the array of bytes, and 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given hostname. In the case of an IPv4 address there must be exactly 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * UnknownHostException} will be thrown. 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The host name and IP address are not validated. 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The hostname either be a machine alias or a valid IPv6 or IPv4 address 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * format. 959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The high order byte is {@code ipAddress[0]}. 961f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param hostName 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the string representation of hostname or IP address. 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param ipAddress 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * either a 4 (IPv4) or 16 (IPv6) byte long array. 966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an {@code InetAddress} instance representing the given IP address 967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and hostname. 968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given byte array has no valid length. 970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static InetAddress getByAddress(String hostName, byte[] ipAddress) 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws UnknownHostException { 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // just call the method by the same name passing in a default scope id 974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // of 0 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getByAddressInternal(hostName, ipAddress, 0); 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the {@code InetAddress} corresponding to the array of bytes, and 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given hostname. In the case of an IPv4 address there must be exactly 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * UnknownHostException} is thrown. The host name and IP address are not 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * validated. The hostname either be a machine alias or a valid IPv6 or IPv4 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * address format. The high order byte is {@code ipAddress[0]}. 985f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param hostName 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * string representation of hostname or IP address. 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param ipAddress 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * either a 4 (IPv4) or 16 (IPv6) byte array. 990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param scope_id 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the scope id for a scoped address. If not a scoped address 992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * just pass in 0. 993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the InetAddress 994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 996fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes static InetAddress getByAddressInternal(String hostName, byte[] ipAddress, int scope_id) 997fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes throws UnknownHostException { 99855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti if (ipAddress == null) { 99938607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson throw new UnknownHostException("ipAddress == null"); 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1001fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes if (ipAddress.length == 4) { 10021f0c4ff5de23e466032f1810172f16ad0077fa65Jesse Wilson return new Inet4Address(ipAddress.clone(), hostName); 1003fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } else if (ipAddress.length == 16) { 1004fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes // First check to see if the address is an IPv6-mapped 1005fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes // IPv4 address. If it is, then we can make it a IPv4 1006fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes // address, otherwise, we'll create an IPv6 address. 1007fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes if (isIPv4MappedAddress(ipAddress)) { 10081f0c4ff5de23e466032f1810172f16ad0077fa65Jesse Wilson return new Inet4Address(ipv4MappedToIPv4(ipAddress), hostName); 1009fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } else { 10101f0c4ff5de23e466032f1810172f16ad0077fa65Jesse Wilson return new Inet6Address(ipAddress.clone(), hostName, scope_id); 1011fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } 1012fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } else { 1013fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes throw badAddressLength(ipAddress); 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1017fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes private static UnknownHostException badAddressLength(byte[] bytes) throws UnknownHostException { 1018fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes throw new UnknownHostException("Address is neither 4 or 16 bytes: " + Arrays.toString(bytes)); 1019fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes } 1020fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final ObjectStreamField[] serialPersistentFields = { 102238607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson new ObjectStreamField("address", Integer.TYPE), 102338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson new ObjectStreamField("family", Integer.TYPE), 102438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson new ObjectStreamField("hostName", String.class) }; 1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void writeObject(ObjectOutputStream stream) throws IOException { 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectOutputStream.PutField fields = stream.putFields(); 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ipaddress == null) { 102938607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson fields.put("address", 0); 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 10310eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes fields.put("address", OSMemory.peekInt(ipaddress, 0, ByteOrder.BIG_ENDIAN)); 1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 103338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson fields.put("family", family); 103438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson fields.put("hostName", hostName); 1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.writeFields(); 1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10390eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectInputStream.GetField fields = stream.readFields(); 104138607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson int addr = fields.get("address", 0); 1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ipaddress = new byte[4]; 10430eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes OSMemory.pokeInt(ipaddress, 0, addr, ByteOrder.BIG_ENDIAN); 104438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson hostName = (String) fields.get("hostName", null); 104538607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson family = fields.get("family", 2); 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10485839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson /* 10495839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson * The spec requires that if we encounter a generic InetAddress in 10505839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson * serialized form then we should interpret it as an Inet4 address. 10515839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson */ 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readResolve() throws ObjectStreamException { 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new Inet4Address(ipaddress, hostName); 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1056