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