Compare commits

...
54 Commits
Author SHA1 Message Date
Max Lv c21bd74302 Merge branch 'beta' 2017-03-11 18:48:12 +08:00
Max Lv a8822330a3 Bump version 2017-03-11 18:43:03 +08:00
Max Lv 1cf6e4802c Update strings 2017-03-11 18:15:34 +08:00
Max Lv f64014eb7b Always forwording UDP traffic #1156 2017-03-11 15:49:06 +08:00
Mygod 2f6f991e6e Fix literal IPv6 address handling in URIs 2017-03-11 12:33:27 +08:00
Mygod 90e00a3857 Refine README.md 2017-03-11 12:11:52 +08:00
Mygod 712b764a9b Update README.md to reflect changes in sbt-android 2017-03-10 08:55:49 +08:00
Mygod 019f9d30e8 Remove redundant group in legacyPattern 2017-03-10 08:54:03 +08:00
Mygod 9c97dc9bf6 Update README.md to reflect changes in sbt-android 2017-03-09 23:54:48 +08:00
Mygod 7d2e0a515f Remove redundant group in legacyPattern 2017-03-09 20:46:34 +08:00
Mygod 26b68876f4 Update build instructions 2017-03-08 01:03:46 +08:00
Mygod a494f56ce8 Refine #1148 2017-03-08 00:25:05 +08:00
Max Lv a433822d0a Add arm64 support 2017-03-07 10:30:29 +08:00
Max Lv 60d7d90565 Fix a DNS issue with GFWList mode 2017-03-05 16:11:24 +08:00
Max Lv d2ba9493c0 Bump version 2017-03-04 10:26:43 +08:00
Max Lv 0eaece7af9 Remove external IP #1148 2017-03-04 09:56:52 +08:00
Max Lv 96320896aa Update licenses 2017-03-02 14:53:53 +08:00
Max Lv 54efe36ffc Add missing -V option 2017-03-02 09:28:12 +08:00
Max Lv d5d6740a5a Fix typos 2017-03-02 09:22:40 +08:00
Mygod 2e69eafdf8 Refine timeout for getting external IP 2017-03-01 22:49:10 +08:00
Mygod 86773085c3 Wait for process to terminate with a better way
Refine #1122.
2017-03-01 22:28:35 +08:00
Mygod b6667b9e0f Use more readable variable name 2017-03-01 17:25:23 +08:00
Max Lv 0ee7e9d40e Build overture from source code 2017-03-01 16:39:04 +08:00
Mygod 5f2ce1804f Refine Overture configuration generation
* Respect remoteDns settings more;
* Make code more readable;
* Handle illegal characters in remoteDns.
2017-03-01 16:08:19 +08:00
Mygod a5e316999a Update dependencies 2017-03-01 15:30:03 +08:00
Max Lv 64a3d75ba2 Update shadowsocks-libev 2017-03-01 12:02:36 +08:00
Max Lv 9d09c9a097 Bump version 2017-03-01 09:59:00 +08:00
Max Lv b78f48504f Merge branch 'develop' into beta 2017-03-01 09:57:45 +08:00
Max Lv a61b03c86c Add 600ms timeout for waitpid 2017-03-01 09:53:35 +08:00
Max Lv f43362fb18 Fix overture with NAT mode 2017-02-25 16:58:31 +08:00
Max Lv 4f0e527df7 Replace PDNSD with overture 2017-02-24 21:00:40 +08:00
Max Lv a8878298cc Bump version 2017-02-24 19:44:46 +08:00
Max Lv c920c0daa4 Bump version 2017-02-24 19:37:23 +08:00
Mygod 8e3854b496 Update dependencies 2017-02-24 19:37:23 +08:00
Max Lv ad42167b2e Update shadowsocks-libev 2017-02-24 19:37:23 +08:00
Max Lv 3bf0963c5a Trim remoteDns 2017-02-24 19:37:23 +08:00
Max Lv c3315d35ed Fix #1130 2017-02-24 19:37:23 +08:00
Max Lv 103dc10a0a Update shadowsocks-libev 2017-02-24 19:37:23 +08:00
Max Lv 36c94b8d83 Fix a memory leak 2017-02-24 19:37:22 +08:00
Max Lv 890be54403 Bump version 2017-02-24 19:36:44 +08:00
Max Lv 31984d1001 Add prebuilt overture libraries 2017-02-24 17:51:06 +08:00
Mygod df72b29302 Fix malformed URL in about.html 2017-02-23 15:17:57 +08:00
Mygod f30c31ae3e Bump plugin lib version 2017-02-23 14:56:23 +08:00
Mygod 05963b6c82 Update support library 2017-02-23 14:55:32 +08:00
Mygod 98da4cd6e5 Update dependencies 2017-02-23 14:55:07 +08:00
Max Lv 64da35c59b Update shadowsocks-libev 2017-02-22 14:56:31 +08:00
Max Lv 458a3473b1 Trim remoteDns 2017-02-17 20:13:13 +08:00
Max Lv 66db347215 Fix #1130 2017-02-17 19:14:33 +08:00
Max Lv f9e32c995b Update shadowsocks-libev 2017-02-17 13:36:41 +08:00
Max Lv 0626ce8787 Fix a memory leak 2017-02-17 12:35:15 +08:00
Max Lv 11d827c6ba Bump version 2017-02-13 09:29:11 +08:00
Max Lv dc46cd971a Merge branch 'beta' 2017-02-13 09:21:18 +08:00
Max Lv 876e92f275 Bump version 2017-02-13 09:17:59 +08:00
Max Lv 41747c976b Update shadowsocks-libev 2017-02-12 20:24:56 +08:00
34 changed files with 7641 additions and 233 deletions
+1
View File
@@ -9,3 +9,4 @@ local.sbt
mobile/src/main/libs mobile/src/main/libs
mobile/src/main/obj mobile/src/main/obj
mobile/src/main/jni/overture
+3 -4
View File
@@ -17,10 +17,6 @@
path = mobile/src/main/jni/redsocks path = mobile/src/main/jni/redsocks
url = https://github.com/shadowsocks/redsocks.git url = https://github.com/shadowsocks/redsocks.git
branch = shadowsocks-android 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"] [submodule "mobile/src/main/jni/mbedtls"]
path = mobile/src/main/jni/mbedtls path = mobile/src/main/jni/mbedtls
url = https://github.com/ARMmbed/mbedtls url = https://github.com/ARMmbed/mbedtls
@@ -37,3 +33,6 @@
[submodule "mobile/src/main/jni/libudns"] [submodule "mobile/src/main/jni/libudns"]
path = mobile/src/main/jni/libudns path = mobile/src/main/jni/libudns
url = https://github.com/shadowsocks/libudns.git 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
View File
@@ -5,8 +5,9 @@ jdk:
env: env:
global: global:
- NDK_VERSION=r12b - NDK_VERSION=r14
- NDK_CCACHE=ccache - NDK_CCACHE=ccache
- GOROOT_BOOTSTRAP=$GOROOT
- ANDROID_NDK_HOME=$HOME/.android/android-ndk-${NDK_VERSION} - ANDROID_NDK_HOME=$HOME/.android/android-ndk-${NDK_VERSION}
- SBTPATH=$HOME/.sbt - SBTPATH=$HOME/.sbt
- PATH=${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools:${PATH} - PATH=${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools:${PATH}
@@ -49,4 +50,4 @@ install:
fi fi
script: script:
- $SBTPATH/sbt android:package - $SBTPATH/sbt go-build android:package
+6 -4
View File
@@ -12,15 +12,17 @@ A [shadowsocks](http://shadowsocks.org) client for Android, written in Scala.
* JDK 1.8 * JDK 1.8
* SBT 0.13.0+ * SBT 0.13.0+
* Go 1.4+
* Android SDK * Android SDK
- Build Tools 25+ - Build Tools 25+
- Android Support Repository and Google Repository (see `build.sbt` for version) - Android Support Repository and Google Repository (see `build.sbt` for version)
* Android NDK r12b+ - Android NDK r14+
### BUILD ### BUILD
* Set environment variable `ANDROID_HOME` to `/path/to/android-sdk` * 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 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 * Create `mobile/local.properties` from `mobile/local.properties.example` with your own key information
* Invoke the building like this * 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 git submodule update --init --recursive
# Build the App # Build the App
sbt clean android:package-release sbt clean go-build android:package-release
``` ```
### TRANSLATE ### 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>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>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>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>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>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> <li>libudns: <a href="https://github.com/shadowsocks/libudns/blob/master/COPYING.LGPL">LGPL</a></li>
+1 -1
View File
@@ -18,7 +18,7 @@ lazy val commonSettings = Seq(
typedResources := false typedResources := false
) )
val supportLibsVersion = "25.1.1" val supportLibsVersion = "25.2.0"
lazy val root = Project(id = "shadowsocks-android", base = file(".")) lazy val root = Project(id = "shadowsocks-android", base = file("."))
.settings(commonSettings) .settings(commonSettings)
.aggregate(plugin, mobile) .aggregate(plugin, mobile)
+15 -7
View File
@@ -2,8 +2,8 @@ enablePlugins(AndroidApp)
android.useSupportVectors android.useSupportVectors
name := "shadowsocks" name := "shadowsocks"
version := "4.0.2" version := "4.1.3"
versionCode := Some(177) versionCode := Some(183)
proguardOptions ++= proguardOptions ++=
"-keep class com.github.shadowsocks.JniHelper { *; }" :: "-keep class com.github.shadowsocks.JniHelper { *; }" ::
@@ -15,24 +15,32 @@ proguardOptions ++=
resConfigs := Seq("ja", "ru", "zh-rCN", "zh-rTW") resConfigs := Seq("ja", "ru", "zh-rCN", "zh-rTW")
val playServicesVersion = "10.0.1" val playServicesVersion = "10.2.0"
resolvers += Resolver.jcenterRepo resolvers += Resolver.jcenterRepo
libraryDependencies ++= libraryDependencies ++=
"com.futuremind.recyclerfastscroll" % "fastscroll" % "0.2.5" :: "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.github.jorgecastilloprz" % "fabprogresscircle" % "1.01" ::
"com.google.android.gms" % "play-services-ads" % playServicesVersion :: "com.google.android.gms" % "play-services-ads" % playServicesVersion ::
"com.google.android.gms" % "play-services-analytics" % playServicesVersion :: "com.google.android.gms" % "play-services-analytics" % playServicesVersion ::
"com.google.android.gms" % "play-services-gcm" % playServicesVersion :: "com.google.android.gms" % "play-services-gcm" % playServicesVersion ::
"com.j256.ormlite" % "ormlite-android" % "5.0" :: "com.j256.ormlite" % "ormlite-android" % "5.0" ::
"com.mikepenz" % "crossfader" % "1.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" % "iconics-core" % "2.8.2" ::
"com.mikepenz" % "materialdrawer" % "5.8.1" :: "com.mikepenz" % "materialdrawer" % "5.8.2" ::
"com.mikepenz" % "materialize" % "1.0.0" :: "com.mikepenz" % "materialize" % "1.0.1" ::
"com.squareup.okhttp3" % "okhttp" % "3.6.0" :: "com.squareup.okhttp3" % "okhttp" % "3.6.0" ::
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2" :: "com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2" ::
"dnsjava" % "dnsjava" % "2.1.8" :: "dnsjava" % "dnsjava" % "2.1.8" ::
"eu.chainfire" % "libsuperuser" % "1.0.0.201608240809" :: "eu.chainfire" % "libsuperuser" % "1.0.0.201608240809" ::
"net.glxn.qrgen" % "android" % "2.0" :: "net.glxn.qrgen" % "android" % "2.0" ::
Nil 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")
}
}
+2
View File
@@ -144,6 +144,8 @@
android:process=":bg"/> android:process=":bg"/>
<service android:name="com.evernote.android.job.gcm.PlatformGcmService" <service android:name="com.evernote.android.job.gcm.PlatformGcmService"
android:process=":bg"/> android:process=":bg"/>
<service android:name="com.evernote.android.job.JobRescheduleService"
android:process=":bg"/>
<receiver android:name="com.evernote.android.job.v14.PlatformAlarmReceiver" <receiver android:name="com.evernote.android.job.v14.PlatformAlarmReceiver"
android:process=":bg"/> android:process=":bg"/>
<receiver android:name="com.evernote.android.job.JobBootReceiver" <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
+1
View File
@@ -0,0 +1 @@
127.0.0.1 localhost
+2 -2
View File
@@ -275,7 +275,7 @@ img {
<body> <body>
<p>A <a href="http://shadowsocks.org">Shadowsocks</a> client for Android, written in Scala.</p> <p>A <a href="http://shadowsocks.org">Shadowsocks</a> client for Android, written in Scala.</p>
<p>Copyright (C) 2017 by Max Lv <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x6d;&#97;x&#46;&#99;.&#108;&#118;&#x40;&#103;&#109;&#97;&#x69;&#108;&#46;&#x63;&#x6f;&#109;">&#x6d;&#97;&#x78;.&#x63;&#x2e;&#108;v&#64;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a></p> <p>Copyright (C) 2017 by Max Lv <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x6d;&#97;x&#46;&#99;.&#108;&#118;&#x40;&#103;&#109;&#97;&#x69;&#108;&#46;&#x63;&#x6f;&#109;">&#x6d;&#97;&#x78;.&#x63;&#x2e;&#108;v&#64;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a></p>
<p>Copyright (C) 2017 by Mygod Studio <a href="contact-shadowsocks-android@mygod.be">contact-shadowsocks-android@mygod.be</a></p> <p>Copyright (C) 2017 by Mygod Studio <a href="mailto:contact-shadowsocks-android@mygod.be">contact-shadowsocks-android@mygod.be</a></p>
<p>This program is free software: you can redistribute it and/or modify <p>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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@@ -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>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>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>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>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>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> <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); ? 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 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 int sendFd(int fd, String path);
public static native void close(int fd); public static native void close(int fd);
} }
+36 -24
View File
@@ -97,7 +97,7 @@ LIBEVENT_SOURCES := \
LOCAL_MODULE := event LOCAL_MODULE := event
LOCAL_SRC_FILES := $(addprefix libevent/, $(LIBEVENT_SOURCES)) 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 \ -I$(LOCAL_PATH)/libevent/include \
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
@@ -117,6 +117,22 @@ LOCAL_SRC_FILES := $(addprefix libancillary/, $(ANCILLARY_SOURCE))
include $(BUILD_STATIC_LIBRARY) 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 ## libipset
######################################################## ########################################################
@@ -223,23 +239,6 @@ LOCAL_CFLAGS := -O2 -std=gnu99 -DUSE_IPTABLES \
include $(BUILD_SHARED_EXECUTABLE) 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 ## shadowsocks-libev local
######################################################## ########################################################
@@ -250,7 +249,7 @@ SHADOWSOCKS_SOURCES := local.c \
cache.c udprelay.c utils.c netutils.c json.c jconf.c \ cache.c udprelay.c utils.c netutils.c json.c jconf.c \
acl.c http.c tls.c rule.c \ acl.c http.c tls.c rule.c \
crypto.c aead.c stream.c base64.c \ crypto.c aead.c stream.c base64.c \
plugin.c \ plugin.c ppbloom.c \
android.c android.c
LOCAL_MODULE := ss-local 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)/mbedtls/include \
-I$(LOCAL_PATH)/pcre \ -I$(LOCAL_PATH)/pcre \
-I$(LOCAL_PATH)/libudns \ -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 \
-I$(LOCAL_PATH)/libsodium/src/libsodium/include/sodium \ -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/libipset/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libbloom \
-I$(LOCAL_PATH)/libev -I$(LOCAL_PATH)/libev
LOCAL_STATIC_LIBRARIES := libev libmbedtls libipset libcork libudns \ LOCAL_STATIC_LIBRARIES := libev libmbedtls libipset libcork libbloom libudns \
libsodium libancillary libpcre libsodium libancillary libpcre
LOCAL_LDLIBS := -llog LOCAL_LDLIBS := -llog
@@ -286,7 +286,7 @@ include $(CLEAR_VARS)
SHADOWSOCKS_SOURCES := tunnel.c \ SHADOWSOCKS_SOURCES := tunnel.c \
cache.c udprelay.c utils.c netutils.c json.c jconf.c \ cache.c udprelay.c utils.c netutils.c json.c jconf.c \
crypto.c aead.c stream.c base64.c \ crypto.c aead.c stream.c base64.c \
plugin.c \ plugin.c ppbloom.c \
android.c android.c
LOCAL_MODULE := ss-tunnel LOCAL_MODULE := ss-tunnel
@@ -297,14 +297,15 @@ LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DMODULE_TUNNEL \
-I$(LOCAL_PATH)/libancillary \ -I$(LOCAL_PATH)/libancillary \
-I$(LOCAL_PATH)/include \ -I$(LOCAL_PATH)/include \
-I$(LOCAL_PATH)/libudns \ -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 \
-I$(LOCAL_PATH)/libsodium/src/libsodium/include/sodium \ -I$(LOCAL_PATH)/libsodium/src/libsodium/include/sodium \
-I$(LOCAL_PATH)/mbedtls/include \ -I$(LOCAL_PATH)/mbedtls/include \
-I$(LOCAL_PATH)/libev \ -I$(LOCAL_PATH)/libev \
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libbloom \
-I$(LOCAL_PATH)/include/shadowsocks-libev -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 LOCAL_LDLIBS := -llog
@@ -476,6 +477,17 @@ LOCAL_SRC_FILES := $(addprefix pcre/, $(libpcre_src_files))
include $(BUILD_STATIC_LIBRARY) 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 # Import cpufeatures
$(call import-module,android/cpufeatures) $(call import-module,android/cpufeatures)
+1 -1
View File
@@ -1,4 +1,4 @@
APP_ABI := armeabi-v7a x86 APP_ABI := armeabi-v7a arm64-v8a x86
APP_PLATFORM := android-19 APP_PLATFORM := android-19
APP_STL := stlport_static APP_STL := stlport_static
NDK_TOOLCHAIN_VERSION := clang NDK_TOOLCHAIN_VERSION := clang
+32 -4
View File
@@ -22,7 +22,7 @@
#define THROW(env, clazz, msg) do { env->ThrowNew(env->FindClass(clazz), msg); } while (0) #define THROW(env, clazz, msg) do { env->ThrowNew(env->FindClass(clazz), msg); } while (0)
static jclass ProcessImpl; static jclass ProcessImpl;
static jfieldID ProcessImpl_pid; static jfieldID ProcessImpl_pid, ProcessImpl_exitValue, ProcessImpl_exitValueMutex;
static int sdk_version() { static int sdk_version() {
char version[PROP_VALUE_MAX + 1]; 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; 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) { void Java_com_github_shadowsocks_jnihelper_close(JNIEnv *env, jobject thiz, jint fd) {
close(fd); close(fd);
} }
@@ -84,11 +102,13 @@ static JNINativeMethod method_table[] = {
{ "sendFd", "(ILjava/lang/String;)I", { "sendFd", "(ILjava/lang/String;)I",
(void*) Java_com_github_shadowsocks_jnihelper_sendfd }, (void*) Java_com_github_shadowsocks_jnihelper_sendfd },
{ "sigterm", "(Ljava/lang/Process;)I", { "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. * 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"); THROW(env, "java/lang/RuntimeException", "ProcessManager$ProcessImpl.pid not found");
goto bail; 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; result = JNI_VERSION_1_6;
+3 -3
View File
@@ -44,8 +44,8 @@
<string name="auto_connect_summary">"システム起動時にバックグラウンドで本サービスを開始"</string> <string name="auto_connect_summary">"システム起動時にバックグラウンドで本サービスを開始"</string>
<string name="tcp_fastopen_summary">"使用するにはROOT権限が必要"</string> <string name="tcp_fastopen_summary">"使用するにはROOT権限が必要"</string>
<string name="tcp_fastopen_summary_unsupported">"ご利用のカーネルバージョンはサポートしておりません:%s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"ご利用のカーネルバージョンはサポートしておりません:%s &lt; 3.7.1"</string>
<string name="udp_dns">"UDP転送"</string> <string name="udp_dns">"DNS転送"</string>
<string name="udp_dns_summary">"UDPプロトコルでリモードサーバーにパケットを転送"</string> <string name="udp_dns_summary">"DNSプロトコルでリモードサーバーにパケットを転送"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"バックグラウンドでサービスを開始しました"</string> <string name="forward_success">"バックグラウンドでサービスを開始しました"</string>
@@ -138,4 +138,4 @@
<string name="proxied_apps_summary_v21">"選択したアプリにプロキシを設定する"</string> <string name="proxied_apps_summary_v21">"選択したアプリにプロキシを設定する"</string>
<string name="acl_rule_templates_generic">"サブネット/ホストネームPCREパターン"</string> <string name="acl_rule_templates_generic">"サブネット/ホストネームPCREパターン"</string>
<string name="acl_rule_templates_domain">"ドメイン及びサブドメイン"</string> <string name="acl_rule_templates_domain">"ドメイン及びサブドメイン"</string>
</resources> </resources>
+3 -3
View File
@@ -52,8 +52,8 @@
<string name="auto_connect_summary">"Запускать Shadowsocks при включении"</string> <string name="auto_connect_summary">"Запускать Shadowsocks при включении"</string>
<string name="tcp_fastopen_summary">"Переключение требует наличия ROOT прав"</string> <string name="tcp_fastopen_summary">"Переключение требует наличия ROOT прав"</string>
<string name="tcp_fastopen_summary_unsupported">"Неподдерживаемая версия ядра: %s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"Неподдерживаемая версия ядра: %s &lt; 3.7.1"</string>
<string name="udp_dns">"Проброс UDP"</string> <string name="udp_dns">"Проброс DNS"</string>
<string name="udp_dns_summary">"Пробрасывать UDP пакеты на удалённый сервер"</string> <string name="udp_dns_summary">"Пробрасывать DNS пакеты на удалённый сервер"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"Shadowsocks запущен."</string> <string name="forward_success">"Shadowsocks запущен."</string>
@@ -121,4 +121,4 @@
<string name="route_entry_bypass_lan_chn">"Обход LAN и Китай"</string> <string name="route_entry_bypass_lan_chn">"Обход LAN и Китай"</string>
<string name="route_entry_chinalist">"Список Китай"</string> <string name="route_entry_chinalist">"Список Китай"</string>
<string name="proxied_apps_summary_v21">"Установить прокси для выбранных приложений"</string> <string name="proxied_apps_summary_v21">"Установить прокси для выбранных приложений"</string>
</resources> </resources>
@@ -45,8 +45,8 @@
<string name="auto_connect_summary">"随系统启动后台服务"</string> <string name="auto_connect_summary">"随系统启动后台服务"</string>
<string name="tcp_fastopen_summary">"切换需要 ROOT 权限"</string> <string name="tcp_fastopen_summary">"切换需要 ROOT 权限"</string>
<string name="tcp_fastopen_summary_unsupported">"不支持的内核版本:%s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"不支持的内核版本:%s &lt; 3.7.1"</string>
<string name="udp_dns">"UDP 转发"</string> <string name="udp_dns">"DNS 转发"</string>
<string name="udp_dns_summary">"由远程服务器转发 UDP 协议的数据包"</string> <string name="udp_dns_summary">"由远程服务器转发 DNS 协议的数据包"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"后台服务已开始运行。"</string> <string name="forward_success">"后台服务已开始运行。"</string>
@@ -140,4 +140,4 @@
<string name="proxied_apps_summary_v21">"为应用程序分别设置代理"</string> <string name="proxied_apps_summary_v21">"为应用程序分别设置代理"</string>
<string name="acl_rule_templates_generic">"子网/域名 PCRE 正则表达式"</string> <string name="acl_rule_templates_generic">"子网/域名 PCRE 正则表达式"</string>
<string name="acl_rule_templates_domain">"域名及其子域名"</string> <string name="acl_rule_templates_domain">"域名及其子域名"</string>
</resources> </resources>
@@ -44,8 +44,8 @@
<string name="auto_connect_summary">"在裝置啟動時啟用 Shadowsocks"</string> <string name="auto_connect_summary">"在裝置啟動時啟用 Shadowsocks"</string>
<string name="tcp_fastopen_summary">"切換需要 ROOT 權限"</string> <string name="tcp_fastopen_summary">"切換需要 ROOT 權限"</string>
<string name="tcp_fastopen_summary_unsupported">"不支援的核心版本:%s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"不支援的核心版本:%s &lt; 3.7.1"</string>
<string name="udp_dns">"UDP 轉送"</string> <string name="udp_dns">"DNS 轉送"</string>
<string name="udp_dns_summary">"向遠端轉送 UDP 封包"</string> <string name="udp_dns_summary">"向遠端轉送 DNS 封包"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"Shadowsocks 已啟動。"</string> <string name="forward_success">"Shadowsocks 已啟動。"</string>
@@ -139,4 +139,4 @@
<string name="proxied_apps_summary_v21">"為已選擇的應用程式設定 Proxy"</string> <string name="proxied_apps_summary_v21">"為已選擇的應用程式設定 Proxy"</string>
<string name="acl_rule_templates_generic">"子網路/主機名稱 PCRE 模式"</string> <string name="acl_rule_templates_generic">"子網路/主機名稱 PCRE 模式"</string>
<string name="acl_rule_templates_domain">"網域及其所有子網域"</string> <string name="acl_rule_templates_domain">"網域及其所有子網域"</string>
</resources> </resources>
+2 -2
View File
@@ -53,8 +53,8 @@
<string name="auto_connect_summary">Enable Shadowsocks on startup</string> <string name="auto_connect_summary">Enable Shadowsocks on startup</string>
<string name="tcp_fastopen_summary">Toggling requires ROOT permission</string> <string name="tcp_fastopen_summary">Toggling requires ROOT permission</string>
<string name="tcp_fastopen_summary_unsupported">Unsupported kernel version: %s &lt; 3.7.1</string> <string name="tcp_fastopen_summary_unsupported">Unsupported kernel version: %s &lt; 3.7.1</string>
<string name="udp_dns">UDP Forwarding</string> <string name="udp_dns">DNS Forwarding</string>
<string name="udp_dns_summary">Forward UDP packets to remote</string> <string name="udp_dns_summary">Force to forward DNS packets to remote</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">Shadowsocks started.</string> <string name="forward_success">Shadowsocks started.</string>
@@ -39,11 +39,11 @@ import com.github.shadowsocks.database.Profile
import com.github.shadowsocks.plugin.{PluginConfiguration, PluginManager, PluginOptions} import com.github.shadowsocks.plugin.{PluginConfiguration, PluginManager, PluginOptions}
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
import okhttp3.{Dns, FormBody, OkHttpClient, Request} 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
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import scala.collection.JavaConversions._
import scala.util.Random import scala.util.Random
trait BaseService extends Service { trait BaseService extends Service {
@@ -328,4 +328,44 @@ trait BaseService extends Service {
IOUtils.writeString(new File(getFilesDir, file), config.toString) IOUtils.writeString(new File(getFilesDir, file), config.toString)
file 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() { private def destroyProcess() {
if (Build.VERSION.SDK_INT < 24) { if (Build.VERSION.SDK_INT < 24) {
JniHelper.sigtermCompat(process) JniHelper.sigtermCompat(process)
process.waitFor() JniHelper.waitForCompat(process, 500)
} }
process.destroy() process.destroy()
} }
@@ -197,15 +197,17 @@ class ShadowsocksApplication extends Application {
def copyAssets() { def copyAssets() {
val assetManager = getAssets val assetManager = getAssets
var files: Array[String] = null for (dir <- List("acl", "overture")) {
try files = assetManager.list("acl") catch { var files: Array[String] = null
case e: IOException => try files = assetManager.list(dir) catch {
Log.e(TAG, e.getMessage) case e: IOException =>
app.track(e) 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() editor.putInt(Key.currentVersionCode, BuildConfig.VERSION_CODE).apply()
} }
@@ -49,7 +49,7 @@ class ShadowsocksNatService extends BaseService {
var sslocalProcess: GuardedProcess = _ var sslocalProcess: GuardedProcess = _
var sstunnelProcess: GuardedProcess = _ var sstunnelProcess: GuardedProcess = _
var redsocksProcess: GuardedProcess = _ var redsocksProcess: GuardedProcess = _
var pdnsdProcess: GuardedProcess = _ var overtureProcess: GuardedProcess = _
var su: Shell.Interactive = _ var su: Shell.Interactive = _
def startShadowsocksDaemon() { def startShadowsocksDaemon() {
@@ -74,7 +74,7 @@ class ShadowsocksNatService extends BaseService {
"-t", "10", "-t", "10",
"-b", "127.0.0.1", "-b", "127.0.0.1",
"-l", (profile.localPort + 63).toString, "-l", (profile.localPort + 63).toString,
"-L", profile.remoteDns + ":53", "-L", profile.remoteDns.trim + ":53",
"-c", buildShadowsocksConfig("ss-tunnel-nat.conf")) "-c", buildShadowsocksConfig("ss-tunnel-nat.conf"))
if (profile.udpdns) cmd.append("-u") if (profile.udpdns) cmd.append("-u")
@@ -83,21 +83,8 @@ class ShadowsocksNatService extends BaseService {
} }
def startDnsDaemon() { def startDnsDaemon() {
val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0" overtureProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/liboverture.so",
IOUtils.writeString(new File(getFilesDir, "pdnsd-nat.conf"), profile.route match { "-c", buildOvertureConfig("overture-nat.conf"))
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")
.start() .start()
} }
@@ -111,11 +98,13 @@ class ShadowsocksNatService extends BaseService {
/** Called when the activity is first created. */ /** Called when the activity is first created. */
def handleConnection() { def handleConnection() {
startDNSTunnel()
startRedsocksDaemon() startRedsocksDaemon()
startShadowsocksDaemon() startShadowsocksDaemon()
if (!profile.udpdns) startDnsDaemon() if (!profile.udpdns)
startDnsDaemon()
else
startDNSTunnel()
setupIptables() setupIptables()
@@ -143,9 +132,9 @@ class ShadowsocksNatService extends BaseService {
redsocksProcess.destroy() redsocksProcess.destroy()
redsocksProcess = null redsocksProcess = null
} }
if (pdnsdProcess != null) { if (overtureProcess != null) {
pdnsdProcess.destroy() overtureProcess.destroy()
pdnsdProcess = null overtureProcess = null
} }
su.addCommand("iptables -t nat -F OUTPUT") su.addCommand("iptables -t nat -F OUTPUT")
@@ -45,8 +45,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
private var notification: ShadowsocksNotification = _ private var notification: ShadowsocksNotification = _
var sslocalProcess: GuardedProcess = _ var sslocalProcess: GuardedProcess = _
var sstunnelProcess: GuardedProcess = _ var overtureProcess: GuardedProcess = _
var pdnsdProcess: GuardedProcess = _
var tun2socksProcess: GuardedProcess = _ var tun2socksProcess: GuardedProcess = _
override def onBind(intent: Intent): IBinder = { override def onBind(intent: Intent): IBinder = {
@@ -94,17 +93,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
sslocalProcess.destroy() sslocalProcess.destroy()
sslocalProcess = null sslocalProcess = null
} }
if (sstunnelProcess != null) {
sstunnelProcess.destroy()
sstunnelProcess = null
}
if (tun2socksProcess != null) { if (tun2socksProcess != null) {
tun2socksProcess.destroy() tun2socksProcess.destroy()
tun2socksProcess = null tun2socksProcess = null
} }
if (pdnsdProcess != null) { if (overtureProcess != null) {
pdnsdProcess.destroy() overtureProcess.destroy()
pdnsdProcess = null overtureProcess = null
} }
} }
@@ -149,15 +144,14 @@ class ShadowsocksVpnService extends VpnService with BaseService {
/** Called when the activity is first created. */ /** Called when the activity is first created. */
def handleConnection() { def handleConnection() {
val fd = startVpn()
if (!sendFd(fd)) throw new Exception("sendFd failed")
startShadowsocksDaemon() startShadowsocksDaemon()
if (!profile.udpdns) { if (!profile.udpdns) {
startDnsDaemon() startDnsDaemon()
startDnsTunnel()
} }
val fd = startVpn()
if (!sendFd(fd)) throw new Exception("sendFd failed")
} }
override protected def buildPluginCommandLine(): ArrayBuffer[String] = super.buildPluginCommandLine() += "-V" override protected def buildPluginCommandLine(): ArrayBuffer[String] = super.buildPluginCommandLine() += "-V"
@@ -165,13 +159,12 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def startShadowsocksDaemon() { def startShadowsocksDaemon() {
val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so", val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so",
"-V", "-V",
"-u",
"-b", "127.0.0.1", "-b", "127.0.0.1",
"-l", profile.localPort.toString, "-l", profile.localPort.toString,
"-t", "600", "-t", "600",
"-c", buildShadowsocksConfig("ss-local-vpn.conf")) "-c", buildShadowsocksConfig("ss-local-vpn.conf"))
if (profile.udpdns) cmd += "-u"
if (profile.route != Acl.ALL) { if (profile.route != Acl.ALL) {
cmd += "--acl" cmd += "--acl"
cmd += Acl.getFile(profile.route).getAbsolutePath cmd += Acl.getFile(profile.route).getAbsolutePath
@@ -182,33 +175,10 @@ class ShadowsocksVpnService extends VpnService with BaseService {
sslocalProcess = new GuardedProcess(cmd: _*).start() 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() { def startDnsDaemon() {
val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0" overtureProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/liboverture.so",
IOUtils.writeString(new File(getFilesDir, "pdnsd-vpn.conf"), profile.route match { "-c", buildOvertureConfig("overture-vpn.conf"), "-V")
case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES => .start()
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()
} }
def startVpn(): Int = { def startVpn(): Int = {
@@ -219,7 +189,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
.setMtu(VPN_MTU) .setMtu(VPN_MTU)
.addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24) .addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24)
builder.addDnsServer(profile.remoteDns) builder.addDnsServer(profile.remoteDns.trim)
if (profile.ipv6) { if (profile.ipv6) {
builder.addAddress(PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "1"), 126) builder.addAddress(PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "1"), 126)
@@ -251,7 +221,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val subnet = Subnet.fromString(cidr) val subnet = Subnet.fromString(cidr)
builder.addRoute(subnet.address.getHostAddress, subnet.prefixSize) builder.addRoute(subnet.address.getHostAddress, subnet.prefixSize)
}) })
builder.addRoute(profile.remoteDns, 32) builder.addRoute(profile.remoteDns.trim, 32)
} }
conn = builder.establish() conn = builder.establish()
@@ -271,9 +241,9 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if (profile.ipv6) if (profile.ipv6)
cmd += ("--netif-ip6addr", PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "2")) cmd += ("--netif-ip6addr", PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "2"))
if (profile.udpdns) cmd += "--enable-udprelay"
cmd += "--enable-udprelay"
else if (!profile.udpdns)
cmd += ("--dnsgw", "%s:%d".formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), cmd += ("--dnsgw", "%s:%d".formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"),
profile.localPort + 53)) profile.localPort + 53))
@@ -98,7 +98,8 @@ class Profile {
.scheme("ss") .scheme("ss")
.encodedAuthority("%s@%s:%d".formatLocal(Locale.ENGLISH, .encodedAuthority("%s@%s:%d".formatLocal(Locale.ENGLISH,
Base64.encodeToString("%s:%s".formatLocal(Locale.ENGLISH, method, password).getBytes, Base64.encodeToString("%s:%s".formatLocal(Locale.ENGLISH, method, password).getBytes,
Base64.NO_PADDING | Base64.NO_WRAP | Base64.URL_SAFE), host, remotePort)) Base64.NO_PADDING | Base64.NO_WRAP | Base64.URL_SAFE),
if (host.contains(':')) '[' + host + ']' else host, remotePort))
val configuration = new PluginConfiguration(plugin) val configuration = new PluginConfiguration(plugin)
if (configuration.selected.nonEmpty) if (configuration.selected.nonEmpty)
builder.appendQueryParameter(Key.plugin, configuration.selectedOptions.toString(false)) builder.appendQueryParameter(Key.plugin, configuration.selectedOptions.toString(false))
@@ -45,86 +45,6 @@ object ConfigUtils {
" port = %d;\n" + " port = %d;\n" +
" type = socks5;\n" + " type = socks5;\n" +
"}\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 { object Key {
@@ -20,22 +20,24 @@
package com.github.shadowsocks.utils package com.github.shadowsocks.utils
import java.net.URI
import android.net.Uri import android.net.Uri
import android.util.{Base64, Log} import android.util.{Base64, Log}
import com.github.shadowsocks.database.Profile import com.github.shadowsocks.database.Profile
object Parser { object Parser {
val TAG = "ShadowParser" 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 userInfoPattern = "^(.+?):(.*)$".r
private val legacyPattern = "^((.+?):(.*)@(.+?):(\\d+?))$".r private val legacyPattern = "^(.+?):(.*)@(.+?):(\\d+?)$".r
def findAll(data: CharSequence): Iterator[Profile] = def findAll(data: CharSequence): Iterator[Profile] =
pattern.findAllMatchIn(if (data == null) "" else data).map(m => { pattern.findAllMatchIn(if (data == null) "" else data).map(m => {
val uri = Uri.parse(m.matched) val uri = Uri.parse(m.matched)
uri.getUserInfo match { uri.getUserInfo match {
case null => new String(Base64.decode(uri.getHost, Base64.NO_PADDING), "UTF-8") match { 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 case legacyPattern(method, password, host, port) => // legacy uri
val profile = new Profile val profile = new Profile
profile.method = method.toLowerCase profile.method = method.toLowerCase
profile.password = password profile.password = password
@@ -54,8 +56,12 @@ object Parser {
val profile = new Profile val profile = new Profile
profile.method = method profile.method = method
profile.password = password profile.password = password
profile.host = uri.getHost // bug in Android: https://code.google.com/p/android/issues/detail?id=192855
profile.remotePort = uri.getPort val javaURI = new URI(m.matched)
profile.host = javaURI.getHost
if (profile.host.headOption.contains('[') && profile.host.lastOption.contains(']'))
profile.host = profile.host.substring(1, profile.host.length - 1)
profile.remotePort = javaURI.getPort
profile.plugin = uri.getQueryParameter(Key.plugin) profile.plugin = uri.getQueryParameter(Key.plugin)
profile.name = uri.getFragment profile.name = uri.getFragment
profile profile
Submodule mobile/src/overture added at 862ce347e1
+2
View File
@@ -1,3 +1,5 @@
* 0.0.3:
* Update support library version to 25.2.0.
* 0.0.2: * 0.0.2:
* Add `getOrDefault` to `PluginOptions`; * Add `getOrDefault` to `PluginOptions`;
* Update support library version to 25.1.1. * Update support library version to 25.1.1.
+1 -1
View File
@@ -2,7 +2,7 @@ enablePlugins(AndroidLib)
android.useSupportVectors android.useSupportVectors
name := "plugin" name := "plugin"
version := "0.0.2" version := "0.0.3"
pomExtra in Global := { pomExtra in Global := {
<url>https://github.com/shadowsocks/shadowsocks-android</url> <url>https://github.com/shadowsocks/shadowsocks-android</url>
+1 -1
View File
@@ -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") addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.10")