diff --git a/framework/jni/android_net_NetworkUtils.cpp b/framework/jni/android_net_NetworkUtils.cpp index 3779a00551..7404f32829 100644 --- a/framework/jni/android_net_NetworkUtils.cpp +++ b/framework/jni/android_net_NetworkUtils.cpp @@ -23,9 +23,9 @@ #include #include +#include // NETID_USE_LOCAL_NAMESERVERS #include #include -#include // NETID_USE_LOCAL_NAMESERVERS #include #include #include @@ -259,6 +259,21 @@ static jboolean android_net_utils_isKernelX86(JNIEnv *env, jclass clazz) { return bpf::isX86(); } +static jlong android_net_utils_getSocketCookie(JNIEnv *env, jclass clazz, + jobject javaFd) { + int sock = AFileDescriptor_getFd(env, javaFd); + uint64_t cookie = 0; + socklen_t cookie_len = sizeof(cookie); + if (getsockopt(sock, SOL_SOCKET, SO_COOKIE, &cookie, &cookie_len)) { + // Failure is almost certainly either EBADF or ENOTSOCK + jniThrowErrnoException(env, "getSocketCookie", errno); + } else if (cookie_len != sizeof(cookie)) { + // This probably cannot actually happen, but... + jniThrowErrnoException(env, "getSocketCookie", 523); // EBADCOOKIE + } + return static_cast(cookie); +} + // ---------------------------------------------------------------------------- /* @@ -283,6 +298,7 @@ static const JNINativeMethod gNetworkUtilMethods[] = { (void*) android_net_utils_setsockoptBytes}, { "isKernel64Bit", "()Z", (void*) android_net_utils_isKernel64Bit }, { "isKernelX86", "()Z", (void*) android_net_utils_isKernelX86 }, + { "getSocketCookie", "(Ljava/io/FileDescriptor;)J", (void*) android_net_utils_getSocketCookie }, }; // clang-format on diff --git a/framework/src/android/net/NetworkUtils.java b/framework/src/android/net/NetworkUtils.java index 18feb84c92..6b2eb08f7a 100644 --- a/framework/src/android/net/NetworkUtils.java +++ b/framework/src/android/net/NetworkUtils.java @@ -443,4 +443,13 @@ public class NetworkUtils { /** Returns whether the Linux Kernel is x86 */ public static native boolean isKernelX86(); + + /** + * Returns socket cookie. + * + * @param fd The socket file descriptor + * @return The socket cookie. + * @throws ErrnoException if retrieving the socket cookie fails. + */ + public static native long getSocketCookie(FileDescriptor fd) throws ErrnoException; }