/* * Copyright (C) 2014 The Android Open Source Project * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.net; import java.io.ObjectStreamException; import java.io.ObjectStreamField; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectInputStream.GetField; import java.io.ObjectOutputStream; import java.io.ObjectOutputStream.PutField; import libcore.net.InetAddressUtils; import sun.net.util.IPAddressUtil; import sun.net.spi.nameservice.*; import libcore.io.Libcore; /** * This class represents an Internet Protocol (IP) address. * *
An IP address is either a 32-bit or 128-bit unsigned number * used by IP, a lower-level protocol on which protocols like UDP and * TCP are built. The IP address architecture is defined by RFC 790: * Assigned Numbers, RFC 1918: * Address Allocation for Private Internets, RFC 2365: * Administratively Scoped IP Multicast, and RFC 2373: IP * Version 6 Addressing Architecture. An instance of an * InetAddress consists of an IP address and possibly its * corresponding host name (depending on whether it is constructed * with a host name or whether it has already done reverse host name * resolution). * *
* **
* unicast *An identifier for a single interface. A packet sent to * a unicast address is delivered to the interface identified by * that address. * * The Unspecified Address -- Also called anylocal or wildcard * address. It must never be assigned to any node. It indicates the * absence of an address. One example of its use is as the target of * bind, which allows a server to accept a client connection on any * interface, in case the server host has multiple interfaces. * *
The unspecified address must not be used as * the destination address of an IP packet. * *
The Loopback Addresses -- This is the address * assigned to the loopback interface. Anything sent to this * IP address loops around and becomes IP input on the local * host. This address is often used when testing a * client.
* multicast *An identifier for a set of interfaces (typically belonging * to different nodes). A packet sent to a multicast address is * delivered to all interfaces identified by that address.
Link-local addresses are designed to be used for addressing * on a single link for purposes such as auto-address configuration, * neighbor discovery, or when no routers are present. * *
Site-local addresses are designed to be used for addressing * inside of a site without the need for a global prefix. * *
Global addresses are unique across the internet. * *
* * For IPv4 address format, please refer to Inet4Address#format; For IPv6 * address format, please refer to Inet6Address#format. * *
There is a couple of * System Properties affecting how IPv4 and IPv6 addresses are used.
* *Reverse name resolution means that for any IP address, * the host associated with the IP address is returned. * *
The InetAddress class provides methods to resolve host names to * their IP addresses and vice versa. * *
By default, when a security manager is installed, in order to * protect against DNS spoofing attacks, * the result of positive host name resolutions are * cached forever. When a security manager is not installed, the default * behavior is to cache entries for a finite (implementation dependent) * period of time. The result of unsuccessful host * name resolution is cached for a very short period of time (10 * seconds) to improve performance. * *
If the default behavior is not desired, then a Java security property * can be set to a different Time-to-live (TTL) value for positive * caching. Likewise, a system admin can configure a different * negative caching TTL value when needed. * *
Two Java security properties control the TTL values used for * positive and negative host name resolution caching: * *
** * @author Chris Warth * @see java.net.InetAddress#getByAddress(byte[]) * @see java.net.InetAddress#getByAddress(java.lang.String, byte[]) * @see java.net.InetAddress#getAllByName(java.lang.String) * @see java.net.InetAddress#getByName(java.lang.String) * @see java.net.InetAddress#getLocalHost() * @since JDK1.0 */ public class InetAddress implements java.io.Serializable { // BEGIN Android-removed: Android uses linux-based OsConstants. /* * Specify the address family: Internet Protocol, Version 4 * @since 1.4 * static final int IPv4 = 1; /** * Specify the address family: Internet Protocol, Version 6 * @since 1.4 * static final int IPv6 = 2; */ // END Android-removed: Android uses linux-based OsConstants. // Android-removed: Android doesn't support the preference. // /* Specify address family preference */ //static transient boolean preferIPv6Address = false; static class InetAddressHolder { /** * Reserve the original application specified hostname. * * The original hostname is useful for domain-based endpoint * identification (see RFC 2818 and RFC 6125). If an address * was created with a raw IP address, a reverse name lookup * may introduce endpoint identification security issue via * DNS forging. * * Oracle JSSE provider is using this original hostname, via * sun.misc.JavaNetAccess, for SSL/TLS endpoint identification. * * Note: May define a new public method in the future if necessary. */ String originalHostName; InetAddressHolder() {} InetAddressHolder(String hostName, int address, int family) { this.originalHostName = hostName; this.hostName = hostName; this.address = address; this.family = family; } void init(String hostName, int family) { this.originalHostName = hostName; this.hostName = hostName; if (family != -1) { this.family = family; } } String hostName; String getHostName() { return hostName; } String getOriginalHostName() { return originalHostName; } /** * Holds a 32-bit IPv4 address. */ int address; int getAddress() { return address; } // Android-changed: Documentation: use Linux-based OsConstants. /** * Specifies the address family type, for instance, AF_INET for IPv4 * addresses, and AF_INET6 for IPv6 addresses. */ int family; int getFamily() { return family; } } transient InetAddressHolder holder; InetAddressHolder holder() { return holder; } /* The implementation is always dual stack IPv6/IPv4 on android */ static final InetAddressImpl impl = new Inet6AddressImpl(); /* Used to store the name service provider */ // Android-changed: Android has only one name service. // Android doesn't allow user to provide custom name services. // private static List*
*- networkaddress.cache.ttl
*- Indicates the caching policy for successful name lookups from * the name service. The value is specified as as integer to indicate * the number of seconds to cache the successful lookup. The default * setting is to cache for an implementation specific period of time. *
** A value of -1 indicates "cache forever". *
- networkaddress.cache.negative.ttl (default: 10)
*- Indicates the caching policy for un-successful name lookups * from the name service. The value is specified as as integer to * indicate the number of seconds to cache the failure for * un-successful lookups. *
** A value of 0 indicates "never cache". * A value of -1 indicates "cache forever". *
* Android implementation attempts ICMP ECHO REQUESTs first, on failure it * will fall back to TCP ECHO REQUESTs. Success on either protocol will * return true. *
* The timeout value, in milliseconds, indicates the maximum amount of time * the try should take. If the operation times out before getting an * answer, the host is deemed unreachable. A negative value will result * in an IllegalArgumentException being thrown. * * @param timeout the time, in milliseconds, before the call aborts * @return a {@code boolean} indicating if the address is reachable. * @throws IOException if a network error occurs * @throws IllegalArgumentException if {@code timeout} is negative. * @since 1.5 */ public boolean isReachable(int timeout) throws IOException { return isReachable(null, 0 , timeout); } // Android-changed: Document that impl tries ICMP ECHO REQUESTs first. // The sole implementation, Inet6AddressImpl.isReachable(), tries ICMP ECHO REQUESTs before // TCP ECHO REQUESTs on Android. On Android, these are both possible without root access. /** * Test whether that address is reachable. Best effort is made by the * implementation to try to reach the host, but firewalls and server * configuration may block requests resulting in a unreachable status * while some specific ports may be accessible. *
* Android implementation attempts ICMP ECHO REQUESTs first, on failure it * will fall back to TCP ECHO REQUESTs. Success on either protocol will * return true. *
* The {@code network interface} and {@code ttl} parameters * let the caller specify which network interface the test will go through * and the maximum number of hops the packets should go through. * A negative value for the {@code ttl} will result in an * IllegalArgumentException being thrown. *
* The timeout value, in milliseconds, indicates the maximum amount of time * the try should take. If the operation times out before getting an * answer, the host is deemed unreachable. A negative value will result * in an IllegalArgumentException being thrown. * * @param netif the NetworkInterface through which the * test will be done, or null for any interface * @param ttl the maximum numbers of hops to try or 0 for the * default * @param timeout the time, in milliseconds, before the call aborts * @throws IllegalArgumentException if either {@code timeout} * or {@code ttl} are negative. * @return a {@code boolean}indicating if the address is reachable. * @throws IOException if a network error occurs * @since 1.5 */ public boolean isReachable(NetworkInterface netif, int ttl, int timeout) throws IOException { if (ttl < 0) throw new IllegalArgumentException("ttl can't be negative"); if (timeout < 0) throw new IllegalArgumentException("timeout can't be negative"); return impl.isReachable(this, timeout, netif, ttl); } // BEGIN Android-added: isReachableByICMP(timeout). /** * @hide For testing only */ public boolean isReachableByICMP(int timeout) throws IOException { return ((Inet6AddressImpl) impl).icmpEcho(this, timeout, null, 0); } // END Android-added: isReachableByICMP(timeout). /** * Gets the host name for this IP address. * *
If this InetAddress was created with a host name, * this host name will be remembered and returned; * otherwise, a reverse name lookup will be performed * and the result will be returned based on the system * configured name lookup service. If a lookup of the name service * is required, call * {@link #getCanonicalHostName() getCanonicalHostName}. * *
If there is a security manager, its * {@code checkConnect} method is first called * with the hostname and {@code -1} * as its arguments to see if the operation is allowed. * If the operation is not allowed, it will return * the textual representation of the IP address. * * @return the host name for this IP address, or if the operation * is not allowed by the security check, the textual * representation of the IP address. * * @see InetAddress#getCanonicalHostName * @see SecurityManager#checkConnect */ public String getHostName() { // Android-changed: Remove SecurityManager check. if (holder().getHostName() == null) { holder().hostName = InetAddress.getHostFromNameService(this); } return holder().getHostName(); } // BEGIN Android-removed: Android doesn't support SecurityManager. /* * Returns the hostname for this address. * If the host is equal to null, then this address refers to any * of the local machine's available network addresses. * this is package private so SocketPermission can make calls into * here without a security check. * *
If there is a security manager, this method first * calls its {@code checkConnect} method * with the hostname and {@code -1} * as its arguments to see if the calling code is allowed to know * the hostname for this IP address, i.e., to connect to the host. * If the operation is not allowed, it will return * the textual representation of the IP address. * * @return the host name for this IP address, or if the operation * is not allowed by the security check, the textual * representation of the IP address. * * @param check make security check if true * * @see SecurityManager#checkConnect * String getHostName(boolean check) { if (holder().getHostName() == null) { holder().hostName = InetAddress.getHostFromNameService(this, check); } return holder().getHostName(); } */ // END Android-removed: Android doesn't support SecurityManager. /** * Gets the fully qualified domain name for this IP address. * Best effort method, meaning we may not be able to return * the FQDN depending on the underlying system configuration. * *
If there is a security manager, this method first * calls its {@code checkConnect} method * with the hostname and {@code -1} * as its arguments to see if the calling code is allowed to know * the hostname for this IP address, i.e., to connect to the host. * If the operation is not allowed, it will return * the textual representation of the IP address. * * @return the fully qualified domain name for this IP address, * or if the operation is not allowed by the security check, * the textual representation of the IP address. * * @see SecurityManager#checkConnect * * @since 1.4 */ public String getCanonicalHostName() { // Android-changed: Remove SecurityManager check. if (canonicalHostName == null) { canonicalHostName = InetAddress.getHostFromNameService(this); } return canonicalHostName; } // Android-changed: Remove SecurityManager check. // * @param check make security check if true /** * Returns the hostname for this address. * *
If there is a security manager, this method first * calls its {@code checkConnect} method * with the hostname and {@code -1} * as its arguments to see if the calling code is allowed to know * the hostname for this IP address, i.e., to connect to the host. * If the operation is not allowed, it will return * the textual representation of the IP address. * * @return the host name for this IP address, or if the operation * is not allowed by the security check, the textual * representation of the IP address. * * @see SecurityManager#checkConnect */ private static String getHostFromNameService(InetAddress addr) { String host = null; try { // first lookup the hostname // Android-changed: Android has only one name service. host = nameService.getHostByAddr(addr.getAddress()); /* now get all the IP addresses for this hostname, * and make sure one of them matches the original IP * address. We do this to try and prevent spoofing. */ InetAddress[] arr = nameService.lookupAllHostAddr(host, NETID_UNSET); boolean ok = false; if (arr != null) { for(int i = 0; !ok && i < arr.length; i++) { ok = addr.equals(arr[i]); } } //XXX: if it looks a spoof just return the address? if (!ok) { host = addr.getHostAddress(); return host; } } catch (UnknownHostException e) { host = addr.getHostAddress(); } return host; } /** * Returns the raw IP address of this {@code InetAddress} * object. The result is in network byte order: the highest order * byte of the address is in {@code getAddress()[0]}. * * @return the raw IP address of this object. */ public byte[] getAddress() { return null; } /** * Returns the IP address string in textual presentation. * * @return the raw IP address in a string format. * @since JDK1.0.2 */ public String getHostAddress() { return null; } /** * Returns a hashcode for this IP address. * * @return a hash code value for this IP address. */ public int hashCode() { return -1; } /** * Compares this object against the specified object. * The result is {@code true} if and only if the argument is * not {@code null} and it represents the same IP address as * this object. *
* Two instances of {@code InetAddress} represent the same IP
* address if the length of the byte arrays returned by
* {@code getAddress} is the same for both, and each of the
* array components is the same for the byte arrays.
*
* @param obj the object to compare against.
* @return {@code true} if the objects are the same;
* {@code false} otherwise.
* @see java.net.InetAddress#getAddress()
*/
public boolean equals(Object obj) {
return false;
}
/**
* Converts this IP address to a {@code String}. The
* string returned is of the form: hostname / literal IP
* address.
*
* If the host name is unresolved, no reverse name service lookup
* is performed. The hostname part will be represented by an empty string.
*
* @return a string representation of this IP address.
*/
public String toString() {
String hostName = holder().getHostName();
return ((hostName != null) ? hostName : "")
+ "/" + getHostAddress();
}
// BEGIN Android-removed: Resolves a hostname using Libcore.os.
/*
* Cached addresses - our own litle nis, not!
*
private static Cache addressCache = new Cache(Cache.Type.Positive);
private static Cache negativeCache = new Cache(Cache.Type.Negative);
private static boolean addressCacheInit = false;
static InetAddress[] unknown_array; // put THIS in cache
static InetAddressImpl impl;
private static final HashMap The host name can either be a machine name, such as
* "{@code java.sun.com}", or a textual representation of its IP
* address.
* No validity checking is done on the host name either.
*
* If addr specifies an IPv4 address an instance of Inet4Address
* will be returned; otherwise, an instance of Inet6Address
* will be returned.
*
* IPv4 address byte array must be 4 bytes long and IPv6 byte array
* must be 16 bytes long
*
* @param host the specified host
* @param addr the raw IP address in network byte order
* @return an InetAddress object created from the raw IP address.
* @exception UnknownHostException if IP address is of illegal length
* @since 1.4
*/
public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException {
return getByAddress(host, addr, -1 /* scopeId */);
}
// Android-added: Called by native code in Libcore.io.
// Do not delete. Called from native code.
private static InetAddress getByAddress(String host, byte[] addr, int scopeId)
throws UnknownHostException {
if (host != null && host.length() > 0 && host.charAt(0) == '[') {
if (host.charAt(host.length()-1) == ']') {
host = host.substring(1, host.length() -1);
}
}
if (addr != null) {
if (addr.length == Inet4Address.INADDRSZ) {
return new Inet4Address(host, addr);
} else if (addr.length == Inet6Address.INADDRSZ) {
byte[] newAddr
= IPAddressUtil.convertFromIPv4MappedAddress(addr);
if (newAddr != null) {
return new Inet4Address(host, newAddr);
} else {
return new Inet6Address(host, addr, scopeId);
}
}
}
throw new UnknownHostException("addr is of illegal length");
}
/**
* Determines the IP address of a host, given the host's name.
*
* The host name can either be a machine name, such as
* "{@code java.sun.com}", or a textual representation of its
* IP address. If a literal IP address is supplied, only the
* validity of the address format is checked.
*
* For {@code host} specified in literal IPv6 address,
* either the form defined in RFC 2732 or the literal IPv6 address
* format defined in RFC 2373 is accepted. IPv6 scoped addresses are also
* supported. See here for a description of IPv6
* scoped addresses.
*
* If the host is {@code null} then an {@code InetAddress}
* representing an address of the loopback interface is returned.
* See RFC 3330
* section 2 and RFC 2373
* section 2.5.3. The host name can either be a machine name, such as
* "{@code java.sun.com}", or a textual representation of its IP
* address. If a literal IP address is supplied, only the
* validity of the address format is checked.
*
* For {@code host} specified in literal IPv6 address,
* either the form defined in RFC 2732 or the literal IPv6 address
* format defined in RFC 2373 is accepted. A literal IPv6 address may
* also be qualified by appending a scoped zone identifier or scope_id.
* The syntax and usage of scope_ids is described
* here.
* If the host is {@code null} then an {@code InetAddress}
* representing an address of the loopback interface is returned.
* See RFC 3330
* section 2 and RFC 2373
* section 2.5.3. If there is a security manager and {@code host} is not
* null and {@code host.length() } is not equal to zero, the
* security manager's
* {@code checkConnect} method is called
* with the hostname and {@code -1}
* as its arguments to see if the operation is allowed.
*
* @param host the name of the host, or {@code null}.
* @return an array of all the IP addresses for a given host name.
*
* @exception UnknownHostException if no IP address for the
* {@code host} could be found, or if a scope_id was specified
* for a global IPv6 address.
* @exception SecurityException if a security manager exists and its
* {@code checkConnect} method doesn't allow the operation.
*
* @see SecurityManager#checkConnect
*/
public static InetAddress[] getAllByName(String host)
throws UnknownHostException {
// Android-changed: Resolves a hostname using Libcore.os.
// Also, returns both the Inet4 and Inet6 loopback for null/empty host
return impl.lookupAllHostAddr(host, NETID_UNSET).clone();
}
/**
* Returns the loopback address.
*
* The InetAddress returned will represent the IPv4
* loopback address, 127.0.0.1, or the IPv6 loopback
* address, ::1. The IPv4 loopback address returned
* is only one of many in the form 127.*.*.*
*
* @return the InetAddress loopback instance.
* @since 1.7
*/
public static InetAddress getLoopbackAddress() {
// Android-changed: Always returns IPv6 loopback address in Android.
return impl.loopbackAddresses()[0];
}
// BEGIN Android-removed: Resolves a hostname using Libcore.os.
/*
* check if the literal address string has %nn appended
* returns -1 if not, or the numeric value otherwise.
*
* %nn may also be a string that represents the displayName of
* a currently available NetworkInterface.
*
private static int checkNumericZone (String s) throws UnknownHostException {
int percent = s.indexOf ('%');
int slen = s.length();
int digit, zone=0;
if (percent == -1) {
return -1;
}
for (int i=percent+1; i This method doesn't block, i.e. no reverse name service lookup
* is performed.
*
* IPv4 address byte array must be 4 bytes long and IPv6 byte array
* must be 16 bytes long
*
* @param addr the raw IP address in network byte order
* @return an InetAddress object created from the raw IP address.
* @exception UnknownHostException if IP address is of illegal length
* @since 1.4
*/
public static InetAddress getByAddress(byte[] addr)
throws UnknownHostException {
return getByAddress(null, addr);
}
// BEGIN Android-removed: Resolves a hostname using Libcore.os.
/*
private static InetAddress cachedLocalHost = null;
private static long cacheTime = 0;
private static final long maxCacheTime = 5000L;
private static final Object cacheLock = new Object();
*/
// END Android-removed: Resolves a hostname using Libcore.os.
/**
* Returns the address of the local host. This is achieved by retrieving
* the name of the host from the system, then resolving that name into
* an {@code InetAddress}.
*
* Note: The resolved address may be cached for a short period of time.
* If there is a security manager, its
* {@code checkConnect} method is called
* with the local host name and {@code -1}
* as its arguments to see if the operation is allowed.
* If the operation is not allowed, an InetAddress representing
* the loopback address is returned.
*
* @return the address of the local host.
*
* @exception UnknownHostException if the local host name could not
* be resolved into an address.
*
* @see SecurityManager#checkConnect
* @see java.net.InetAddress#getByName(java.lang.String)
*/
public static InetAddress getLocalHost() throws UnknownHostException {
// BEGIN Android-changed: Resolves a hostname using Libcore.os.
/*
SecurityManager security = System.getSecurityManager();
try {
String local = impl.getLocalHostName();
if (security != null) {
security.checkConnect(local, -1);
}
if (local.equals("localhost")) {
return impl.loopbackAddress();
}
InetAddress ret = null;
synchronized (cacheLock) {
long now = System.currentTimeMillis();
if (cachedLocalHost != null) {
if ((now - cacheTime) < maxCacheTime) // Less than 5s old?
ret = cachedLocalHost;
else
cachedLocalHost = null;
}
// we are calling getAddressesFromNameService directly
// to avoid getting localHost from cache
if (ret == null) {
InetAddress[] localAddrs;
try {
localAddrs =
InetAddress.getAddressesFromNameService(local, null);
} catch (UnknownHostException uhe) {
// Rethrow with a more informative error message.
UnknownHostException uhe2 =
new UnknownHostException(local + ": " +
uhe.getMessage());
uhe2.initCause(uhe);
throw uhe2;
}
cachedLocalHost = localAddrs[0];
cacheTime = now;
ret = localAddrs[0];
}
}
return ret;
} catch (java.lang.SecurityException e) {
return impl.loopbackAddress();
}
*/
String local = Libcore.os.uname().nodename;
return impl.lookupAllHostAddr(local, NETID_UNSET)[0];
// END Android-changed: Resolves a hostname using Libcore.os.
}
// BEGIN Android-removed: Android doesn't need to call native init.
/**
* Perform class load-time initializations.
*
private static native void init();
*/
// END Android-removed: Android doesn't need to call native init.
/*
* Returns the InetAddress representing anyLocalAddress
* (typically 0.0.0.0 or ::0)
*/
static InetAddress anyLocalAddress() {
return impl.anyLocalAddress();
}
// BEGIN Android-removed: Android doesn't load user-provided implementation.
/*
* Load and instantiate an underlying impl class
*
static InetAddressImpl loadImpl(String implName) {
Object impl = null;
/*
* Property "impl.prefix" will be prepended to the classname
* of the implementation object we instantiate, to which we
* delegate the real work (like native methods). This
* property can vary across implementations of the java.
* classes. The default is an empty String "".
*
String prefix = AccessController.doPrivileged(
new GetPropertyAction("impl.prefix", ""));
try {
impl = Class.forName("java.net." + prefix + implName).newInstance();
} catch (ClassNotFoundException e) {
System.err.println("Class not found: java.net." + prefix +
implName + ":\ncheck impl.prefix property " +
"in your properties file.");
} catch (InstantiationException e) {
System.err.println("Could not instantiate: java.net." + prefix +
implName + ":\ncheck impl.prefix property " +
"in your properties file.");
} catch (IllegalAccessException e) {
System.err.println("Cannot access class: java.net." + prefix +
implName + ":\ncheck impl.prefix property " +
"in your properties file.");
}
if (impl == null) {
try {
impl = Class.forName(implName).newInstance();
} catch (Exception e) {
throw new Error("System property impl.prefix incorrect");
}
}
return (InetAddressImpl) impl;
}
*/
// END Android-removed: Android doesn't load user-provided implementation.
private void readObjectNoData (ObjectInputStream s) throws
IOException, ClassNotFoundException {
// Android-changed: Don't use null to mean the boot classloader.
if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
throw new SecurityException ("invalid address type");
}
}
// Android-changed: Don't use null to mean the boot classloader.
private static final ClassLoader BOOT_CLASSLOADER = Object.class.getClassLoader();
private void readObject (ObjectInputStream s) throws
IOException, ClassNotFoundException {
// Android-changed: Don't use null to mean the boot classloader.
if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
throw new SecurityException ("invalid address type");
}
GetField gf = s.readFields();
String host = (String)gf.get("hostName", null);
int address= gf.get("address", 0);
int family= gf.get("family", 0);
holder = new InetAddressHolder(host, address, family);
}
/* needed because the serializable fields no longer exist */
/**
* @serialField hostName String
* @serialField address int
* @serialField family int
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("hostName", String.class),
new ObjectStreamField("address", int.class),
new ObjectStreamField("family", int.class),
};
private void writeObject (ObjectOutputStream s) throws
IOException {
// Android-changed: Don't use null to mean the boot classloader.
if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
throw new SecurityException ("invalid address type");
}
PutField pf = s.putFields();
pf.put("hostName", holder().hostName);
pf.put("address", holder().address);
pf.put("family", holder().family);
s.writeFields();
s.flush();
}
static final int NETID_UNSET = 0;
// BEGIN Android-added: Add methods required by frameworks/base.
// Particularly those required to deal with scope ids.
/**
* Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1").
*
* This copes with all forms of address that Java supports, detailed in the
* {@link InetAddress} class documentation. An empty string is not treated as numeric.
*
* @hide used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup.
* @deprecated Use {@link InetAddressUtils#isNumericAddress(String)} instead, if possible.
* @throws NullPointerException if the {@code address} is {@code null}.
*/
@Deprecated
public static boolean isNumeric(String address) {
return InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(address) != null;
}
/**
* Returns an InetAddress corresponding to the given numeric address (such
* as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
*
* This method will never do a DNS lookup. Non-numeric addresses are errors. Passing either
* an empty string or a {@code null} as the {@code numericAddress} will return the
* {@link Inet6Address#LOOPBACK} address.
*
* @hide used by frameworks/base's NetworkUtils.numericToInetAddress
* @throws IllegalArgumentException if {@code numericAddress} is not a numeric address
* @deprecated Use {@link InetAddressUtils#parseNumericAddress(String)} instead, if possible.
*/
@Deprecated
public static InetAddress parseNumericAddress(String numericAddress) {
if (numericAddress == null || numericAddress.isEmpty()) {
return Inet6Address.LOOPBACK;
}
InetAddress result = InetAddressUtils
.parseNumericAddressNoThrowStripOptionalBrackets(numericAddress);
if (result == null) {
throw new IllegalArgumentException("Not a numeric address: " + numericAddress);
}
return result;
}
/**
* Removes all entries from the VM's DNS cache. This does not affect the C library's DNS
* cache, nor any caching DNS servers between you and the canonical server.
* @hide
*/
public static void clearDnsCache() {
impl.clearAddressCache();
}
// END Android-added: Add methods required by frameworks/base.
// BEGIN Android-added: Support for network (netId)-specific DNS resolution.
/**
* Operates identically to {@code getByName} except host resolution is
* performed on the network designated by {@code netId}.
*
* @param host
* the hostName to be resolved to an address or {@code null}.
* @param netId the network to use for host resolution.
* @return the {@code InetAddress} instance representing the host.
* @throws UnknownHostException if the address lookup fails.
* @hide
*/
public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException {
return impl.lookupAllHostAddr(host, netId)[0];
}
/**
* Operates identically to {@code getAllByName} except host resolution is
* performed on the network designated by {@code netId}.
*
* @param host the hostname or literal IP string to be resolved.
* @param netId the network to use for host resolution.
* @return the array of addresses associated with the specified host.
* @throws UnknownHostException if the address lookup fails.
* @hide
*/
public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
return impl.lookupAllHostAddr(host, netId).clone();
}
// END Android-added: Support for network (netId)-specific DNS resolution.
}
// BEGIN Android-removed: Android doesn't load user-provided implementation.
/*
* Simple factory to create the impl
*
class InetAddressImplFactory {
static InetAddressImpl create() {
return InetAddress.loadImpl(isIPv6Supported() ?
"Inet6AddressImpl" : "Inet4AddressImpl");
}
static native boolean isIPv6Supported();
}
*/
// END Android-removed: Android doesn't load user-provided implementation.