From 083606292bfd3445046144aeccecc4b9e0c39352 Mon Sep 17 00:00:00 2001 From: markchien Date: Fri, 16 Jul 2021 23:07:19 +0800 Subject: [PATCH] Replace throwErrnoException with JNIHelp jniThrowException Rather than adding throwErrnoException local function, using standard jniThrowException in JNIHelp.h. Also improve the readability: 1. Use throwIOException for jniThrowExceptionFmt(env, "java/io/IOException", ...); 2. Use throwSoecktException for jniThrowExceptionFmt(env, "java/net/SocketException", ...); then the code can fit to one line. Test: atest TetheringPrivilegedTests (ErrnoException is test in BpfMapTest) Change-Id: I396771e2c68e319f510d7a4ea5f263d18d7fad9d --- .../jni/android_net_util_TetheringUtils.cpp | 28 +++++------ ..._android_networkstack_tethering_BpfMap.cpp | 47 ++----------------- ...ndroid_networkstack_tethering_BpfUtils.cpp | 31 +++++------- 3 files changed, 28 insertions(+), 78 deletions(-) diff --git a/Tethering/jni/android_net_util_TetheringUtils.cpp b/Tethering/jni/android_net_util_TetheringUtils.cpp index 27c84cf280..2e76501cae 100644 --- a/Tethering/jni/android_net_util_TetheringUtils.cpp +++ b/Tethering/jni/android_net_util_TetheringUtils.cpp @@ -34,6 +34,10 @@ static const uint32_t kIPv6NextHeaderOffset = offsetof(ip6_hdr, ip6_nxt); static const uint32_t kIPv6PayloadStart = sizeof(ip6_hdr); static const uint32_t kICMPv6TypeOffset = kIPv6PayloadStart + offsetof(icmp6_hdr, icmp6_type); +static void throwSocketException(JNIEnv *env, const char* msg, int error) { + jniThrowExceptionFmt(env, "java/net/SocketException", "%s: %s", msg, strerror(error)); +} + static void android_net_util_setupIcmpFilter(JNIEnv *env, jobject javaFd, uint32_t type) { sock_filter filter_code[] = { // Check header is ICMPv6. @@ -56,8 +60,7 @@ static void android_net_util_setupIcmpFilter(JNIEnv *env, jobject javaFd, uint32 int fd = netjniutils::GetNativeFileDescriptor(env, javaFd); if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno)); + throwSocketException(env, "setsockopt(SO_ATTACH_FILTER)", errno); } } @@ -84,8 +87,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only); socklen_t len = sizeof(rs_only); if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(ICMP6_FILTER): %s", strerror(errno)); + throwSocketException(env, "setsockopt(ICMP6_FILTER)", errno); return; } @@ -97,8 +99,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j int hops = kLinkLocalHopLimit; len = sizeof(hops); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno)); + throwSocketException(env, "setsockopt(IPV6_MULTICAST_HOPS)", errno); return; } @@ -106,8 +107,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j hops = kLinkLocalHopLimit; len = sizeof(hops); if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno)); + throwSocketException(env, "setsockopt(IPV6_UNICAST_HOPS)", errno); return; } @@ -115,16 +115,14 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j int off = 0; len = sizeof(off); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno)); + throwSocketException(env, "setsockopt(IPV6_MULTICAST_LOOP)", errno); return; } // Specify the IPv6 interface to use for outbound multicast. len = sizeof(ifIndex); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno)); + throwSocketException(env, "setsockopt(IPV6_MULTICAST_IF)", errno); return; } @@ -144,8 +142,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j auto sa = reinterpret_cast(&sin6); len = sizeof(sin6); if (bind(fd, sa, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "bind(IN6ADDR_ANY): %s", strerror(errno)); + throwSocketException(env, "bind(IN6ADDR_ANY)", errno); return; } @@ -156,8 +153,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j }; len = sizeof(all_rtrs); if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno)); + throwSocketException(env, "setsockopt(IPV6_JOIN_GROUP)", errno); return; } } diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp index eadc210e31..7970a238ab 100644 --- a/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp +++ b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp @@ -27,40 +27,11 @@ namespace android { -static jclass sErrnoExceptionClass; -static jmethodID sErrnoExceptionCtor2; -static jmethodID sErrnoExceptionCtor3; - -static void throwErrnoException(JNIEnv* env, const char* functionName, int error) { - if (sErrnoExceptionClass == nullptr || sErrnoExceptionClass == nullptr) return; - - jthrowable cause = nullptr; - if (env->ExceptionCheck()) { - cause = env->ExceptionOccurred(); - env->ExceptionClear(); - } - - ScopedLocalRef msg(env, env->NewStringUTF(functionName)); - - // Not really much we can do here if msg is null, let's try to stumble on... - if (msg.get() == nullptr) env->ExceptionClear(); - - jobject errnoException; - if (cause != nullptr) { - errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor3, msg.get(), - error, cause); - } else { - errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor2, msg.get(), - error); - } - env->Throw(static_cast(errnoException)); -} - static jint com_android_networkstack_tethering_BpfMap_closeMap(JNIEnv *env, jobject clazz, jint fd) { int ret = close(fd); - if (ret) throwErrnoException(env, "closeMap", errno); + if (ret) jniThrowErrnoException(env, "closeMap", errno); return ret; } @@ -82,13 +53,13 @@ static void com_android_networkstack_tethering_BpfMap_writeToMapEntry(JNIEnv *en int ret = bpf::writeToMapEntry(static_cast(fd), keyRO.get(), valueRO.get(), static_cast(flags)); - if (ret) throwErrnoException(env, "writeToMapEntry", errno); + if (ret) jniThrowErrnoException(env, "writeToMapEntry", errno); } static jboolean throwIfNotEnoent(JNIEnv *env, const char* functionName, int ret, int err) { if (ret == 0) return true; - if (err != ENOENT) throwErrnoException(env, functionName, err); + if (err != ENOENT) jniThrowErrnoException(env, functionName, err); return false; } @@ -155,18 +126,6 @@ static const JNINativeMethod gMethods[] = { }; int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env) { - sErrnoExceptionClass = static_cast(env->NewGlobalRef( - env->FindClass("android/system/ErrnoException"))); - if (sErrnoExceptionClass == nullptr) return JNI_ERR; - - sErrnoExceptionCtor2 = env->GetMethodID(sErrnoExceptionClass, "", - "(Ljava/lang/String;I)V"); - if (sErrnoExceptionCtor2 == nullptr) return JNI_ERR; - - sErrnoExceptionCtor3 = env->GetMethodID(sErrnoExceptionClass, "", - "(Ljava/lang/String;ILjava/lang/Throwable;)V"); - if (sErrnoExceptionCtor3 == nullptr) return JNI_ERR; - return jniRegisterNativeMethods(env, "com/android/networkstack/tethering/BpfMap", gMethods, NELEM(gMethods)); diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp index 2fb59858e4..2d679a853f 100644 --- a/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp +++ b/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp @@ -44,37 +44,36 @@ namespace android { const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK; const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0}; +static void throwIOException(JNIEnv *env, const char* msg, int error) { + jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg, strerror(error)); +} + // TODO: move to frameworks/libs/net/common/native for sharing with // system/netd/server/OffloadUtils.{c, h}. static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len) { int fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); // TODO: use unique_fd if (fd == -1) { - jniThrowExceptionFmt(env, "java/io/IOException", - "socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE): %s", - strerror(errno)); + throwIOException(env, "socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE)", errno); return; } static constexpr int on = 1; if (setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on))) { - jniThrowExceptionFmt(env, "java/io/IOException", - "setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, %d)", on); + throwIOException(env, "setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, 1)", errno); close(fd); return; } // this is needed to get valid strace netlink parsing, it allocates the pid if (bind(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) { - jniThrowExceptionFmt(env, "java/io/IOException", "bind(fd, {AF_NETLINK, 0, 0}): %s", - strerror(errno)); + throwIOException(env, "bind(fd, {AF_NETLINK, 0, 0})", errno); close(fd); return; } // we do not want to receive messages from anyone besides the kernel if (connect(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) { - jniThrowExceptionFmt(env, "java/io/IOException", "connect(fd, {AF_NETLINK, 0, 0}): %s", - strerror(errno)); + throwIOException(env, "connect(fd, {AF_NETLINK, 0, 0})", errno); close(fd); return; } @@ -82,15 +81,13 @@ static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len) int rv = send(fd, req, len, 0); if (rv == -1) { - jniThrowExceptionFmt(env, "java/io/IOException", "send(fd, req, len, 0): %s", - strerror(errno)); + throwIOException(env, "send(fd, req, len, 0)", errno); close(fd); return; } if (rv != len) { - jniThrowExceptionFmt(env, "java/io/IOException", "send(fd, req, len, 0): %s", - strerror(EMSGSIZE)); + throwIOException(env, "send(fd, req, len, 0)", EMSGSIZE); close(fd); return; } @@ -104,7 +101,7 @@ static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len) rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC); if (rv == -1) { - jniThrowExceptionFmt(env, "java/io/IOException", "recv() failed: %s", strerror(errno)); + throwIOException(env, "recv() failed", errno); close(fd); return; } @@ -131,8 +128,7 @@ static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len) } if (resp.e.error) { // returns 0 on success - jniThrowExceptionFmt(env, "java/io/IOException", "NLMSG_ERROR message return error: %s", - strerror(-resp.e.error)); + throwIOException(env, "NLMSG_ERROR message return error", -resp.e.error); } close(fd); return; @@ -198,8 +194,7 @@ static void com_android_networkstack_tethering_BpfUtils_tcFilterAddDevBpf( const int bpfFd = bpf::retrieveProgram(pathname.c_str()); if (bpfFd == -1) { - jniThrowExceptionFmt(env, "java/io/IOException", "retrieveProgram failed %s", - strerror(errno)); + throwIOException(env, "retrieveProgram failed", errno); return; }