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
diff --git a/Tethering/jni/android_net_util_TetheringUtils.cpp b/Tethering/jni/android_net_util_TetheringUtils.cpp
index 27c84cf..2e76501 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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
auto sa = reinterpret_cast<const struct sockaddr *>(&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 @@
};
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 eadc210..7970a23 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<jstring> 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<jthrowable>(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 @@
int ret = bpf::writeToMapEntry(static_cast<int>(fd), keyRO.get(), valueRO.get(),
static_cast<int>(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 @@
};
int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env) {
- sErrnoExceptionClass = static_cast<jclass>(env->NewGlobalRef(
- env->FindClass("android/system/ErrnoException")));
- if (sErrnoExceptionClass == nullptr) return JNI_ERR;
-
- sErrnoExceptionCtor2 = env->GetMethodID(sErrnoExceptionClass, "<init>",
- "(Ljava/lang/String;I)V");
- if (sErrnoExceptionCtor2 == nullptr) return JNI_ERR;
-
- sErrnoExceptionCtor3 = env->GetMethodID(sErrnoExceptionClass, "<init>",
- "(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 2fb5985..2d679a8 100644
--- a/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfUtils.cpp
@@ -44,37 +44,36 @@
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 @@
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 @@
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 @@
}
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 @@
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;
}