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