Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
712b764a9b | ||
|
|
019f9d30e8 | ||
|
|
26b68876f4 | ||
|
|
a494f56ce8 | ||
|
|
a433822d0a | ||
|
|
60d7d90565 | ||
|
|
d2ba9493c0 | ||
|
|
0eaece7af9 | ||
|
|
96320896aa | ||
|
|
54efe36ffc | ||
|
|
d5d6740a5a | ||
|
|
2e69eafdf8 | ||
|
|
86773085c3 | ||
|
|
b6667b9e0f | ||
|
|
0ee7e9d40e | ||
|
|
5f2ce1804f | ||
|
|
a5e316999a | ||
|
|
64a3d75ba2 | ||
|
|
9d09c9a097 | ||
|
|
b78f48504f | ||
|
|
a61b03c86c | ||
|
|
f43362fb18 | ||
|
|
4f0e527df7 | ||
|
|
a8878298cc | ||
|
|
890be54403 | ||
|
|
31984d1001 | ||
|
|
f30c31ae3e | ||
|
|
05963b6c82 | ||
|
|
98da4cd6e5 | ||
|
|
64da35c59b | ||
|
|
458a3473b1 | ||
|
|
66db347215 | ||
|
|
f9e32c995b | ||
|
|
0626ce8787 |
@@ -9,3 +9,4 @@ local.sbt
|
||||
|
||||
mobile/src/main/libs
|
||||
mobile/src/main/obj
|
||||
mobile/src/main/jni/overture
|
||||
|
||||
+3
-4
@@ -17,10 +17,6 @@
|
||||
path = mobile/src/main/jni/redsocks
|
||||
url = https://github.com/shadowsocks/redsocks.git
|
||||
branch = shadowsocks-android
|
||||
[submodule "mobile/src/main/jni/pdnsd"]
|
||||
path = mobile/src/main/jni/pdnsd
|
||||
url = https://github.com/shadowsocks/pdnsd.git
|
||||
branch = shadowsocks-android
|
||||
[submodule "mobile/src/main/jni/mbedtls"]
|
||||
path = mobile/src/main/jni/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls
|
||||
@@ -37,3 +33,6 @@
|
||||
[submodule "mobile/src/main/jni/libudns"]
|
||||
path = mobile/src/main/jni/libudns
|
||||
url = https://github.com/shadowsocks/libudns.git
|
||||
[submodule "mobile/src/overture"]
|
||||
path = mobile/src/overture
|
||||
url = https://github.com/shadowsocks/overture-android.git
|
||||
|
||||
+3
-2
@@ -5,8 +5,9 @@ jdk:
|
||||
|
||||
env:
|
||||
global:
|
||||
- NDK_VERSION=r12b
|
||||
- NDK_VERSION=r14
|
||||
- NDK_CCACHE=ccache
|
||||
- GOROOT_BOOTSTRAP=$GOROOT
|
||||
- ANDROID_NDK_HOME=$HOME/.android/android-ndk-${NDK_VERSION}
|
||||
- SBTPATH=$HOME/.sbt
|
||||
- PATH=${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools:${PATH}
|
||||
@@ -49,4 +50,4 @@ install:
|
||||
fi
|
||||
|
||||
script:
|
||||
- $SBTPATH/sbt android:package
|
||||
- $SBTPATH/sbt go-build android:package
|
||||
|
||||
@@ -12,15 +12,17 @@ A [shadowsocks](http://shadowsocks.org) client for Android, written in Scala.
|
||||
|
||||
* JDK 1.8
|
||||
* SBT 0.13.0+
|
||||
* Go 1.4+
|
||||
* Android SDK
|
||||
- Build Tools 25+
|
||||
- Android Support Repository and Google Repository (see `build.sbt` for version)
|
||||
* Android NDK r12b+
|
||||
* Android NDK r14+
|
||||
|
||||
### BUILD
|
||||
|
||||
* Set environment variable `ANDROID_HOME` to `/path/to/android-sdk`
|
||||
* Set environment variable `ANDROID_NDK_HOME` to `/path/to/android-ndk`
|
||||
* (optional) Set environment variable `ANDROID_NDK_HOME` to `/path/to/android-ndk` (default: `$ANDROID_HOME/ndk-bundle`)
|
||||
* Set environment variable `GOROOT_BOOTSTRAP` to `/path/to/go`
|
||||
* Create your key following the instructions at https://developer.android.com/studio/publish/app-signing.html
|
||||
* Create `mobile/local.properties` from `mobile/local.properties.example` with your own key information
|
||||
* Invoke the building like this
|
||||
@@ -29,7 +31,7 @@ A [shadowsocks](http://shadowsocks.org) client for Android, written in Scala.
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Build the App
|
||||
sbt clean android:package-release
|
||||
sbt clean go-build android:package-release
|
||||
```
|
||||
|
||||
### TRANSLATE
|
||||
@@ -50,7 +52,7 @@ Translators can go to [POEditor](https://poeditor.com/join/project/u5VHO9vhSf) t
|
||||
<li>pcre: <a href="https://android.googlesource.com/platform/external/pcre/+/master/dist2/LICENCE">BSD</a></li>
|
||||
<li>libancillary: <a href="https://github.com/shadowsocks/libancillary/blob/shadowsocks-android/COPYING">BSD</a></li>
|
||||
<li>shadowsocks-libev: <a href="https://github.com/shadowsocks/shadowsocks-libev/blob/master/LICENSE">GPLv3</a></li>
|
||||
<li>pdnsd: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/pdnsd/COPYING">GPLv3</a></li>
|
||||
<li>overture: <a href="https://github.com/shawn1m/overture/blob/master/LICENSE">MIT</a></li>
|
||||
<li>libev: <a href="https://github.com/shadowsocks/shadowsocks-libev/blob/master/libev/LICENSE">GPLv2</a></li>
|
||||
<li>libsodium: <a href="https://github.com/jedisct1/libsodium/blob/master/LICENSE">ISC</a></li>
|
||||
<li>libudns: <a href="https://github.com/shadowsocks/libudns/blob/master/COPYING.LGPL">LGPL</a></li>
|
||||
|
||||
@@ -18,7 +18,7 @@ lazy val commonSettings = Seq(
|
||||
typedResources := false
|
||||
)
|
||||
|
||||
val supportLibsVersion = "25.1.1"
|
||||
val supportLibsVersion = "25.2.0"
|
||||
lazy val root = Project(id = "shadowsocks-android", base = file("."))
|
||||
.settings(commonSettings)
|
||||
.aggregate(plugin, mobile)
|
||||
|
||||
+15
-7
@@ -2,8 +2,8 @@ enablePlugins(AndroidApp)
|
||||
android.useSupportVectors
|
||||
|
||||
name := "shadowsocks"
|
||||
version := "4.0.3"
|
||||
versionCode := Some(178)
|
||||
version := "4.1.2"
|
||||
versionCode := Some(182)
|
||||
|
||||
proguardOptions ++=
|
||||
"-keep class com.github.shadowsocks.JniHelper { *; }" ::
|
||||
@@ -15,24 +15,32 @@ proguardOptions ++=
|
||||
|
||||
resConfigs := Seq("ja", "ru", "zh-rCN", "zh-rTW")
|
||||
|
||||
val playServicesVersion = "10.0.1"
|
||||
val playServicesVersion = "10.2.0"
|
||||
resolvers += Resolver.jcenterRepo
|
||||
libraryDependencies ++=
|
||||
"com.futuremind.recyclerfastscroll" % "fastscroll" % "0.2.5" ::
|
||||
"com.evernote" % "android-job" % "1.1.5" ::
|
||||
"com.evernote" % "android-job" % "1.1.7" ::
|
||||
"com.github.jorgecastilloprz" % "fabprogresscircle" % "1.01" ::
|
||||
"com.google.android.gms" % "play-services-ads" % playServicesVersion ::
|
||||
"com.google.android.gms" % "play-services-analytics" % playServicesVersion ::
|
||||
"com.google.android.gms" % "play-services-gcm" % playServicesVersion ::
|
||||
"com.j256.ormlite" % "ormlite-android" % "5.0" ::
|
||||
"com.mikepenz" % "crossfader" % "1.5.0" ::
|
||||
"com.mikepenz" % "fastadapter" % "2.1.6" ::
|
||||
"com.mikepenz" % "fastadapter" % "2.1.7" ::
|
||||
"com.mikepenz" % "iconics-core" % "2.8.2" ::
|
||||
"com.mikepenz" % "materialdrawer" % "5.8.1" ::
|
||||
"com.mikepenz" % "materialize" % "1.0.0" ::
|
||||
"com.mikepenz" % "materialdrawer" % "5.8.2" ::
|
||||
"com.mikepenz" % "materialize" % "1.0.1" ::
|
||||
"com.squareup.okhttp3" % "okhttp" % "3.6.0" ::
|
||||
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2" ::
|
||||
"dnsjava" % "dnsjava" % "2.1.8" ::
|
||||
"eu.chainfire" % "libsuperuser" % "1.0.0.201608240809" ::
|
||||
"net.glxn.qrgen" % "android" % "2.0" ::
|
||||
Nil
|
||||
|
||||
lazy val goBuild = TaskKey[Unit]("go-build", "Build go and kcptun")
|
||||
goBuild := {
|
||||
Process(Seq("mobile/src/overture/make.bash", minSdkVersion.value)) ! streams.value.log match {
|
||||
case 0 => // Success!
|
||||
case n => sys.error(s"Native build script exit code: $n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
android:process=":bg"/>
|
||||
<service android:name="com.evernote.android.job.gcm.PlatformGcmService"
|
||||
android:process=":bg"/>
|
||||
<service android:name="com.evernote.android.job.JobRescheduleService"
|
||||
android:process=":bg"/>
|
||||
<receiver android:name="com.evernote.android.job.v14.PlatformAlarmReceiver"
|
||||
android:process=":bg"/>
|
||||
<receiver android:name="com.evernote.android.job.JobBootReceiver"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
127.0.0.1 localhost
|
||||
@@ -296,7 +296,7 @@ along with this program. If not, see <a href="http://www.gnu.org/licenses/">http
|
||||
<li>pcre: <a href="https://android.googlesource.com/platform/external/pcre/+/master/dist2/LICENCE">BSD</a></li>
|
||||
<li>libancillary: <a href="https://github.com/shadowsocks/libancillary/blob/shadowsocks-android/COPYING">BSD</a></li>
|
||||
<li>shadowsocks-libev: <a href="https://github.com/shadowsocks/shadowsocks-libev/blob/master/LICENSE">GPLv3</a></li>
|
||||
<li>pdnsd: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/pdnsd/COPYING">GPLv3</a></li>
|
||||
<li>overture: <a href="https://github.com/shawn1m/overture/blob/master/LICENSE">MIT</a></li>
|
||||
<li>libev: <a href="https://github.com/shadowsocks/shadowsocks-libev/blob/master/libev/LICENSE">GPLv2</a></li>
|
||||
<li>libsodium: <a href="https://github.com/jedisct1/libsodium/blob/master/LICENSE">ISC</a></li>
|
||||
<li>libudns: <a href="https://github.com/shadowsocks/libudns/blob/master/COPYING.LGPL">LGPL</a></li>
|
||||
|
||||
@@ -54,7 +54,19 @@ public class JniHelper {
|
||||
? new ErrnoException("kill", errno) : new Exception("kill failed: " + errno);
|
||||
}
|
||||
|
||||
@Deprecated // only implemented for before API 24
|
||||
public static boolean waitForCompat(Process process, long millis) throws Exception {
|
||||
if (Build.VERSION.SDK_INT >= 24) throw new UnsupportedOperationException("Never call this method in OpenJDK!");
|
||||
final Object mutex = getExitValueMutex(process);
|
||||
synchronized (mutex) {
|
||||
if (getExitValue(process) == null) mutex.wait(millis);
|
||||
return getExitValue(process) != null;
|
||||
}
|
||||
}
|
||||
|
||||
private static native int sigterm(Process process);
|
||||
private static native Integer getExitValue(Process process);
|
||||
private static native Object getExitValueMutex(Process process);
|
||||
public static native int sendFd(int fd, String path);
|
||||
public static native void close(int fd);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ LIBEVENT_SOURCES := \
|
||||
|
||||
LOCAL_MODULE := event
|
||||
LOCAL_SRC_FILES := $(addprefix libevent/, $(LIBEVENT_SOURCES))
|
||||
LOCAL_CFLAGS := -O2 -I$(LOCAL_PATH)/libevent \
|
||||
LOCAL_CFLAGS := -O2 -D_EVENT_HAVE_ARC4RANDOM -I$(LOCAL_PATH)/libevent \
|
||||
-I$(LOCAL_PATH)/libevent/include \
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -117,6 +117,22 @@ LOCAL_SRC_FILES := $(addprefix libancillary/, $(ANCILLARY_SOURCE))
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
########################################################
|
||||
## libbloom
|
||||
########################################################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
BLOOM_SOURCE := bloom.c murmur2/MurmurHash2.c
|
||||
|
||||
LOCAL_MODULE := libbloom
|
||||
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libbloom \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libbloom/murmur2
|
||||
|
||||
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libbloom/, $(BLOOM_SOURCE))
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
########################################################
|
||||
## libipset
|
||||
########################################################
|
||||
@@ -223,23 +239,6 @@ LOCAL_CFLAGS := -O2 -std=gnu99 -DUSE_IPTABLES \
|
||||
|
||||
include $(BUILD_SHARED_EXECUTABLE)
|
||||
|
||||
########################################################
|
||||
## pdnsd
|
||||
########################################################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
PDNSD_SOURCES := $(wildcard $(LOCAL_PATH)/pdnsd/src/*.c)
|
||||
|
||||
LOCAL_MODULE := pdnsd
|
||||
LOCAL_SRC_FILES := $(PDNSD_SOURCES:$(LOCAL_PATH)/%=%)
|
||||
LOCAL_CFLAGS := -DANDROID -Wall -O2 -I$(LOCAL_PATH)/pdnsd \
|
||||
-I$(LOCAL_PATH)/include/pdnsd -I$(LOCAL_PATH)/libancillary
|
||||
LOCAL_STATIC_LIBRARIES := libancillary
|
||||
LOCAL_LDLIBS := -llog
|
||||
|
||||
include $(BUILD_SHARED_EXECUTABLE)
|
||||
|
||||
########################################################
|
||||
## shadowsocks-libev local
|
||||
########################################################
|
||||
@@ -250,7 +249,7 @@ SHADOWSOCKS_SOURCES := local.c \
|
||||
cache.c udprelay.c utils.c netutils.c json.c jconf.c \
|
||||
acl.c http.c tls.c rule.c \
|
||||
crypto.c aead.c stream.c base64.c \
|
||||
plugin.c \
|
||||
plugin.c ppbloom.c \
|
||||
android.c
|
||||
|
||||
LOCAL_MODULE := ss-local
|
||||
@@ -264,13 +263,14 @@ LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DMODULE_LOCAL \
|
||||
-I$(LOCAL_PATH)/mbedtls/include \
|
||||
-I$(LOCAL_PATH)/pcre \
|
||||
-I$(LOCAL_PATH)/libudns \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||
-I$(LOCAL_PATH)/libsodium/src/libsodium/include \
|
||||
-I$(LOCAL_PATH)/libsodium/src/libsodium/include/sodium \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libipset/include \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libbloom \
|
||||
-I$(LOCAL_PATH)/libev
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libev libmbedtls libipset libcork libudns \
|
||||
LOCAL_STATIC_LIBRARIES := libev libmbedtls libipset libcork libbloom libudns \
|
||||
libsodium libancillary libpcre
|
||||
|
||||
LOCAL_LDLIBS := -llog
|
||||
@@ -286,7 +286,7 @@ include $(CLEAR_VARS)
|
||||
SHADOWSOCKS_SOURCES := tunnel.c \
|
||||
cache.c udprelay.c utils.c netutils.c json.c jconf.c \
|
||||
crypto.c aead.c stream.c base64.c \
|
||||
plugin.c \
|
||||
plugin.c ppbloom.c \
|
||||
android.c
|
||||
|
||||
LOCAL_MODULE := ss-tunnel
|
||||
@@ -297,14 +297,15 @@ LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DMODULE_TUNNEL \
|
||||
-I$(LOCAL_PATH)/libancillary \
|
||||
-I$(LOCAL_PATH)/include \
|
||||
-I$(LOCAL_PATH)/libudns \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||
-I$(LOCAL_PATH)/libsodium/src/libsodium/include \
|
||||
-I$(LOCAL_PATH)/libsodium/src/libsodium/include/sodium \
|
||||
-I$(LOCAL_PATH)/mbedtls/include \
|
||||
-I$(LOCAL_PATH)/libev \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||
-I$(LOCAL_PATH)/shadowsocks-libev/libbloom \
|
||||
-I$(LOCAL_PATH)/include/shadowsocks-libev
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libev libmbedtls libsodium libcork libudns libancillary
|
||||
LOCAL_STATIC_LIBRARIES := libev libmbedtls libsodium libcork libbloom libudns libancillary
|
||||
|
||||
LOCAL_LDLIBS := -llog
|
||||
|
||||
@@ -476,6 +477,17 @@ LOCAL_SRC_FILES := $(addprefix pcre/, $(libpcre_src_files))
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
########################################################
|
||||
## overture
|
||||
########################################################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := overture
|
||||
LOCAL_SRC_FILES := overture/$(TARGET_ARCH_ABI)/liboverture.so
|
||||
|
||||
include $(PREBUILT_SHARED_LIBRARY)
|
||||
|
||||
# Import cpufeatures
|
||||
$(call import-module,android/cpufeatures)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
APP_ABI := armeabi-v7a x86
|
||||
APP_ABI := armeabi-v7a arm64-v8a x86
|
||||
APP_PLATFORM := android-19
|
||||
APP_STL := stlport_static
|
||||
NDK_TOOLCHAIN_VERSION := clang
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define THROW(env, clazz, msg) do { env->ThrowNew(env->FindClass(clazz), msg); } while (0)
|
||||
|
||||
static jclass ProcessImpl;
|
||||
static jfieldID ProcessImpl_pid;
|
||||
static jfieldID ProcessImpl_pid, ProcessImpl_exitValue, ProcessImpl_exitValueMutex;
|
||||
|
||||
static int sdk_version() {
|
||||
char version[PROP_VALUE_MAX + 1];
|
||||
@@ -41,6 +41,24 @@ jint Java_com_github_shadowsocks_jnihelper_sigterm(JNIEnv *env, jobject thiz, jo
|
||||
return kill(pid, SIGTERM) == -1 && errno != ESRCH ? errno : 0;
|
||||
}
|
||||
|
||||
jobject Java_com_github_shadowsocks_jnihelper_getExitValue(JNIEnv *env, jobject thiz, jobject process) {
|
||||
if (!env->IsInstanceOf(process, ProcessImpl)) {
|
||||
THROW(env, "java/lang/ClassCastException",
|
||||
"Unsupported process object. Only java.lang.ProcessManager$ProcessImpl is accepted.");
|
||||
return NULL;
|
||||
}
|
||||
return env->GetObjectField(process, ProcessImpl_exitValue);
|
||||
}
|
||||
|
||||
jobject Java_com_github_shadowsocks_jnihelper_getExitValueMutex(JNIEnv *env, jobject thiz, jobject process) {
|
||||
if (!env->IsInstanceOf(process, ProcessImpl)) {
|
||||
THROW(env, "java/lang/ClassCastException",
|
||||
"Unsupported process object. Only java.lang.ProcessManager$ProcessImpl is accepted.");
|
||||
return NULL;
|
||||
}
|
||||
return env->GetObjectField(process, ProcessImpl_exitValueMutex);
|
||||
}
|
||||
|
||||
void Java_com_github_shadowsocks_jnihelper_close(JNIEnv *env, jobject thiz, jint fd) {
|
||||
close(fd);
|
||||
}
|
||||
@@ -84,11 +102,13 @@ static JNINativeMethod method_table[] = {
|
||||
{ "sendFd", "(ILjava/lang/String;)I",
|
||||
(void*) Java_com_github_shadowsocks_jnihelper_sendfd },
|
||||
{ "sigterm", "(Ljava/lang/Process;)I",
|
||||
(void*) Java_com_github_shadowsocks_jnihelper_sigterm }
|
||||
(void*) Java_com_github_shadowsocks_jnihelper_sigterm },
|
||||
{ "getExitValue", "(Ljava/lang/Process;)Ljava/lang/Integer;",
|
||||
(void*) Java_com_github_shadowsocks_jnihelper_getExitValue },
|
||||
{ "getExitValueMutex", "(Ljava/lang/Process;)Ljava/lang/Object;",
|
||||
(void*) Java_com_github_shadowsocks_jnihelper_getExitValueMutex }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Register several native methods for one class.
|
||||
*/
|
||||
@@ -161,6 +181,14 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
THROW(env, "java/lang/RuntimeException", "ProcessManager$ProcessImpl.pid not found");
|
||||
goto bail;
|
||||
}
|
||||
if (!(ProcessImpl_exitValue = env->GetFieldID(ProcessImpl, "exitValue", "Ljava/lang/Integer;"))) {
|
||||
THROW(env, "java/lang/RuntimeException", "ProcessManager$ProcessImpl.exitValue not found");
|
||||
goto bail;
|
||||
}
|
||||
if (!(ProcessImpl_exitValueMutex = env->GetFieldID(ProcessImpl, "exitValueMutex", "Ljava/lang/Object;"))) {
|
||||
THROW(env, "java/lang/RuntimeException", "ProcessManager$ProcessImpl.exitValueMutex not found");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
result = JNI_VERSION_1_6;
|
||||
|
||||
Submodule mobile/src/main/jni/pdnsd deleted from f6b0a56c74
Submodule mobile/src/main/jni/shadowsocks-libev updated: 46fa5de9e4...de0cebb62e
@@ -39,11 +39,11 @@ import com.github.shadowsocks.database.Profile
|
||||
import com.github.shadowsocks.plugin.{PluginConfiguration, PluginManager, PluginOptions}
|
||||
import com.github.shadowsocks.utils._
|
||||
import okhttp3.{Dns, FormBody, OkHttpClient, Request}
|
||||
import org.json.JSONObject
|
||||
import org.json.{JSONArray, JSONObject}
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.collection.JavaConversions._
|
||||
import scala.util.Random
|
||||
|
||||
trait BaseService extends Service {
|
||||
@@ -328,4 +328,44 @@ trait BaseService extends Service {
|
||||
IOUtils.writeString(new File(getFilesDir, file), config.toString)
|
||||
file
|
||||
}
|
||||
|
||||
protected final def buildOvertureConfig(file: String): String = {
|
||||
val config = new JSONObject()
|
||||
.put("BindAddress", ":" + (profile.localPort + 53))
|
||||
.put("RedirectIPv6Record", true)
|
||||
.put("DomainBase64Decode", true)
|
||||
.put("HostsFile", "hosts")
|
||||
.put("MinimumTTL", 3600)
|
||||
.put("CacheSize", 4096)
|
||||
def makeDns(name: String, address: String, edns: Boolean = true) = {
|
||||
val dns = new JSONObject()
|
||||
.put("Name", name)
|
||||
.put("Address", address + ":53")
|
||||
.put("Timeout", 6)
|
||||
.put("EDNSClientSubnet", new JSONObject().put("Policy", "disable"))
|
||||
if (edns) dns
|
||||
.put("Protocol", "tcp")
|
||||
.put("Socks5Address", "127.0.0.1:" + profile.localPort)
|
||||
else dns.put("Protocol", "udp")
|
||||
dns
|
||||
}
|
||||
profile.route match {
|
||||
case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES => config
|
||||
.put("PrimaryDNS", new JSONArray(Array(
|
||||
makeDns("Primary-1", "119.29.29.29", edns = false),
|
||||
makeDns("Primary-2", "114.114.114.114", edns = false)
|
||||
)))
|
||||
.put("AlternativeDNS", new JSONArray().put(makeDns("Alternative", profile.remoteDns)))
|
||||
.put("IPNetworkFile", "china_ip_list.txt")
|
||||
.put("DomainFile", "gfwlist.txt")
|
||||
case Acl.CHINALIST => config
|
||||
.put("PrimaryDNS", new JSONArray().put(makeDns("Primary", "119.29.29.29")))
|
||||
.put("AlternativeDNS", new JSONArray().put(makeDns("Alternative", profile.remoteDns)))
|
||||
case _ => config
|
||||
.put("PrimaryDNS", new JSONArray().put(makeDns("Primary", profile.remoteDns)))
|
||||
.put("AlternativeDNS", new JSONArray().put(makeDns("Alternative", "208.67.222.222")))
|
||||
}
|
||||
IOUtils.writeString(new File(getFilesDir, file), config.toString)
|
||||
file
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ class GuardedProcess(cmd: String*) {
|
||||
private def destroyProcess() {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
JniHelper.sigtermCompat(process)
|
||||
process.waitFor()
|
||||
JniHelper.waitForCompat(process, 500)
|
||||
}
|
||||
process.destroy()
|
||||
}
|
||||
|
||||
@@ -197,15 +197,17 @@ class ShadowsocksApplication extends Application {
|
||||
|
||||
def copyAssets() {
|
||||
val assetManager = getAssets
|
||||
var files: Array[String] = null
|
||||
try files = assetManager.list("acl") catch {
|
||||
case e: IOException =>
|
||||
Log.e(TAG, e.getMessage)
|
||||
app.track(e)
|
||||
for (dir <- List("acl", "overture")) {
|
||||
var files: Array[String] = null
|
||||
try files = assetManager.list(dir) catch {
|
||||
case e: IOException =>
|
||||
Log.e(TAG, e.getMessage)
|
||||
app.track(e)
|
||||
}
|
||||
if (files != null) for (file <- files) autoClose(assetManager.open(dir + "/" + file))(in =>
|
||||
autoClose(new FileOutputStream(new File(getFilesDir, file)))(out =>
|
||||
IOUtils.copy(in, out)))
|
||||
}
|
||||
if (files != null) for (file <- files) autoClose(assetManager.open("acl/" + file))(in =>
|
||||
autoClose(new FileOutputStream(new File(getFilesDir, file)))(out =>
|
||||
IOUtils.copy(in, out)))
|
||||
editor.putInt(Key.currentVersionCode, BuildConfig.VERSION_CODE).apply()
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class ShadowsocksNatService extends BaseService {
|
||||
var sslocalProcess: GuardedProcess = _
|
||||
var sstunnelProcess: GuardedProcess = _
|
||||
var redsocksProcess: GuardedProcess = _
|
||||
var pdnsdProcess: GuardedProcess = _
|
||||
var overtureProcess: GuardedProcess = _
|
||||
var su: Shell.Interactive = _
|
||||
|
||||
def startShadowsocksDaemon() {
|
||||
@@ -74,7 +74,7 @@ class ShadowsocksNatService extends BaseService {
|
||||
"-t", "10",
|
||||
"-b", "127.0.0.1",
|
||||
"-l", (profile.localPort + 63).toString,
|
||||
"-L", profile.remoteDns + ":53",
|
||||
"-L", profile.remoteDns.trim + ":53",
|
||||
"-c", buildShadowsocksConfig("ss-tunnel-nat.conf"))
|
||||
|
||||
if (profile.udpdns) cmd.append("-u")
|
||||
@@ -83,21 +83,8 @@ class ShadowsocksNatService extends BaseService {
|
||||
}
|
||||
|
||||
def startDnsDaemon() {
|
||||
val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0"
|
||||
IOUtils.writeString(new File(getFilesDir, "pdnsd-nat.conf"), profile.route match {
|
||||
case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES =>
|
||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getCacheDir.getAbsolutePath,
|
||||
"127.0.0.1", profile.localPort + 53, "114.114.114.114, 223.5.5.5, 1.2.4.8",
|
||||
getBlackList, reject, profile.localPort + 63, reject)
|
||||
case Acl.CHINALIST =>
|
||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getCacheDir.getAbsolutePath,
|
||||
"127.0.0.1", profile.localPort + 53, "8.8.8.8, 8.8.4.4, 208.67.222.222",
|
||||
"", reject, profile.localPort + 63, reject)
|
||||
case _ =>
|
||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "", getCacheDir.getAbsolutePath,
|
||||
"127.0.0.1", profile.localPort + 53, profile.localPort + 63, reject)
|
||||
})
|
||||
pdnsdProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/libpdnsd.so", "-c", "pdnsd-nat.conf")
|
||||
overtureProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/liboverture.so",
|
||||
"-c", buildOvertureConfig("overture-nat.conf"))
|
||||
.start()
|
||||
}
|
||||
|
||||
@@ -111,11 +98,13 @@ class ShadowsocksNatService extends BaseService {
|
||||
/** Called when the activity is first created. */
|
||||
def handleConnection() {
|
||||
|
||||
startDNSTunnel()
|
||||
startRedsocksDaemon()
|
||||
startShadowsocksDaemon()
|
||||
|
||||
if (!profile.udpdns) startDnsDaemon()
|
||||
if (!profile.udpdns)
|
||||
startDnsDaemon()
|
||||
else
|
||||
startDNSTunnel()
|
||||
|
||||
setupIptables()
|
||||
|
||||
@@ -143,9 +132,9 @@ class ShadowsocksNatService extends BaseService {
|
||||
redsocksProcess.destroy()
|
||||
redsocksProcess = null
|
||||
}
|
||||
if (pdnsdProcess != null) {
|
||||
pdnsdProcess.destroy()
|
||||
pdnsdProcess = null
|
||||
if (overtureProcess != null) {
|
||||
overtureProcess.destroy()
|
||||
overtureProcess = null
|
||||
}
|
||||
|
||||
su.addCommand("iptables -t nat -F OUTPUT")
|
||||
|
||||
@@ -45,8 +45,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
private var notification: ShadowsocksNotification = _
|
||||
|
||||
var sslocalProcess: GuardedProcess = _
|
||||
var sstunnelProcess: GuardedProcess = _
|
||||
var pdnsdProcess: GuardedProcess = _
|
||||
var overtureProcess: GuardedProcess = _
|
||||
var tun2socksProcess: GuardedProcess = _
|
||||
|
||||
override def onBind(intent: Intent): IBinder = {
|
||||
@@ -94,17 +93,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
sslocalProcess.destroy()
|
||||
sslocalProcess = null
|
||||
}
|
||||
if (sstunnelProcess != null) {
|
||||
sstunnelProcess.destroy()
|
||||
sstunnelProcess = null
|
||||
}
|
||||
if (tun2socksProcess != null) {
|
||||
tun2socksProcess.destroy()
|
||||
tun2socksProcess = null
|
||||
}
|
||||
if (pdnsdProcess != null) {
|
||||
pdnsdProcess.destroy()
|
||||
pdnsdProcess = null
|
||||
if (overtureProcess != null) {
|
||||
overtureProcess.destroy()
|
||||
overtureProcess = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,15 +144,14 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
/** Called when the activity is first created. */
|
||||
def handleConnection() {
|
||||
|
||||
val fd = startVpn()
|
||||
if (!sendFd(fd)) throw new Exception("sendFd failed")
|
||||
|
||||
startShadowsocksDaemon()
|
||||
|
||||
if (!profile.udpdns) {
|
||||
startDnsDaemon()
|
||||
startDnsTunnel()
|
||||
}
|
||||
|
||||
val fd = startVpn()
|
||||
if (!sendFd(fd)) throw new Exception("sendFd failed")
|
||||
}
|
||||
|
||||
override protected def buildPluginCommandLine(): ArrayBuffer[String] = super.buildPluginCommandLine() += "-V"
|
||||
@@ -182,33 +176,10 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
sslocalProcess = new GuardedProcess(cmd: _*).start()
|
||||
}
|
||||
|
||||
def startDnsTunnel(): Unit =
|
||||
sstunnelProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/libss-tunnel.so",
|
||||
"-V",
|
||||
"-t", "10",
|
||||
"-b", "127.0.0.1",
|
||||
"-l", (profile.localPort + 63).toString,
|
||||
"-L" , profile.remoteDns + ":53",
|
||||
"-c", buildShadowsocksConfig("ss-tunnel-vpn.conf")).start()
|
||||
|
||||
def startDnsDaemon() {
|
||||
val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0"
|
||||
IOUtils.writeString(new File(getFilesDir, "pdnsd-vpn.conf"), profile.route match {
|
||||
case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES =>
|
||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "protect = \"protect_path\";", getCacheDir.getAbsolutePath,
|
||||
"0.0.0.0", profile.localPort + 53, "114.114.114.114, 223.5.5.5, 1.2.4.8",
|
||||
getBlackList, reject, profile.localPort + 63, reject)
|
||||
case Acl.CHINALIST =>
|
||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "protect = \"protect_path\";", getCacheDir.getAbsolutePath,
|
||||
"0.0.0.0", profile.localPort + 53, "8.8.8.8, 8.8.4.4, 208.67.222.222",
|
||||
"", reject, profile.localPort + 63, reject)
|
||||
case _ =>
|
||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "protect = \"protect_path\";", getCacheDir.getAbsolutePath,
|
||||
"0.0.0.0", profile.localPort + 53, profile.localPort + 63, reject)
|
||||
})
|
||||
val cmd = Array(getApplicationInfo.nativeLibraryDir + "/libpdnsd.so", "-c", "pdnsd-vpn.conf")
|
||||
|
||||
pdnsdProcess = new GuardedProcess(cmd: _*).start()
|
||||
overtureProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/liboverture.so",
|
||||
"-c", buildOvertureConfig("overture-vpn.conf"), "-V")
|
||||
.start()
|
||||
}
|
||||
|
||||
def startVpn(): Int = {
|
||||
@@ -219,7 +190,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
.setMtu(VPN_MTU)
|
||||
.addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24)
|
||||
|
||||
builder.addDnsServer(profile.remoteDns)
|
||||
builder.addDnsServer(profile.remoteDns.trim)
|
||||
|
||||
if (profile.ipv6) {
|
||||
builder.addAddress(PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "1"), 126)
|
||||
@@ -251,7 +222,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
val subnet = Subnet.fromString(cidr)
|
||||
builder.addRoute(subnet.address.getHostAddress, subnet.prefixSize)
|
||||
})
|
||||
builder.addRoute(profile.remoteDns, 32)
|
||||
builder.addRoute(profile.remoteDns.trim, 32)
|
||||
}
|
||||
|
||||
conn = builder.establish()
|
||||
|
||||
@@ -45,86 +45,6 @@ object ConfigUtils {
|
||||
" port = %d;\n" +
|
||||
" type = socks5;\n" +
|
||||
"}\n"
|
||||
|
||||
val PDNSD_LOCAL =
|
||||
"""
|
||||
|global {
|
||||
| perm_cache = 2048;
|
||||
| %s
|
||||
| cache_dir = "%s";
|
||||
| server_ip = %s;
|
||||
| server_port = %d;
|
||||
| query_method = tcp_only;
|
||||
| min_ttl = 15m;
|
||||
| max_ttl = 1w;
|
||||
| timeout = 10;
|
||||
| daemon = off;
|
||||
|}
|
||||
|
|
||||
|server {
|
||||
| label = "local";
|
||||
| ip = 127.0.0.1;
|
||||
| port = %d;
|
||||
| reject = %s;
|
||||
| reject_policy = negate;
|
||||
| reject_recursively = on;
|
||||
|}
|
||||
|
|
||||
|rr {
|
||||
| name=localhost;
|
||||
| reverse=on;
|
||||
| a=127.0.0.1;
|
||||
| owner=localhost;
|
||||
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||
|}
|
||||
""".stripMargin
|
||||
|
||||
val PDNSD_DIRECT =
|
||||
"""
|
||||
|global {
|
||||
| perm_cache = 2048;
|
||||
| %s
|
||||
| cache_dir = "%s";
|
||||
| server_ip = %s;
|
||||
| server_port = %d;
|
||||
| query_method = udp_only;
|
||||
| min_ttl = 15m;
|
||||
| max_ttl = 1w;
|
||||
| timeout = 10;
|
||||
| daemon = off;
|
||||
| par_queries = 4;
|
||||
|}
|
||||
|
|
||||
|server {
|
||||
| label = "remote-servers";
|
||||
| ip = %s;
|
||||
| timeout = 3;
|
||||
| query_method = udp_only;
|
||||
| %s
|
||||
| policy = included;
|
||||
| reject = %s;
|
||||
| reject_policy = fail;
|
||||
| reject_recursively = on;
|
||||
|}
|
||||
|
|
||||
|server {
|
||||
| label = "local-server";
|
||||
| ip = 127.0.0.1;
|
||||
| query_method = tcp_only;
|
||||
| port = %d;
|
||||
| reject = %s;
|
||||
| reject_policy = negate;
|
||||
| reject_recursively = on;
|
||||
|}
|
||||
|
|
||||
|rr {
|
||||
| name=localhost;
|
||||
| reverse=on;
|
||||
| a=127.0.0.1;
|
||||
| owner=localhost;
|
||||
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||
|}
|
||||
""".stripMargin
|
||||
}
|
||||
|
||||
object Key {
|
||||
|
||||
@@ -26,16 +26,16 @@ import com.github.shadowsocks.database.Profile
|
||||
|
||||
object Parser {
|
||||
val TAG = "ShadowParser"
|
||||
private val pattern = "(?i)^ss://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]$".r
|
||||
private val pattern = "(?i)ss://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]".r
|
||||
private val userInfoPattern = "^(.+?):(.*)$".r
|
||||
private val legacyPattern = "^((.+?):(.*)@(.+?):(\\d+?))$".r
|
||||
private val legacyPattern = "^(.+?):(.*)@(.+?):(\\d+?)$".r
|
||||
|
||||
def findAll(data: CharSequence): Iterator[Profile] =
|
||||
pattern.findAllMatchIn(if (data == null) "" else data).map(m => {
|
||||
val uri = Uri.parse(m.matched)
|
||||
uri.getUserInfo match {
|
||||
case null => new String(Base64.decode(uri.getHost, Base64.NO_PADDING), "UTF-8") match {
|
||||
case legacyPattern(_, method, password, host, port) => // legacy uri
|
||||
case null => val str = new String(Base64.decode(uri.getHost, Base64.NO_PADDING), "UTF-8"); str match {
|
||||
case legacyPattern(method, password, host, port) => // legacy uri
|
||||
val profile = new Profile
|
||||
profile.method = method.toLowerCase
|
||||
profile.password = password
|
||||
|
||||
Submodule
+1
Submodule mobile/src/overture added at 862ce347e1
@@ -1,3 +1,5 @@
|
||||
* 0.0.3:
|
||||
* Update support library version to 25.2.0.
|
||||
* 0.0.2:
|
||||
* Add `getOrDefault` to `PluginOptions`;
|
||||
* Update support library version to 25.1.1.
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ enablePlugins(AndroidLib)
|
||||
android.useSupportVectors
|
||||
|
||||
name := "plugin"
|
||||
version := "0.0.2"
|
||||
version := "0.0.3"
|
||||
|
||||
pomExtra in Global := {
|
||||
<url>https://github.com/shadowsocks/shadowsocks-android</url>
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
addSbtPlugin("org.scala-android" % "sbt-android" % "1.7.4")
|
||||
addSbtPlugin("org.scala-android" % "sbt-android" % "1.7.6")
|
||||
|
||||
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.10")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user