diff options
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | api/system-current.txt | 1 | ||||
-rw-r--r-- | core/java/android/net/Network.java | 29 | ||||
-rw-r--r-- | native/android/Android.mk | 10 | ||||
-rw-r--r-- | native/android/net.c | 85 |
5 files changed, 123 insertions, 3 deletions
diff --git a/api/current.txt b/api/current.txt index 8d8ee3b..912535f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -18202,6 +18202,7 @@ package android.net { method public int describeContents(); method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException; method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException; + method public long getNetworkHandle(); method public javax.net.SocketFactory getSocketFactory(); method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException; method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException; diff --git a/api/system-current.txt b/api/system-current.txt index f071534..28e8e7f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -19656,6 +19656,7 @@ package android.net { method public int describeContents(); method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException; method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException; + method public long getNetworkHandle(); method public javax.net.SocketFactory getSocketFactory(); method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException; method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException; diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index 65d325a1..67ecb5d 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -340,6 +340,35 @@ public class Network implements Parcelable { } } + /** + * Returns a handle representing this {@code Network}, for use with the NDK API. + */ + public long getNetworkHandle() { + // The network handle is explicitly not the same as the netId. + // + // The netId is an implementation detail which might be changed in the + // future, or which alone (i.e. in the absence of some additional + // context) might not be sufficient to fully identify a Network. + // + // As such, the intention is to prevent accidental misuse of the API + // that might result if a developer assumed that handles and netIds + // were identical and passing a netId to a call expecting a handle + // "just worked". Such accidental misuse, if widely deployed, might + // prevent future changes to the semantics of the netId field or + // inhibit the expansion of state required for Network objects. + // + // This extra layer of indirection might be seen as paranoia, and might + // never end up being necessary, but the added complexity is trivial. + // At some future date it may be desirable to realign the handle with + // Multiple Provisioning Domains API recommendations, as made by the + // IETF mif working group. + // + // The HANDLE_MAGIC value MUST be kept in sync with the corresponding + // value in the native/android/net.c NDK implementation. + final long HANDLE_MAGIC = 0xfacade; + return (((long) netId) << 32) | HANDLE_MAGIC; + } + // implement the Parcelable interface public int describeContents() { return 0; diff --git a/native/android/Android.mk b/native/android/Android.mk index b3a74a8..12fdf71 100644 --- a/native/android/Android.mk +++ b/native/android/Android.mk @@ -12,9 +12,10 @@ LOCAL_SRC_FILES:= \ looper.cpp \ native_activity.cpp \ native_window.cpp \ + net.c \ obb.cpp \ sensor.cpp \ - storage_manager.cpp + storage_manager.cpp \ LOCAL_SHARED_LIBRARIES := \ liblog \ @@ -25,14 +26,17 @@ LOCAL_SHARED_LIBRARIES := \ libbinder \ libui \ libgui \ - libandroid_runtime + libandroid_runtime \ + libnetd_client \ LOCAL_STATIC_LIBRARIES := \ libstorage LOCAL_C_INCLUDES += \ frameworks/base/native/include \ - frameworks/base/core/jni/android + frameworks/base/core/jni/android \ + bionic/libc/dns/include \ + system/netd/include \ LOCAL_MODULE := libandroid diff --git a/native/android/net.c b/native/android/net.c new file mode 100644 index 0000000..de4b90c --- /dev/null +++ b/native/android/net.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <android/multinetwork.h> +#include <errno.h> +#include <NetdClient.h> // the functions that communicate with netd +#include <resolv_netid.h> // android_getaddrinfofornet() +#include <stdlib.h> +#include <sys/limits.h> + + +static int getnetidfromhandle(net_handle_t handle, unsigned *netid) { + static const uint32_t k32BitMask = 0xffffffff; + // This value MUST be kept in sync with the corresponding value in + // the android.net.Network#getNetworkHandle() implementation. + static const uint32_t kHandleMagic = 0xfacade; + + // Check for minimum acceptable version of the API in the low bits. + if (handle != NETWORK_UNSPECIFIED && + (handle & k32BitMask) != kHandleMagic) { + return 0; + } + + if (netid != NULL) { + *netid = ((handle >> (CHAR_BIT * sizeof(k32BitMask))) & k32BitMask); + } + return 1; +} + + +int android_setsocknetwork(net_handle_t network, int fd) { + unsigned netid; + if (!getnetidfromhandle(network, &netid)) { + errno = EINVAL; + return -1; + } + + int rval = setNetworkForSocket(netid, fd); + if (rval < 0) { + errno = -rval; + rval = -1; + } + return rval; +} + +int android_setprocnetwork(net_handle_t network) { + unsigned netid; + if (!getnetidfromhandle(network, &netid)) { + errno = EINVAL; + return -1; + } + + int rval = setNetworkForProcess(netid); + if (rval < 0) { + errno = -rval; + rval = -1; + } + return rval; +} + +int android_getaddrinfofornetwork(net_handle_t network, + const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res) { + unsigned netid; + if (!getnetidfromhandle(network, &netid)) { + errno = EINVAL; + return EAI_SYSTEM; + } + + return android_getaddrinfofornet(node, service, hints, netid, 0, res); +} |