Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6841848a3 | ||
|
|
52cb15069c | ||
|
|
70ed2189b1 | ||
|
|
aeee9c2fac | ||
|
|
70dc8e9995 | ||
|
|
558a39ec14 | ||
|
|
5f95cccce4 | ||
|
|
55f25d3272 | ||
|
|
93273cbc44 | ||
|
|
c0514ee169 | ||
|
|
06d736b22d | ||
|
|
e34d5675eb | ||
|
|
94c7ffb788 | ||
|
|
0647ef4c6d | ||
|
|
97c6ff95cd | ||
|
|
971ef22186 | ||
|
|
c35a92a927 | ||
|
|
c05a63a75b | ||
|
|
6074a99eb6 | ||
|
|
e52719d1be |
+3
-3
@@ -11,14 +11,14 @@ before_install:
|
|||||||
- sudo apt-get install ccache
|
- sudo apt-get install ccache
|
||||||
- export NDK_CCACHE=ccache
|
- export NDK_CCACHE=ccache
|
||||||
- export ARCH=`uname -m`
|
- export ARCH=`uname -m`
|
||||||
- wget http://dl.google.com/android/android-sdk_r23-linux.tgz
|
- wget http://dl.google.com/android/android-sdk_r23.0.2-linux.tgz
|
||||||
- tar xf android-sdk_r23-linux.tgz
|
- tar xf android-sdk_r23.0.2-linux.tgz
|
||||||
- wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2
|
- wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2
|
||||||
- tar xf 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=`pwd`/android-ndk-r9d
|
||||||
- export ANDROID_HOME=`pwd`/android-sdk-linux
|
- 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_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 tools,platform-tools,build-tools-21.0.1,android-21,extra-google-m2repository --no-ui --no-https -a
|
||||||
- echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
|
- echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
|
||||||
script:
|
script:
|
||||||
- ./build-ndk.sh
|
- ./build-ndk.sh
|
||||||
|
|||||||
+19
-29
@@ -1,38 +1,28 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Target 9
|
function try () {
|
||||||
cp jni/Application.mk.9 jni/Application.mk
|
"$@" || exit -1
|
||||||
ndk-build clean
|
}
|
||||||
ndk-build
|
|
||||||
rm -rf src/main/assets/armeabi
|
# Build
|
||||||
|
try ndk-build clean
|
||||||
|
try ndk-build
|
||||||
|
|
||||||
|
# copy executables
|
||||||
rm -rf src/main/assets/armeabi-v7a
|
rm -rf src/main/assets/armeabi-v7a
|
||||||
rm -rf src/main/assets/x86
|
rm -rf src/main/assets/x86
|
||||||
mkdir -p src/main/assets/armeabi
|
|
||||||
mkdir -p src/main/assets/armeabi-v7a
|
mkdir -p src/main/assets/armeabi-v7a
|
||||||
mkdir -p src/main/assets/x86
|
mkdir -p src/main/assets/x86
|
||||||
for app in pdnsd redsocks
|
for app in pdnsd redsocks iptables
|
||||||
do
|
do
|
||||||
mv libs/armeabi/$app src/main/assets/armeabi/
|
try mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/
|
||||||
mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/
|
try mv libs/x86/$app src/main/assets/x86/
|
||||||
mv libs/x86/$app src/main/assets/x86/
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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
|
done
|
||||||
|
|
||||||
|
# copy libraries
|
||||||
|
rm -rf src/main/jni/armeabi-v7a
|
||||||
|
rm -rf src/main/jni/x86
|
||||||
|
mkdir -p src/main/jni/armeabi-v7a
|
||||||
|
mkdir -p src/main/jni/x86
|
||||||
|
try mv libs/armeabi-v7a/*.so src/main/jni/armeabi-v7a/
|
||||||
|
try mv libs/x86/*.so src/main/jni/x86/
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import android.Dependencies.{apklib,aar}
|
|||||||
|
|
||||||
android.Plugin.androidBuild
|
android.Plugin.androidBuild
|
||||||
|
|
||||||
platformTarget in Android := "android-19"
|
platformTarget in Android := "android-21"
|
||||||
|
|
||||||
name := "shadowsocks"
|
name := "shadowsocks"
|
||||||
|
|
||||||
@@ -23,12 +23,12 @@ libraryDependencies ++= Seq(
|
|||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
|
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
|
||||||
"com.google.android.gms" % "play-services" % "5.2.08",
|
"com.google.android.gms" % "play-services" % "5.0.89",
|
||||||
"com.android.support" % "support-v4" % "19.1.0"
|
"com.android.support" % "support-v4" % "19.1.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"de.keyboardsurfer.android.widget" % "crouton" % "1.8.1" exclude("com.google.android", "support-v4"),
|
"de.keyboardsurfer.android.widget" % "crouton" % "1.8.4" exclude("com.google.android", "support-v4"),
|
||||||
"com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4",
|
"com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4",
|
||||||
"com.j256.ormlite" % "ormlite-core" % "4.47",
|
"com.j256.ormlite" % "ormlite-core" % "4.47",
|
||||||
"com.j256.ormlite" % "ormlite-android" % "4.47"
|
"com.j256.ormlite" % "ormlite-android" % "4.47"
|
||||||
|
|||||||
+7
-7
@@ -335,13 +335,13 @@ openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \
|
|||||||
include $(openssl_subdirs)
|
include $(openssl_subdirs)
|
||||||
|
|
||||||
# Iptables
|
# Iptables
|
||||||
# LOCAL_PATH := $(ROOT_PATH)
|
LOCAL_PATH := $(ROOT_PATH)
|
||||||
# iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \
|
iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \
|
||||||
# iptables \
|
iptables \
|
||||||
# extensions \
|
extensions \
|
||||||
# libiptc \
|
libiptc \
|
||||||
# ))
|
))
|
||||||
# include $(iptables_subdirs)
|
include $(iptables_subdirs)
|
||||||
|
|
||||||
# Import cpufeatures
|
# Import cpufeatures
|
||||||
$(call import-module,android/cpufeatures)
|
$(call import-module,android/cpufeatures)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
APP_ABI := armeabi armeabi-v7a x86
|
APP_ABI := armeabi-v7a x86
|
||||||
APP_PLATFORM := android-16
|
APP_PLATFORM := android-16
|
||||||
APP_STL := stlport_static
|
APP_STL := stlport_static
|
||||||
NDK_TOOLCHAIN_VERSION := 4.8
|
NDK_TOOLCHAIN_VERSION := 4.8
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
APP_ABI := armeabi armeabi-v7a x86
|
|
||||||
APP_PLATFORM := android-9
|
|
||||||
APP_STL := stlport_static
|
|
||||||
NDK_TOOLCHAIN_VERSION := 4.8
|
|
||||||
+1
-1
Submodule jni/shadowsocks updated: d37f8d3025...5d7dd372fc
+5
-5
@@ -21,11 +21,11 @@ jstring Java_com_github_shadowsocks_system_getabi(JNIEnv *env, jobject thiz) {
|
|||||||
} else if (family == ANDROID_CPU_FAMILY_MIPS) {
|
} else if (family == ANDROID_CPU_FAMILY_MIPS) {
|
||||||
abi = "mips";
|
abi = "mips";
|
||||||
} else if (family == ANDROID_CPU_FAMILY_ARM) {
|
} else if (family == ANDROID_CPU_FAMILY_ARM) {
|
||||||
if (features & ANDROID_CPU_ARM_FEATURE_ARMv7) {
|
// if (features & ANDROID_CPU_ARM_FEATURE_ARMv7) {
|
||||||
abi = "armeabi-v7a";
|
abi = "armeabi-v7a";
|
||||||
} else {
|
// } else {
|
||||||
abi = "armeabi";
|
// abi = "armeabi";
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
return env->NewStringUTF(abi);
|
return env->NewStringUTF(abi);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.github.shadowsocks"
|
package="com.github.shadowsocks"
|
||||||
android:versionCode="70"
|
android:versionCode="76"
|
||||||
android:versionName="2.2.2">
|
android:versionName="2.3.1">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
android:required="false"/>
|
android:required="false"/>
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="14"
|
android:minSdkVersion="16"
|
||||||
android:targetSdkVersion="19"/>
|
android:targetSdkVersion="21"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
<string name="forward_stop">后台服务已停止。</string>
|
<string name="forward_stop">后台服务已停止。</string>
|
||||||
<string name="service_failed">请检查你的网络状态后并重试。</string>
|
<string name="service_failed">请检查你的网络状态后并重试。</string>
|
||||||
<string name="stop">停止服务</string>
|
<string name="stop">停止服务</string>
|
||||||
<string name="vpn_error">无法启动 VPN 服务:\"%s\"。看来和你的设备存在兼容性问题,请使用 Root 模式。</string>
|
<string name="vpn_error">无法启动服务:\"%s\"。</string>
|
||||||
<string name="ok_iknow">确定</string>
|
<string name="ok_iknow">确定</string>
|
||||||
<string name="port_alert">端口号应大于1024</string>
|
<string name="port_alert">端口号应大于1024</string>
|
||||||
<string name="port_empty">端口号不能为空</string>
|
<string name="port_empty">端口号不能为空</string>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
<string name="forward_stop">Shadowsocks stopped.</string>
|
<string name="forward_stop">Shadowsocks stopped.</string>
|
||||||
<string name="service_failed">Please check your network status and try again.</string>
|
<string name="service_failed">Please check your network status and try again.</string>
|
||||||
<string name="stop">Stop the service</string>
|
<string name="stop">Stop the service</string>
|
||||||
<string name="vpn_error">Unable to start VPN service: "%s". It seems to be a compatibility issue with your device. Please consider using ROOT mode instead.</string>
|
<string name="vpn_error">Unable to start service: "%s".</string>
|
||||||
|
|
||||||
<!-- alert category -->
|
<!-- alert category -->
|
||||||
<string name="ok_iknow">OK</string>
|
<string name="ok_iknow">OK</string>
|
||||||
|
|||||||
@@ -89,8 +89,9 @@ object AppManager {
|
|||||||
case a => {
|
case a => {
|
||||||
val uid = a.uid
|
val uid = a.uid
|
||||||
val userName = uid.toString
|
val userName = uid.toString
|
||||||
|
val packageName = a.packageName
|
||||||
val proxied = proxiedApps.binarySearch(userName) >= 0
|
val proxied = proxiedApps.binarySearch(userName) >= 0
|
||||||
new ProxiedApp(uid, userName, proxied)
|
new ProxiedApp(uid, packageName, proxied)
|
||||||
}
|
}
|
||||||
}.toArray
|
}.toArray
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ object Shadowsocks {
|
|||||||
val FEATRUE_PREFS = Array(Key.isGFWList, Key.isGlobalProxy, Key.proxyedApps, Key.isTrafficStat,
|
val FEATRUE_PREFS = Array(Key.isGFWList, Key.isGlobalProxy, Key.proxyedApps, Key.isTrafficStat,
|
||||||
Key.isUdpDns, Key.isAutoConnect)
|
Key.isUdpDns, Key.isAutoConnect)
|
||||||
|
|
||||||
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS)
|
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.IPTABLES)
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
def updateListPreference(pref: Preference, value: String) {
|
def updateListPreference(pref: Preference, value: String) {
|
||||||
@@ -213,6 +213,8 @@ class Shadowsocks
|
|||||||
setPreferenceEnabled(enabled = false)
|
setPreferenceEnabled(enabled = false)
|
||||||
}
|
}
|
||||||
state = bgService.getState
|
state = bgService.getState
|
||||||
|
// set the listener
|
||||||
|
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def onServiceDisconnected(name: ComponentName) {
|
override def onServiceDisconnected(name: ComponentName) {
|
||||||
@@ -494,7 +496,7 @@ class Shadowsocks
|
|||||||
|
|
||||||
// Bind to the service
|
// Bind to the service
|
||||||
spawn {
|
spawn {
|
||||||
val isRoot = Console.isRoot
|
val isRoot = Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP && Console.isRoot
|
||||||
handler.post(new Runnable {
|
handler.post(new Runnable {
|
||||||
override def run() {
|
override def run() {
|
||||||
status.edit.putBoolean(Key.isRoot, isRoot).commit()
|
status.edit.putBoolean(Key.isRoot, isRoot).commit()
|
||||||
@@ -746,14 +748,13 @@ class Shadowsocks
|
|||||||
changeSwitch(checked = false)
|
changeSwitch(checked = false)
|
||||||
}
|
}
|
||||||
state = bgService.getState
|
state = bgService.getState
|
||||||
|
// set the listener
|
||||||
|
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
|
||||||
}
|
}
|
||||||
// set the listener
|
|
||||||
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
|
|
||||||
ConfigUtils.refresh(this)
|
ConfigUtils.refresh(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def setPreferenceEnabled(enabled: Boolean) {
|
private def setPreferenceEnabled(enabled: Boolean) {
|
||||||
val isRoot = status.getBoolean(Key.isRoot, false)
|
|
||||||
for (name <- Shadowsocks.PROXY_PREFS) {
|
for (name <- Shadowsocks.PROXY_PREFS) {
|
||||||
val pref = findPreference(name)
|
val pref = findPreference(name)
|
||||||
if (pref != null) {
|
if (pref != null) {
|
||||||
@@ -765,7 +766,7 @@ class Shadowsocks
|
|||||||
if (pref != null) {
|
if (pref != null) {
|
||||||
if (Seq(Key.isGlobalProxy, Key.isTrafficStat, Key.proxyedApps)
|
if (Seq(Key.isGlobalProxy, Key.isTrafficStat, Key.proxyedApps)
|
||||||
.contains(name)) {
|
.contains(name)) {
|
||||||
pref.setEnabled(enabled && isRoot)
|
pref.setEnabled(enabled && (!isVpnEnabled || Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP))
|
||||||
} else {
|
} else {
|
||||||
pref.setEnabled(enabled)
|
pref.setEnabled(enabled)
|
||||||
}
|
}
|
||||||
@@ -823,15 +824,7 @@ class Shadowsocks
|
|||||||
|
|
||||||
crash_recovery()
|
crash_recovery()
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 16) {
|
copyAssets(System.getABI)
|
||||||
copyAssets("api-16/" + System.getABI)
|
|
||||||
} else {
|
|
||||||
copyAssets(System.getABI)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 20) {
|
|
||||||
copyToSystem()
|
|
||||||
}
|
|
||||||
|
|
||||||
val ab = new ArrayBuffer[String]
|
val ab = new ArrayBuffer[String]
|
||||||
for (executable <- Shadowsocks.EXECUTABLES) {
|
for (executable <- Shadowsocks.EXECUTABLES) {
|
||||||
@@ -881,8 +874,8 @@ class Shadowsocks
|
|||||||
|
|
||||||
def isVpnEnabled: Boolean = {
|
def isVpnEnabled: Boolean = {
|
||||||
if (vpnEnabled < 0) {
|
if (vpnEnabled < 0) {
|
||||||
vpnEnabled = if (Build.VERSION.SDK_INT
|
vpnEnabled = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
|
||||||
>= Build.VERSION_CODES.ICE_CREAM_SANDWICH && !status.getBoolean(Key.isRoot, false)) {
|
|| !status.getBoolean(Key.isRoot, false)) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
@@ -930,8 +923,6 @@ class Shadowsocks
|
|||||||
bgService.start(ConfigUtils.load(settings))
|
bgService.start(ConfigUtils.load(settings))
|
||||||
|
|
||||||
if (isVpnEnabled) {
|
if (isVpnEnabled) {
|
||||||
val style = new Style.Builder().setBackgroundColorValue(Style.holoBlueLight).build()
|
|
||||||
val config = new Configuration.Builder().setDuration(Configuration.DURATION_LONG).build()
|
|
||||||
changeSwitch(checked = false)
|
changeSwitch(checked = false)
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
@@ -997,7 +988,6 @@ class Shadowsocks
|
|||||||
changeSwitch(checked = false)
|
changeSwitch(checked = false)
|
||||||
Crouton.cancelAllCroutons()
|
Crouton.cancelAllCroutons()
|
||||||
if (m != null) {
|
if (m != null) {
|
||||||
Crouton.cancelAllCroutons()
|
|
||||||
val style = new Style.Builder().setBackgroundColorValue(Style.holoRedLight).build()
|
val style = new Style.Builder().setBackgroundColorValue(Style.holoRedLight).build()
|
||||||
val config = new Configuration.Builder()
|
val config = new Configuration.Builder()
|
||||||
.setDuration(Configuration.DURATION_LONG)
|
.setDuration(Configuration.DURATION_LONG)
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ import java.util.{Timer, TimerTask}
|
|||||||
import android.app.{Notification, NotificationManager, PendingIntent, Service}
|
import android.app.{Notification, NotificationManager, PendingIntent, Service}
|
||||||
import android.content._
|
import android.content._
|
||||||
import android.content.pm.{PackageInfo, PackageManager}
|
import android.content.pm.{PackageInfo, PackageManager}
|
||||||
import android.graphics.Color
|
|
||||||
import android.net.TrafficStats
|
import android.net.TrafficStats
|
||||||
import android.os._
|
import android.os._
|
||||||
import android.support.v4.app.NotificationCompat
|
import android.support.v4.app.NotificationCompat
|
||||||
@@ -114,49 +113,52 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val raw_args = ("ss-local -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -f " +
|
val cmd = new ArrayBuffer[String]
|
||||||
Path.BASE + "ss-local.pid")
|
cmd += ("ss-local"
|
||||||
.format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod)
|
, "-b" , "127.0.0.1"
|
||||||
val args = if (Build.VERSION.SDK_INT >= 20) {
|
, "-s" , config.proxy
|
||||||
raw_args
|
, "-p" , config.remotePort.toString
|
||||||
} else {
|
, "-l" , config.localPort.toString
|
||||||
Path.BASE + raw_args
|
, "-k" , config.sitekey
|
||||||
}
|
, "-m" , config.encMethod
|
||||||
val cmd = if (config.isGFWList && isACLEnabled) args + " --acl " + Path.BASE + "chn.acl" else args
|
, "-f" , (Path.BASE + "ss-local.pid"))
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
|
||||||
|
|
||||||
Core.sslocal(cmd.split(" "))
|
if (config.isGFWList && isACLEnabled) {
|
||||||
|
cmd += "--acl"
|
||||||
|
cmd += (Path.BASE + "chn.acl")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
|
|
||||||
|
Core.sslocal(cmd.toArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
def startDnsDaemon() {
|
def startDnsDaemon() {
|
||||||
val args = if (config.isUdpDns) {
|
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 " +
|
val cmd = new ArrayBuffer[String]
|
||||||
Path.BASE + "ss-tunnel.pid")
|
cmd += ("ss-tunnel" , "-u"
|
||||||
.format(config.proxy, config.remotePort, 8153, config.sitekey, config.encMethod)
|
, "-b" , "127.0.0.1"
|
||||||
|
, "-l" , "8153"
|
||||||
|
, "-L" , "8.8.8.8:53"
|
||||||
|
, "-s" , config.proxy
|
||||||
|
, "-p" , config.remotePort.toString
|
||||||
|
, "-k" , config.sitekey
|
||||||
|
, "-m" , config.encMethod
|
||||||
|
, "-f" , (Path.BASE + "ss-tunnel.pid"))
|
||||||
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
|
Core.sstunnel(cmd.toArray)
|
||||||
} else {
|
} else {
|
||||||
val conf = {
|
val conf = {
|
||||||
if (config.isGFWList)
|
ConfigUtils.PDNSD.format("127.0.0.1")
|
||||||
ConfigUtils.PDNSD_BYPASS.format("127.0.0.1", getString(R.string.exclude))
|
|
||||||
else
|
|
||||||
ConfigUtils.PDNSD.format("127.0.0.1")
|
|
||||||
}
|
}
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
|
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
|
||||||
p.println(conf)
|
p.println(conf)
|
||||||
})
|
})
|
||||||
"pdnsd -c " + Path.BASE + "pdnsd.conf"
|
|
||||||
}
|
|
||||||
|
|
||||||
val cmd = if (Build.VERSION.SDK_INT >= 20) {
|
val args = "pdnsd -c " + Path.BASE + "pdnsd.conf"
|
||||||
"/system/bin/" + args
|
val cmd = Path.BASE + args
|
||||||
} else {
|
|
||||||
Path.BASE + args
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
||||||
|
|
||||||
if (config.isUdpDns) {
|
|
||||||
Core.sstunnel(cmd.split(" "))
|
|
||||||
} else {
|
|
||||||
Console.runRootCommand(cmd)
|
Console.runRootCommand(cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,11 +182,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
ConfigUtils.printToFile(new File(Path.BASE + "redsocks.conf"))(p => {
|
ConfigUtils.printToFile(new File(Path.BASE + "redsocks.conf"))(p => {
|
||||||
p.println(conf)
|
p.println(conf)
|
||||||
})
|
})
|
||||||
val cmd = if (Build.VERSION.SDK_INT >= 20) {
|
val cmd = Path.BASE + args
|
||||||
"/system/bin/" + args
|
|
||||||
} else {
|
|
||||||
Path.BASE + args
|
|
||||||
}
|
|
||||||
Console.runRootCommand(cmd)
|
Console.runRootCommand(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,10 +223,6 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
|
|
||||||
val icon = getResources.getDrawable(R.drawable.ic_stat_shadowsocks)
|
val icon = getResources.getDrawable(R.drawable.ic_stat_shadowsocks)
|
||||||
if (rate >= 0) {
|
if (rate >= 0) {
|
||||||
val bitmap = Utils
|
|
||||||
.getBitmap(rate.toString, icon.getIntrinsicWidth * 4, icon.getIntrinsicHeight * 4,
|
|
||||||
Color.TRANSPARENT)
|
|
||||||
builder.setLargeIcon(bitmap)
|
|
||||||
|
|
||||||
if (rate < 1000) {
|
if (rate < 1000) {
|
||||||
builder.setSmallIcon(R.drawable.ic_stat_speed, rate)
|
builder.setSmallIcon(R.drawable.ic_stat_speed, rate)
|
||||||
@@ -254,22 +248,6 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
startForegroundCompat(1, builder.build)
|
startForegroundCompat(1, builder.build)
|
||||||
}
|
}
|
||||||
|
|
||||||
def notifyAlert(title: String, info: String) {
|
|
||||||
val openIntent: Intent = new Intent(this, classOf[Shadowsocks])
|
|
||||||
openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
||||||
val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
|
|
||||||
val builder: NotificationCompat.Builder = new NotificationCompat.Builder(this)
|
|
||||||
builder
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_shadowsocks)
|
|
||||||
.setWhen(0)
|
|
||||||
.setTicker(title)
|
|
||||||
.setContentTitle(getString(R.string.app_name))
|
|
||||||
.setContentText(info)
|
|
||||||
.setContentIntent(contentIntent)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
notificationManager.notify(1, builder.build)
|
|
||||||
}
|
|
||||||
|
|
||||||
def onBind(intent: Intent): IBinder = {
|
def onBind(intent: Intent): IBinder = {
|
||||||
Log.d(TAG, "onBind")
|
Log.d(TAG, "onBind")
|
||||||
if (Action.SERVICE == intent.getAction) {
|
if (Action.SERVICE == intent.getAction) {
|
||||||
@@ -343,10 +321,6 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid))
|
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid))
|
||||||
|
|
||||||
if (config.isGFWList) {
|
if (config.isGFWList) {
|
||||||
// Bypass DNS in China
|
|
||||||
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 114.114.114.114"))
|
|
||||||
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 114.114.115.115"))
|
|
||||||
|
|
||||||
if (!isACLEnabled)
|
if (!isACLEnabled)
|
||||||
{
|
{
|
||||||
val chn_list: Array[String] = getResources.getStringArray(R.array.chn_list)
|
val chn_list: Array[String] = getResources.getStringArray(R.array.chn_list)
|
||||||
@@ -492,44 +466,46 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
spawn {
|
spawn {
|
||||||
|
|
||||||
if (config.proxy == "198.199.101.152") {
|
if (config.proxy == "198.199.101.152") {
|
||||||
val holder = application.containerHolder
|
val holder = application.containerHolder
|
||||||
try {
|
try {
|
||||||
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
|
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
|
||||||
} catch {
|
} catch {
|
||||||
case ex: Exception =>
|
case ex: Exception =>
|
||||||
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
|
changeState(State.STOPPED, getString(R.string.service_failed))
|
||||||
stopRunner()
|
stopRunner()
|
||||||
changeState(State.STOPPED)
|
config = null
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
killProcesses()
|
if (config != null) {
|
||||||
|
|
||||||
var resolved: Boolean = false
|
killProcesses()
|
||||||
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
|
|
||||||
!InetAddressUtils.isIPv6Address(config.proxy)) {
|
var resolved: Boolean = false
|
||||||
Utils.resolve(config.proxy, enableIPv6 = true) match {
|
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
|
||||||
case Some(a) =>
|
!InetAddressUtils.isIPv6Address(config.proxy)) {
|
||||||
config.proxy = a
|
Utils.resolve(config.proxy, enableIPv6 = true) match {
|
||||||
resolved = true
|
case Some(a) =>
|
||||||
case None => resolved = false
|
config.proxy = a
|
||||||
|
resolved = true
|
||||||
|
case None => resolved = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resolved = true
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
resolved = true
|
|
||||||
}
|
|
||||||
|
|
||||||
hasRedirectSupport = Utils.getHasRedirectSupport
|
hasRedirectSupport = Utils.getHasRedirectSupport
|
||||||
|
|
||||||
if (resolved && handleConnection) {
|
if (resolved && handleConnection) {
|
||||||
notifyForegroundAlert(getString(R.string.forward_success),
|
notifyForegroundAlert(getString(R.string.forward_success),
|
||||||
getString(R.string.service_running).format(config.profileName))
|
getString(R.string.service_running).format(config.profileName))
|
||||||
changeState(State.CONNECTED)
|
changeState(State.CONNECTED)
|
||||||
} else {
|
} else {
|
||||||
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
|
changeState(State.STOPPED, getString(R.string.service_failed))
|
||||||
stopRunner()
|
stopRunner()
|
||||||
changeState(State.STOPPED)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -565,6 +541,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
unregisterReceiver(receiver)
|
unregisterReceiver(receiver)
|
||||||
receiver = null
|
receiver = null
|
||||||
}
|
}
|
||||||
|
|
||||||
stopForegroundCompat(1)
|
stopForegroundCompat(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ class ShadowsocksRunnerActivity extends Activity {
|
|||||||
|
|
||||||
def isVpnEnabled: Boolean = {
|
def isVpnEnabled: Boolean = {
|
||||||
if (vpnEnabled < 0) {
|
if (vpnEnabled < 0) {
|
||||||
vpnEnabled = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH
|
vpnEnabled = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
|
||||||
&& !Console.isRoot) {
|
|| !Console.isRoot) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import com.google.android.gms.analytics.HitBuilders
|
|||||||
import org.apache.commons.net.util.SubnetUtils
|
import org.apache.commons.net.util.SubnetUtils
|
||||||
import org.apache.http.conn.util.InetAddressUtils
|
import org.apache.http.conn.util.InetAddressUtils
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
import scala.concurrent.ops._
|
import scala.concurrent.ops._
|
||||||
|
|
||||||
@@ -74,26 +75,65 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
|
|
||||||
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
|
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
|
||||||
|
|
||||||
|
def isACLEnabled: Boolean = {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def isByass(net: SubnetUtils): Boolean = {
|
def isByass(net: SubnetUtils): Boolean = {
|
||||||
val info = net.getInfo
|
val info = net.getInfo
|
||||||
info.isInRange(config.proxy) || info.isInRange("114.114.114.114") || info.isInRange("114.114.115.115")
|
info.isInRange(config.proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
def startShadowsocksDaemon() {
|
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 " +
|
if (isACLEnabled && config.isGFWList) {
|
||||||
Path.BASE + "ss-local.pid")
|
val chn_list: Array[String] = getResources.getStringArray(R.array.chn_list_full)
|
||||||
.format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod)
|
ConfigUtils.printToFile(new File(Path.BASE + "chn.acl"))(p => {
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
chn_list.foreach(item => p.println(item))
|
||||||
Core.sslocal(cmd.split(" "))
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
val cmd = new ArrayBuffer[String]
|
||||||
|
cmd += ("ss-local" , "-u"
|
||||||
|
, "-b" , "127.0.0.1"
|
||||||
|
, "-s" , config.proxy
|
||||||
|
, "-p" , config.remotePort.toString
|
||||||
|
, "-l" , config.localPort.toString
|
||||||
|
, "-k" , config.sitekey
|
||||||
|
, "-m" , config.encMethod
|
||||||
|
, "-f" , Path.BASE + "ss-local.pid")
|
||||||
|
|
||||||
|
if (config.isGFWList && isACLEnabled) {
|
||||||
|
cmd += "--acl"
|
||||||
|
cmd += (Path.BASE + "chn.acl")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
|
Core.sslocal(cmd.toArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
def startDnsTunnel() = {
|
||||||
|
val cmd = new ArrayBuffer[String]
|
||||||
|
cmd += ("ss-tunnel"
|
||||||
|
, "-b" , "127.0.0.1"
|
||||||
|
, "-l" , "8163"
|
||||||
|
, "-L" , "8.8.8.8:53"
|
||||||
|
, "-s" , config.proxy
|
||||||
|
, "-p" , config.remotePort.toString
|
||||||
|
, "-k" , config.sitekey
|
||||||
|
, "-m" , config.encMethod
|
||||||
|
, "-f" , Path.BASE + "ss-tunnel.pid")
|
||||||
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
|
Core.sstunnel(cmd.toArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
def startDnsDaemon() {
|
def startDnsDaemon() {
|
||||||
val conf = {
|
val conf = {
|
||||||
if (config.isGFWList)
|
ConfigUtils.PDNSD_LOCAL.format("0.0.0.0", 8163)
|
||||||
ConfigUtils.PDNSD_BYPASS.format("0.0.0.0", getString(R.string.exclude))
|
|
||||||
else
|
|
||||||
ConfigUtils.PDNSD.format("0.0.0.0")
|
|
||||||
}
|
}
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
|
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
|
||||||
p.println(conf)
|
p.println(conf)
|
||||||
@@ -124,11 +164,36 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
.addAddress(PRIVATE_VLAN.format("1"), 24)
|
.addAddress(PRIVATE_VLAN.format("1"), 24)
|
||||||
.addDnsServer("8.8.8.8")
|
.addDnsServer("8.8.8.8")
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
if (!config.isGlobalProxy) {
|
||||||
|
val apps = AppManager.getProxiedApps(this, config.proxiedAppString)
|
||||||
|
val pkgSet: mutable.HashSet[String] = new mutable.HashSet[String]
|
||||||
|
for (app <- apps) {
|
||||||
|
if (app.proxied) {
|
||||||
|
pkgSet.add(app.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (pkg <- pkgSet) {
|
||||||
|
if (!config.isBypassApps) {
|
||||||
|
builder.addAllowedApplication(pkg)
|
||||||
|
} else {
|
||||||
|
builder.addDisallowedApplication(pkg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.isBypassApps) {
|
||||||
|
builder.addDisallowedApplication(this.getPackageName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.addDisallowedApplication(this.getPackageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (InetAddressUtils.isIPv6Address(config.proxy)) {
|
if (InetAddressUtils.isIPv6Address(config.proxy)) {
|
||||||
builder.addRoute("0.0.0.0", 0)
|
builder.addRoute("0.0.0.0", 0)
|
||||||
} else if (config.isGFWList) {
|
} else if (!isACLEnabled && config.isGFWList) {
|
||||||
val gfwList = {
|
val gfwList = {
|
||||||
if (Build.VERSION.SDK_INT == 19) {
|
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
|
||||||
getResources.getStringArray(R.array.simple_list)
|
getResources.getStringArray(R.array.simple_list)
|
||||||
} else {
|
} else {
|
||||||
getResources.getStringArray(R.array.gfw_list)
|
getResources.getStringArray(R.array.gfw_list)
|
||||||
@@ -142,24 +207,28 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
for (i <- 1 to 254) {
|
if (isACLEnabled) {
|
||||||
if (i != 26 && i != 127) {
|
builder.addRoute("0.0.0.0", 0)
|
||||||
val addr = i.toString + ".0.0.0"
|
} else {
|
||||||
val cidr = addr + "/8"
|
for (i <- 1 to 223) {
|
||||||
val net = new SubnetUtils(cidr)
|
if (i != 26 && i != 127) {
|
||||||
|
val addr = i.toString + ".0.0.0"
|
||||||
|
val cidr = addr + "/8"
|
||||||
|
val net = new SubnetUtils(cidr)
|
||||||
|
|
||||||
if (!isByass(net)) {
|
if (!isByass(net)) {
|
||||||
if (!InetAddress.getByName(addr).isSiteLocalAddress) {
|
if (!InetAddress.getByName(addr).isSiteLocalAddress) {
|
||||||
builder.addRoute(addr, 8)
|
builder.addRoute(addr, 8)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (j <- 0 to 255) {
|
for (j <- 0 to 255) {
|
||||||
val subAddr = i.toString + "." + j.toString + ".0.0"
|
val subAddr = i.toString + "." + j.toString + ".0.0"
|
||||||
val subCidr = subAddr + "/16"
|
val subCidr = subAddr + "/16"
|
||||||
val subNet = new SubnetUtils(subCidr)
|
val subNet = new SubnetUtils(subCidr)
|
||||||
if (!isByass(subNet)) {
|
if (!isByass(subNet)) {
|
||||||
if (!InetAddress.getByName(subAddr).isSiteLocalAddress) {
|
if (!InetAddress.getByName(subAddr).isSiteLocalAddress) {
|
||||||
builder.addRoute(subAddr, 16)
|
builder.addRoute(subAddr, 16)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,22 +279,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
def handleConnection: Boolean = {
|
def handleConnection: Boolean = {
|
||||||
startVpn()
|
startVpn()
|
||||||
startShadowsocksDaemon()
|
startShadowsocksDaemon()
|
||||||
if (!config.isUdpDns) startDnsDaemon()
|
if (!config.isUdpDns) {
|
||||||
|
startDnsDaemon()
|
||||||
|
startDnsTunnel()
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
def notifyAlert(title: String, info: String) {
|
|
||||||
val builder = new NotificationCompat.Builder(this)
|
|
||||||
builder
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_shadowsocks)
|
|
||||||
.setWhen(0)
|
|
||||||
.setTicker(title)
|
|
||||||
.setContentTitle(getString(R.string.app_name))
|
|
||||||
.setContentText(info)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
notificationManager.notify(1, builder.build)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onBind(intent: Intent): IBinder = {
|
override def onBind(intent: Intent): IBinder = {
|
||||||
val action = intent.getAction
|
val action = intent.getAction
|
||||||
if (VpnService.SERVICE_INTERFACE == action) {
|
if (VpnService.SERVICE_INTERFACE == action) {
|
||||||
@@ -250,13 +310,15 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def killProcesses() {
|
def killProcesses() {
|
||||||
val ab = new ArrayBuffer[String]
|
for (task <- Array("ss-local", "ss-tunnel", "tun2socks", "pdnsd")) {
|
||||||
|
try {
|
||||||
ab.append("kill -9 `cat " + Path.BASE + "ss-local.pid`")
|
val pid = scala.io.Source.fromFile(Path.BASE + task + ".pid").mkString.trim.toInt
|
||||||
ab.append("kill -9 `cat " + Path.BASE + "tun2socks.pid`")
|
Process.killProcess(pid)
|
||||||
ab.append("kill -15 `cat " + Path.BASE + "pdnsd.pid`")
|
Log.d(TAG, "kill pid: " + pid)
|
||||||
|
} catch {
|
||||||
Console.runCommand(ab.toArray)
|
case e: Throwable => Log.e(TAG, "unable to kill " + task, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def startRunner(c: Config) {
|
override def startRunner(c: Config) {
|
||||||
@@ -297,36 +359,37 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
|
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
|
||||||
} catch {
|
} catch {
|
||||||
case ex: Exception =>
|
case ex: Exception =>
|
||||||
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
|
changeState(State.STOPPED, getString(R.string.service_failed))
|
||||||
stopRunner()
|
stopRunner()
|
||||||
changeState(State.STOPPED)
|
config = null
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the context
|
if (config != null) {
|
||||||
killProcesses()
|
|
||||||
|
|
||||||
// Resolve the server address
|
// reset the context
|
||||||
var resolved: Boolean = false
|
killProcesses()
|
||||||
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
|
|
||||||
!InetAddressUtils.isIPv6Address(config.proxy)) {
|
// Resolve the server address
|
||||||
Utils.resolve(config.proxy, enableIPv6 = true) match {
|
var resolved: Boolean = false
|
||||||
case Some(addr) =>
|
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
|
||||||
config.proxy = addr
|
!InetAddressUtils.isIPv6Address(config.proxy)) {
|
||||||
resolved = true
|
Utils.resolve(config.proxy, enableIPv6 = true) match {
|
||||||
case None => resolved = false
|
case Some(addr) =>
|
||||||
|
config.proxy = addr
|
||||||
|
resolved = true
|
||||||
|
case None => resolved = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resolved = true
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
resolved = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolved && handleConnection) {
|
if (resolved && handleConnection) {
|
||||||
changeState(State.CONNECTED)
|
changeState(State.CONNECTED)
|
||||||
} else {
|
} else {
|
||||||
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
|
changeState(State.STOPPED, getString(R.string.service_failed))
|
||||||
changeState(State.STOPPED)
|
stopRunner()
|
||||||
stopRunner()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,9 +425,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
unregisterReceiver(receiver)
|
unregisterReceiver(receiver)
|
||||||
receiver = null
|
receiver = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset notifications
|
|
||||||
notificationManager.cancel(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override def stopBackgroundService() {
|
override def stopBackgroundService() {
|
||||||
|
|||||||
@@ -92,6 +92,38 @@ object ConfigUtils {
|
|||||||
|}
|
|}
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
|
|
||||||
|
val PDNSD_LOCAL =
|
||||||
|
"""
|
||||||
|
|global {
|
||||||
|
| perm_cache = 2048;
|
||||||
|
| cache_dir = "/data/data/com.github.shadowsocks";
|
||||||
|
| server_ip = %s;
|
||||||
|
| server_port = 8153;
|
||||||
|
| query_method = tcp_only;
|
||||||
|
| run_ipv4 = on;
|
||||||
|
| min_ttl = 15m;
|
||||||
|
| max_ttl = 1w;
|
||||||
|
| timeout = 10;
|
||||||
|
| daemon = on;
|
||||||
|
| pid_file = "/data/data/com.github.shadowsocks/pdnsd.pid";
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|server {
|
||||||
|
| label = "local";
|
||||||
|
| ip = 127.0.0.1;
|
||||||
|
| port = %d;
|
||||||
|
| timeout = 5;
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|rr {
|
||||||
|
| name=localhost;
|
||||||
|
| reverse=on;
|
||||||
|
| a=127.0.0.1;
|
||||||
|
| owner=localhost;
|
||||||
|
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||||
|
|}
|
||||||
|
""".stripMargin
|
||||||
|
|
||||||
val PDNSD_BYPASS =
|
val PDNSD_BYPASS =
|
||||||
"""
|
"""
|
||||||
|global {
|
|global {
|
||||||
|
|||||||
@@ -57,7 +57,10 @@ object Console {
|
|||||||
.open(new OnCommandResultListener {
|
.open(new OnCommandResultListener {
|
||||||
override def onCommandResult(commandCode: Int, exitCode: Int,
|
override def onCommandResult(commandCode: Int, exitCode: Int,
|
||||||
output: util.List[String]) {
|
output: util.List[String]) {
|
||||||
if (exitCode < 0) shell = null
|
if (exitCode < 0) {
|
||||||
|
shell.close()
|
||||||
|
shell = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -82,8 +85,9 @@ object Console {
|
|||||||
if (shell == null) {
|
if (shell == null) {
|
||||||
openShell()
|
openShell()
|
||||||
}
|
}
|
||||||
shell.addCommand(commands)
|
val ts = shell
|
||||||
shell.waitForIdle()
|
ts.addCommand(commands)
|
||||||
|
ts.waitForIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
def runRootCommand(command: String): String = runRootCommand(Array(command))
|
def runRootCommand(command: String): String = runRootCommand(Array(command))
|
||||||
@@ -95,11 +99,13 @@ object Console {
|
|||||||
if (rootShell == null) {
|
if (rootShell == null) {
|
||||||
openRootShell()
|
openRootShell()
|
||||||
}
|
}
|
||||||
|
val ts = rootShell
|
||||||
val sb = new StringBuilder
|
val sb = new StringBuilder
|
||||||
rootShell.addCommand(commands, 0, new OnCommandResultListener {
|
ts.addCommand(commands, 0, new OnCommandResultListener {
|
||||||
override def onCommandResult(commandCode: Int, exitCode: Int,
|
override def onCommandResult(commandCode: Int, exitCode: Int,
|
||||||
output: util.List[String]) {
|
output: util.List[String]) {
|
||||||
if (exitCode < 0) {
|
if (exitCode < 0) {
|
||||||
|
rootShell.close()
|
||||||
rootShell = null
|
rootShell = null
|
||||||
} else {
|
} else {
|
||||||
import scala.collection.JavaConversions._
|
import scala.collection.JavaConversions._
|
||||||
@@ -107,7 +113,7 @@ object Console {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (rootShell.waitForIdle()) sb.toString()
|
if (ts.waitForIdle()) sb.toString()
|
||||||
else null
|
else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user