diff --git a/build.sh b/build.sh index 14cfaff6..d4bc155b 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 tun2socks +for app in pdnsd redsocks ss-local ss-tunnel 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 new file mode 100644 index 00000000..7b25c1c4 --- /dev/null +++ b/src/main/java/com/github/shadowsocks/Tun2Socks.java @@ -0,0 +1,49 @@ +/* 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 a8093491..68a5f705 100755 --- a/src/main/jni/Android.mk +++ b/src/main/jni/Android.mk @@ -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)) +LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES)) tun2socks-jni.cpp -include $(BUILD_EXECUTABLE) +include $(BUILD_SHARED_LIBRARY) # 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 1818630e..a4d30169 100644 --- a/src/main/jni/badvpn/tun2socks/tun2socks.c +++ b/src/main/jni/badvpn/tun2socks/tun2socks.c @@ -402,13 +402,6 @@ int main (int argc, char **argv) goto fail0; } - if (options.fake_proc) { - // Fake process name to cheat on Lollipop - strcpy(argv[0], "com.github.shadowsocks"); - prctl(PR_SET_NAME, "com.github.shadowsocks"); - } - - // handle --help and --version if (options.help) { print_version(); @@ -668,7 +661,6 @@ void print_help (const char *name) " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" " [--channel-loglevel <0-5/none/error/warning/notice/info/debug>] ...\n" #ifdef ANDROID - " [--fake-proc]\n" " [--tunfd ]\n" " [--tunmtu ]\n" " [--dnsgw ]\n" @@ -818,9 +810,6 @@ int parse_arguments (int argc, char *argv[]) i += 2; } #ifdef ANDROID - else if (!strcmp(arg, "--fake-proc")) { - options.fake_proc = 1; - } else if (!strcmp(arg, "--tunfd")) { if (1 >= argc - i) { fprintf(stderr, "%s: requires an argument\n", arg); diff --git a/src/main/jni/tun2socks-jni.cpp b/src/main/jni/tun2socks-jni.cpp new file mode 100644 index 00000000..8d77f679 --- /dev/null +++ b/src/main/jni/tun2socks-jni.cpp @@ -0,0 +1,80 @@ +#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/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index c2412aa8..a1148865 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -320,13 +320,9 @@ class ShadowsocksVpnService extends VpnService with BaseService { else cmd += " --dnsgw %s:8153".format(PRIVATE_VLAN.format("1")) - if (Utils.isLollipopOrAbove) { - cmd += " --fake-proc"; - } - if (BuildConfig.DEBUG) Log.d(TAG, cmd) - System.exec(cmd); + Tun2Socks.start(cmd.split(" ")) } /** Called when the activity is first created. */