summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Jensen <pauljensen@google.com>2014-05-12 23:40:42 -0400
committerLorenzo Colitti <lorenzo@google.com>2014-05-13 19:46:56 -0700
commit3e58734d651080009c9190c7062837fca5c7cf4e (patch)
treed213742063128c6be8b785ae4fd7816b95a71879
parent8f3ae282cb56de80de35b90408c9d832c8e3c424 (diff)
downloadlibcore-3e58734d651080009c9190c7062837fca5c7cf4e.zip
libcore-3e58734d651080009c9190c7062837fca5c7cf4e.tar.gz
libcore-3e58734d651080009c9190c7062837fca5c7cf4e.tar.bz2
Add support for network-specific host name resolution.
For now all such support is hidden. Change-Id: I932f73158a8f6e3ccc36c319d138180dff2aa070
-rw-r--r--NativeCode.mk2
-rw-r--r--luni/src/main/java/android/system/Os.java4
-rw-r--r--luni/src/main/java/java/net/AddressCache.java50
-rw-r--r--luni/src/main/java/java/net/InetAddress.java61
-rw-r--r--luni/src/main/java/libcore/io/ForwardingOs.java2
-rw-r--r--luni/src/main/java/libcore/io/Os.java2
-rw-r--r--luni/src/main/java/libcore/io/Posix.java2
-rw-r--r--luni/src/main/native/Portability.h9
-rw-r--r--luni/src/main/native/libcore_io_Posix.cpp14
9 files changed, 110 insertions, 36 deletions
diff --git a/NativeCode.mk b/NativeCode.mk
index 733f62e..429360a 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -66,7 +66,7 @@ $(foreach dir, \
core_c_includes := libcore/include $(LOCAL_C_INCLUDES)
core_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
core_static_libraries := $(LOCAL_STATIC_LIBRARIES)
-core_cflags := -Wall -Wextra -Werror
+core_cflags := $(LOCAL_CFLAGS) -Wall -Wextra -Werror
core_cppflags += -std=gnu++11
core_test_files := \
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index beb785f..0b80b52 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -61,6 +61,8 @@ public final class Os {
*/
public static boolean access(String path, int mode) throws ErrnoException { return Libcore.os.access(path, mode); }
+ /** @hide */ public static InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return Libcore.os.android_getaddrinfo(node, hints, netId); }
+
/**
* See <a href="http://man7.org/linux/man-pages/man2/bind.2.html">bind(2)</a>.
*/
@@ -155,8 +157,6 @@ public final class Os {
*/
public static String gai_strerror(int error) { return Libcore.os.gai_strerror(error); }
- /** @hide */ public static InetAddress[] getaddrinfo(String node, StructAddrinfo hints) throws GaiException { return Libcore.os.getaddrinfo(node, hints); }
-
/**
* See <a href="http://man7.org/linux/man-pages/man2/getegid.2.html">getegid(2)</a>.
*/
diff --git a/luni/src/main/java/java/net/AddressCache.java b/luni/src/main/java/java/net/AddressCache.java
index 194761a..2aba78b 100644
--- a/luni/src/main/java/java/net/AddressCache.java
+++ b/luni/src/main/java/java/net/AddressCache.java
@@ -37,8 +37,36 @@ class AddressCache {
private static final long TTL_NANOS = 2 * 1000000000L;
// The actual cache.
- private final BasicLruCache<String, AddressCacheEntry> cache
- = new BasicLruCache<String, AddressCacheEntry>(MAX_ENTRIES);
+ private final BasicLruCache<AddressCacheKey, AddressCacheEntry> cache
+ = new BasicLruCache<AddressCacheKey, AddressCacheEntry>(MAX_ENTRIES);
+
+ static class AddressCacheKey {
+ private final String mHostname;
+ private final int mNetId;
+
+ AddressCacheKey(String hostname, int netId) {
+ mHostname = hostname;
+ mNetId = netId;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof AddressCacheKey)) {
+ return false;
+ }
+ AddressCacheKey lhs = (AddressCacheKey) o;
+ return mHostname.equals(lhs.mHostname) && mNetId == lhs.mNetId;
+ }
+
+ @Override public int hashCode() {
+ int result = 17;
+ result = 31 * result + mNetId;
+ result = 31 * result + mHostname.hashCode();
+ return result;
+ }
+ }
static class AddressCacheEntry {
// Either an InetAddress[] for a positive entry,
@@ -67,12 +95,12 @@ class AddressCache {
}
/**
- * Returns the cached InetAddress[] associated with 'hostname'. Returns null if nothing is known
- * about 'hostname'. Returns a String suitable for use as an UnknownHostException detail
- * message if 'hostname' is known not to exist.
+ * Returns the cached InetAddress[] for 'hostname' on network 'netId'. Returns null
+ * if nothing is known about 'hostname'. Returns a String suitable for use as an
+ * UnknownHostException detail message if 'hostname' is known not to exist.
*/
- public Object get(String hostname) {
- AddressCacheEntry entry = cache.get(hostname);
+ public Object get(String hostname, int netId) {
+ AddressCacheEntry entry = cache.get(new AddressCacheKey(hostname, netId));
// Do we have a valid cache entry?
if (entry != null && entry.expiryNanos >= System.nanoTime()) {
return entry.value;
@@ -86,15 +114,15 @@ class AddressCache {
* Associates the given 'addresses' with 'hostname'. The association will expire after a
* certain length of time.
*/
- public void put(String hostname, InetAddress[] addresses) {
- cache.put(hostname, new AddressCacheEntry(addresses));
+ public void put(String hostname, int netId, InetAddress[] addresses) {
+ cache.put(new AddressCacheKey(hostname, netId), new AddressCacheEntry(addresses));
}
/**
* Records that 'hostname' is known not to have any associated addresses. (I.e. insert a
* negative cache entry.)
*/
- public void putUnknownHost(String hostname, String detailMessage) {
- cache.put(hostname, new AddressCacheEntry(detailMessage));
+ public void putUnknownHost(String hostname, int netId, String detailMessage) {
+ cache.put(new AddressCacheKey(hostname, netId), new AddressCacheEntry(detailMessage));
}
}
diff --git a/luni/src/main/java/java/net/InetAddress.java b/luni/src/main/java/java/net/InetAddress.java
index e31b4c3..5cfa15a 100644
--- a/luni/src/main/java/java/net/InetAddress.java
+++ b/luni/src/main/java/java/net/InetAddress.java
@@ -127,6 +127,9 @@ public class InetAddress implements Serializable {
private static final long serialVersionUID = 3286316764910316507L;
+ /** Using NetID of NETID_UNSET indicates resolution should be done on default network. */
+ private static final int NETID_UNSET = 0;
+
private int family;
byte[] ipaddress;
@@ -209,14 +212,29 @@ public class InetAddress implements Serializable {
* @throws UnknownHostException if the address lookup fails.
*/
public static InetAddress[] getAllByName(String host) throws UnknownHostException {
- return getAllByNameImpl(host).clone();
+ return getAllByNameImpl(host, NETID_UNSET).clone();
}
/**
- * Returns the InetAddresses for {@code host}. The returned array is shared
- * and must be cloned before it is returned to application code.
+ * 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 internal use only
*/
- private static InetAddress[] getAllByNameImpl(String host) throws UnknownHostException {
+ public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
+ return getAllByNameImpl(host, netId).clone();
+ }
+
+ /**
+ * Returns the InetAddresses for {@code host} on network {@code netId}. The
+ * returned array is shared and must be cloned before it is returned to
+ * application code.
+ */
+ private static InetAddress[] getAllByNameImpl(String host, int netId) throws UnknownHostException {
if (host == null || host.isEmpty()) {
return loopbackAddresses();
}
@@ -231,7 +249,7 @@ public class InetAddress implements Serializable {
return new InetAddress[] { result };
}
- return lookupHostByName(host).clone();
+ return lookupHostByName(host, netId).clone();
}
private static InetAddress makeInetAddress(byte[] bytes, String hostName) throws UnknownHostException {
@@ -264,7 +282,7 @@ public class InetAddress implements Serializable {
hints.ai_flags = AI_NUMERICHOST;
InetAddress[] addresses = null;
try {
- addresses = Libcore.os.getaddrinfo(address, hints);
+ addresses = Libcore.os.android_getaddrinfo(address, hints, NETID_UNSET);
} catch (GaiException ignored) {
}
return (addresses != null) ? addresses[0] : null;
@@ -284,7 +302,22 @@ public class InetAddress implements Serializable {
* if the address lookup fails.
*/
public static InetAddress getByName(String host) throws UnknownHostException {
- return getAllByNameImpl(host)[0];
+ return getAllByNameImpl(host, NETID_UNSET)[0];
+ }
+
+ /**
+ * 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 internal use only
+ */
+ public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException {
+ return getAllByNameImpl(host, netId)[0];
}
/**
@@ -360,7 +393,7 @@ public class InetAddress implements Serializable {
*/
public static InetAddress getLocalHost() throws UnknownHostException {
String host = Libcore.os.uname().nodename;
- return lookupHostByName(host)[0];
+ return lookupHostByName(host, NETID_UNSET)[0];
}
/**
@@ -377,12 +410,14 @@ public class InetAddress implements Serializable {
* Resolves a hostname to its IP addresses using a cache.
*
* @param host the hostname to resolve.
+ * @param netId the network to perform resolution upon.
* @return the IP addresses of the host.
*/
- private static InetAddress[] lookupHostByName(String host) throws UnknownHostException {
+ private static InetAddress[] lookupHostByName(String host, int netId)
+ throws UnknownHostException {
BlockGuard.getThreadPolicy().onNetwork();
// Do we have a result cached?
- Object cachedResult = addressCache.get(host);
+ Object cachedResult = addressCache.get(host, netId);
if (cachedResult != null) {
if (cachedResult instanceof InetAddress[]) {
// A cached positive result.
@@ -400,12 +435,12 @@ public class InetAddress implements Serializable {
// for SOCK_STREAM and one for SOCK_DGRAM. Since we do not return the family
// anyway, just pick one.
hints.ai_socktype = SOCK_STREAM;
- InetAddress[] addresses = Libcore.os.getaddrinfo(host, hints);
+ InetAddress[] addresses = Libcore.os.android_getaddrinfo(host, hints, netId);
// TODO: should getaddrinfo set the hostname of the InetAddresses it returns?
for (InetAddress address : addresses) {
address.hostName = host;
}
- addressCache.put(host, addresses);
+ addressCache.put(host, netId, addresses);
return addresses;
} catch (GaiException gaiException) {
// If the failure appears to have been a lack of INTERNET permission, throw a clear
@@ -418,7 +453,7 @@ public class InetAddress implements Serializable {
}
// Otherwise, throw an UnknownHostException.
String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error);
- addressCache.putUnknownHost(host, detailMessage);
+ addressCache.putUnknownHost(host, netId, detailMessage);
throw gaiException.rethrowAsUnknownHostException(detailMessage);
}
}
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index d09e442..bf4b448 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -52,6 +52,7 @@ public class ForwardingOs implements Os {
public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return os.accept(fd, peerAddress); }
public boolean access(String path, int mode) throws ErrnoException { return os.access(path, mode); }
+ public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return os.android_getaddrinfo(node, hints, netId); }
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
public void chown(String path, int uid, int gid) throws ErrnoException { os.chown(path, uid, gid); }
@@ -73,7 +74,6 @@ public class ForwardingOs implements Os {
public void fsync(FileDescriptor fd) throws ErrnoException { os.fsync(fd); }
public void ftruncate(FileDescriptor fd, long length) throws ErrnoException { os.ftruncate(fd, length); }
public String gai_strerror(int error) { return os.gai_strerror(error); }
- public InetAddress[] getaddrinfo(String node, StructAddrinfo hints) throws GaiException { return os.getaddrinfo(node, hints); }
public int getegid() { return os.getegid(); }
public int geteuid() { return os.geteuid(); }
public int getgid() { return os.getgid(); }
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index a537aeb..511bb27 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -43,6 +43,7 @@ import java.nio.ByteBuffer;
public interface Os {
public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException;
public boolean access(String path, int mode) throws ErrnoException;
+ public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public void chmod(String path, int mode) throws ErrnoException;
public void chown(String path, int uid, int gid) throws ErrnoException;
@@ -64,7 +65,6 @@ public interface Os {
public void fsync(FileDescriptor fd) throws ErrnoException;
public void ftruncate(FileDescriptor fd, long length) throws ErrnoException;
public String gai_strerror(int error);
- public InetAddress[] getaddrinfo(String node, StructAddrinfo hints) throws GaiException;
public int getegid();
public int geteuid();
public int getgid();
diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java
index 7551190..f5eaaa3 100644
--- a/luni/src/main/java/libcore/io/Posix.java
+++ b/luni/src/main/java/libcore/io/Posix.java
@@ -46,6 +46,7 @@ public final class Posix implements Os {
public native FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException;
public native boolean access(String path, int mode) throws ErrnoException;
+ public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public native void chmod(String path, int mode) throws ErrnoException;
public native void chown(String path, int uid, int gid) throws ErrnoException;
@@ -67,7 +68,6 @@ public final class Posix implements Os {
public native void fsync(FileDescriptor fd) throws ErrnoException;
public native void ftruncate(FileDescriptor fd, long length) throws ErrnoException;
public native String gai_strerror(int error);
- public native InetAddress[] getaddrinfo(String node, StructAddrinfo hints) throws GaiException;
public native int getegid();
public native int geteuid();
public native int getgid();
diff --git a/luni/src/main/native/Portability.h b/luni/src/main/native/Portability.h
index 60b7062..3c8384d 100644
--- a/luni/src/main/native/Portability.h
+++ b/luni/src/main/native/Portability.h
@@ -74,6 +74,15 @@ static inline int mincore(void* addr, size_t length, unsigned char* vec) {
#include <sys/sendfile.h>
#include <sys/statvfs.h>
+#if !defined(__BIONIC__)
+#include <netdb.h>
+#include "../../bionic/libc/dns/include/resolv_netid.h"
+inline int android_getaddrinfofornet(const char *hostname, const char *servname,
+ const struct addrinfo *hints, unsigned /*netid*/, unsigned /*mark*/, struct addrinfo **res) {
+ return getaddrinfo(hostname, servname, hints, res);
+}
+#endif
+
#endif
#endif // PORTABILITY_H_included
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index b1217c0..6eee7f0 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -25,6 +25,7 @@
#include "NetworkUtilities.h"
#include "Portability.h"
#include "readlink.h"
+#include "../../bionic/libc/dns/include/resolv_netid.h" // For android_getaddrinfofornet.
#include "ScopedBytes.h"
#include "ScopedLocalRef.h"
#include "ScopedPrimitiveArray.h"
@@ -645,7 +646,8 @@ static jstring Posix_gai_strerror(JNIEnv* env, jobject, jint error) {
return env->NewStringUTF(gai_strerror(error));
}
-static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jobject javaHints) {
+static jobjectArray Posix_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,
+ jobject javaHints, jint netId) {
ScopedUtfChars node(env, javaNode);
if (node.c_str() == NULL) {
return NULL;
@@ -665,10 +667,10 @@ static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jo
addrinfo* addressList = NULL;
errno = 0;
- int rc = getaddrinfo(node.c_str(), NULL, &hints, &addressList);
+ int rc = android_getaddrinfofornet(node.c_str(), NULL, &hints, netId, 0, &addressList);
UniquePtr<addrinfo, addrinfo_deleter> addressListDeleter(addressList);
if (rc != 0) {
- throwGaiException(env, "getaddrinfo", rc);
+ throwGaiException(env, "android_getaddrinfo", rc);
return NULL;
}
@@ -678,7 +680,7 @@ static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jo
if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6) {
++addressCount;
} else {
- ALOGE("getaddrinfo unexpected ai_family %i", ai->ai_family);
+ ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);
}
}
if (addressCount == 0) {
@@ -696,7 +698,7 @@ static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jo
for (addrinfo* ai = addressList; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
// Unknown address family. Skip this address.
- ALOGE("getaddrinfo unexpected ai_family %i", ai->ai_family);
+ ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);
continue;
}
@@ -1499,6 +1501,7 @@ static jint Posix_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buff
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/InetSocketAddress;)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"),
+ NATIVE_METHOD(Posix, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
NATIVE_METHOD(Posix, chmod, "(Ljava/lang/String;I)V"),
NATIVE_METHOD(Posix, chown, "(Ljava/lang/String;II)V"),
@@ -1520,7 +1523,6 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, fsync, "(Ljava/io/FileDescriptor;)V"),
NATIVE_METHOD(Posix, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
NATIVE_METHOD(Posix, gai_strerror, "(I)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;)[Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, getegid, "()I"),
NATIVE_METHOD(Posix, geteuid, "()I"),
NATIVE_METHOD(Posix, getgid, "()I"),