From 6c7f62c237ddd6e655e5243776113e3457caae89 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 25 Nov 2014 08:59:30 +0800 Subject: [PATCH] pass the tun fd directly to tun2socks --- build.sh | 2 +- .../com/github/shadowsocks/Tun2Socks.java | 48 ------ src/main/jni/Android.mk | 8 +- src/main/jni/badvpn/tun2socks/tun2socks.c | 138 +----------------- src/main/jni/main-jni.cpp | 86 ----------- src/main/jni/tun2socks-jni.cpp | 79 ---------- .../com/github/shadowsocks/Shadowsocks.scala | 2 +- .../shadowsocks/ShadowsocksVpnService.scala | 20 +-- 8 files changed, 12 insertions(+), 371 deletions(-) delete mode 100755 src/main/java/com/github/shadowsocks/Tun2Socks.java delete mode 100644 src/main/jni/main-jni.cpp delete mode 100644 src/main/jni/tun2socks-jni.cpp diff --git a/build.sh b/build.sh index d4bc155b..14cfaff6 100755 --- a/build.sh +++ b/build.sh @@ -15,7 +15,7 @@ rm -rf assets/armeabi-v7a rm -rf assets/x86 mkdir -p assets/armeabi-v7a mkdir -p assets/x86 -for app in pdnsd redsocks ss-local ss-tunnel +for app in pdnsd redsocks ss-local ss-tunnel tun2socks do try mv libs/armeabi-v7a/$app assets/armeabi-v7a/ try mv libs/x86/$app assets/x86/ diff --git a/src/main/java/com/github/shadowsocks/Tun2Socks.java b/src/main/java/com/github/shadowsocks/Tun2Socks.java deleted file mode 100755 index 1bd34898..00000000 --- a/src/main/java/com/github/shadowsocks/Tun2Socks.java +++ /dev/null @@ -1,48 +0,0 @@ -/* Shadowsocks - A shadowsocks client for Android - * Copyright (C) 2014 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * - * ___====-_ _-====___ - * _--^^^#####// \\#####^^^--_ - * _-^##########// ( ) \\##########^-_ - * -############// |\^^/| \\############- - * _/############// (@::@) \\############\_ - * /#############(( \\// ))#############\ - * -###############\\ (oo) //###############- - * -#################\\ / VV \ //#################- - * -###################\\/ \//###################- - * _#/|##########/\######( /\ )######/\##########|\#_ - * |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \| - * ` |/ V V ` V \#\| | | |/#/ V ' V V \| ' - * ` ` ` ` / | | | | \ ' ' ' ' - * ( | | | | ) - * __\ | | | | /__ - * (vvv(VVV)(VVV)vvv) - * - * HERE BE DRAGONS - * - */ - -package com.github.shadowsocks; - -public class Tun2Socks { - static { - java.lang.System.loadLibrary("tun2socks"); - } - - public static native void start(String[] cmd); - public static native void stop(); -} diff --git a/src/main/jni/Android.mk b/src/main/jni/Android.mk index f1bc8a7e..a8093491 100755 --- a/src/main/jni/Android.mk +++ b/src/main/jni/Android.mk @@ -204,7 +204,7 @@ LOCAL_STATIC_LIBRARIES := cpufeatures include $(BUILD_SHARED_LIBRARY) ######################################################## -## tun2socks-library +## tun2socks ######################################################## include $(CLEAR_VARS) @@ -214,7 +214,7 @@ LOCAL_CFLAGS += -DBADVPN_THREADWORK_USE_PTHREAD -DBADVPN_LINUX -DBADVPN_BREACTOR LOCAL_CFLAGS += -DBADVPN_USE_SELFPIPE -DBADVPN_USE_EPOLL LOCAL_CFLAGS += -DBADVPN_LITTLE_ENDIAN -DBADVPN_THREAD_SAFE LOCAL_CFLAGS += -DNDEBUG -DANDROID -LOCAL_CFLAGS += -DTUN2SOCKS_JNI +# LOCAL_CFLAGS += -DTUN2SOCKS_JNI LOCAL_C_INCLUDES:= \ $(LOCAL_PATH)/badvpn/lwip/src/include/ipv4 \ @@ -288,9 +288,9 @@ LOCAL_MODULE := tun2socks LOCAL_LDLIBS := -ldl -llog -LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES)) tun2socks-jni.cpp +LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES)) -include $(BUILD_SHARED_LIBRARY) +include $(BUILD_EXECUTABLE) # OpenSSL openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \ diff --git a/src/main/jni/badvpn/tun2socks/tun2socks.c b/src/main/jni/badvpn/tun2socks/tun2socks.c index b595bbb4..2a9ef44f 100644 --- a/src/main/jni/badvpn/tun2socks/tun2socks.c +++ b/src/main/jni/badvpn/tun2socks/tun2socks.c @@ -71,6 +71,7 @@ #include #ifdef ANDROID +#include #include #include BAVL connections_tree; @@ -146,91 +147,6 @@ static void tcp_remove(struct tcp_pcb* pcb_list) } } -ssize_t -sock_fd_write(int sock, void *buf, ssize_t buflen, int fd) -{ - ssize_t size; - struct msghdr msg; - struct iovec iov; - union { - struct cmsghdr cmsghdr; - char control[CMSG_SPACE(sizeof (int))]; - } cmsgu; - struct cmsghdr *cmsg; - - iov.iov_base = buf; - iov.iov_len = buflen; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - if (fd != -1) { - msg.msg_control = cmsgu.control; - msg.msg_controllen = sizeof(cmsgu.control); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(sizeof (int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - *((int *) CMSG_DATA(cmsg)) = fd; - } else { - msg.msg_control = NULL; - msg.msg_controllen = 0; - } - - size = sendmsg(sock, &msg, 0); - - return size; -} - -ssize_t -sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd) -{ - ssize_t size; - - if (fd) { - struct msghdr msg; - struct iovec iov; - union { - struct cmsghdr cmsghdr; - char control[CMSG_SPACE(sizeof (int))]; - } cmsgu; - struct cmsghdr *cmsg; - - iov.iov_base = buf; - iov.iov_len = bufsize; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = cmsgu.control; - msg.msg_controllen = sizeof(cmsgu.control); - size = recvmsg (sock, &msg, 0); - if (size < 0) { - return -1; - } - cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { - if (cmsg->cmsg_level != SOL_SOCKET) { - return -1; - } - if (cmsg->cmsg_type != SCM_RIGHTS) { - return -1; - } - - *fd = *((int *) CMSG_DATA(cmsg)); - } else { - *fd = -1; - return -1; - } - } - return size; -} - #endif #define LOGGER_STDOUT 1 @@ -467,54 +383,6 @@ static void daemonize(const char* path) { close(STDOUT_FILENO); close(STDERR_FILENO); } - -int -recv_tun_fd (void) -{ - int s_fd, fd_to_read; - struct sockaddr_un addr; - socklen_t addr_len; - - s_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (s_fd < 0) { - BLog(BLOG_ERROR, "Error to create local socket"); - return -1; - } - - BLog(BLOG_NOTICE, "Create socket"); - - addr_len = sizeof(struct sockaddr_un); - memset(&addr, 0, addr_len); - addr.sun_family = AF_UNIX; - addr.sun_path[0] = '\0'; - strcpy(addr.sun_path+1, "tun2socks"); - - if (connect(s_fd, (struct sockaddr *)&addr, addr_len) != -1) - { - char buf[16]; - - BLog(BLOG_NOTICE, "Connected"); - - read(s_fd, buf, 1); - sock_fd_read(s_fd, buf, sizeof(buf), &fd_to_read); - - buf[0] = 0; - write(s_fd, buf, 1); - close(s_fd); - } - else - { - BLog(BLOG_ERROR, "Error to connect: %s", strerror(errno)); - close(s_fd); - return -1; - } - - close(s_fd); - - if (fd_to_read == 0) return -1; - options.tun_fd = fd_to_read; -} - #endif int main (int argc, char **argv) @@ -523,6 +391,10 @@ int main (int argc, char **argv) return 1; } + // Fake process name to cheat on Lollipop + strcpy(argv[0], "com.github.shadowsocks"); + prctl(PR_SET_NAME, "com.github.shadowsocks"); + // open standard streams open_standard_streams(); diff --git a/src/main/jni/main-jni.cpp b/src/main/jni/main-jni.cpp deleted file mode 100644 index fcb95b11..00000000 --- a/src/main/jni/main-jni.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include - -typedef unsigned short char16_t; - -class String8 { -public: - String8() { - mString = 0; - } - - ~String8() { - if (mString) { - free(mString); - } - } - - void set(const char16_t* o, size_t numChars) { - if (mString) { - free(mString); - } - mString = (char*) malloc(numChars + 1); - if (!mString) { - return; - } - for (size_t i = 0; i < numChars; i++) { - mString[i] = (char) o[i]; - } - mString[numChars] = '\0'; - } - - const char* string() { - return mString; - } -private: - char* mString; -}; - -extern "C" { - -int main(int argc, char* args[]); - -#if defined(PDNSD_JNI) -jint Java_com_github_shadowsocks_Core_pdnsd(JNIEnv *env, jobject thiz, jobjectArray argv) { -#elif defined(SSLOCAL_JNI) -jint Java_com_github_shadowsocks_Core_sslocal(JNIEnv *env, jobject thiz, jobjectArray argv) { -#elif defined(SSTUNNEL_JNI) -jint Java_com_github_shadowsocks_Core_sstunnel(JNIEnv *env, jobject thiz, jobjectArray argv) { -#elif defined(REDSOCKS_JNI) -jint Java_com_github_shadowsocks_Core_redsocks(JNIEnv *env, jobject thiz, jobjectArray argv) { -#elif defined(TUN2SOCKS_JNI) -jint Java_com_github_shadowsocks_Core_tun2socks(JNIEnv *env, jobject thiz, jobjectArray argv) { -#else -#error "invalid header" -#endif - - int argc = argv ? env->GetArrayLength(argv) : 0; - char **args = NULL; - String8 tmp_8; - - if (argc > 0) { - args = (char **)malloc((argc+1)*sizeof(char *)); - for (int i = 0; i < argc; ++i) { - jstring arg = reinterpret_cast(env->GetObjectArrayElement(argv, i)); - const jchar *str = env->GetStringCritical(arg, 0); - tmp_8.set(str, env->GetStringLength(arg)); - env->ReleaseStringCritical(arg, str); - args[i] = strdup(tmp_8.string()); - } - args[argc] = NULL; - - pid_t pid; - pid = fork(); - if (pid == 0) { - int ret = main(argc, args); - return ret; - } - - if (args != NULL) free(args); - } - - return 0; -} - -} diff --git a/src/main/jni/tun2socks-jni.cpp b/src/main/jni/tun2socks-jni.cpp deleted file mode 100644 index aac2834f..00000000 --- a/src/main/jni/tun2socks-jni.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include - -typedef unsigned short char16_t; - -class String8 { -public: - String8() { - mString = 0; - } - - ~String8() { - if (mString) { - free(mString); - } - } - - void set(const char16_t* o, size_t numChars) { - if (mString) { - free(mString); - } - mString = (char*) malloc(numChars + 1); - if (!mString) { - return; - } - for (size_t i = 0; i < numChars; i++) { - mString[i] = (char) o[i]; - } - mString[numChars] = '\0'; - } - - const char* string() { - return mString; - } -private: - char* mString; -}; - -extern "C" { - -int main(int argc, char* args[]); -void terminate (void); - -jint Java_com_github_shadowsocks_Tun2Socks_start(JNIEnv *env, jobject thiz, jobjectArray argv) { - - int argc = argv ? env->GetArrayLength(argv) : 0; - char **args = NULL; - String8 tmp_8; - - if (argc > 0) { - args = (char **)malloc((argc+1)*sizeof(char *)); - for (int i = 0; i < argc; ++i) { - jstring arg = reinterpret_cast(env->GetObjectArrayElement(argv, i)); - const jchar *str = env->GetStringCritical(arg, 0); - tmp_8.set(str, env->GetStringLength(arg)); - env->ReleaseStringCritical(arg, str); - args[i] = strdup(tmp_8.string()); - } - args[argc] = NULL; - - pid_t pid; - pid = fork(); - if (pid == 0) { - int ret = main(argc, args); - return ret; - } - - if (args != NULL) free(args); - } - - return 0; -} - -jint Java_com_github_shadowsocks_Tun2Socks_stop(JNIEnv *env, jobject thiz) { - terminate(); -} - -} diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 012cf9ae..aa6d93b6 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -123,7 +123,7 @@ object Shadowsocks { val FEATRUE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps, Key.isUdpDns, Key.isAutoConnect) - val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL) + val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL, Executable.TUN2SOCKS) // Helper functions def updateListPreference(pref: Preference, value: String) { diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 5547cf34..7122a494 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -322,25 +322,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { if (BuildConfig.DEBUG) Log.d(TAG, cmd) - Tun2Socks.start(cmd.split(" ")) - } - - def startTunFdServer() { - spawn { - val fdServer = new LocalServerSocket("tun2socks") - try { - val localSocket = fdServer.accept() - localSocket.setFileDescriptorsForSend(Array(conn.getFileDescriptor)) - val output = localSocket.getOutputStream - output.write(1) - output.flush() - output.close() - localSocket.close() - fdServer.close() - } catch { - case ex: Exception => Log.e(TAG, "Exception", ex) // Ignored - } - } + System.exec(cmd); } /** Called when the activity is first created. */