From aa71142549ab2aa31d5f8cdbded93b54e5dcf24f Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 27 Jun 2014 14:42:12 +0800 Subject: [PATCH 01/18] using jni based to WAR Android L issue --- build-ndk.sh | 2 +- jni/Android.mk | 33 ++++++++++++++----- .../shadowsocks/ShadowsocksNatService.scala | 5 +-- .../shadowsocks/ShadowsocksVpnService.scala | 14 +++----- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/build-ndk.sh b/build-ndk.sh index c127ad7f..6678ff04 100755 --- a/build-ndk.sh +++ b/build-ndk.sh @@ -4,7 +4,7 @@ ndk-build mkdir -p src/main/assets/armeabi mkdir -p src/main/assets/armeabi-v7a mkdir -p src/main/assets/x86 -for app in ip6tables iptables pdnsd redsocks ss-local ss-tunnel tun2socks +for app in ip6tables iptables pdnsd redsocks ss-tunnel do mv libs/armeabi/$app src/main/assets/armeabi/ mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/ diff --git a/jni/Android.mk b/jni/Android.mk index 2d4feca0..39af4ce1 100755 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -143,16 +143,30 @@ LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/pdnsd include $(BUILD_EXECUTABLE) ######################################################## -## shadowsocks local +## pdnsd library +######################################################## + +include $(CLEAR_VARS) + +PDNSD_SOURCES := $(wildcard $(LOCAL_PATH)/pdnsd/src/*.c) main-jni.cpp + +LOCAL_MODULE := pdnsd-jni +LOCAL_SRC_FILES := $(PDNSD_SOURCES:$(LOCAL_PATH)/%=%) +LOCAL_CFLAGS := -Wall -O2 -DPDNSD_JNI -I$(LOCAL_PATH)/pdnsd + +include $(BUILD_SHARED_LIBRARY) + +######################################################## +## shadowsocks local library ######################################################## include $(CLEAR_VARS) SHADOWSOCKS_SOURCES := local.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c acl.c -LOCAL_MODULE := ss-local -LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES)) -LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL \ +LOCAL_MODULE := ss-local-jni +LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES)) main-jni.cpp +LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DSSLOCAL_JNI \ -DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \ -I$(LOCAL_PATH)/libev/ \ -I$(LOCAL_PATH)/openssl/include \ @@ -163,7 +177,7 @@ LOCAL_STATIC_LIBRARIES := libev libcrypto libipset libcork LOCAL_LDLIBS := -llog -include $(BUILD_EXECUTABLE) +include $(BUILD_SHARED_LIBRARY) ######################################################## ## shadowsocks tunnel @@ -204,7 +218,7 @@ LOCAL_STATIC_LIBRARIES := cpufeatures include $(BUILD_SHARED_LIBRARY) ######################################################## -## tun2socks +## tun2socks-library ######################################################## include $(CLEAR_VARS) @@ -214,6 +228,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_C_INCLUDES:= \ $(LOCAL_PATH)/badvpn/lwip/src/include/ipv4 \ @@ -283,13 +298,13 @@ TUN2SOCKS_SOURCES := \ tun2socks/SocksUdpGwClient.c \ udpgw_client/UdpGwClient.c -LOCAL_MODULE := tun2socks +LOCAL_MODULE := tun2socks-jni LOCAL_LDLIBS := -ldl -llog -LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES)) +LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES)) main-jni.cpp -include $(BUILD_EXECUTABLE) +include $(BUILD_SHARED_LIBRARY) # OpenSSL openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \ diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 39137b75..93163739 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -119,12 +119,13 @@ class ShadowsocksNatService extends Service with BaseService { } val args = (Path.BASE + - "ss-local -b 127.0.0.1 -s '%s' -p '%d' -l '%d' -k ''%s' -m '%s' -f " + + "ss-local -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -f " + Path.BASE + "ss-local.pid") .format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod) val cmd = if (config.isGFWList && isACLEnabled) args + " --acl " + Path.BASE + "chn.acl" else args if (BuildConfig.DEBUG) Log.d(TAG, cmd) - Console.runCommand(cmd) + + Core.sslocal(cmd.split(" ")) } def startDnsDaemon() { diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 96195592..32b0fc3e 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -82,11 +82,11 @@ class ShadowsocksVpnService extends VpnService with BaseService { def startShadowsocksDaemon() { val cmd: String = (Path.BASE + - "ss-local -b 127.0.0.1 -s '%s' -p '%d' -l '%d' -k '%s' -m '%s' -u -f " + + "ss-local -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -u -f " + Path.BASE + "ss-local.pid") .format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod) if (BuildConfig.DEBUG) Log.d(TAG, cmd) - System.exec(cmd) + Core.sslocal(cmd.split(" ")) } def startDnsDaemon() { @@ -101,7 +101,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { }) val cmd = Path.BASE + "pdnsd -c " + Path.BASE + "pdnsd.conf" if (BuildConfig.DEBUG) Log.d(TAG, cmd) - System.exec(cmd) + Core.pdnsd(cmd.split(" ")) } def getVersionName: String = { @@ -202,10 +202,9 @@ class ShadowsocksVpnService extends VpnService with BaseService { else cmd += " --dnsgw %s:8153".format(PRIVATE_VLAN.format("1")) - if (BuildConfig.DEBUG) - Log.d(TAG, cmd) + if (BuildConfig.DEBUG) Log.d(TAG, cmd) - System.exec(cmd) + Core.tun2socks(cmd.split(" ")) } /** Called when the activity is first created. */ @@ -260,11 +259,8 @@ class ShadowsocksVpnService extends VpnService with BaseService { val ab = new ArrayBuffer[String] ab.append("kill -9 `cat " + Path.BASE + "ss-local.pid`") - ab.append("killall -9 ss-local") ab.append("kill -9 `cat " + Path.BASE + "tun2socks.pid`") - ab.append("killall -9 tun2socks") ab.append("kill -15 `cat " + Path.BASE + "pdnsd.pid`") - ab.append("killall -15 pdnsd") Console.runCommand(ab.toArray) } From 8ece167ffd105300f4aaa684d061c540a3c15021 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 27 Jun 2014 14:58:11 +0800 Subject: [PATCH 02/18] add missing files --- jni/main-jni.cpp | 84 +++++++++++++++++++ .../java/com/github/shadowsocks/Core.java | 51 +++++++++++ 2 files changed, 135 insertions(+) create mode 100644 jni/main-jni.cpp create mode 100755 src/main/java/com/github/shadowsocks/Core.java diff --git a/jni/main-jni.cpp b/jni/main-jni.cpp new file mode 100644 index 00000000..fa0298ac --- /dev/null +++ b/jni/main-jni.cpp @@ -0,0 +1,84 @@ +#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(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/java/com/github/shadowsocks/Core.java b/src/main/java/com/github/shadowsocks/Core.java new file mode 100755 index 00000000..7af88993 --- /dev/null +++ b/src/main/java/com/github/shadowsocks/Core.java @@ -0,0 +1,51 @@ +/* Shadowsocks - A shadowsocks client for Android + * Copyright (C) 2012 + * + * 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 Core { + static { + java.lang.System.loadLibrary("ss-local-jni"); + java.lang.System.loadLibrary("tun2socks-jni"); + java.lang.System.loadLibrary("pdnsd-jni"); + } + + public static native void sslocal(String[] cmd); + public static native void tun2socks(String[] cmd); + public static native void pdnsd(String[] cmd); +} From 5aefc885c89a97ab60e10151dd741379f30119ab Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 27 Jun 2014 16:04:09 +0800 Subject: [PATCH 03/18] update travis --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9799b7a8..8e38b84f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,14 +11,14 @@ before_install: - sudo apt-get install ccache - export NDK_CCACHE=ccache - export ARCH=`uname -m` -- wget http://dl.google.com/android/android-sdk_r22.6.2-linux.tgz -- tar xf android-sdk_r22.6.2-linux.tgz +- wget http://dl.google.com/android/android-sdk_r23-linux.tgz +- tar xf android-sdk_r23-linux.tgz - wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2 - tar xf android-ndk-r9d-linux-${ARCH}.tar.bz2 - export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d - export ANDROID_HOME=`pwd`/android-sdk-linux - export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools -- echo "y" | android update sdk --filter tools,platform-tools,build-tools-19.0.3,android-19,extra-google-m2repository,extra-android-m2repository --no-ui --no-https -a +- echo "y" | android update sdk --filter tools,platform-tools,build-tools-20,android-19,extra-google-m2repository,extra-android-m2repository --no-ui --no-https -a install: - gem install --version 0.8.9 faraday - gem install travis-artifacts From 8923c93b6e984f54e8f15a64aef382fabf437666 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 28 Jun 2014 19:02:38 +0800 Subject: [PATCH 04/18] update travis --- .gitignore | 2 + .travis.yml | 3 +- build-ndk.sh | 18 +++++ jni/Application.mk.16 | 4 + jni/{Application.mk => Application.mk.9} | 0 .../com/github/shadowsocks/Shadowsocks.scala | 75 ++++++++++++------- .../shadowsocks/ShadowsocksNatService.scala | 30 ++++++-- 7 files changed, 94 insertions(+), 38 deletions(-) create mode 100644 jni/Application.mk.16 rename jni/{Application.mk => Application.mk.9} (100%) diff --git a/.gitignore b/.gitignore index bae30917..2d654430 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,8 @@ src/main/libs src/main/assets/armeabi src/main/assets/armeabi-v7a src/main/assets/x86 +src/main/assets/api-16/ src/main/jni +jni/Application.mk obj libs diff --git a/.travis.yml b/.travis.yml index bed6d677..ee7fd518 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,8 @@ before_install: - export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d - export ANDROID_HOME=`pwd`/android-sdk-linux - export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools -- echo -e "y\ny\ny" | android update sdk --filter tools,platform-tools,build-tools-19.0.3,android-19,extra-google-m2repository,extra-android-m2repository --no-ui --no-https -a +- echo "y" | android update sdk --filter tools,platform-tools,build-tools-19.0.3,android-19,extra-google-m2repository --no-ui --no-https -a +- echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a - ln -s $ANDROID_HOME/build-tools/20.0.0/zipalign $ANDROID_HOME/tools/ install: - gem install --version 0.8.9 faraday diff --git a/build-ndk.sh b/build-ndk.sh index 6678ff04..170dfc7e 100755 --- a/build-ndk.sh +++ b/build-ndk.sh @@ -1,4 +1,7 @@ #!/bin/bash + +# Target 9 +cp jni/Application.mk.9 jni/Application.mk ndk-build clean ndk-build mkdir -p src/main/assets/armeabi @@ -12,3 +15,18 @@ do done rm -rf src/main/jni mv libs src/main/jni + +# Target 16 +cp jni/Application.mk.16 jni/Application.mk +ndk-build clean +ndk-build +mkdir -p src/main/assets/api-16/armeabi +mkdir -p src/main/assets/api-16/armeabi-v7a +mkdir -p src/main/assets/api-16/x86 +for app in pdnsd redsocks ss-tunnel +do + mv libs/armeabi/$app src/main/assets/api-16/armeabi/ + mv libs/armeabi-v7a/$app src/main/assets/api-16/armeabi-v7a/ + mv libs/x86/$app src/main/assets/api-16/x86/ +done + diff --git a/jni/Application.mk.16 b/jni/Application.mk.16 new file mode 100644 index 00000000..73844094 --- /dev/null +++ b/jni/Application.mk.16 @@ -0,0 +1,4 @@ +APP_ABI := armeabi armeabi-v7a x86 +APP_PLATFORM := android-16 +APP_STL := stlport_static +NDK_TOOLCHAIN_VERSION := 4.8 diff --git a/jni/Application.mk b/jni/Application.mk.9 similarity index 100% rename from jni/Application.mk rename to jni/Application.mk.9 diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index d087bf4e..e559a99f 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -38,41 +38,37 @@ */ package com.github.shadowsocks +import java.util +import java.io.{OutputStream, InputStream, ByteArrayInputStream, ByteArrayOutputStream, IOException, FileOutputStream} + +import android.app.backup.BackupManager import android.app.{Activity, AlertDialog, ProgressDialog} import android.content._ +import android.content.pm.{PackageInfo, PackageManager} import android.content.res.AssetManager -import android.graphics.{Color, Bitmap, Typeface} +import android.graphics.{Bitmap, Color, Typeface} +import android.net.{Uri, VpnService} import android.os._ import android.preference._ -import android.util.{Log, DisplayMetrics} +import android.util.{DisplayMetrics, Log} import android.view._ +import android.webkit.{WebView, WebViewClient} import android.widget._ -import com.google.analytics.tracking.android.{MapBuilder, EasyTracker} -import de.keyboardsurfer.android.widget.crouton.{Crouton, Style, Configuration} -import java.util.Hashtable import com.actionbarsherlock.app.SherlockPreferenceActivity -import org.jraf.android.backport.switchwidget.Switch -import android.content.pm.{PackageInfo, PackageManager} -import android.net.{Uri, VpnService} -import android.webkit.{WebViewClient, WebView} -import android.app.backup.BackupManager -import scala.concurrent.ops._ -import com.google.android.gms.ads.{AdRequest, AdSize, AdView} -import net.simonvt.menudrawer.MenuDrawer - +import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback} import com.github.shadowsocks.database._ -import scala.collection.mutable.{ArrayBuffer, ListBuffer} -import com.github.shadowsocks.database.Profile -import com.nostra13.universalimageloader.core.download.BaseImageDownloader -import com.github.shadowsocks.preferences.{ProfileEditTextPreference, PasswordEditTextPreference, SummaryEditTextPreference} +import com.github.shadowsocks.preferences.{PasswordEditTextPreference, ProfileEditTextPreference, SummaryEditTextPreference} import com.github.shadowsocks.utils._ +import com.google.analytics.tracking.android.{EasyTracker, MapBuilder} +import com.google.android.gms.ads.{AdRequest, AdSize, AdView} import com.google.zxing.integration.android.IntentIntegrator -import com.github.shadowsocks.aidl.{IShadowsocksServiceCallback, IShadowsocksService} -import java.io._ -import scala.Some -import com.github.shadowsocks.database.Item -import com.github.shadowsocks.database.Category -import com.github.shadowsocks.utils.Console +import com.nostra13.universalimageloader.core.download.BaseImageDownloader +import de.keyboardsurfer.android.widget.crouton.{Configuration, Crouton, Style} +import net.simonvt.menudrawer.MenuDrawer +import org.jraf.android.backport.switchwidget.Switch + +import scala.collection.mutable.{ArrayBuffer, ListBuffer} +import scala.concurrent.ops._ class ProfileIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int) extends BaseImageDownloader(context, connectTimeout, readTimeout) { @@ -113,7 +109,7 @@ object Typefaces { } private final val TAG = "Typefaces" - private final val cache = new Hashtable[String, Typeface] + private final val cache = new util.Hashtable[String, Typeface] } object Shadowsocks { @@ -128,8 +124,8 @@ object Shadowsocks { val FEATRUE_PREFS = Array(Key.isGFWList, Key.isGlobalProxy, Key.proxyedApps, Key.isTrafficStat, Key.isUdpDns, Key.isAutoConnect) - val EXECUTABLES = Array(Executable.IPTABLES, Executable.PDNSD, Executable.REDSOCKS, - Executable.SS_LOCAL, Executable.SS_TUNNEL, Executable.TUN2SOCKS) + val SYSTEM_EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS,Executable.SS_TUNNEL) + val EXECUTABLES = Array(Executable.IPTABLES) ++ SYSTEM_EXECUTABLES // Helper functions def updateListPreference(pref: Preference, value: String) { @@ -427,7 +423,7 @@ class Shadowsocks if (settings.getString(Key.proxy, "") == "198.199.101.152") { val layoutView = { if (Build.VERSION.SDK_INT > 10) { - drawer.getContentContainer.asInstanceOf[ViewGroup].getChildAt(0) + drawer.getContentContainer.getChildAt(0) } else { getLayoutView(drawer.getContentContainer.getParent) } @@ -803,9 +799,30 @@ class Shadowsocks new BackupManager(this).dataChanged() } + def copyToSystem() { + val ab = new ArrayBuffer[String] + ab.append("mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system") + for (executable <- Shadowsocks.SYSTEM_EXECUTABLES) { + ab.append("cp %s%s /system/bin/".format(Path.BASE, executable)) + } + ab.append("mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system") + Console.runRootCommand(ab.toArray) + + } + def reset() { + crash_recovery() - copyAssets(System.getABI) + + if (Build.VERSION.SDK_INT >= 16) { + copyAssets("api-16/" + System.getABI) + } else { + copyAssets(System.getABI) + } + + if (Build.VERSION.SDK_INT >= 20) { + copyToSystem() + } val ab = new ArrayBuffer[String] for (executable <- Shadowsocks.EXECUTABLES) { diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 93163739..3e350478 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -118,10 +118,14 @@ class ShadowsocksNatService extends Service with BaseService { }) } - val args = (Path.BASE + - "ss-local -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -f " + + val raw_args = ("ss-local -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -f " + Path.BASE + "ss-local.pid") .format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod) + val args = if (Build.VERSION.SDK_INT >= 20) { + raw_args + } else { + Path.BASE + raw_args + } val cmd = if (config.isGFWList && isACLEnabled) args + " --acl " + Path.BASE + "chn.acl" else args if (BuildConfig.DEBUG) Log.d(TAG, cmd) @@ -129,9 +133,8 @@ class ShadowsocksNatService extends Service with BaseService { } def startDnsDaemon() { - val cmd = if (config.isUdpDns) { - (Path.BASE + - "ss-tunnel -b 127.0.0.1 -s '%s' -p '%d' -l '%d' -k '%s' -m '%s' -L 8.8.8.8:53 -u -f " + + val args = if (config.isUdpDns) { + ("ss-tunnel -b 127.0.0.1 -s '%s' -p '%d' -l '%d' -k '%s' -m '%s' -L 8.8.8.8:53 -u -f " + Path.BASE + "ss-tunnel.pid") .format(config.proxy, config.remotePort, 8153, config.sitekey, config.encMethod) } else { @@ -144,7 +147,13 @@ class ShadowsocksNatService extends Service with BaseService { ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => { p.println(conf) }) - Path.BASE + "pdnsd -c " + Path.BASE + "pdnsd.conf" + "pdnsd -c " + Path.BASE + "pdnsd.conf" + } + + val cmd = if (Build.VERSION.SDK_INT >= 20) { + args + } else { + Path.BASE + args } if (BuildConfig.DEBUG) Log.d(TAG, cmd) Console.runRootCommand(cmd) @@ -164,11 +173,16 @@ class ShadowsocksNatService extends Service with BaseService { def startRedsocksDaemon() { val conf = ConfigUtils.REDSOCKS.format(config.localPort) - val cmd = "%sredsocks -p %sredsocks.pid -c %sredsocks.conf" - .format(Path.BASE, Path.BASE, Path.BASE) + val args = "redsocks -p %sredsocks.pid -c %sredsocks.conf" + .format(Path.BASE, Path.BASE) ConfigUtils.printToFile(new File(Path.BASE + "redsocks.conf"))(p => { p.println(conf) }) + val cmd = if (Build.VERSION.SDK_INT >= 20) { + args + } else { + Path.BASE + args + } Console.runRootCommand(cmd) } From 250e41714cf46d65e732ad53ee048d134012613d Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 28 Jun 2014 19:37:54 +0800 Subject: [PATCH 05/18] reduce the apk size --- build-ndk.sh | 10 ++++-- jni/Android.mk | 35 +++++++++++++++---- .../java/com/github/shadowsocks/Core.java | 2 ++ .../com/github/shadowsocks/Shadowsocks.scala | 7 ++-- .../shadowsocks/ShadowsocksNatService.scala | 16 ++++++--- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/build-ndk.sh b/build-ndk.sh index 170dfc7e..79427e1d 100755 --- a/build-ndk.sh +++ b/build-ndk.sh @@ -4,10 +4,13 @@ cp jni/Application.mk.9 jni/Application.mk ndk-build clean ndk-build +rm -rf src/main/assets/armeabi +rm -rf src/main/assets/armeabi-v7a +rm -rf src/main/assets/x86 mkdir -p src/main/assets/armeabi mkdir -p src/main/assets/armeabi-v7a mkdir -p src/main/assets/x86 -for app in ip6tables iptables pdnsd redsocks ss-tunnel +for app in pdnsd redsocks do mv libs/armeabi/$app src/main/assets/armeabi/ mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/ @@ -20,10 +23,13 @@ mv libs src/main/jni cp jni/Application.mk.16 jni/Application.mk ndk-build clean ndk-build +rm -rf src/main/assets/api-16/armeabi +rm -rf src/main/assets/api-16/armeabi-v7a +rm -rf src/main/assets/api-16/x86 mkdir -p src/main/assets/api-16/armeabi mkdir -p src/main/assets/api-16/armeabi-v7a mkdir -p src/main/assets/api-16/x86 -for app in pdnsd redsocks ss-tunnel +for app in pdnsd redsocks do mv libs/armeabi/$app src/main/assets/api-16/armeabi/ mv libs/armeabi-v7a/$app src/main/assets/api-16/armeabi-v7a/ diff --git a/jni/Android.mk b/jni/Android.mk index 39af4ce1..0c4e5c1c 100755 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -200,6 +200,27 @@ LOCAL_LDLIBS := -llog include $(BUILD_EXECUTABLE) +######################################################## +## shadowsocks tunnel library +######################################################## + +include $(CLEAR_VARS) + +SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c + +LOCAL_MODULE := ss-tunnel-jni +LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES)) main-jni.cpp +LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \ + -DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H -DSSTUNNEL_JNI \ + -I$(LOCAL_PATH)/libev/ \ + -I$(LOCAL_PATH)/openssl/include + +LOCAL_STATIC_LIBRARIES := libev libcrypto + +LOCAL_LDLIBS := -llog + +include $(BUILD_SHARED_LIBRARY) + ######################################################## ## system ######################################################## @@ -314,13 +335,13 @@ openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \ include $(openssl_subdirs) # Iptables -LOCAL_PATH := $(ROOT_PATH) -iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \ - iptables \ - extensions \ - libiptc \ - )) -include $(iptables_subdirs) +# LOCAL_PATH := $(ROOT_PATH) +# iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \ +# iptables \ +# extensions \ +# libiptc \ +# )) +# include $(iptables_subdirs) # Import cpufeatures $(call import-module,android/cpufeatures) diff --git a/src/main/java/com/github/shadowsocks/Core.java b/src/main/java/com/github/shadowsocks/Core.java index 7af88993..792638cd 100755 --- a/src/main/java/com/github/shadowsocks/Core.java +++ b/src/main/java/com/github/shadowsocks/Core.java @@ -41,11 +41,13 @@ package com.github.shadowsocks; public class Core { static { java.lang.System.loadLibrary("ss-local-jni"); + java.lang.System.loadLibrary("ss-tunnel-jni"); java.lang.System.loadLibrary("tun2socks-jni"); java.lang.System.loadLibrary("pdnsd-jni"); } public static native void sslocal(String[] cmd); + public static native void sstunnel(String[] cmd); public static native void tun2socks(String[] cmd); public static native void pdnsd(String[] cmd); } diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index e559a99f..fa60a21d 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -124,8 +124,7 @@ object Shadowsocks { val FEATRUE_PREFS = Array(Key.isGFWList, Key.isGlobalProxy, Key.proxyedApps, Key.isTrafficStat, Key.isUdpDns, Key.isAutoConnect) - val SYSTEM_EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS,Executable.SS_TUNNEL) - val EXECUTABLES = Array(Executable.IPTABLES) ++ SYSTEM_EXECUTABLES + val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS) // Helper functions def updateListPreference(pref: Preference, value: String) { @@ -329,8 +328,6 @@ class Shadowsocks ab.append("kill -9 `cat /data/data/com.github.shadowsocks/ss-tunnel.pid`") ab.append("kill -9 `cat /data/data/com.github.shadowsocks/tun2socks.pid`") ab.append("killall -9 pdnsd") - ab.append("killall -9 ss-local") - ab.append("killall -9 ss-tunnel") ab.append("killall -9 tun2socks") ab.append("rm /data/data/com.github.shadowsocks/pdnsd.conf") ab.append("rm /data/data/com.github.shadowsocks/pdnsd.cache") @@ -802,7 +799,7 @@ class Shadowsocks def copyToSystem() { val ab = new ArrayBuffer[String] ab.append("mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system") - for (executable <- Shadowsocks.SYSTEM_EXECUTABLES) { + for (executable <- Shadowsocks.EXECUTABLES) { ab.append("cp %s%s /system/bin/".format(Path.BASE, executable)) } ab.append("mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system") diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 3e350478..530300cc 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -134,7 +134,7 @@ class ShadowsocksNatService extends Service with BaseService { def startDnsDaemon() { val args = if (config.isUdpDns) { - ("ss-tunnel -b 127.0.0.1 -s '%s' -p '%d' -l '%d' -k '%s' -m '%s' -L 8.8.8.8:53 -u -f " + + ("ss-tunnel -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -L 8.8.8.8:53 -u -f " + Path.BASE + "ss-tunnel.pid") .format(config.proxy, config.remotePort, 8153, config.sitekey, config.encMethod) } else { @@ -155,8 +155,14 @@ class ShadowsocksNatService extends Service with BaseService { } else { Path.BASE + args } + if (BuildConfig.DEBUG) Log.d(TAG, cmd) - Console.runRootCommand(cmd) + + if (config.isUdpDns) { + Core.sstunnel(cmd.split(" ")) + } else { + Console.runRootCommand(cmd) + } } def getVersionName: String = { @@ -308,10 +314,11 @@ class ShadowsocksNatService extends Service with BaseService { val ab = new ArrayBuffer[String] + ab.append("kill -9 `cat " + Path.BASE + "ss-tunnel.pid`") + ab.append("kill -9 `cat " + Path.BASE +"redsocks.pid`") ab.append("killall -9 redsocks") - ab.append("kill -9 `cat " + Path.BASE + "ss-tunnel.pid`") - ab.append("killall -9 ss-tunnel") + ab.append("kill -15 `cat " + Path.BASE + "pdnsd.pid`") ab.append("killall -15 pdnsd") @@ -319,7 +326,6 @@ class ShadowsocksNatService extends Service with BaseService { ab.clear() ab.append("kill -9 `cat " + Path.BASE + "ss-local.pid`") - ab.append("killall -9 ss-local") Console.runCommand(ab.toArray) } From 1b626207989a56d9b099e2ca15b28a45b6b5e42a Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 28 Jun 2014 21:15:31 +0800 Subject: [PATCH 06/18] Fix all our own issues. Waiting for Android's official fix for their broken NAT implementation. --- src/main/scala/com/github/shadowsocks/Shadowsocks.scala | 3 +++ .../com/github/shadowsocks/ShadowsocksNatService.scala | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index fa60a21d..5fa3eeec 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -801,6 +801,8 @@ class Shadowsocks ab.append("mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system") for (executable <- Shadowsocks.EXECUTABLES) { ab.append("cp %s%s /system/bin/".format(Path.BASE, executable)) + ab.append("chmod 755 /system/bin/" + executable) + ab.append("chown root:shell /system/bin/" + executable) } ab.append("mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system") Console.runRootCommand(ab.toArray) @@ -826,6 +828,7 @@ class Shadowsocks ab.append("chmod 755 " + Path.BASE + executable) } Console.runCommand(ab.toArray) + } private def recovery() { diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 530300cc..8dd694b0 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -151,7 +151,7 @@ class ShadowsocksNatService extends Service with BaseService { } val cmd = if (Build.VERSION.SDK_INT >= 20) { - args + "system/bin/" + args } else { Path.BASE + args } @@ -185,7 +185,7 @@ class ShadowsocksNatService extends Service with BaseService { p.println(conf) }) val cmd = if (Build.VERSION.SDK_INT >= 20) { - args + "system/bin/" + args } else { Path.BASE + args } @@ -195,10 +195,10 @@ class ShadowsocksNatService extends Service with BaseService { /** Called when the activity is first created. */ def handleConnection: Boolean = { - startShadowsocksDaemon() startDnsDaemon() startRedsocksDaemon() - setupIptables + startShadowsocksDaemon() + setupIptables() flushDNS() true From 686c9dad5883e4527e6649ce2c8512198907d3bc Mon Sep 17 00:00:00 2001 From: Max Lv Date: Mon, 30 Jun 2014 13:38:46 +0800 Subject: [PATCH 07/18] fix a build issue --- .../scala/com/github/shadowsocks/ShadowsocksNatService.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 8dd694b0..76172754 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -338,7 +338,7 @@ class ShadowsocksNatService extends Service with BaseService { Console.runRootCommand(Array("ndc resolver flushdefaultif", "ndc resolver flushif wlan0")) } - def setupIptables: Boolean = { + def setupIptables() = { val init_sb = new ArrayBuffer[String] val http_sb = new ArrayBuffer[String] @@ -405,7 +405,6 @@ class ShadowsocksNatService extends Service with BaseService { } Console.runRootCommand(init_sb.toArray) Console.runRootCommand(http_sb.toArray) - true } /** From d5ff7b5cae3df7a8fa8a56e093c20e23fb9b05a7 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 4 Jul 2014 12:31:44 +0800 Subject: [PATCH 08/18] fix a overflow bug --- jni/shadowsocks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jni/shadowsocks b/jni/shadowsocks index c2819d62..0017b7c1 160000 --- a/jni/shadowsocks +++ b/jni/shadowsocks @@ -1 +1 @@ -Subproject commit c2819d62433eaef7a23023184b88cc31a3f1992d +Subproject commit 0017b7c1988c30c4b4850714908399248aa73a8e From 232ac78ee688af59854c7fbcadb554bfb4a8e4be Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 4 Jul 2014 13:41:30 +0800 Subject: [PATCH 09/18] update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ee7fd518..101d538a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_install: - export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d - export ANDROID_HOME=`pwd`/android-sdk-linux - export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools -- echo "y" | android update sdk --filter tools,platform-tools,build-tools-19.0.3,android-19,extra-google-m2repository --no-ui --no-https -a +- echo "y" | android update sdk --filter tools,platform-tools,build-tools-20.0.0,android-19,extra-google-m2repository --no-ui --no-https -a - echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a - ln -s $ANDROID_HOME/build-tools/20.0.0/zipalign $ANDROID_HOME/tools/ install: From 4e39705a7ae9e7614986a47892773a7c511cd99c Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 11 Jul 2014 09:08:17 +0800 Subject: [PATCH 10/18] refine the commands --- src/main/scala/com/github/shadowsocks/Shadowsocks.scala | 3 --- .../com/github/shadowsocks/ShadowsocksNatService.scala | 8 +++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 5fa3eeec..fb51012a 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -327,8 +327,6 @@ class Shadowsocks ab.append("kill -9 `cat /data/data/com.github.shadowsocks/ss-local.pid`") ab.append("kill -9 `cat /data/data/com.github.shadowsocks/ss-tunnel.pid`") ab.append("kill -9 `cat /data/data/com.github.shadowsocks/tun2socks.pid`") - ab.append("killall -9 pdnsd") - ab.append("killall -9 tun2socks") ab.append("rm /data/data/com.github.shadowsocks/pdnsd.conf") ab.append("rm /data/data/com.github.shadowsocks/pdnsd.cache") @@ -336,7 +334,6 @@ class Shadowsocks ab.clear() ab.append("kill -9 `cat /data/data/com.github.shadowsocks/redsocks.pid`") - ab.append("killall -9 redsocks") ab.append("rm /data/data/com.github.shadowsocks/redsocks.conf") ab.append(Utils.getIptables + " -t nat -F OUTPUT") diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 76172754..a799f4a8 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -151,7 +151,7 @@ class ShadowsocksNatService extends Service with BaseService { } val cmd = if (Build.VERSION.SDK_INT >= 20) { - "system/bin/" + args + "/system/bin/" + args } else { Path.BASE + args } @@ -185,7 +185,7 @@ class ShadowsocksNatService extends Service with BaseService { p.println(conf) }) val cmd = if (Build.VERSION.SDK_INT >= 20) { - "system/bin/" + args + "/system/bin/" + args } else { Path.BASE + args } @@ -315,16 +315,14 @@ class ShadowsocksNatService extends Service with BaseService { val ab = new ArrayBuffer[String] ab.append("kill -9 `cat " + Path.BASE + "ss-tunnel.pid`") - ab.append("kill -9 `cat " + Path.BASE +"redsocks.pid`") ab.append("killall -9 redsocks") - ab.append("kill -15 `cat " + Path.BASE + "pdnsd.pid`") ab.append("killall -15 pdnsd") Console.runRootCommand(ab.toArray) - ab.clear() + ab.clear() ab.append("kill -9 `cat " + Path.BASE + "ss-local.pid`") Console.runCommand(ab.toArray) From 028c5a64634abad0e17b38bf7a3eabceefca6a21 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 25 Jul 2014 16:25:17 +0800 Subject: [PATCH 11/18] fix #100 --- .../scala/com/github/shadowsocks/Shadowsocks.scala | 4 ++-- .../github/shadowsocks/ShadowsocksVpnService.scala | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index fb51012a..cbaa4686 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -507,7 +507,7 @@ class Shadowsocks val intent = new Intent(this, s) intent.setAction(Action.SERVICE) bindService(intent, connection, Context.BIND_AUTO_CREATE) - startService(new Intent(this, s)) + if (!isVpnEnabled) startService(new Intent(this, s)) } } @@ -518,9 +518,9 @@ class Shadowsocks } catch { case ignored: RemoteException => // Nothing } - unbindService(connection) bgService = null } + unbindService(connection) } override def onRestoreInstanceState(inState: Bundle) { diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 32b0fc3e..464f771a 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -52,12 +52,12 @@ import org.apache.http.conn.util.InetAddressUtils import android.os.Message import scala.concurrent.ops._ import org.apache.commons.net.util.SubnetUtils -import java.net.InetAddress import com.github.shadowsocks.utils._ import scala.Some import com.github.shadowsocks.aidl.{IShadowsocksService, Config} import scala.collection.mutable.ArrayBuffer import java.io.File +import java.net.InetAddress class ShadowsocksVpnService extends VpnService with BaseService { @@ -118,8 +118,13 @@ class ShadowsocksVpnService extends VpnService with BaseService { def startVpn() { + val openIntent: Intent = new Intent(this, classOf[Shadowsocks]) + openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + val configIntent = PendingIntent.getActivity(this, 0, openIntent, 0) + val builder = new Builder() builder + .setConfigureIntent(configIntent) .setSession(config.profileName) .setMtu(VPN_MTU) .addAddress(PRIVATE_VLAN.format("1"), 24) @@ -265,10 +270,6 @@ class ShadowsocksVpnService extends VpnService with BaseService { Console.runCommand(ab.toArray) } - override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = { - Service.START_STICKY - } - override def startRunner(c: Config) { config = c @@ -383,7 +384,6 @@ class ShadowsocksVpnService extends VpnService with BaseService { override def stopBackgroundService() { stopRunner() - stopSelf() } override def getTag = TAG From 4e22d26e843ce535f7250e24a1d87b92ee6d01b0 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 25 Jul 2014 18:13:51 +0800 Subject: [PATCH 12/18] refine #100 --- .../com/github/shadowsocks/BaseService.scala | 20 ++++++++++--------- .../com/github/shadowsocks/Shadowsocks.scala | 2 +- .../shadowsocks/ShadowsocksNatService.scala | 14 ++++++------- .../shadowsocks/ShadowsocksVpnService.scala | 7 ++++--- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/BaseService.scala b/src/main/scala/com/github/shadowsocks/BaseService.scala index e955d2e1..19da9814 100644 --- a/src/main/scala/com/github/shadowsocks/BaseService.scala +++ b/src/main/scala/com/github/shadowsocks/BaseService.scala @@ -49,8 +49,8 @@ import android.content.Context trait BaseService { - var state = State.INIT - var callbackCount = 0 + @volatile var state = State.INIT + @volatile var callbackCount = 0 final val callbacks = new RemoteCallbackList[IShadowsocksServiceCallback] @@ -105,15 +105,17 @@ trait BaseService { handler.post(new Runnable { override def run() { if (state != s) { - val n = callbacks.beginBroadcast() - for (i <- 0 to n - 1) { - try { - callbacks.getBroadcastItem(i).stateChanged(s, msg) - } catch { - case _: Exception => // Ignore + if (callbackCount > 0) { + val n = callbacks.beginBroadcast() + for (i <- 0 to n - 1) { + try { + callbacks.getBroadcastItem(i).stateChanged(s, msg) + } catch { + case _: Exception => // Ignore + } } + callbacks.finishBroadcast() } - callbacks.finishBroadcast() state = s } } diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index cbaa4686..b0db7bf5 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -507,7 +507,7 @@ class Shadowsocks val intent = new Intent(this, s) intent.setAction(Action.SERVICE) bindService(intent, connection, Context.BIND_AUTO_CREATE) - if (!isVpnEnabled) startService(new Intent(this, s)) + startService(new Intent(this, s)) } } diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index a799f4a8..4357c001 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -309,6 +309,11 @@ class ShadowsocksNatService extends Service with BaseService { } } + override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = { + Service.START_NOT_STICKY + } + + def killProcesses() { Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT") @@ -328,10 +333,6 @@ class ShadowsocksNatService extends Service with BaseService { Console.runCommand(ab.toArray) } - override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = { - Service.START_STICKY - } - def flushDNS() { Console.runRootCommand(Array("ndc resolver flushdefaultif", "ndc resolver flushif wlan0")) } @@ -453,9 +454,7 @@ class ShadowsocksNatService extends Service with BaseService { filter.addAction(Action.CLOSE) receiver = new BroadcastReceiver() { def onReceive(p1: Context, p2: Intent) { - spawn { - stopRunner() - } + stopRunner() } } registerReceiver(receiver, filter) @@ -580,7 +579,6 @@ class ShadowsocksNatService extends Service with BaseService { override def stopBackgroundService() { stopRunner() - stopSelf() } override def getTag = TAG diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 464f771a..6e19bfdd 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -253,7 +253,10 @@ class ShadowsocksVpnService extends VpnService with BaseService { notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) .asInstanceOf[NotificationManager] + } + override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = { + Service.START_NOT_STICKY } override def onRevoke() { @@ -295,9 +298,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { filter.addAction(Intent.ACTION_SHUTDOWN) receiver = new BroadcastReceiver { def onReceive(p1: Context, p2: Intent) { - spawn { - stopRunner() - } + stopRunner() } } registerReceiver(receiver, filter) From 31a5cff9560b4c8b38e6ae45477b076d81f7e77d Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 25 Jul 2014 20:53:17 +0800 Subject: [PATCH 13/18] refine #100 --- build-ndk.sh | 4 +-- jni/Android.mk | 32 +++++++++---------- project/plugins.sbt | 2 +- .../shadowsocks/ShadowsocksNatService.scala | 5 ++- .../shadowsocks/ShadowsocksVpnService.scala | 6 +++- 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/build-ndk.sh b/build-ndk.sh index 79427e1d..ddc4a59e 100755 --- a/build-ndk.sh +++ b/build-ndk.sh @@ -16,8 +16,8 @@ do mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/ mv libs/x86/$app src/main/assets/x86/ done -rm -rf src/main/jni -mv libs src/main/jni +rm -rf src/main/libs +mv libs src/main/ # Target 16 cp jni/Application.mk.16 jni/Application.mk diff --git a/jni/Android.mk b/jni/Android.mk index 0c4e5c1c..654be81a 100755 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -183,22 +183,22 @@ include $(BUILD_SHARED_LIBRARY) ## shadowsocks tunnel ######################################################## -include $(CLEAR_VARS) - -SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c - -LOCAL_MODULE := ss-tunnel -LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES)) -LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \ - -DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \ - -I$(LOCAL_PATH)/libev/ \ - -I$(LOCAL_PATH)/openssl/include - -LOCAL_STATIC_LIBRARIES := libev libcrypto - -LOCAL_LDLIBS := -llog - -include $(BUILD_EXECUTABLE) +# include $(CLEAR_VARS) +# +# SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c +# +# LOCAL_MODULE := ss-tunnel +# LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES)) +# LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \ +# -DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \ +# -I$(LOCAL_PATH)/libev/ \ +# -I$(LOCAL_PATH)/openssl/include +# +# LOCAL_STATIC_LIBRARIES := libev libcrypto +# +# LOCAL_LDLIBS := -llog +# +# include $(BUILD_EXECUTABLE) ######################################################## ## shadowsocks tunnel library diff --git a/project/plugins.sbt b/project/plugins.sbt index b552dddb..4f5571cd 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns) -addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.2.16") +addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.3.3") addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0") diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 4357c001..b6ddbc54 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -310,9 +310,12 @@ class ShadowsocksNatService extends Service with BaseService { } override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = { - Service.START_NOT_STICKY + Service.START_STICKY } + override def onTaskRemoved(intent: Intent) { + stopRunner() + } def killProcesses() { Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT") diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 6e19bfdd..87105c0e 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -256,7 +256,11 @@ class ShadowsocksVpnService extends VpnService with BaseService { } override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = { - Service.START_NOT_STICKY + Service.START_STICKY + } + + override def onTaskRemoved(intent: Intent) { + stopRunner() } override def onRevoke() { From 93af9c8cb1de62ee438858c50911346910075688 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 26 Jul 2014 08:24:26 +0800 Subject: [PATCH 14/18] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 101d538a..86e1d9de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,9 @@ before_install: - tar xf android-sdk_r23-linux.tgz - wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2 - tar xf android-ndk-r9d-linux-${ARCH}.tar.bz2 -- export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d +- export ANDROID_NDK=`pwd`/android-ndk-r9d - export ANDROID_HOME=`pwd`/android-sdk-linux -- export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools +- export PATH=${PATH}:${ANDROID_NDK}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools - echo "y" | android update sdk --filter tools,platform-tools,build-tools-20.0.0,android-19,extra-google-m2repository --no-ui --no-https -a - echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a - ln -s $ANDROID_HOME/build-tools/20.0.0/zipalign $ANDROID_HOME/tools/ From 308ea08d58012a8305c8c43157702b6d9d376db5 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 26 Jul 2014 09:37:20 +0800 Subject: [PATCH 15/18] update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 86e1d9de..6bc72285 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: scala scala: -- 2.10.3 +- 2.9.2 before_install: - sudo apt-get update - sudo apt-get install libc6-dev-i386 From 588c7284f68c32a2d9a14cf8d3eb1bd641389e6d Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 26 Jul 2014 10:18:41 +0800 Subject: [PATCH 16/18] Update .travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6bc72285..8edecbe8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ language: scala +jdk: +- openjdk6 scala: - 2.9.2 before_install: From c305d33f53ca8416239ea60140480ef0ff76260a Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 26 Jul 2014 11:45:34 +0800 Subject: [PATCH 17/18] update sbt --- .travis.yml | 9 +++------ project/build.properties | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8edecbe8..0f478c28 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: scala -jdk: -- openjdk6 scala: -- 2.9.2 +- 2.10.4 before_install: - sudo apt-get update - sudo apt-get install libc6-dev-i386 @@ -17,12 +15,11 @@ before_install: - tar xf android-sdk_r23-linux.tgz - wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2 - tar xf android-ndk-r9d-linux-${ARCH}.tar.bz2 -- export ANDROID_NDK=`pwd`/android-ndk-r9d +- export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d - export ANDROID_HOME=`pwd`/android-sdk-linux -- export PATH=${PATH}:${ANDROID_NDK}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools +- export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools - echo "y" | android update sdk --filter tools,platform-tools,build-tools-20.0.0,android-19,extra-google-m2repository --no-ui --no-https -a - echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a -- ln -s $ANDROID_HOME/build-tools/20.0.0/zipalign $ANDROID_HOME/tools/ install: - gem install --version 0.8.9 faraday - gem install travis-artifacts diff --git a/project/build.properties b/project/build.properties index 9b860e23..be6c454f 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.12.3 +sbt.version=0.13.5 From 429c67ff279b50a3f71a76b4cb2a9a06886ce179 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 26 Jul 2014 12:31:12 +0800 Subject: [PATCH 18/18] revert sbt --- build-ndk.sh | 4 ++-- project/plugins.sbt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build-ndk.sh b/build-ndk.sh index ddc4a59e..79427e1d 100755 --- a/build-ndk.sh +++ b/build-ndk.sh @@ -16,8 +16,8 @@ do mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/ mv libs/x86/$app src/main/assets/x86/ done -rm -rf src/main/libs -mv libs src/main/ +rm -rf src/main/jni +mv libs src/main/jni # Target 16 cp jni/Application.mk.16 jni/Application.mk diff --git a/project/plugins.sbt b/project/plugins.sbt index 4f5571cd..c69b7e51 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns) -addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.3.3") +addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.2.20") addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")