Merge "Replace throwErrnoException with JNIHelp jniThrowException"
This commit is contained in:
@@ -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<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 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 @@ static void com_android_networkstack_tethering_BpfMap_writeToMapEntry(JNIEnv *en
|
||||
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 @@ static const JNINativeMethod gMethods[] = {
|
||||
};
|
||||
|
||||
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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user