Merge "Replace throwErrnoException with JNIHelp jniThrowException" am: 7d36391ba4

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1769765

Change-Id: I89b051b54202df96192dea0d868acce2b12159c6
This commit is contained in:
Mark Chien
2021-07-21 06:36:07 +00:00
committed by Automerger Merge Worker
3 changed files with 28 additions and 78 deletions

View File

@@ -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 kIPv6PayloadStart = sizeof(ip6_hdr);
static const uint32_t kICMPv6TypeOffset = kIPv6PayloadStart + offsetof(icmp6_hdr, icmp6_type); 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) { static void android_net_util_setupIcmpFilter(JNIEnv *env, jobject javaFd, uint32_t type) {
sock_filter filter_code[] = { sock_filter filter_code[] = {
// Check header is ICMPv6. // 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); int fd = netjniutils::GetNativeFileDescriptor(env, javaFd);
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) { if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "setsockopt(SO_ATTACH_FILTER)", errno);
"setsockopt(SO_ATTACH_FILTER): %s", strerror(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); ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only);
socklen_t len = sizeof(rs_only); socklen_t len = sizeof(rs_only);
if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) { if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "setsockopt(ICMP6_FILTER)", errno);
"setsockopt(ICMP6_FILTER): %s", strerror(errno));
return; return;
} }
@@ -97,8 +99,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j
int hops = kLinkLocalHopLimit; int hops = kLinkLocalHopLimit;
len = sizeof(hops); len = sizeof(hops);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) { if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "setsockopt(IPV6_MULTICAST_HOPS)", errno);
"setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno));
return; return;
} }
@@ -106,8 +107,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j
hops = kLinkLocalHopLimit; hops = kLinkLocalHopLimit;
len = sizeof(hops); len = sizeof(hops);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) { if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "setsockopt(IPV6_UNICAST_HOPS)", errno);
"setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno));
return; return;
} }
@@ -115,16 +115,14 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j
int off = 0; int off = 0;
len = sizeof(off); len = sizeof(off);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) { if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "setsockopt(IPV6_MULTICAST_LOOP)", errno);
"setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno));
return; return;
} }
// Specify the IPv6 interface to use for outbound multicast. // Specify the IPv6 interface to use for outbound multicast.
len = sizeof(ifIndex); len = sizeof(ifIndex);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) { if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "setsockopt(IPV6_MULTICAST_IF)", errno);
"setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno));
return; return;
} }
@@ -144,8 +142,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j
auto sa = reinterpret_cast<const struct sockaddr *>(&sin6); auto sa = reinterpret_cast<const struct sockaddr *>(&sin6);
len = sizeof(sin6); len = sizeof(sin6);
if (bind(fd, sa, len) != 0) { if (bind(fd, sa, len) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "bind(IN6ADDR_ANY)", errno);
"bind(IN6ADDR_ANY): %s", strerror(errno));
return; return;
} }
@@ -156,8 +153,7 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j
}; };
len = sizeof(all_rtrs); len = sizeof(all_rtrs);
if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) { if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException", throwSocketException(env, "setsockopt(IPV6_JOIN_GROUP)", errno);
"setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno));
return; return;
} }
} }

View File

@@ -27,40 +27,11 @@
namespace android { 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, static jint com_android_networkstack_tethering_BpfMap_closeMap(JNIEnv *env, jobject clazz,
jint fd) { jint fd) {
int ret = close(fd); int ret = close(fd);
if (ret) throwErrnoException(env, "closeMap", errno); if (ret) jniThrowErrnoException(env, "closeMap", errno);
return ret; return ret;
} }
@@ -82,13 +53,13 @@ static void com_android_networkstack_tethering_BpfMap_writeToMapEntry(JNIEnv *en
int ret = bpf::writeToMapEntry(static_cast<int>(fd), keyRO.get(), valueRO.get(), int ret = bpf::writeToMapEntry(static_cast<int>(fd), keyRO.get(), valueRO.get(),
static_cast<int>(flags)); 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) { static jboolean throwIfNotEnoent(JNIEnv *env, const char* functionName, int ret, int err) {
if (ret == 0) return true; if (ret == 0) return true;
if (err != ENOENT) throwErrnoException(env, functionName, err); if (err != ENOENT) jniThrowErrnoException(env, functionName, err);
return false; return false;
} }
@@ -155,18 +126,6 @@ static const JNINativeMethod gMethods[] = {
}; };
int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env) { 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, return jniRegisterNativeMethods(env,
"com/android/networkstack/tethering/BpfMap", "com/android/networkstack/tethering/BpfMap",
gMethods, NELEM(gMethods)); gMethods, NELEM(gMethods));

View File

@@ -44,37 +44,36 @@ namespace android {
const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK; const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0}; 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 // TODO: move to frameworks/libs/net/common/native for sharing with
// system/netd/server/OffloadUtils.{c, h}. // system/netd/server/OffloadUtils.{c, h}.
static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len) { 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 int fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); // TODO: use unique_fd
if (fd == -1) { if (fd == -1) {
jniThrowExceptionFmt(env, "java/io/IOException", throwIOException(env, "socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE)", errno);
"socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE): %s",
strerror(errno));
return; return;
} }
static constexpr int on = 1; static constexpr int on = 1;
if (setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on))) { if (setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on))) {
jniThrowExceptionFmt(env, "java/io/IOException", throwIOException(env, "setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, 1)", errno);
"setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, %d)", on);
close(fd); close(fd);
return; return;
} }
// this is needed to get valid strace netlink parsing, it allocates the pid // this is needed to get valid strace netlink parsing, it allocates the pid
if (bind(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) { if (bind(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) {
jniThrowExceptionFmt(env, "java/io/IOException", "bind(fd, {AF_NETLINK, 0, 0}): %s", throwIOException(env, "bind(fd, {AF_NETLINK, 0, 0})", errno);
strerror(errno));
close(fd); close(fd);
return; return;
} }
// we do not want to receive messages from anyone besides the kernel // we do not want to receive messages from anyone besides the kernel
if (connect(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) { if (connect(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR))) {
jniThrowExceptionFmt(env, "java/io/IOException", "connect(fd, {AF_NETLINK, 0, 0}): %s", throwIOException(env, "connect(fd, {AF_NETLINK, 0, 0})", errno);
strerror(errno));
close(fd); close(fd);
return; return;
} }
@@ -82,15 +81,13 @@ static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len)
int rv = send(fd, req, len, 0); int rv = send(fd, req, len, 0);
if (rv == -1) { if (rv == -1) {
jniThrowExceptionFmt(env, "java/io/IOException", "send(fd, req, len, 0): %s", throwIOException(env, "send(fd, req, len, 0)", errno);
strerror(errno));
close(fd); close(fd);
return; return;
} }
if (rv != len) { if (rv != len) {
jniThrowExceptionFmt(env, "java/io/IOException", "send(fd, req, len, 0): %s", throwIOException(env, "send(fd, req, len, 0)", EMSGSIZE);
strerror(EMSGSIZE));
close(fd); close(fd);
return; return;
} }
@@ -104,7 +101,7 @@ static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len)
rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC); rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC);
if (rv == -1) { if (rv == -1) {
jniThrowExceptionFmt(env, "java/io/IOException", "recv() failed: %s", strerror(errno)); throwIOException(env, "recv() failed", errno);
close(fd); close(fd);
return; return;
} }
@@ -131,8 +128,7 @@ static void sendAndProcessNetlinkResponse(JNIEnv* env, const void* req, int len)
} }
if (resp.e.error) { // returns 0 on success if (resp.e.error) { // returns 0 on success
jniThrowExceptionFmt(env, "java/io/IOException", "NLMSG_ERROR message return error: %s", throwIOException(env, "NLMSG_ERROR message return error", -resp.e.error);
strerror(-resp.e.error));
} }
close(fd); close(fd);
return; return;
@@ -198,8 +194,7 @@ static void com_android_networkstack_tethering_BpfUtils_tcFilterAddDevBpf(
const int bpfFd = bpf::retrieveProgram(pathname.c_str()); const int bpfFd = bpf::retrieveProgram(pathname.c_str());
if (bpfFd == -1) { if (bpfFd == -1) {
jniThrowExceptionFmt(env, "java/io/IOException", "retrieveProgram failed %s", throwIOException(env, "retrieveProgram failed", errno);
strerror(errno));
return; return;
} }