Commit 856f726d authored by Max Lv's avatar Max Lv

Refine sendFD #2030

parent c60f7be7
......@@ -48,7 +48,19 @@ public class JniHelper {
System.loadLibrary("jni-helper");
}
public static native void sendFd(int fd, @NonNull String path) throws ErrnoException;
public static void sendFd(int fd, @NonNull String path) throws ErrnoException {
int[] ret = sendFdInternal(fd, path);
if (ret != null) {
if (ret[0] == -1)
throw new ErrnoException("socket", ret[1]);
else if (ret[0] == -2)
throw new ErrnoException("connect", ret[1]);
else if (ret[0] == -3)
throw new ErrnoException("ancil_send_fd", ret[1]);
}
}
public static native int[] sendFdInternal(int fd, @NonNull String path) throws ErrnoException;
@Nullable
public static native byte[] parseNumericAddress(@NonNull String str);
}
......@@ -169,7 +169,9 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
super.startNativeProcesses()
sendFd(startVpn())
val fd = startVpn()
sendFd(fd)
}
override fun buildAdditionalArguments(cmd: ArrayList<String>): ArrayList<String> {
......@@ -246,13 +248,8 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
cmd += "--dnsgw"
cmd += "127.0.0.1:${DataStore.portLocalDns}"
}
data.processes.start(cmd) {
try {
sendFd(fd)
} catch (e: ErrnoException) {
stopRunner(true, e.message)
}
}
data.processes.start(cmd)
return fd
}
......@@ -261,11 +258,11 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
var tries = 0
val path = File(Core.deviceStorage.noBackupFilesDir, "sock_path").absolutePath
while (true) try {
Thread.sleep(30L shl tries)
Thread.sleep(500L shl tries)
JniHelper.sendFd(fd, path)
return
} catch (e: ErrnoException) {
if (tries >= 10) throw e
if (tries >= 3) throw e
tries += 1
}
}
......
Subproject commit 58f8a8883e51e5cb97391c4b6733ce255bf11f95
Subproject commit 9965ce070a5330602a71e97fdd41213e1fdd8d6d
......@@ -10,35 +10,26 @@
using namespace std;
// Based on: https://android.googlesource.com/platform/libcore/+/564c7e8/luni/src/main/native/libcore_io_Linux.cpp#256
static void throwException(JNIEnv* env, jclass exceptionClass, jmethodID ctor2, const char* functionName, int error) {
jstring detailMessage = env->NewStringUTF(functionName);
if (detailMessage == NULL) {
// Not really much we can do here. We're probably dead in the water,
// but let's try to stumble on...
env->ExceptionClear();
}
env->Throw(reinterpret_cast<jthrowable>(env->NewObject(exceptionClass, ctor2, detailMessage, error)));
env->DeleteLocalRef(detailMessage);
}
static void throwErrnoException(JNIEnv* env, const char* functionName) {
int error = errno;
static jclass ErrnoException = env->FindClass("android/system/ErrnoException");
static jmethodID ctor2 = env->GetMethodID(ErrnoException, "<init>", "(Ljava/lang/String;I)V");
throwException(env, ErrnoException, ctor2, functionName, error);
}
// return -1 for socket error
// return -2 for connect error
// return -3 for ancil_send_fd error
#pragma clang diagnostic ignored "-Wunused-parameter"
extern "C" {
JNIEXPORT void JNICALL
Java_com_github_shadowsocks_JniHelper_sendFd(JNIEnv *env, jobject thiz, jint tun_fd, jstring path) {
JNIEXPORT jintArray JNICALL
Java_com_github_shadowsocks_JniHelper_sendFdInternal(JNIEnv *env, jobject thiz, jint tun_fd, jstring path) {
int fd;
struct sockaddr_un addr;
const char *sock_str = env->GetStringUTFChars(path, 0);
jint info[2] = {0};
jintArray ret = env->NewIntArray(2);
if (ret == nullptr) {
goto quit3;
}
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
throwErrnoException(env, "socket");
info[0] = -1;
info[1] = errno;
goto quit2;
}
......@@ -47,17 +38,23 @@ JNIEXPORT void JNICALL
strncpy(addr.sun_path, sock_str, sizeof(addr.sun_path)-1);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
throwErrnoException(env, "connect");
info[0] = -2;
info[1] = errno;
goto quit;
}
if (ancil_send_fd(fd, tun_fd)) throwErrnoException(env, "ancil_send_fd");
if (ancil_send_fd(fd, tun_fd)) {
info[0] = -3;
info[1] = errno;
}
quit:
close(fd);
quit2:
env->ReleaseStringUTFChars(path, sock_str);
return;
env->SetIntArrayRegion(ret, 0, 2, info);
quit3:
return ret;
}
JNIEXPORT jbyteArray JNICALL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment