InetAddress.java revision 048303b64df9c987ae2f57b6bf88ff5ac1b5cca0
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 java.io.FileDescriptor;
21import java.io.IOException;
22import java.io.ObjectInputStream;
23import java.io.ObjectOutputStream;
24import java.io.ObjectStreamException;
25import java.io.ObjectStreamField;
26import java.io.Serializable;
27import java.security.AccessController;
28import java.util.Arrays;
29import java.util.ArrayList;
30import java.util.Comparator;
31import java.util.Enumeration;
32import java.util.StringTokenizer;
33
34import org.apache.harmony.luni.net.NetUtil;
35import org.apache.harmony.luni.platform.INetworkSystem;
36import org.apache.harmony.luni.platform.Platform;
37import org.apache.harmony.luni.util.Inet6Util;
38import org.apache.harmony.luni.util.Msg;
39import org.apache.harmony.luni.util.PriviAction;
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 * <p>
47 * An {@code InetAddress} may have a hostname (accessible via {@code getHostName}), but may not,
48 * depending on how the {@code InetAddress} was created.
49 * <p>
50 * On Android, addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are
51 * cached for 10 seconds. The underlying C library or OS may cache for longer, but you can control
52 * the Java-level caching with the usual {@code "networkaddress.cache.ttl"} and
53 * {@code "networkaddress.cache.negative.ttl"} system properties. These are parsed as integer
54 * numbers of seconds, where the special value 0 means "don't cache" and -1 means "cache forever".
55 * <p>
56 * Note also that on Android &ndash; unlike the RI &ndash; the cache is not unbounded. The current
57 * implementation caches around 512 entries, removed on a least-recently-used basis.
58 * (Obviously, you should not rely on these details.)
59 *
60 * @see Inet4Address
61 * @see Inet6Address
62 */
63public class InetAddress implements Serializable {
64    // BEGIN android-added: better DNS caching.
65    // Our Java-side DNS cache.
66    private static final AddressCache addressCache = new AddressCache();
67    // END android-added
68
69    private final static INetworkSystem NETIMPL = Platform.getNetworkSystem();
70
71    private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused"; //$NON-NLS-1$
72
73    private static final long serialVersionUID = 3286316764910316507L;
74
75    String hostName;
76
77    private static class WaitReachable {
78    }
79
80    private transient Object waitReachable = new WaitReachable();
81
82    private boolean reached;
83
84    private int addrCount;
85
86    int family = 0;
87    static final int AF_INET = 2;
88    static final int AF_INET6 = 10;
89
90    byte[] ipaddress;
91
92    // BEGIN android-removed
93    // // Fill in the JNI id caches
94    // private static native void oneTimeInitialization(boolean supportsIPv6);
95    //
96    // static {
97    //     oneTimeInitialization(true);
98    // }
99    // END android-removed
100
101    /**
102     * Constructs an {@code InetAddress}.
103     *
104     * Note: this constructor should not be used. Creating an InetAddress
105     * without specifying whether it's an IPv4 or IPv6 address does not make
106     * sense, because subsequent code cannot know which of of the subclasses'
107     * methods need to be called to implement a given InetAddress method. The
108     * proper way to create an InetAddress is to call new Inet4Address or
109     * Inet6Address or to use one of the static methods that return
110     * InetAddresses (e.g., getByAddress). That is why the API does not have
111     * public constructors for any of these classes.
112     */
113    InetAddress() {
114        super();
115    }
116
117    // BEGIN android-removed
118    /**
119     * Constructs an {@code InetAddress}, representing the {@code address} and
120     * {@code hostName}.
121     *
122     * @param address
123     *            the network address.
124     */
125    // InetAddress(byte[] address) {
126    //     super();
127    //     this.ipaddress = address;
128    // }
129    // END android-removed
130
131    // BEGIN android-removed
132    /**
133     * Constructs an {@code InetAddress}, representing the {@code address} and
134     * {@code hostName}.
135     *
136     * @param address
137     *            the network address.
138     *
139     */
140    // InetAddress(byte[] address, String hostName) {
141    //     super();
142    //     this.ipaddress = address;
143    //     this.hostName = hostName;
144    // }
145    // END android-removed
146
147    // BEGIN android-removed
148    // CacheElement cacheElement() {
149    //     return new CacheElement();
150    // }
151    // END android-removed
152
153    /**
154     * Compares this {@code InetAddress} instance against the specified address
155     * in {@code obj}. Two addresses are equal if their address byte arrays have
156     * the same length and if the bytes in the arrays are equal.
157     *
158     * @param obj
159     *            the object to be tested for equality.
160     * @return {@code true} if both objects are equal, {@code false} otherwise.
161     */
162    @Override
163    public boolean equals(Object obj) {
164        // BEGIN android-changed
165        if (!(obj instanceof InetAddress)) {
166            return false;
167        }
168        return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress);
169        // END android-changed
170    }
171
172    /**
173     * Returns the IP address represented by this {@code InetAddress} instance
174     * as a byte array. The elements are in network order (the highest order
175     * address byte is in the zeroth element).
176     *
177     * @return the address in form of a byte array.
178     */
179    public byte[] getAddress() {
180        return ipaddress.clone();
181    }
182
183    // BEGIN android-added
184    static final Comparator<byte[]> SHORTEST_FIRST = new Comparator<byte[]>() {
185        public int compare(byte[] a1, byte[] a2) {
186            return a1.length - a2.length;
187        }
188    };
189
190    static final Comparator<byte[]> LONGEST_FIRST = new Comparator<byte[]>() {
191        public int compare(byte[] a1, byte[] a2) {
192            return a2.length - a1.length;
193        }
194    };
195
196    /**
197     * Converts an array of byte arrays representing raw IP addresses of a host
198     * to an array of InetAddress objects, sorting to respect the value of the
199     * system preferIPv6Addresses preference.
200     *
201     * @param rawAddresses the raw addresses to convert.
202     * @param hostName the hostname corresponding to the IP address.
203     * @return the corresponding InetAddresses, appropriately sorted.
204     */
205    static InetAddress[] bytesToInetAddresses(byte[][] rawAddresses,
206            String hostName) {
207        // Sort the raw byte arrays.
208        Comparator<byte[]> comparator = preferIPv6Addresses()
209                ? LONGEST_FIRST : SHORTEST_FIRST;
210        Arrays.sort(rawAddresses, comparator);
211
212        // Convert the byte arrays to InetAddresses.
213        InetAddress[] returnedAddresses = new InetAddress[rawAddresses.length];
214        for (int i = 0; i < rawAddresses.length; i++) {
215            byte[] rawAddress = rawAddresses[i];
216            if (rawAddress.length == 16) {
217                returnedAddresses[i] = new Inet6Address(rawAddress, hostName);
218            } else if (rawAddress.length == 4) {
219                returnedAddresses[i] = new Inet4Address(rawAddress, hostName);
220            } else {
221              // Cannot happen, because the underlying code only returns
222              // addresses that are 4 or 16 bytes long.
223              throw new AssertionError("Impossible address length " +
224                                       rawAddress.length);
225            }
226        }
227        return returnedAddresses;
228    }
229    // END android-added
230
231    /**
232     * Gets all IP addresses associated with the given {@code host} identified
233     * by name or literal IP address. The IP address is resolved by the
234     * configured name service. If the host name is empty or {@code null} an
235     * {@code UnknownHostException} is thrown. If the host name is a literal IP
236     * address string an array with the corresponding single {@code InetAddress}
237     * is returned.
238     *
239     * @param host the hostname or literal IP string to be resolved.
240     * @return the array of addresses associated with the specified host.
241     * @throws UnknownHostException if the address lookup fails.
242     */
243    public static InetAddress[] getAllByName(String host)
244            throws UnknownHostException {
245        // BEGIN android-changed
246        return getAllByNameImpl(host, true);
247        // END android-changed
248    }
249
250    // BEGIN android-added
251    /**
252     * Implementation of getAllByName.
253     *
254     * @param host the hostname or literal IP string to be resolved.
255     * @param returnUnshared requests a result that is modifiable by the caller.
256     * @return the array of addresses associated with the specified host.
257     * @throws UnknownHostException if the address lookup fails.
258     */
259    static InetAddress[] getAllByNameImpl(String host, boolean returnUnshared)
260            throws UnknownHostException {
261        if (host == null || 0 == host.length()) {
262            if (preferIPv6Addresses()) {
263                return new InetAddress[] { Inet6Address.LOOPBACK,
264                                           Inet4Address.LOOPBACK };
265            } else {
266                return new InetAddress[] { Inet4Address.LOOPBACK,
267                                           Inet6Address.LOOPBACK };
268            }
269        }
270
271        // Special-case "0" for legacy IPv4 applications.
272        if (host.equals("0")) { //$NON-NLS-1$
273            return new InetAddress[] { Inet4Address.ANY };
274        }
275
276        if (isHostName(host)) {
277            SecurityManager security = System.getSecurityManager();
278            if (security != null) {
279                security.checkConnect(host, -1);
280            }
281            if (returnUnshared) {
282                return lookupHostByName(host).clone();
283            } else {
284                return lookupHostByName(host);
285            }
286        }
287
288        byte[] hBytes = NETIMPL.ipStringToByteArray(host);
289        if (hBytes.length == 4) {
290            return (new InetAddress[] { new Inet4Address(hBytes) });
291        } else if (hBytes.length == 16) {
292            return (new InetAddress[] { new Inet6Address(hBytes) });
293        } else {
294            throw new UnknownHostException(
295                    Msg.getString("K0339")); //$NON-NLS-1$
296        }
297    }
298    // END android-added
299
300    /**
301     * Returns the address of a host according to the given host string name
302     * {@code host}. The host string may be either a machine name or a dotted
303     * string IP address. If the latter, the {@code hostName} field is
304     * determined upon demand. {@code host} can be {@code null} which means that
305     * an address of the loopback interface is returned.
306     *
307     * @param host
308     *            the hostName to be resolved to an address or {@code null}.
309     * @return the {@code InetAddress} instance representing the host.
310     * @throws UnknownHostException
311     *             if the address lookup fails.
312     */
313    public static InetAddress getByName(String host) throws UnknownHostException {
314        return getAllByNameImpl(host, false)[0];
315    }
316
317    // BEGIN android-added
318    /**
319     * Returns the numeric string form of the given IP address.
320     *
321     * @param ipAddress
322     *         the byte array to convert; length 4 for IPv4, 16 for IPv6.
323     * @throws IllegalArgumentException
324     *         if ipAddress is of length other than 4 or 16.
325     */
326    private static String ipAddressToString(byte[] ipAddress) {
327        try {
328            return NETIMPL.byteArrayToIpString(ipAddress);
329        } catch (IOException ex) {
330            throw new IllegalArgumentException("byte[] neither 4 nor 16 bytes", ex);
331        }
332    }
333    // END android-added
334
335    /**
336     * Gets the textual representation of this IP address.
337     *
338     * @return the textual representation of host's IP address.
339     */
340    public String getHostAddress() {
341        return ipAddressToString(ipaddress);
342    }
343
344    /**
345     * Gets the host name of this IP address. If the IP address could not be
346     * resolved, the textual representation in a dotted-quad-notation is
347     * returned.
348     *
349     * @return the corresponding string name of this IP address.
350     */
351    public String getHostName() {
352        try {
353            if (hostName == null) {
354                int address = 0;
355                if (ipaddress.length == 4) {
356                    address = bytesToInt(ipaddress, 0);
357                    if (address == 0) {
358                        return hostName = ipAddressToString(ipaddress);
359                    }
360                }
361                hostName = getHostByAddrImpl(ipaddress).hostName;
362                if (hostName.equals("localhost") && ipaddress.length == 4 //$NON-NLS-1$
363                        && address != 0x7f000001) {
364                    return hostName = ipAddressToString(ipaddress);
365                }
366            }
367        } catch (UnknownHostException e) {
368            return hostName = ipAddressToString(ipaddress);
369        }
370        SecurityManager security = System.getSecurityManager();
371        try {
372            // Only check host names, not addresses
373            if (security != null && isHostName(hostName)) {
374                security.checkConnect(hostName, -1);
375            }
376        } catch (SecurityException e) {
377            return ipAddressToString(ipaddress);
378        }
379        return hostName;
380    }
381
382    /**
383     * Gets the fully qualified domain name for the host associated with this IP
384     * address. If a security manager is set, it is checked if the method caller
385     * is allowed to get the hostname. Otherwise, the textual representation in
386     * a dotted-quad-notation is returned.
387     *
388     * @return the fully qualified domain name of this IP address.
389     */
390    public String getCanonicalHostName() {
391        String canonicalName;
392        try {
393            int address = 0;
394            if (ipaddress.length == 4) {
395                address = bytesToInt(ipaddress, 0);
396                if (address == 0) {
397                    return ipAddressToString(ipaddress);
398                }
399            }
400            canonicalName = getHostByAddrImpl(ipaddress).hostName;
401        } catch (UnknownHostException e) {
402            return ipAddressToString(ipaddress);
403        }
404        SecurityManager security = System.getSecurityManager();
405        try {
406            // Only check host names, not addresses
407            if (security != null && isHostName(canonicalName)) {
408                security.checkConnect(canonicalName, -1);
409            }
410        } catch (SecurityException e) {
411            return ipAddressToString(ipaddress);
412        }
413        return canonicalName;
414    }
415
416    /**
417     * Gets the local host address if the security policy allows this.
418     * Otherwise, gets the loopback address which allows this machine to be
419     * contacted.
420     *
421     * @return the {@code InetAddress} representing the local host.
422     * @throws UnknownHostException
423     *             if the address lookup fails.
424     */
425    public static InetAddress getLocalHost() throws UnknownHostException {
426        String host = gethostname();
427        SecurityManager security = System.getSecurityManager();
428        try {
429            if (security != null) {
430                security.checkConnect(host, -1);
431            }
432        } catch (SecurityException e) {
433            return Inet4Address.LOOPBACK;
434        }
435        return lookupHostByName(host)[0];
436    }
437    private static native String gethostname();
438
439    /**
440     * Gets the hashcode of the represented IP address.
441     *
442     * @return the appropriate hashcode value.
443     */
444    @Override
445    public int hashCode() {
446        // BEGIN android-changed
447        return Arrays.hashCode(ipaddress);
448        // END android-changed
449    }
450
451    // BEGIN android-changed
452    /*
453     * Returns whether this address is an IP multicast address or not. This
454     * implementation returns always {@code false}.
455     *
456     * @return {@code true} if this address is in the multicast group, {@code
457     *         false} otherwise.
458     */
459    public boolean isMulticastAddress() {
460        return false;
461    }
462    // END android-changed
463
464    /**
465     * Resolves a hostname to its IP addresses using a cache.
466     *
467     * @param host the hostname to resolve.
468     * @return the IP addresses of the host.
469     */
470    // BEGIN android-changed
471    private static InetAddress[] lookupHostByName(String host) throws UnknownHostException {
472        // Do we have a result cached?
473        InetAddress[] cachedResult = addressCache.get(host);
474        if (cachedResult != null) {
475            if (cachedResult.length > 0) {
476                // A cached positive result.
477                return cachedResult;
478            } else {
479                // A cached negative result.
480                throw new UnknownHostException(host);
481            }
482        }
483        try {
484            InetAddress[] addresses = bytesToInetAddresses(getaddrinfo(host), host);
485            addressCache.put(host, addresses);
486            return addresses;
487        } catch (UnknownHostException e) {
488            addressCache.putUnknownHost(host);
489            throw new UnknownHostException(host);
490        }
491    }
492    private static native byte[][] getaddrinfo(String name) throws UnknownHostException;
493    // END android-changed
494
495    // BEGIN android-deleted
496    // static native InetAddress[] getAliasesByNameImpl(String name)
497    //     throws UnknownHostException;
498    // END android-deleted
499
500    /**
501     * Query the IP stack for the host address. The host is in address form.
502     *
503     * @param addr
504     *            the host address to lookup.
505     * @throws UnknownHostException
506     *             if an error occurs during lookup.
507     */
508    // BEGIN android-changed
509    // static native InetAddress getHostByAddrImpl(byte[] addr)
510    //    throws UnknownHostException;
511    static InetAddress getHostByAddrImpl(byte[] addr)
512            throws UnknownHostException {
513        if (addr.length == 4) {
514            return new Inet4Address(addr, getnameinfo(addr));
515        } else if (addr.length == 16) {
516            return new Inet6Address(addr, getnameinfo(addr));
517        } else {
518            throw new UnknownHostException(Msg.getString(
519                    "K0339")); //$NON-NLS-1$
520        }
521    }
522
523    /**
524     * Resolves an IP address to a hostname. Thread safe.
525     */
526    private static native String getnameinfo(byte[] addr);
527    // END android-changed
528
529    // BEGIN android-removed
530    // static int inetAddr(String host) throws UnknownHostException
531    // END android-removed
532
533    /**
534     * Convert a string containing an IPv4 Internet Protocol dotted address into
535     * a binary address. Note, the special case of '255.255.255.255' throws an
536     * exception, so this value should not be used as an argument. See also
537     * inetAddr(String).
538     */
539    // BEGIN android-removed
540    // static native int inetAddrImpl(String host) throws UnknownHostException;
541    // END android-removed
542
543    /**
544     * Convert a binary address into a string containing an Ipv4 Internet
545     * Protocol dotted address.
546     */
547    // BEGIN android-removed
548    // static native String inetNtoaImpl(int hipAddr);
549    // END android-removed
550
551    // BEGIN android-removed
552    /**
553     * Query the IP stack for the host address. The host is in string name form.
554     *
555     * @param name
556     *            the host name to lookup
557     * @param preferIPv6Address
558     *            address preference if underlying platform is V4/V6
559     * @return InetAddress the host address
560     * @throws UnknownHostException
561     *             if an error occurs during lookup
562     */
563    // static native InetAddress getHostByNameImpl(String name,
564    //         boolean preferIPv6Address) throws UnknownHostException;
565    // END android-removed
566
567    static String getHostNameInternal(String host, boolean isCheck) throws UnknownHostException {
568        if (host == null || 0 == host.length()) {
569            return Inet4Address.LOOPBACK.getHostAddress();
570        }
571        if (isHostName(host)) {
572            if (isCheck) {
573                SecurityManager sm = System.getSecurityManager();
574                if (sm != null) {
575                    sm.checkConnect(host, -1);
576                }
577            }
578            return lookupHostByName(host)[0].getHostAddress();
579        }
580        return host;
581    }
582
583    /**
584     * Returns a string containing a concise, human-readable description of this
585     * IP address.
586     *
587     * @return the description, as host/address.
588     */
589    @Override
590    public String toString() {
591        return (hostName == null ? "" : hostName) + "/" + getHostAddress(); //$NON-NLS-1$ //$NON-NLS-2$
592    }
593
594    /**
595     * Returns true if the string is a host name, false if it is an IP Address.
596     */
597    private static boolean isHostName(String value) {
598        try {
599            NETIMPL.ipStringToByteArray(value);
600            return false;
601        } catch (UnknownHostException e) {
602            return true;
603        }
604    }
605
606    /**
607     * Returns whether this address is a loopback address or not. This
608     * implementation returns always {@code false}. Valid IPv4 loopback
609     * addresses are 127.d.d.d The only valid IPv6 loopback address is ::1.
610     *
611     * @return {@code true} if this instance represents a loopback address,
612     *         {@code false} otherwise.
613     */
614    public boolean isLoopbackAddress() {
615        return false;
616    }
617
618    /**
619     * Returns whether this address is a link-local address or not. This
620     * implementation returns always {@code false}.
621     * <p>
622     * Valid IPv6 link-local addresses are FE80::0 through to
623     * FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
624     * <p>
625     * There are no valid IPv4 link-local addresses.
626     *
627     * @return {@code true} if this instance represents a link-local address,
628     *         {@code false} otherwise.
629     */
630    public boolean isLinkLocalAddress() {
631        return false;
632    }
633
634    /**
635     * Returns whether this address is a site-local address or not. This
636     * implementation returns always {@code false}.
637     * <p>
638     * Valid IPv6 site-local addresses are FEC0::0 through to
639     * FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
640     * <p>
641     * There are no valid IPv4 site-local addresses.
642     *
643     * @return {@code true} if this instance represents a site-local address,
644     *         {@code false} otherwise.
645     */
646    public boolean isSiteLocalAddress() {
647        return false;
648    }
649
650    /**
651     * Returns whether this address is a global multicast address or not. This
652     * implementation returns always {@code false}.
653     * <p>
654     * Valid IPv6 link-global multicast addresses are FFxE:/112 where x is a set
655     * of flags, and the additional 112 bits make up the global multicast
656     * address space.
657     * <p>
658     * Valid IPv4 global multicast addresses are between: 224.0.1.0 to
659     * 238.255.255.255.
660     *
661     * @return {@code true} if this instance represents a global multicast
662     *         address, {@code false} otherwise.
663     */
664    public boolean isMCGlobal() {
665        return false;
666    }
667
668    /**
669     * Returns whether this address is a node-local multicast address or not.
670     * This implementation returns always {@code false}.
671     * <p>
672     * Valid IPv6 node-local multicast addresses are FFx1:/112 where x is a set
673     * of flags, and the additional 112 bits make up the node-local multicast
674     * address space.
675     * <p>
676     * There are no valid IPv4 node-local multicast addresses.
677     *
678     * @return {@code true} if this instance represents a node-local multicast
679     *         address, {@code false} otherwise.
680     */
681    public boolean isMCNodeLocal() {
682        return false;
683    }
684
685    /**
686     * Returns whether this address is a link-local multicast address or not.
687     * This implementation returns always {@code false}.
688     * <p>
689     * Valid IPv6 link-local multicast addresses are FFx2:/112 where x is a set
690     * of flags, and the additional 112 bits make up the link-local multicast
691     * address space.
692     * <p>
693     * Valid IPv4 link-local addresses are between: 224.0.0.0 to 224.0.0.255
694     *
695     * @return {@code true} if this instance represents a link-local multicast
696     *         address, {@code false} otherwise.
697     */
698    public boolean isMCLinkLocal() {
699        return false;
700    }
701
702    /**
703     * Returns whether this address is a site-local multicast address or not.
704     * This implementation returns always {@code false}.
705     * <p>
706     * Valid IPv6 site-local multicast addresses are FFx5:/112 where x is a set
707     * of flags, and the additional 112 bits make up the site-local multicast
708     * address space.
709     * <p>
710     * Valid IPv4 site-local addresses are between: 239.252.0.0 to
711     * 239.255.255.255
712     *
713     * @return {@code true} if this instance represents a site-local multicast
714     *         address, {@code false} otherwise.
715     */
716    public boolean isMCSiteLocal() {
717        return false;
718    }
719
720    /**
721     * Returns whether this address is a organization-local multicast address or
722     * not. This implementation returns always {@code false}.
723     * <p>
724     * Valid IPv6 organization-local multicast addresses are FFx8:/112 where x
725     * is a set of flags, and the additional 112 bits make up the
726     * organization-local multicast address space.
727     * <p>
728     * Valid IPv4 organization-local addresses are between: 239.192.0.0 to
729     * 239.251.255.255
730     *
731     * @return {@code true} if this instance represents a organization-local
732     *         multicast address, {@code false} otherwise.
733     */
734    public boolean isMCOrgLocal() {
735        return false;
736    }
737
738    /**
739     * Returns whether this is a wildcard address or not. This implementation
740     * returns always {@code false}.
741     *
742     * @return {@code true} if this instance represents a wildcard address,
743     *         {@code false} otherwise.
744     */
745    public boolean isAnyLocalAddress() {
746        return false;
747    }
748
749    /**
750     * Tries to reach this {@code InetAddress}. This method first tries to use
751     * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
752     * on port 7 (Echo) of the remote host is established.
753     *
754     * @param timeout
755     *            timeout in milliseconds before the test fails if no connection
756     *            could be established.
757     * @return {@code true} if this address is reachable, {@code false}
758     *         otherwise.
759     * @throws IOException
760     *             if an error occurs during an I/O operation.
761     * @throws IllegalArgumentException
762     *             if timeout is less than zero.
763     */
764    public boolean isReachable(int timeout) throws IOException {
765        return isReachable(null, 0, timeout);
766    }
767
768    /**
769     * Tries to reach this {@code InetAddress}. This method first tries to use
770     * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
771     * on port 7 (Echo) of the remote host is established.
772     *
773     * @param netif
774     *            the network interface on which to connection should be
775     *            established.
776     * @param ttl
777     *            the maximum count of hops (time-to-live).
778     * @param timeout
779     *            timeout in milliseconds before the test fails if no connection
780     *            could be established.
781     * @return {@code true} if this address is reachable, {@code false}
782     *         otherwise.
783     * @throws IOException
784     *             if an error occurs during an I/O operation.
785     * @throws IllegalArgumentException
786     *             if ttl or timeout is less than zero.
787     */
788    public boolean isReachable(NetworkInterface netif, final int ttl,
789            final int timeout) throws IOException {
790        if (0 > ttl || 0 > timeout) {
791            throw new IllegalArgumentException(Msg.getString("K0051")); //$NON-NLS-1$
792        }
793        boolean reachable = false;
794        if (null == netif) {
795            // network interface is null, binds to no address
796            // BEGIN android-changed
797            // reachable = NETIMPL.isReachableByICMP(this, null, ttl, timeout);
798            // if (!reachable) {
799                reachable = isReachableByTCP(this, null, timeout);
800            // }
801            // END android-changed
802        } else {
803            // Not Bind to any address
804            if (null == netif.addresses) {
805                return false;
806            }
807            // binds to all address on this NetworkInterface, tries ICMP ping
808            // first
809            // BEGIN android-changed
810            // reachable = isReachableByICMPUseMultiThread(netif, ttl, timeout);
811            // if (!reachable) {
812                // tries TCP echo if ICMP ping fails
813                reachable = isReachableByMultiThread(netif, ttl, timeout);
814            // }
815            // END adnroid-changed
816        }
817        return reachable;
818    }
819
820    /*
821     * Uses multi-Thread to try if isReachable, returns true if any of threads
822     * returns in time
823     */
824    // BEGIN android-changed
825    private boolean isReachableByMultiThread(NetworkInterface netif,
826            final int ttl, final int timeout)
827    // END android-changed
828            throws IOException {
829        if (null == netif.addresses) {
830            return false;
831        }
832        Enumeration<InetAddress> addresses = netif.getInetAddresses();
833        reached = false;
834        addrCount = netif.addresses.length;
835        boolean needWait = false;
836        while (addresses.hasMoreElements()) {
837            final InetAddress addr = addresses.nextElement();
838
839            // loopback interface can only reach to local addresses
840            if (addr.isLoopbackAddress()) {
841                Enumeration<NetworkInterface> NetworkInterfaces = NetworkInterface
842                        .getNetworkInterfaces();
843                while (NetworkInterfaces.hasMoreElements()) {
844                    NetworkInterface networkInterface = NetworkInterfaces
845                            .nextElement();
846                    Enumeration<InetAddress> localAddresses = networkInterface
847                            .getInetAddresses();
848                    while (localAddresses.hasMoreElements()) {
849                        if (InetAddress.this.equals(localAddresses
850                                .nextElement())) {
851                            return true;
852                        }
853                    }
854                }
855
856                synchronized (waitReachable) {
857                    addrCount--;
858
859                    if (addrCount == 0) {
860                        // if count equals zero, all thread
861                        // expired,notifies main thread
862                        waitReachable.notifyAll();
863                    }
864                }
865                continue;
866            }
867
868            needWait = true;
869            new Thread() {
870                @Override
871                public void run() {
872                    boolean threadReached = false;
873                    // BEGIN android-changed
874                    // if isICMP, tries ICMP ping, else TCP echo
875                    // if (isICMP) {
876                    //     threadReached = NETIMPL.isReachableByICMP(
877                    //             InetAddress.this, addr, ttl, timeout);
878                    // } else {
879                        try {
880                            threadReached = isReachableByTCP(addr,
881                                    InetAddress.this, timeout);
882                        } catch (IOException e) {
883                            // do nothing
884                        }
885                    // }
886                    // END android-changed
887
888                    synchronized (waitReachable) {
889                        if (threadReached) {
890                            // if thread reached this address, sets reached to
891                            // true and notifies main thread
892                            reached = true;
893                            waitReachable.notifyAll();
894                        } else {
895                            addrCount--;
896                            if (0 == addrCount) {
897                                // if count equals zero, all thread
898                                // expired,notifies main thread
899                                waitReachable.notifyAll();
900                            }
901                        }
902                    }
903                }
904            }.start();
905        }
906
907        if (needWait) {
908            synchronized (waitReachable) {
909                try {
910                    while (!reached && (addrCount != 0)) {
911                        // wait for notification
912                        waitReachable.wait(1000);
913                    }
914                } catch (InterruptedException e) {
915                    // do nothing
916                }
917                return reached;
918            }
919        }
920
921        return false;
922    }
923
924    // BEGIN android-removed
925    // private boolean isReachableByICMPUseMultiThread(NetworkInterface netif,
926    //         int ttl, int timeout) throws IOException {
927    //     return isReachableByMultiThread(netif, ttl, timeout, true);
928    // }
929    //
930    // private boolean isReachableByTCPUseMultiThread(NetworkInterface netif,
931    //         int ttl, int timeout) throws IOException {
932    //     return isReachableByMultiThread(netif, ttl, timeout, false);
933    // }
934    // END android-removed
935
936    private boolean isReachableByTCP(InetAddress dest, InetAddress source,
937            int timeout) throws IOException {
938        FileDescriptor fd = new FileDescriptor();
939        // define traffic only for parameter
940        int traffic = 0;
941        boolean reached = false;
942        NETIMPL.createStreamSocket(fd, NetUtil.preferIPv4Stack());
943        try {
944            if (null != source) {
945                NETIMPL.bind(fd, source, 0);
946            }
947            NETIMPL.connectStreamWithTimeoutSocket(fd, 7, timeout, traffic,
948                    dest);
949            reached = true;
950        } catch (IOException e) {
951            if (ERRMSG_CONNECTION_REFUSED.equals(e.getMessage())) {
952                // Connection refused means the IP is reachable
953                reached = true;
954            }
955        }
956
957        NETIMPL.socketClose(fd);
958
959        return reached;
960    }
961
962    /**
963     * Returns the {@code InetAddress} corresponding to the array of bytes. In
964     * the case of an IPv4 address there must be exactly 4 bytes and for IPv6
965     * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown.
966     * <p>
967     * The IP address is not validated by a name service.
968     * <p>
969     * The high order byte is {@code ipAddress[0]}.
970     *
971     * @param ipAddress
972     *            is either a 4 (IPv4) or 16 (IPv6) byte long array.
973     * @return an {@code InetAddress} instance representing the given IP address
974     *         {@code ipAddress}.
975     * @throws UnknownHostException
976     *             if the given byte array has no valid length.
977     */
978    public static InetAddress getByAddress(byte[] ipAddress)
979            throws UnknownHostException {
980        // simply call the method by the same name specifying the default scope
981        // id of 0
982        return getByAddressInternal(null, ipAddress, 0);
983    }
984
985    /**
986     * Returns the {@code InetAddress} corresponding to the array of bytes. In
987     * the case of an IPv4 address there must be exactly 4 bytes and for IPv6
988     * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown. The
989     * IP address is not validated by a name service. The high order byte is
990     * {@code ipAddress[0]}.
991     *
992     * @param ipAddress
993     *            either a 4 (IPv4) or 16 (IPv6) byte array.
994     * @param scope_id
995     *            the scope id for an IPV6 scoped address. If not a scoped
996     *            address just pass in 0.
997     * @return the InetAddress
998     * @throws UnknownHostException
999     */
1000    static InetAddress getByAddress(byte[] ipAddress, int scope_id)
1001            throws UnknownHostException {
1002        return getByAddressInternal(null, ipAddress, scope_id);
1003    }
1004
1005    private static boolean isIPv4MappedAddress(byte ipAddress[]) {
1006        // Check if the address matches ::FFFF:d.d.d.d
1007        // The first 10 bytes are 0. The next to are -1 (FF).
1008        // The last 4 bytes are varied.
1009        if (ipAddress == null || ipAddress.length != 16) {
1010            return false;
1011        }
1012        for (int i = 0; i < 10; i++) {
1013            if (ipAddress[i] != 0) {
1014                return false;
1015            }
1016        }
1017        if (ipAddress[10] != -1 || ipAddress[11] != -1) {
1018            return false;
1019        }
1020        return true;
1021    }
1022
1023    private static byte[] ipv4MappedToIPv4(byte[] mappedAddress) {
1024        byte[] ipv4Address = new byte[4];
1025        for(int i = 0; i < 4; i++) {
1026            ipv4Address[i] = mappedAddress[12 + i];
1027        }
1028        return ipv4Address;
1029    }
1030
1031    /**
1032     * Returns the {@code InetAddress} corresponding to the array of bytes, and
1033     * the given hostname. In the case of an IPv4 address there must be exactly
1034     * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code
1035     * UnknownHostException} will be thrown.
1036     * <p>
1037     * The host name and IP address are not validated.
1038     * <p>
1039     * The hostname either be a machine alias or a valid IPv6 or IPv4 address
1040     * format.
1041     * <p>
1042     * The high order byte is {@code ipAddress[0]}.
1043     *
1044     * @param hostName
1045     *            the string representation of hostname or IP address.
1046     * @param ipAddress
1047     *            either a 4 (IPv4) or 16 (IPv6) byte long array.
1048     * @return an {@code InetAddress} instance representing the given IP address
1049     *         and hostname.
1050     * @throws UnknownHostException
1051     *             if the given byte array has no valid length.
1052     */
1053    public static InetAddress getByAddress(String hostName, byte[] ipAddress)
1054            throws UnknownHostException {
1055        // just call the method by the same name passing in a default scope id
1056        // of 0
1057        return getByAddressInternal(hostName, ipAddress, 0);
1058    }
1059
1060    /**
1061     * Returns the {@code InetAddress} corresponding to the array of bytes, and
1062     * the given hostname. In the case of an IPv4 address there must be exactly
1063     * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code
1064     * UnknownHostException} is thrown. The host name and IP address are not
1065     * validated. The hostname either be a machine alias or a valid IPv6 or IPv4
1066     * address format. The high order byte is {@code ipAddress[0]}.
1067     *
1068     * @param hostName
1069     *            string representation of hostname or IP address.
1070     * @param ipAddress
1071     *            either a 4 (IPv4) or 16 (IPv6) byte array.
1072     * @param scope_id
1073     *            the scope id for a scoped address. If not a scoped address
1074     *            just pass in 0.
1075     * @return the InetAddress
1076     * @throws UnknownHostException
1077     */
1078    static InetAddress getByAddressInternal(String hostName, byte[] ipAddress,
1079            int scope_id) throws UnknownHostException {
1080        if (ipAddress == null) {
1081            // We don't throw NullPointerException here for RI compatibility,
1082            // but we do say "address is null" (K0331), instead of "addr is of
1083            // illegal length".
1084            throw new UnknownHostException(
1085                Msg.getString("K0331", hostName)); //$NON-NLS-1$
1086        }
1087        switch (ipAddress.length) {
1088            case 4:
1089                return new Inet4Address(ipAddress.clone());
1090            case 16:
1091                // First check to see if the address is an IPv6-mapped
1092                // IPv4 address. If it is, then we can make it a IPv4
1093                // address, otherwise, we'll create an IPv6 address.
1094                if (isIPv4MappedAddress(ipAddress)) {
1095                    return new Inet4Address(ipv4MappedToIPv4(ipAddress));
1096                } else {
1097                    return new Inet6Address(ipAddress.clone(), scope_id);
1098                }
1099            default:
1100                if (hostName != null) {
1101                    // "Invalid IP Address is neither 4 or 16 bytes: <hostName>"
1102                    throw new UnknownHostException(
1103                            Msg.getString("K0332", hostName)); //$NON-NLS-1$
1104                } else {
1105                    // "Invalid IP Address is neither 4 or 16 bytes"
1106                    throw new UnknownHostException(
1107                            Msg.getString("K0339")); //$NON-NLS-1$
1108                }
1109        }
1110    }
1111
1112    /**
1113     * Takes the integer and chops it into 4 bytes, putting it into the byte
1114     * array starting with the high order byte at the index start. This method
1115     * makes no checks on the validity of the parameters.
1116     */
1117    static void intToBytes(int value, byte bytes[], int start) {
1118        // Shift the int so the current byte is right-most
1119        // Use a byte mask of 255 to single out the last byte.
1120        bytes[start] = (byte) ((value >> 24) & 255);
1121        bytes[start + 1] = (byte) ((value >> 16) & 255);
1122        bytes[start + 2] = (byte) ((value >> 8) & 255);
1123        bytes[start + 3] = (byte) (value & 255);
1124    }
1125
1126    /**
1127     * Takes the byte array and creates an integer out of four bytes starting at
1128     * start as the high-order byte. This method makes no checks on the validity
1129     * of the parameters.
1130     */
1131    static int bytesToInt(byte bytes[], int start) {
1132        // First mask the byte with 255, as when a negative
1133        // signed byte converts to an integer, it has bits
1134        // on in the first 3 bytes, we are only concerned
1135        // about the right-most 8 bits.
1136        // Then shift the rightmost byte to align with its
1137        // position in the integer.
1138        int value = ((bytes[start + 3] & 255))
1139                | ((bytes[start + 2] & 255) << 8)
1140                | ((bytes[start + 1] & 255) << 16)
1141                | ((bytes[start] & 255) << 24);
1142        return value;
1143    }
1144
1145    static boolean preferIPv6Addresses() {
1146        String result = AccessController.doPrivileged(new PriviAction<String>(
1147                "java.net.preferIPv6Addresses")); //$NON-NLS-1$
1148        return "true".equals(result); //$NON-NLS-1$
1149    }
1150
1151    private static final ObjectStreamField[] serialPersistentFields = {
1152            new ObjectStreamField("address", Integer.TYPE), //$NON-NLS-1$
1153            new ObjectStreamField("family", Integer.TYPE), //$NON-NLS-1$
1154            new ObjectStreamField("hostName", String.class) }; //$NON-NLS-1$
1155
1156    private void writeObject(ObjectOutputStream stream) throws IOException {
1157        ObjectOutputStream.PutField fields = stream.putFields();
1158        if (ipaddress == null) {
1159            fields.put("address", 0); //$NON-NLS-1$
1160        } else {
1161            fields.put("address", bytesToInt(ipaddress, 0)); //$NON-NLS-1$
1162        }
1163        fields.put("family", family); //$NON-NLS-1$
1164        fields.put("hostName", hostName); //$NON-NLS-1$
1165
1166        stream.writeFields();
1167    }
1168
1169    private void readObject(ObjectInputStream stream) throws IOException,
1170            ClassNotFoundException {
1171        ObjectInputStream.GetField fields = stream.readFields();
1172        int addr = fields.get("address", 0); //$NON-NLS-1$
1173        ipaddress = new byte[4];
1174        intToBytes(addr, ipaddress, 0);
1175        hostName = (String) fields.get("hostName", null); //$NON-NLS-1$
1176        family = fields.get("family", 2); //$NON-NLS-1$
1177    }
1178
1179    /*
1180     * The spec requires that if we encounter a generic InetAddress in
1181     * serialized form then we should interpret it as an Inet4 address.
1182     */
1183    private Object readResolve() throws ObjectStreamException {
1184        return new Inet4Address(ipaddress, hostName);
1185    }
1186}
1187