diff --git a/core/jni/Android.bp b/core/jni/Android.bp index f49a834a96e03..f1fa5dbcbbdc5 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -238,6 +238,7 @@ cc_library_shared { "android.hardware.camera.device@3.2", "media_permission-aidl-cpp", "libandroidicu", + "libandroid_net", "libbpf_android", "libnetdbpf", "libnetdutils", diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index b01878b3070b5..85513cad489cb 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -285,6 +285,7 @@ LIBANDROID { ATrace_endAsyncSection; # introduced=29 ATrace_setCounter; # introduced=29 android_getaddrinfofornetwork; # introduced=23 + android_getprocnetwork; # introduced=31 android_setprocnetwork; # introduced=23 android_setsocknetwork; # introduced=23 android_res_cancel; # introduced=29 @@ -309,4 +310,4 @@ LIBANDROID_PLATFORM { ASurfaceControlStats_getAcquireTime*; ASurfaceControlStats_getFrameNumber*; }; -} LIBANDROID; \ No newline at end of file +} LIBANDROID; diff --git a/native/android/libandroid_net.map.txt b/native/android/libandroid_net.map.txt index 8d4e9009cc569..cc8dd727408f1 100644 --- a/native/android/libandroid_net.map.txt +++ b/native/android/libandroid_net.map.txt @@ -14,6 +14,8 @@ LIBANDROID_NET { android_res_nquery; # llndk android_res_nresult; # llndk android_res_nsend; # llndk + # These functions have been part of the NDK since API 31. + android_getprocnetwork; # llndk local: *; }; diff --git a/native/android/net.c b/native/android/net.c index a8104fc230417..d4b888845b27c 100644 --- a/native/android/net.c +++ b/native/android/net.c @@ -22,12 +22,13 @@ #include #include +// This value MUST be kept in sync with the corresponding value in +// the android.net.Network#getNetworkHandle() implementation. +static const uint32_t kHandleMagic = 0xcafed00d; +static const uint32_t kHandleMagicSize = 32; 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 = 0xcafed00d; // Check for minimum acceptable version of the API in the low bits. if (handle != NETWORK_UNSPECIFIED && @@ -41,6 +42,12 @@ static int getnetidfromhandle(net_handle_t handle, unsigned *netid) { return 1; } +static net_handle_t gethandlefromnetid(unsigned netid) { + if (netid == NETID_UNSET) { + return NETWORK_UNSPECIFIED; + } + return (((net_handle_t) netid) << kHandleMagicSize) | kHandleMagic; +} int android_setsocknetwork(net_handle_t network, int fd) { unsigned netid; @@ -72,6 +79,17 @@ int android_setprocnetwork(net_handle_t network) { return rval; } +int android_getprocnetwork(net_handle_t *network) { + if (network == NULL) { + errno = EINVAL; + return -1; + } + + unsigned netid = getNetworkForProcess(); + *network = gethandlefromnetid(netid); + return 0; +} + int android_getaddrinfofornetwork(net_handle_t network, const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp index 657d5a3d2eae7..3553c1f053109 100644 --- a/packages/Connectivity/framework/Android.bp +++ b/packages/Connectivity/framework/Android.bp @@ -128,6 +128,7 @@ cc_library_static { srcs: [ "jni/android_net_NetworkUtils.cpp", ], + shared_libs: ["libandroid_net"], apex_available: [ "//apex_available:platform", "com.android.tethering", @@ -140,6 +141,7 @@ cc_library_shared { srcs: [ "jni/onload.cpp", ], + shared_libs: ["libandroid"], static_libs: ["libconnectivityframeworkutils"], apex_available: [ "//apex_available:platform", diff --git a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp index c5b1ff8112609..c7c0beee5ba24 100644 --- a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp +++ b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -94,14 +95,21 @@ static void android_net_utils_detachBPFFilter(JNIEnv *env, jobject clazz, jobjec } } -static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId) +static jboolean android_net_utils_bindProcessToNetworkHandle(JNIEnv *env, jobject thiz, + jlong netHandle) { - return (jboolean) !setNetworkForProcess(netId); + return (jboolean) !android_setprocnetwork(netHandle); } -static jint android_net_utils_getBoundNetworkForProcess(JNIEnv *env, jobject thiz) +static jlong android_net_utils_getBoundNetworkHandleForProcess(JNIEnv *env, jobject thiz) { - return getNetworkForProcess(); + net_handle_t network; + if (android_getprocnetwork(&network) != 0) { + jniThrowExceptionFmt(env, "java/lang/IllegalStateException", + "android_getprocnetwork(): %s", strerror(errno)); + return NETWORK_UNSPECIFIED; + } + return (jlong) network; } static jboolean android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz, @@ -255,8 +263,8 @@ static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, j // clang-format off static const JNINativeMethod gNetworkUtilMethods[] = { /* name, signature, funcPtr */ - { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork }, - { "getBoundNetworkForProcess", "()I", (void*) android_net_utils_getBoundNetworkForProcess }, + { "bindProcessToNetworkHandle", "(J)Z", (void*) android_net_utils_bindProcessToNetworkHandle }, + { "getBoundNetworkHandleForProcess", "()J", (void*) android_net_utils_getBoundNetworkHandleForProcess }, { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution }, { "bindSocketToNetwork", "(Ljava/io/FileDescriptor;I)I", (void*) android_net_utils_bindSocketToNetwork }, { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess }, diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java index c4bebc0a982e3..16ae55f8c11e8 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java +++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java @@ -16,6 +16,8 @@ package android.net; +import static android.net.ConnectivityManager.NETID_UNSET; + import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.system.ErrnoException; @@ -55,6 +57,8 @@ public class NetworkUtils { */ public static native void detachBPFFilter(FileDescriptor fd) throws SocketException; + private static native boolean bindProcessToNetworkHandle(long netHandle); + /** * Binds the current process to the network designated by {@code netId}. All sockets created * in the future (and not explicitly bound via a bound {@link SocketFactory} (see @@ -63,13 +67,20 @@ public class NetworkUtils { * is by design so an application doesn't accidentally use sockets it thinks are still bound to * a particular {@code Network}. Passing NETID_UNSET clears the binding. */ - public native static boolean bindProcessToNetwork(int netId); + public static boolean bindProcessToNetwork(int netId) { + return bindProcessToNetworkHandle(new Network(netId).getNetworkHandle()); + } + + private static native long getBoundNetworkHandleForProcess(); /** * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}. */ - public native static int getBoundNetworkForProcess(); + public static int getBoundNetworkForProcess() { + final long netHandle = getBoundNetworkHandleForProcess(); + return netHandle == 0L ? NETID_UNSET : Network.fromNetworkHandle(netHandle).getNetId(); + } /** * Binds host resolutions performed by this process to the network designated by {@code netId}.