InetAddress.java revision 4f11ebea266eada830d507b8f011e811a8e5d7bc
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;
29ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colittiimport java.util.Arrays;
30d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.Collections;
31ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colittiimport java.util.Comparator;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration;
33d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.List;
344f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughesimport libcore.io.GaiException;
357341b9ed7157a1e37a3e69a0974676da358b735aElliott Hughesimport libcore.io.Libcore;
36454a95f6a28855aa3c88d168b15a45bf315efc99Elliott Hughesimport libcore.io.IoUtils;
37f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughesimport libcore.io.Memory;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.Platform;
394f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughesimport static libcore.io.OsConstants.*;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
42048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * An Internet Protocol (IP) address. This can be either an IPv4 address or an IPv6 address, and
43048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * in practice you'll have an instance of either {@code Inet4Address} or {@code Inet6Address} (this
44048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * class cannot be instantiated directly). Most code does not need to distinguish between the two
45048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * families, and should use {@code InetAddress}.
464adff24306c86433ce4f771da8489a574e63318eElliott Hughes *
474adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>An {@code InetAddress} may have a hostname (accessible via {@code getHostName}), but may not,
48048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * depending on how the {@code InetAddress} was created.
494adff24306c86433ce4f771da8489a574e63318eElliott Hughes *
504adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <h4>IPv4 numeric address formats</h4>
514adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>The {@code getAllByName} method accepts IPv4 addresses in the following forms:
524adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <ul>
534adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "1.2.3.4"} - 1.2.3.4
544adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "1.2.3"} - 1.2.0.3
554adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "1.2"} - 1.0.0.2
564adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>{@code "16909060"} - 1.2.3.4
574adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </ul>
584adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>In the first three cases, each number is treated as an 8-bit value between 0 and 255.
594adff24306c86433ce4f771da8489a574e63318eElliott Hughes * In the fourth case, the single number is treated as a 32-bit value representing the entire
604adff24306c86433ce4f771da8489a574e63318eElliott Hughes * address.
614adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Note that each numeric part can be expressed in decimal (as above) or hex. For example,
624adff24306c86433ce4f771da8489a574e63318eElliott Hughes * {@code "0x01020304"} is equivalent to 1.2.3.4 and {@code "0xa.0xb.0xc.0xd"} is equivalent
634adff24306c86433ce4f771da8489a574e63318eElliott Hughes * to 10.11.12.13.
644adff24306c86433ce4f771da8489a574e63318eElliott Hughes *
654adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Typically, only the four-dot decimal form ({@code "1.2.3.4"}) is ever used. Any method that
664adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <i>returns</i> a textual numeric address will use four-dot decimal form.
674adff24306c86433ce4f771da8489a574e63318eElliott Hughes *
684adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <h4>IPv6 numeric address formats</h4>
694adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>The {@code getAllByName} method accepts IPv6 addresses in the following forms (this text
704adff24306c86433ce4f771da8489a574e63318eElliott Hughes * comes from <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>, which you should consult
714adff24306c86433ce4f771da8489a574e63318eElliott Hughes * for full details of IPv6 addressing):
724adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <ul>
734adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li><p>The preferred form is {@code x:x:x:x:x:x:x:x}, where the 'x's are the
744adff24306c86433ce4f771da8489a574e63318eElliott Hughes * hexadecimal values of the eight 16-bit pieces of the address.
754adff24306c86433ce4f771da8489a574e63318eElliott Hughes * Note that it is not necessary to write the leading zeros in an
764adff24306c86433ce4f771da8489a574e63318eElliott Hughes * individual field, but there must be at least one numeral in every
774adff24306c86433ce4f771da8489a574e63318eElliott Hughes * field (except for the case described in the next bullet).
784adff24306c86433ce4f771da8489a574e63318eElliott Hughes * Examples:
794adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre>
804adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
814adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     1080:0:0:0:8:800:200C:417A</pre>
824adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </li>
834adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li>Due to some methods of allocating certain styles of IPv6
844adff24306c86433ce4f771da8489a574e63318eElliott Hughes * addresses, it will be common for addresses to contain long strings
854adff24306c86433ce4f771da8489a574e63318eElliott Hughes * of zero bits.  In order to make writing addresses containing zero
864adff24306c86433ce4f771da8489a574e63318eElliott Hughes * bits easier a special syntax is available to compress the zeros.
874adff24306c86433ce4f771da8489a574e63318eElliott Hughes * The use of "::" indicates multiple groups of 16-bits of zeros.
884adff24306c86433ce4f771da8489a574e63318eElliott Hughes * The "::" can only appear once in an address.  The "::" can also be
894adff24306c86433ce4f771da8489a574e63318eElliott Hughes * used to compress the leading and/or trailing zeros in an address.
904adff24306c86433ce4f771da8489a574e63318eElliott Hughes *
914adff24306c86433ce4f771da8489a574e63318eElliott Hughes * For example the following addresses:
924adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre>
934adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     1080:0:0:0:8:800:200C:417A  a unicast address
944adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     FF01:0:0:0:0:0:0:101        a multicast address
954adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     0:0:0:0:0:0:0:1             the loopback address
964adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     0:0:0:0:0:0:0:0             the unspecified addresses</pre>
974adff24306c86433ce4f771da8489a574e63318eElliott Hughes * may be represented as:
984adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre>
994adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     1080::8:800:200C:417A       a unicast address
1004adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     FF01::101                   a multicast address
1014adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     ::1                         the loopback address
1024adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     ::                          the unspecified addresses</pre>
1034adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </li>
1044adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <li><p>An alternative form that is sometimes more convenient when dealing
1054adff24306c86433ce4f771da8489a574e63318eElliott Hughes * with a mixed environment of IPv4 and IPv6 nodes is
1064adff24306c86433ce4f771da8489a574e63318eElliott Hughes * {@code x:x:x:x:x:x:d.d.d.d}, where the 'x's are the hexadecimal values of
1074adff24306c86433ce4f771da8489a574e63318eElliott Hughes * the six high-order 16-bit pieces of the address, and the 'd's are
1084adff24306c86433ce4f771da8489a574e63318eElliott Hughes * the decimal values of the four low-order 8-bit pieces of the
1094adff24306c86433ce4f771da8489a574e63318eElliott Hughes * address (standard IPv4 representation).  Examples:
1104adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre>
1114adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     0:0:0:0:0:0:13.1.68.3
1124adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     0:0:0:0:0:FFFF:129.144.52.38</pre>
1134adff24306c86433ce4f771da8489a574e63318eElliott Hughes * or in compressed form:
1144adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <pre>
1154adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     ::13.1.68.3
1164adff24306c86433ce4f771da8489a574e63318eElliott Hughes *     ::FFFF:129.144.52.38</pre>
1174adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </li>
1184adff24306c86433ce4f771da8489a574e63318eElliott Hughes * </ul>
1194adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Scopes are given using a trailing {@code %} followed by the scope id, as in
1204adff24306c86433ce4f771da8489a574e63318eElliott Hughes * {@code 1080::8:800:200C:417A%2} or {@code 1080::8:800:200C:417A%en0}.
1214adff24306c86433ce4f771da8489a574e63318eElliott Hughes * See <a href="https://www.ietf.org/rfc/rfc4007.txt">RFC 4007</a> for more on IPv6's scoped
1224adff24306c86433ce4f771da8489a574e63318eElliott Hughes * address architecture.
1234adff24306c86433ce4f771da8489a574e63318eElliott Hughes *
1240d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * <p>Additionally, for backwards compatibility, IPv6 addresses may be surrounded by square
1250d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * brackets.
1260d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes *
1274adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <h4>DNS caching</h4>
1284adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>On Android, addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are
129048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * cached for 10 seconds. The underlying C library or OS may cache for longer, but you can control
130048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * the Java-level caching with the usual {@code "networkaddress.cache.ttl"} and
131048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * {@code "networkaddress.cache.negative.ttl"} system properties. These are parsed as integer
132048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * numbers of seconds, where the special value 0 means "don't cache" and -1 means "cache forever".
1334adff24306c86433ce4f771da8489a574e63318eElliott Hughes *
1344adff24306c86433ce4f771da8489a574e63318eElliott Hughes * <p>Note also that on Android &ndash; unlike the RI &ndash; the cache is not unbounded. The
1354adff24306c86433ce4f771da8489a574e63318eElliott Hughes * current implementation caches around 512 entries, removed on a least-recently-used basis.
136048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * (Obviously, you should not rely on these details.)
137f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
138048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * @see Inet4Address
139048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * @see Inet6Address
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
141048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughespublic class InetAddress implements Serializable {
14238607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson    /** Our Java-side DNS cache. */
143048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static final AddressCache addressCache = new AddressCache();
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
14538607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson    private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused";
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
147ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    private static final long serialVersionUID = 3286316764910316507L;
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1494f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    private transient Object waitReachable = new Object();
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean reached;
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int addrCount;
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1554f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    private int family;
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    byte[] ipaddress;
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1594f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    String hostName;
1604f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
162051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Constructs an {@code InetAddress}.
163051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     *
164051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Note: this constructor should not be used. Creating an InetAddress
165051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * without specifying whether it's an IPv4 or IPv6 address does not make
166051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * sense, because subsequent code cannot know which of of the subclasses'
167051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * methods need to be called to implement a given InetAddress method. The
168051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * proper way to create an InetAddress is to call new Inet4Address or
169051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Inet6Address or to use one of the static methods that return
170051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * InetAddresses (e.g., getByAddress). That is why the API does not have
171051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * public constructors for any of these classes.
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1734f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    InetAddress(int family, byte[] ipaddress, String hostName) {
1744f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        this.family = family;
1754f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        this.ipaddress = ipaddress;
1764f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        this.hostName = hostName;
1774f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares this {@code InetAddress} instance against the specified address
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in {@code obj}. Two addresses are equal if their address byte arrays have
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the same length and if the bytes in the arrays are equal.
183f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to be tested for equality.
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if both objects are equal, {@code false} otherwise.
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object obj) {
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(obj instanceof InetAddress)) {
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
193051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress);
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the IP address represented by this {@code InetAddress} instance
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as a byte array. The elements are in network order (the highest order
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address byte is in the zeroth element).
200f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the address in form of a byte array.
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getAddress() {
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ipaddress.clone();
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2074f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    private static final Comparator<byte[]> SHORTEST_FIRST = new Comparator<byte[]>() {
208ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        public int compare(byte[] a1, byte[] a2) {
209ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            return a1.length - a2.length;
210ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
211ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    };
212ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
213ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    /**
214ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * Converts an array of byte arrays representing raw IP addresses of a host
215ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * to an array of InetAddress objects, sorting to respect the value of the
2164c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * system property {@code "java.net.preferIPv6Addresses"}.
217ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     *
218ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param rawAddresses the raw addresses to convert.
219ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param hostName the hostname corresponding to the IP address.
220ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @return the corresponding InetAddresses, appropriately sorted.
221ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     */
2224f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    private static InetAddress[] bytesToInetAddresses(byte[][] rawAddresses, String hostName)
223fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            throws UnknownHostException {
224fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        // If we prefer IPv4, ignore the RFC3484 ordering we get from getaddrinfo(3)
225a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        // and always put IPv4 addresses first. Arrays.sort() is stable, so the
226a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        // internal ordering will not be changed.
2274f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        if (!IoUtils.preferIPv6Addresses()) {
228a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson            Arrays.sort(rawAddresses, SHORTEST_FIRST);
229a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        }
230ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
231ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        // Convert the byte arrays to InetAddresses.
232ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        InetAddress[] returnedAddresses = new InetAddress[rawAddresses.length];
233ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        for (int i = 0; i < rawAddresses.length; i++) {
234fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            returnedAddresses[i] = makeInetAddress(rawAddresses[i], hostName);
235ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
236ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        return returnedAddresses;
237ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    }
238ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets all IP addresses associated with the given {@code host} identified
241ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * by name or literal IP address. The IP address is resolved by the
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * configured name service. If the host name is empty or {@code null} an
243ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * {@code UnknownHostException} is thrown. If the host name is a literal IP
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address string an array with the corresponding single {@code InetAddress}
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is returned.
246f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
247ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param host the hostname or literal IP string to be resolved.
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the array of addresses associated with the specified host.
249ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @throws UnknownHostException if the address lookup fails.
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
25138607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson    public static InetAddress[] getAllByName(String host) throws UnknownHostException {
25238607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        return getAllByNameImpl(host).clone();
253ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    }
254ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
255ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    /**
25638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson     * Returns the InetAddresses for {@code host}. The returned array is shared
25738607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson     * and must be cloned before it is returned to application code.
258ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     */
2594f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    private static InetAddress[] getAllByNameImpl(String host) throws UnknownHostException {
26038607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        if (host == null || host.isEmpty()) {
26146bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes            return loopbackAddresses();
262ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
263ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
264ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        // Special-case "0" for legacy IPv4 applications.
26538607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        if (host.equals("0")) {
266051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti            return new InetAddress[] { Inet4Address.ANY };
267ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2690d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes        // Is it a numeric address?
2700d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes        byte[] bytes = ipStringToByteArray(host);
2710d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes        if (bytes != null) {
2720d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes            return new InetAddress[] { makeInetAddress(bytes, null) };
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27538607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        return lookupHostByName(host);
27638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson    }
27738607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson
2784f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes    private static InetAddress makeInetAddress(byte[] bytes, String hostName) throws UnknownHostException {
279fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        if (bytes.length == 4) {
2804f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes            return new Inet4Address(bytes, hostName);
281fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        } else if (bytes.length == 16) {
2824f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes            return new Inet6Address(bytes, hostName, 0);
283fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        } else {
284fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            throw badAddressLength(bytes);
285fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        }
286fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes    }
287fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes
2880d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes    static native byte[] ipStringToByteArray(String address);
289753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the address of a host according to the given host string name
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code host}. The host string may be either a machine name or a dotted
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * string IP address. If the latter, the {@code hostName} field is
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * determined upon demand. {@code host} can be {@code null} which means that
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an address of the loopback interface is returned.
296f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param host
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the hostName to be resolved to an address or {@code null}.
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the {@code InetAddress} instance representing the host.
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the address lookup fails.
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
303ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    public static InetAddress getByName(String host) throws UnknownHostException {
30438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        return getAllByNameImpl(host)[0];
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
307e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti    /**
3084f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes     * Returns the numeric representation of this IP address (such as "127.0.0.1").
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getHostAddress() {
3114f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        return Libcore.os.getnameinfo(this, NI_NUMERICHOST); // Can't throw.
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3154f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes     * Returns the host name corresponding to this IP address. This may or may not be a
3164f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes     * fully-qualified name. If the IP address could not be resolved, the numeric representation
3174f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes     * is returned instead (see {@link #getHostAddress}).
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getHostName() {
3204f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        if (hostName == null) {
3214f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes            try {
3224f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes                hostName = getHostByAddrImpl(this).hostName;
3234f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes                // If the unqualified name happens to be "localhost", it would be misleading to
3244f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes                // return that, so use the numeric representation instead in that case.
3254f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes                if (hostName.equals("localhost") && !isLoopbackAddress()) {
3264f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes                    hostName = getHostAddress();
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
3284f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes            } catch (UnknownHostException ex) {
3294f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes                hostName = getHostAddress();
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return hostName;
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3364f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes     * Returns the fully qualified hostname corresponding to this IP address.
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getCanonicalHostName() {
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
3404f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes            return getHostByAddrImpl(this).hostName;
3414f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        } catch (UnknownHostException ex) {
3424f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes            return getHostAddress();
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
347ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * Returns an {@code InetAddress} for the local host if possible, or the
348ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * loopback address otherwise. This method works by getting the hostname,
349ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * performing a DNS lookup, and then taking the first returned address.
350ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * For devices with multiple network interfaces and/or multiple addresses
351ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * per interface, this does not necessarily return the {@code InetAddress}
352ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * you want.
353f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
354ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * <p>Multiple interface/address configurations were relatively rare
355ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * when this API was designed, but multiple interfaces are the default for
356ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * modern mobile devices (with separate wifi and radio interfaces), and
357ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * the need to support both IPv4 and IPv6 has made multiple addresses
358ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * commonplace. New code should thus avoid this method except where it's
359ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * basically being used to get a loopback address or equivalent.
360ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     *
361ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * <p>There are two main ways to get a more specific answer:
362ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * <ul>
363ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * <li>If you have a connected socket, you should probably use
364ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * {@link Socket#getLocalAddress} instead: that will give you the address
365ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * that's actually in use for that connection. (It's not possible to ask
366ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * the question "what local address would a connection to a given remote
367ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * address use?"; you have to actually make the connection and see.)</li>
368ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * <li>For other use cases, see {@link NetworkInterface}, which lets you
369ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * enumerate all available network interfaces and their addresses.</li>
370ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * </ul>
371ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     *
372ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * <p>Note that if the host doesn't have a hostname set&nbsp;&ndash; as
373ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * Android devices typically don't&nbsp;&ndash; this method will
374ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * effectively return the loopback address, albeit by getting the name
375ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * {@code localhost} and then doing a lookup to translate that to
376ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * {@code 127.0.0.1}.
377ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     *
378ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * @return an {@code InetAddress} representing the local host, or the
379ce64852f32d7d10ebd61a9c8f9ba2e91068f9bd2Elliott Hughes     * loopback address.
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the address lookup fails.
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static InetAddress getLocalHost() throws UnknownHostException {
3847341b9ed7157a1e37a3e69a0974676da358b735aElliott Hughes        String host = Libcore.os.uname().nodename; // Can only throw EFAULT (which can't happen).
385ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        return lookupHostByName(host)[0];
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the hashcode of the represented IP address.
390f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the appropriate hashcode value.
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
395051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        return Arrays.hashCode(ipaddress);
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
398051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    /*
399051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Returns whether this address is an IP multicast address or not. This
400051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * implementation returns always {@code false}.
401f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this address is in the multicast group, {@code
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         false} otherwise.
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMulticastAddress() {
406051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        return false;
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
408051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti
409ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    /**
410048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes     * Resolves a hostname to its IP addresses using a cache.
411ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     *
412ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param host the hostname to resolve.
413ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @return the IP addresses of the host.
414ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     */
415048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static InetAddress[] lookupHostByName(String host) throws UnknownHostException {
4167983be972905950b4a4e7d66df908f083c81ee29Brad Fitzpatrick        BlockGuard.getThreadPolicy().onNetwork();
417048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes        // Do we have a result cached?
418fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        Object cachedResult = addressCache.get(host);
419048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes        if (cachedResult != null) {
420fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            if (cachedResult instanceof InetAddress[]) {
421048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes                // A cached positive result.
422fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes                return (InetAddress[]) cachedResult;
423048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            } else {
424048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes                // A cached negative result.
425fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes                throw new UnknownHostException((String) cachedResult);
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
429048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            InetAddress[] addresses = bytesToInetAddresses(getaddrinfo(host), host);
430048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            addressCache.put(host, addresses);
431048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            return addresses;
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (UnknownHostException e) {
433fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            String detailMessage = e.getMessage();
434fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            addressCache.putUnknownHost(host, detailMessage);
435fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            throw new UnknownHostException(detailMessage);
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
438048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static native byte[][] getaddrinfo(String name) throws UnknownHostException;
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
441b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes     * Removes all entries from the VM's DNS cache. This does not affect the C library's DNS
442b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes     * cache, nor any caching DNS servers between you and the canonical server.
443b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes     * @hide
444b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes     */
445b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes    public static void clearDnsCache() {
446b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes        addressCache.clear();
447b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes    }
448b744a7edf23c14216698ad69ea59151e07cc50b8Elliott Hughes
4494f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    private static InetAddress getHostByAddrImpl(InetAddress address) throws UnknownHostException {
4507983be972905950b4a4e7d66df908f083c81ee29Brad Fitzpatrick        BlockGuard.getThreadPolicy().onNetwork();
4514f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        try {
4524f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes            String hostname = Libcore.os.getnameinfo(address, NI_NAMEREQD);
4534f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes            return makeInetAddress(address.ipaddress.clone(), hostname);
4544f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        } catch (GaiException gaiException) {
4554f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes            throw gaiException.rethrowAsUnknownHostException();
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of this
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * IP address.
462f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the description, as host/address.
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
46738607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        return (hostName == null ? "" : hostName) + "/" + getHostAddress();
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4710d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1").
4720d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * This copes with all forms of address that Java supports, detailed in the {@link InetAddress}
4730d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * class documentation.
4740d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     *
475f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     * @hide used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup.
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4770d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes    public static boolean isNumeric(String address) {
4780d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes        return ipStringToByteArray(address) != null;
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
482f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     * Returns an InetAddress corresponding to the given numeric address (such
483f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
484f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     * This method will never do a DNS lookup. Non-numeric addresses are errors.
485f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     *
486f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     * @hide used by frameworks/base's NetworkUtils.numericToInetAddress
487f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     * @throws IllegalArgumentException if {@code numericAddress} is not a numeric address
488f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes     */
489f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes    public static InetAddress parseNumericAddress(String numericAddress) {
49046bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes        if (numericAddress == null || numericAddress.isEmpty()) {
49146bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes            return loopbackAddresses()[0];
49246bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes        }
493f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes        byte[] bytes = ipStringToByteArray(numericAddress);
494f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes        if (bytes == null) {
495f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes            throw new IllegalArgumentException("Not a numeric address: " + numericAddress);
496f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes        }
497f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes        try {
498f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes            return makeInetAddress(bytes, null);
499f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes        } catch (UnknownHostException ex) {
500f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes            // UnknownHostException can't be thrown if you pass null to makeInetAddress.
501f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes            throw new AssertionError(ex);
502f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes        }
503f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes    }
504f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes
50546bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes    private static InetAddress[] loopbackAddresses() {
5064f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes        if (IoUtils.preferIPv6Addresses()) {
50746bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes            return new InetAddress[] { Inet6Address.LOOPBACK, Inet4Address.LOOPBACK };
50846bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes        } else {
50946bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes            return new InetAddress[] { Inet4Address.LOOPBACK, Inet6Address.LOOPBACK };
51046bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes        }
51146bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes    }
51246bed6a47a20d8105f0e099d162d547a7964b4feElliott Hughes
513f39b892d87e85835f021e8ad77ffdd215735604bElliott Hughes    /**
5145d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes     * Returns the IPv6 loopback address {@code ::1} or the IPv4 loopback address {@code 127.0.0.1}.
5155d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes     * @since 1.7
5165d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes     * @hide 1.7
5175d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes     */
5185d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes    public static InetAddress getLoopbackAddress() {
5195d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes        return loopbackAddresses()[0];
5205d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes    }
5215d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes
5225d3f5562c167120b5ec00e509af0f0ab9308bff5Elliott Hughes    /**
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a loopback address or not. This
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}. Valid IPv4 loopback
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * addresses are 127.d.d.d The only valid IPv6 loopback address is ::1.
526f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a loopback address,
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isLoopbackAddress() {
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a link-local address or not. This
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}.
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 link-local addresses are FE80::0 through to
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * There are no valid IPv4 link-local addresses.
542f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a link-local address,
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isLinkLocalAddress() {
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a site-local address or not. This
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}.
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 site-local addresses are FEC0::0 through to
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * There are no valid IPv4 site-local addresses.
558f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a site-local address,
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isSiteLocalAddress() {
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a global multicast address or not. This
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}.
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 link-global multicast addresses are FFxE:/112 where x is a set
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the global multicast
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 global multicast addresses are between: 224.0.1.0 to
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 238.255.255.255.
576f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a global multicast
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCGlobal() {
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a node-local multicast address or not.
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This implementation returns always {@code false}.
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 node-local multicast addresses are FFx1:/112 where x is a set
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the node-local multicast
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * There are no valid IPv4 node-local multicast addresses.
593f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a node-local multicast
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCNodeLocal() {
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a link-local multicast address or not.
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This implementation returns always {@code false}.
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 link-local multicast addresses are FFx2:/112 where x is a set
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the link-local multicast
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 link-local addresses are between: 224.0.0.0 to 224.0.0.255
610f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a link-local multicast
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCLinkLocal() {
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a site-local multicast address or not.
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This implementation returns always {@code false}.
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 site-local multicast addresses are FFx5:/112 where x is a set
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the site-local multicast
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 site-local addresses are between: 239.252.0.0 to
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 239.255.255.255
628f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a site-local multicast
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCSiteLocal() {
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a organization-local multicast address or
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * not. This implementation returns always {@code false}.
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 organization-local multicast addresses are FFx8:/112 where x
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is a set of flags, and the additional 112 bits make up the
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * organization-local multicast address space.
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 organization-local addresses are between: 239.192.0.0 to
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 239.251.255.255
646f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a organization-local
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         multicast address, {@code false} otherwise.
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCOrgLocal() {
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this is a wildcard address or not. This implementation
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returns always {@code false}.
657f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a wildcard address,
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isAnyLocalAddress() {
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tries to reach this {@code InetAddress}. This method first tries to use
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * on port 7 (Echo) of the remote host is established.
669f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            timeout in milliseconds before the test fails if no connection
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            could be established.
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this address is reachable, {@code false}
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise.
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs during an I/O operation.
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if timeout is less than zero.
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isReachable(int timeout) throws IOException {
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isReachable(null, 0, timeout);
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tries to reach this {@code InetAddress}. This method first tries to use
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * on port 7 (Echo) of the remote host is established.
688f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
689d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes     * @param networkInterface
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the network interface on which to connection should be
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            established.
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ttl
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the maximum count of hops (time-to-live).
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            timeout in milliseconds before the test fails if no connection
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            could be established.
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this address is reachable, {@code false}
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise.
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs during an I/O operation.
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if ttl or timeout is less than zero.
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
704d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes    public boolean isReachable(NetworkInterface networkInterface, final int ttl,
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            final int timeout) throws IOException {
706d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        if (ttl < 0 || timeout < 0) {
70738607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson            throw new IllegalArgumentException("ttl < 0 || timeout < 0");
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
709d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        if (networkInterface == null) {
710d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes            return isReachableByTCP(this, null, timeout);
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
712d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes            return isReachableByMultiThread(networkInterface, ttl, timeout);
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Uses multi-Thread to try if isReachable, returns true if any of threads
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returns in time
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isReachableByMultiThread(NetworkInterface netif,
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            final int ttl, final int timeout)
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
723d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        List<InetAddress> addresses = Collections.list(netif.getInetAddresses());
724d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        if (addresses.isEmpty()) {
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reached = false;
728d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        addrCount = addresses.size();
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean needWait = false;
730d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        for (final InetAddress addr : addresses) {
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // loopback interface can only reach to local addresses
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (addr.isLoopbackAddress()) {
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Enumeration<NetworkInterface> NetworkInterfaces = NetworkInterface
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .getNetworkInterfaces();
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (NetworkInterfaces.hasMoreElements()) {
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    NetworkInterface networkInterface = NetworkInterfaces
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .nextElement();
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Enumeration<InetAddress> localAddresses = networkInterface
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getInetAddresses();
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    while (localAddresses.hasMoreElements()) {
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (InetAddress.this.equals(localAddresses
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                .nextElement())) {
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return true;
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                synchronized (waitReachable) {
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    addrCount--;
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (addrCount == 0) {
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // if count equals zero, all thread
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // expired,notifies main thread
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        waitReachable.notifyAll();
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            needWait = true;
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new Thread() {
76238607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                @Override public void run() {
76338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                    /*
76438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                     * Spec violation! This implementation doesn't attempt an
76538607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                     * ICMP; it skips right to TCP echo.
76638607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                     */
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    boolean threadReached = false;
76838607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                    try {
76938607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                        threadReached = isReachableByTCP(addr, InetAddress.this, timeout);
77038607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                    } catch (IOException e) {
77138607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson                    }
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    synchronized (waitReachable) {
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (threadReached) {
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // if thread reached this address, sets reached to
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // true and notifies main thread
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            reached = true;
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            waitReachable.notifyAll();
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        } else {
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            addrCount--;
781b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes                            if (addrCount == 0) {
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                // if count equals zero, all thread
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                // expired,notifies main thread
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                waitReachable.notifyAll();
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            }
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }.start();
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (needWait) {
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            synchronized (waitReachable) {
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    while (!reached && (addrCount != 0)) {
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // wait for notification
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        waitReachable.wait(1000);
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (InterruptedException e) {
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // do nothing
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return reached;
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
809454a95f6a28855aa3c88d168b15a45bf315efc99Elliott Hughes    private boolean isReachableByTCP(InetAddress destination, InetAddress source, int timeout) throws IOException {
810454a95f6a28855aa3c88d168b15a45bf315efc99Elliott Hughes        FileDescriptor fd = IoUtils.socket(true);
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean reached = false;
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
813b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes            if (source != null) {
8143db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes                Platform.NETWORK.bind(fd, source, 0);
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
8163db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes            Platform.NETWORK.connect(fd, destination, 7, timeout);
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            reached = true;
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ERRMSG_CONNECTION_REFUSED.equals(e.getMessage())) {
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Connection refused means the IP is reachable
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                reached = true;
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
8253db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes        Platform.NETWORK.close(fd);
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return reached;
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
8314f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * Equivalent to {@code getByAddress(null, ipAddress, 0)}. Handy for IPv4 addresses with
8324f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * no associated hostname.
833f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
8344f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * <p>(Note that numeric addresses such as {@code "127.0.0.1"} are names for the
8354f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * purposes of this API. Most callers probably want {@link #getAllByName} instead.)
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
8374f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes    public static InetAddress getByAddress(byte[] ipAddress) throws UnknownHostException {
83855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        return getByAddressInternal(null, ipAddress, 0);
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
8424f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * Equivalent to {@code getByAddress(hostName, ipAddress, 0)}. Handy for IPv4 addresses
8434f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * with an associated hostname.
8444f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     *
8454f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * <p>(Note that numeric addresses such as {@code "127.0.0.1"} are names for the
8464f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * purposes of this API. Most callers probably want {@link #getAllByName} instead.)
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
8484f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes    public static InetAddress getByAddress(String hostName, byte[] ipAddress) throws UnknownHostException {
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getByAddressInternal(hostName, ipAddress, 0);
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
8534f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * Returns an {@code InetAddress} corresponding to the given network-order
8544f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * bytes {@code ipAddress} and {@code scopeId}.
855f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
8564f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * <p>For an IPv4 address, the byte array must be of length 4, and the scopeId is ignored.
8574f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * For IPv6, the byte array must be of length 16. Any other length will cause an {@code
8584f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * UnknownHostException}.
8594f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     *
8604f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * <p>No reverse lookup is performed. The given {@code hostName} (which may be null) is
8614f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * associated with the new {@code InetAddress} with no validation done.
8624f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     *
8634f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * <p>(Note that numeric addresses such as {@code "127.0.0.1"} are names for the
8644f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * purposes of this API. Most callers probably want {@link #getAllByName} instead.)
8654f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     *
8664f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes     * @throws UnknownHostException if {@code ipAddress} is null or the wrong length.
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
8684f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes    private static InetAddress getByAddressInternal(String hostName, byte[] ipAddress, int scopeId)
869fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            throws UnknownHostException {
87055b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        if (ipAddress == null) {
87138607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson            throw new UnknownHostException("ipAddress == null");
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
873fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        if (ipAddress.length == 4) {
8741f0c4ff5de23e466032f1810172f16ad0077fa65Jesse Wilson            return new Inet4Address(ipAddress.clone(), hostName);
875fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        } else if (ipAddress.length == 16) {
876fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            // First check to see if the address is an IPv6-mapped
877fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            // IPv4 address. If it is, then we can make it a IPv4
878fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            // address, otherwise, we'll create an IPv6 address.
879fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            if (isIPv4MappedAddress(ipAddress)) {
8801f0c4ff5de23e466032f1810172f16ad0077fa65Jesse Wilson                return new Inet4Address(ipv4MappedToIPv4(ipAddress), hostName);
881fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            } else {
8824f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes                return new Inet6Address(ipAddress.clone(), hostName, scopeId);
883fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            }
884fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        } else {
885fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes            throw badAddressLength(ipAddress);
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
889fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes    private static UnknownHostException badAddressLength(byte[] bytes) throws UnknownHostException {
890fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes        throw new UnknownHostException("Address is neither 4 or 16 bytes: " + Arrays.toString(bytes));
891fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes    }
892fbbae9740d65620b417b85576aa0d6c7daf4ba34Elliott Hughes
8934f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes    private static boolean isIPv4MappedAddress(byte[] ipAddress) {
8944f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        // Check if the address matches ::FFFF:d.d.d.d
8954f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        // The first 10 bytes are 0. The next to are -1 (FF).
8964f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        // The last 4 bytes are varied.
8974f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        if (ipAddress == null || ipAddress.length != 16) {
8984f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes            return false;
8994f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        }
9004f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        for (int i = 0; i < 10; i++) {
9014f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes            if (ipAddress[i] != 0) {
9024f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes                return false;
9034f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes            }
9044f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        }
9054f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        if (ipAddress[10] != -1 || ipAddress[11] != -1) {
9064f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes            return false;
9074f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        }
9084f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        return true;
9094f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes    }
9104f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes
9114f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes    private static byte[] ipv4MappedToIPv4(byte[] mappedAddress) {
9124f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        byte[] ipv4Address = new byte[4];
9134f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        for(int i = 0; i < 4; i++) {
9144f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes            ipv4Address[i] = mappedAddress[12 + i];
9154f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        }
9164f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes        return ipv4Address;
9174f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes    }
9184f9ffffd8a2835c30647f9785afb48fa96a0f045Elliott Hughes
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final ObjectStreamField[] serialPersistentFields = {
920e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes        new ObjectStreamField("address", int.class),
921e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes        new ObjectStreamField("family", int.class),
92228eb98ecd43c27702e85b0561e040e2da10320a6Elliott Hughes        new ObjectStreamField("hostName", String.class),
92328eb98ecd43c27702e85b0561e040e2da10320a6Elliott Hughes    };
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void writeObject(ObjectOutputStream stream) throws IOException {
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectOutputStream.PutField fields = stream.putFields();
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (ipaddress == null) {
92838607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson            fields.put("address", 0);
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
930f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes            fields.put("address", Memory.peekInt(ipaddress, 0, ByteOrder.BIG_ENDIAN));
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
93238607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        fields.put("family", family);
93338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        fields.put("hostName", hostName);
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        stream.writeFields();
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
9380eb70e31581a977afa5df3292d1c96e42e548821Elliott Hughes    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectInputStream.GetField fields = stream.readFields();
94038607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        int addr = fields.get("address", 0);
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ipaddress = new byte[4];
942f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes        Memory.pokeInt(ipaddress, 0, addr, ByteOrder.BIG_ENDIAN);
94338607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        hostName = (String) fields.get("hostName", null);
94438607710cdc82cb1a0e81c2fc5c78278b435e4fcJesse Wilson        family = fields.get("family", 2);
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
9475839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson    /*
9485839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson     * The spec requires that if we encounter a generic InetAddress in
9494f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes     * serialized form then we should interpret it as an Inet4Address.
9505839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson     */
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readResolve() throws ObjectStreamException {
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new Inet4Address(ipaddress, hostName);
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
955