Compare commits

...
77 Commits
Author SHA1 Message Date
Max Lv d3018fc090 update travis 2015-03-10 16:42:02 +08:00
Max Lv f1f585b4d9 update travis 2015-03-10 16:34:40 +08:00
Max Lv 3653f73e0b update travis 2015-03-10 16:15:31 +08:00
Max Lv d648910aac fix travis 2015-03-10 09:59:30 +08:00
Max Lv 1e2f8c3bd3 Merge pull request #258 from lozen130/patch-1
Fix a coding style issue
2015-03-07 14:35:06 +08:00
Lozen Liu b94c16c725 Fix a coding style issue
Method name should conform to the standard
2015-03-07 14:32:29 +08:00
Max Lv a03a6af5ba update #250 2015-02-25 12:20:29 +08:00
Max Lv b9414c6b0a Merge pull request #249 from Mygod/master
Providing up navigation
2015-02-25 07:44:52 +08:00
Mygod 0d54d9cd9b bugfix 2015-02-24 22:52:57 +08:00
Mygod 8611a66cdc fix indent 2015-02-24 22:38:37 +08:00
Mygod 740dcc3ca9 providing up navigation 2015-02-24 22:34:14 +08:00
Max Lv 730efbafc0 refine URL parser 2015-02-09 18:45:40 +08:00
Max Lv 8b05476823 Merge pull request #241 from cloudtrends/master
add export ANDROID_NDK_HOME variable
2015-02-07 08:37:16 +08:00
ChunFeng 50b890423a add export ANDROID_NDK_HOME variable
add export ANDROID_NDK_HOME variable
2015-02-07 07:57:19 +08:00
Max Lv fb63268895 fix a corner case 2015-01-29 10:20:59 +08:00
Max Lv 41934f8909 try to workaround travis-ci's limit 2015-01-28 13:21:12 +08:00
Max Lv bedc7a0443 add caching to travis 2015-01-28 13:14:00 +08:00
Max Lv 537f790386 fix travis-ci 2015-01-28 13:03:29 +08:00
Max Lv 62afcf51d7 update travis-ci 2015-01-28 12:56:55 +08:00
Max Lv 6c1ae68931 update shadowsocks-libev 2015-01-27 21:00:25 +08:00
Max Lv 2703e91bbe bump version 2015-01-27 17:52:06 +08:00
Max Lv 8fba319db2 fix #228 2015-01-25 13:18:42 +08:00
Max Lv 3e04734b9b update shadowsocks-libev 2015-01-21 20:55:35 +08:00
Max Lv fe33997494 update shadowsocks-libev 2015-01-19 12:08:34 +08:00
Max Lv 86cd49d3e1 update shadowsocks-libev 2015-01-16 13:16:07 +08:00
Max Lv ff13792192 update strings 2015-01-16 13:11:51 +08:00
Max Lv f36a8c784d update shadowsocks-libev 2015-01-13 14:44:58 +08:00
Max Lv 57f8c0f307 disable notification auto-hiding on Kitkat and below #216 2015-01-11 21:26:59 +08:00
Max Lv 601c227644 update shadowsocks-libev 2015-01-08 12:14:54 +08:00
Max Lv 220143aee1 fix #211 2015-01-08 10:44:54 +08:00
Max Lv 81a19c4a81 bump version 2015-01-02 14:16:21 +08:00
Max Lv 27cc53baf8 revert to tcp_only mode 2014-12-28 21:47:43 +08:00
Max Lv 935fddcb15 update submodule 2014-12-28 10:05:12 +08:00
Max Lv 49458080a1 bump version 2014-12-28 09:50:11 +08:00
Max Lv 8101fc935e update shadowsocks 2014-12-27 19:55:33 +08:00
Max Lv 491ebe500f remove https dns query 2014-12-27 08:49:08 +08:00
Max Lv 98ce68774a update black list 2014-12-26 22:08:20 +08:00
Max Lv b0e20552dd refine list 2014-12-26 20:02:26 +08:00
Max Lv 0d478cfbc4 refine reject list 2014-12-26 17:54:35 +08:00
Max Lv d1d135ccdd refine dns black list 2014-12-26 17:30:20 +08:00
Max Lv a28303ee76 update reject list 2014-12-26 16:13:07 +08:00
Max Lv 2b09ebcd2c bump version 2014-12-24 17:38:17 +08:00
Max Lv 59ede2586a update google service 2014-12-24 17:26:48 +08:00
Max Lv abd1d0220c bump version for a build error 2014-12-20 16:42:38 +08:00
Max Lv 5427e00012 fallback to gcc 2014-12-20 10:40:13 +08:00
Max Lv 7f226d3f0c replace crouton with snackbar 2014-12-19 17:32:00 +08:00
Max Lv ee3f3c2338 fix for clang 2014-12-19 13:54:38 +08:00
Max Lv 6ac90abbf7 update OpenSSL's header 2014-12-18 15:29:21 +08:00
Max Lv 2f553b156a fix #188 2014-12-18 14:33:32 +08:00
Max Lv dec098fbc5 refine the lock screen receiver 2014-12-18 09:17:57 +08:00
Max Lv 000d03ad4c update shadowsocks-libev 2014-12-17 08:49:43 +08:00
Max Lv 667619f701 tune timeout for long tcp connection 2014-12-17 08:42:43 +08:00
Max Lv afd91b7155 fix #186 2014-12-15 17:19:40 +08:00
Max Lv e10272c8e5 disable uptest in pdnsd 2014-12-14 14:46:16 +08:00
Max Lv 0f5651fef7 refine pdnsd settings 2014-12-14 09:55:11 +08:00
Max Lv f258de36d7 update ulimit -n 2014-12-13 19:51:21 +08:00
Max Lv e71db2160e update shadowsocks 2014-12-13 18:54:59 +08:00
Max Lv f1cbfb7ea7 update shadowsocks 2014-12-13 16:11:43 +08:00
Max Lv 8c2a2f032a add salsa20 and chacha20 2014-12-13 15:59:08 +08:00
Max Lv 24d45cc2a2 Merge branch 'master' of github.com:shadowsocks/shadowsocks-android 2014-12-13 15:57:23 +08:00
Max Lv 5220f302c5 add libsodium 2014-12-13 15:55:55 +08:00
Max Lv f0ef6c8e35 fix #166 2014-12-12 13:19:55 +08:00
Max Lv 10de6ea6d9 remote the DNS WAR 2014-12-10 19:39:54 +08:00
Max Lv c1f55c80f9 refine UI 2014-12-10 17:54:47 +08:00
Max Lv 3503e7233f fix #176 2014-12-10 13:07:09 +08:00
Max Lv 3db8e9d775 refine #171 2014-12-09 21:04:54 +08:00
Max Lv e708e117be fix #171 2014-12-09 20:59:04 +08:00
Max Lv 836088534b bump version 2014-12-09 17:37:58 +08:00
Max Lv 6ae97e630e fix #170 2014-12-09 17:20:29 +08:00
Max Lv bae0b9e746 fix a bug 2014-12-08 14:53:30 +08:00
Max Lv 15262343f4 restore DNS nicely 2014-12-08 10:35:59 +08:00
Max Lv be31a0ce82 bump version 2014-12-06 19:16:08 +08:00
Max Lv 0b0b6137b8 disable NAT mode on lollipop by default 2014-12-06 19:15:41 +08:00
Max Lv 156b0c27f5 refine DNS settings 2014-12-06 11:54:42 +08:00
Max Lv ca99596270 Merge branch 'master' of github.com:shadowsocks/shadowsocks-android
Conflicts:
	src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
2014-12-06 11:30:07 +08:00
Max Lv e22ffa8601 improve DNS utils 2014-12-06 11:29:11 +08:00
Max Lv 24233f104a Fix #167 2014-12-04 19:21:22 +08:00
33 changed files with 9891 additions and 46509 deletions
+3 -3
View File
@@ -1,3 +1,3 @@
[submodule "src/main/jni/shadowsocks"]
path = src/main/jni/shadowsocks
url = https://github.com/madeye/shadowsocks-libev
[submodule "src/main/jni/shadowsocks-libev"]
path = src/main/jni/shadowsocks-libev
url = https://github.com/shadowsocks/shadowsocks-libev
+17 -12
View File
@@ -1,21 +1,26 @@
language: scala
scala:
- 2.10.4
language: android
android:
components:
- tools
- platform-tools
- build-tools-21.1.1
- android-21
- extra-google-m2repository
- extra-android-m2repository
cache:
- apt
before_install:
- echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
- sudo apt-get update
install:
- sudo apt-get install -y libc6-dev-i386 lib32ncurses5-dev libx11-dev g++-multilib lib32z1-dev ccache
- sudo apt-get install -y --force-yes sbt libc6-dev-i386 lib32ncurses5-dev libx11-dev g++-multilib lib32z1-dev ccache
- export NDK_CCACHE=ccache
- export ARCH=`uname -m`
- wget http://dl.google.com/android/android-sdk_r23.0.2-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
- tar xf android-ndk-r9d-linux-${ARCH}.tar.bz2
- export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d
- export ANDROID_HOME=`pwd`/android-sdk-linux
- wget http://dl.google.com/android/ndk/android-ndk-r10d-linux-${ARCH}.bin
- chmod +x android-ndk-r10d-linux-${ARCH}.bin
- ./android-ndk-r10d-linux-${ARCH}.bin -y | grep gcc
- export ANDROID_NDK_HOME=`pwd`/android-ndk-r10d
- export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
- 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
script:
- cp local.properties.travis local.properties
- ./build.sh
+1
View File
@@ -40,6 +40,7 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
* Install Android SDK and NDK by run `brew install android-ndk android-sdk`
* Add `export ANDROID_HOME=/usr/local/Cellar/android-sdk/$version` to your .bashrc , then reopen the shell to load it.
* Add `export ANDROID_NDK_HOME=/usr/local/Cellar/android-ndk/$version` to your .bashrc , then reopen the shell to load it.
* 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
* Create your key following the instructions at http://developer.android.com/guide/publishing/app-signing.html#cert
+7 -4
View File
@@ -14,6 +14,8 @@ ndkJavah in Android := List()
ndkBuild in Android := List()
typedResources in Android := false
resolvers += "JRAF" at "http://JRAF.org/static/maven/2"
resolvers += "madeye private releases" at "http://madeye-maven-repository.googlecode.com/git/"
@@ -22,17 +24,18 @@ libraryDependencies ++= Seq(
"dnsjava" % "dnsjava" % "2.1.5",
"com.github.kevinsawicki" % "http-request" % "5.6",
"commons-net" % "commons-net" % "3.3",
"com.google.zxing" % "android-integration" % "2.2"
"com.google.zxing" % "android-integration" % "3.1.0"
)
libraryDependencies ++= Seq(
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
"com.google.android.gms" % "play-services" % "5.0.89",
"com.android.support" % "support-v4" % "19.1.0"
"com.google.android.gms" % "play-services-base" % "6.5.87",
"com.google.android.gms" % "play-services-ads" % "6.5.87",
"com.android.support" % "support-v4" % "21.0.3"
)
libraryDependencies ++= Seq(
"de.keyboardsurfer.android.widget" % "crouton" % "1.8.4" exclude("com.google.android", "support-v4"),
"com.github.mrengineer13" % "snackbar" % "0.5.0",
"com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4",
"com.j256.ormlite" % "ormlite-core" % "4.47",
"com.j256.ormlite" % "ormlite-android" % "4.47"
File diff suppressed because it is too large Load Diff
-4488
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks"
android:versionCode="89"
android:versionName="2.5.1">
android:versionCode="103"
android:versionName="2.6.5">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
@@ -65,7 +65,8 @@
<activity
android:name=".AppManager"
android:theme="@style/Theme.AppManager"
android:label="@string/app_name">
android:label="@string/app_name"
android:parentActivityName=".Shadowsocks">
<intent-filter>
<action android:name="com.github.shadowsocks.AppManager"/>
<category android:name="android.intent.category.DEFAULT"/>
+108 -15
View File
@@ -16,6 +16,73 @@
LOCAL_PATH := $(call my-dir)
ROOT_PATH := $(LOCAL_PATH)
########################################################
## libsodium
########################################################
include $(CLEAR_VARS)
crypto_aead_src := crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c
crypto_auth_src := crypto_auth/crypto_auth.c crypto_auth/hmacsha256/auth_hmacsha256_api.c crypto_auth/hmacsha256/cp/hmac_hmacsha256.c crypto_auth/hmacsha256/cp/verify_hmacsha256.c crypto_auth/hmacsha512/auth_hmacsha512_api.c crypto_auth/hmacsha512/cp/hmac_hmacsha512.c crypto_auth/hmacsha512/cp/verify_hmacsha512.c crypto_auth/hmacsha512256/auth_hmacsha512256_api.c crypto_auth/hmacsha512256/cp/hmac_hmacsha512256.c crypto_auth/hmacsha512256/cp/verify_hmacsha512256.c
crypto_box_src := crypto_box/crypto_box.c crypto_box/crypto_box_easy.c crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305_api.c crypto_box/curve25519xsalsa20poly1305/ref/after_curve25519xsalsa20poly1305.c crypto_box/curve25519xsalsa20poly1305/ref/before_curve25519xsalsa20poly1305.c crypto_box/curve25519xsalsa20poly1305/ref/box_curve25519xsalsa20poly1305.c crypto_box/curve25519xsalsa20poly1305/ref/keypair_curve25519xsalsa20poly1305.c
crypto_core_src := crypto_core/hsalsa20/core_hsalsa20_api.c crypto_core/hsalsa20/ref2/core_hsalsa20.c crypto_core/salsa20/core_salsa20_api.c crypto_core/salsa20/ref/core_salsa20.c crypto_core/salsa2012/core_salsa2012_api.c crypto_core/salsa2012/ref/core_salsa2012.c crypto_core/salsa208/core_salsa208_api.c crypto_core/salsa208/ref/core_salsa208.c
crypto_generichash_src := crypto_generichash/blake2/generichash_blake2_api.c crypto_generichash/blake2/ref/blake2b-ref.c crypto_generichash/blake2/ref/generichash_blake2b.c crypto_generichash/crypto_generichash.c
crypto_hash_src := crypto_hash/crypto_hash.c crypto_hash/sha256/cp/hash_sha256.c crypto_hash/sha256/hash_sha256_api.c crypto_hash/sha512/cp/hash_sha512.c crypto_hash/sha512/hash_sha512_api.c
crypto_onetimeauth_src := crypto_onetimeauth/crypto_onetimeauth.c crypto_onetimeauth/poly1305/donna/auth_poly1305_donna.c crypto_onetimeauth/poly1305/donna/verify_poly1305_donna.c crypto_onetimeauth/poly1305/onetimeauth_poly1305.c crypto_onetimeauth/poly1305/onetimeauth_poly1305_api.c crypto_onetimeauth/poly1305/onetimeauth_poly1305_try.c
crypto_pwhash_src := crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c
crypto_scalarmult_src := crypto_scalarmult/crypto_scalarmult.c crypto_scalarmult/curve25519/donna_c64/base_curve25519_donna_c64.c crypto_scalarmult/curve25519/donna_c64/smult_curve25519_donna_c64.c crypto_scalarmult/curve25519/ref10/base_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_0_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_1_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_add_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_copy_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_cswap_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_frombytes_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_invert_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_mul121666_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_mul_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_sq_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_sub_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_tobytes_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/scalarmult_curve25519_ref10.c crypto_scalarmult/curve25519/scalarmult_curve25519_api.c
crypto_secretbox_src := crypto_secretbox/crypto_secretbox.c crypto_secretbox/crypto_secretbox_easy.c crypto_secretbox/xsalsa20poly1305/ref/box_xsalsa20poly1305.c crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305_api.c
crypto_shorthash_src := crypto_shorthash/crypto_shorthash.c crypto_shorthash/siphash24/ref/shorthash_siphash24.c crypto_shorthash/siphash24/shorthash_siphash24_api.c
crypto_sign_src := crypto_sign/crypto_sign.c crypto_sign/ed25519/ref10/fe_0.c crypto_sign/ed25519/ref10/fe_1.c crypto_sign/ed25519/ref10/fe_add.c crypto_sign/ed25519/ref10/fe_cmov.c crypto_sign/ed25519/ref10/fe_copy.c crypto_sign/ed25519/ref10/fe_frombytes.c crypto_sign/ed25519/ref10/fe_invert.c crypto_sign/ed25519/ref10/fe_isnegative.c crypto_sign/ed25519/ref10/fe_isnonzero.c crypto_sign/ed25519/ref10/fe_mul.c crypto_sign/ed25519/ref10/fe_neg.c crypto_sign/ed25519/ref10/fe_pow22523.c crypto_sign/ed25519/ref10/fe_sq.c crypto_sign/ed25519/ref10/fe_sq2.c crypto_sign/ed25519/ref10/fe_sub.c crypto_sign/ed25519/ref10/fe_tobytes.c crypto_sign/ed25519/ref10/ge_add.c crypto_sign/ed25519/ref10/ge_double_scalarmult.c crypto_sign/ed25519/ref10/ge_frombytes.c crypto_sign/ed25519/ref10/ge_madd.c crypto_sign/ed25519/ref10/ge_msub.c crypto_sign/ed25519/ref10/ge_p1p1_to_p2.c crypto_sign/ed25519/ref10/ge_p1p1_to_p3.c crypto_sign/ed25519/ref10/ge_p2_0.c crypto_sign/ed25519/ref10/ge_p2_dbl.c crypto_sign/ed25519/ref10/ge_p3_0.c crypto_sign/ed25519/ref10/ge_p3_dbl.c crypto_sign/ed25519/ref10/ge_p3_to_cached.c crypto_sign/ed25519/ref10/ge_p3_to_p2.c crypto_sign/ed25519/ref10/ge_p3_tobytes.c crypto_sign/ed25519/ref10/ge_precomp_0.c crypto_sign/ed25519/ref10/ge_scalarmult_base.c crypto_sign/ed25519/ref10/ge_sub.c crypto_sign/ed25519/ref10/ge_tobytes.c crypto_sign/ed25519/ref10/keypair.c crypto_sign/ed25519/ref10/open.c crypto_sign/ed25519/ref10/sc_muladd.c crypto_sign/ed25519/ref10/sc_reduce.c crypto_sign/ed25519/ref10/sign.c crypto_sign/ed25519/sign_ed25519_api.c crypto_sign/edwards25519sha512batch/ref/fe25519_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/ref/ge25519_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/ref/sc25519_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/ref/sign_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/sign_edwards25519sha512batch_api.c
crypto_stream_src := crypto_stream/aes128ctr/portable/afternm_aes128ctr.c crypto_stream/aes128ctr/portable/beforenm_aes128ctr.c crypto_stream/aes128ctr/portable/common_aes128ctr.c crypto_stream/aes128ctr/portable/consts_aes128ctr.c crypto_stream/aes128ctr/portable/int128_aes128ctr.c crypto_stream/aes128ctr/portable/stream_aes128ctr.c crypto_stream/aes128ctr/portable/xor_afternm_aes128ctr.c crypto_stream/aes128ctr/stream_aes128ctr_api.c crypto_stream/chacha20/ref/stream_chacha20_ref.c crypto_stream/chacha20/stream_chacha20_api.c crypto_stream/crypto_stream.c crypto_stream/salsa20/ref/stream_salsa20_ref.c crypto_stream/salsa20/ref/xor_salsa20_ref.c crypto_stream/salsa20/stream_salsa20_api.c crypto_stream/salsa2012/ref/stream_salsa2012.c crypto_stream/salsa2012/ref/xor_salsa2012.c crypto_stream/salsa2012/stream_salsa2012_api.c crypto_stream/salsa208/ref/stream_salsa208.c crypto_stream/salsa208/ref/xor_salsa208.c crypto_stream/salsa208/stream_salsa208_api.c crypto_stream/xsalsa20/ref/stream_xsalsa20.c crypto_stream/xsalsa20/ref/xor_xsalsa20.c crypto_stream/xsalsa20/stream_xsalsa20_api.c
crypto_verify_src := crypto_verify/16/ref/verify_16.c crypto_verify/16/verify_16_api.c crypto_verify/32/ref/verify_32.c crypto_verify/32/verify_32_api.c crypto_verify/64/ref/verify_64.c crypto_verify/64/verify_64_api.c
randombytes_src := randombytes/randombytes.c randombytes/salsa20/randombytes_salsa20_random.c randombytes/sysrandom/randombytes_sysrandom.c
sodium_src := sodium/core.c sodium/runtime.c sodium/utils.c sodium/version.c
SODIUM_SOURCE := $(crypto_aead_src) $(crypto_auth_src) $(crypto_box_src) \
$(crypto_core_src) $(crypto_generichash_src) $(crypto_hash_src) \
$(crypto_onetimeauth_src) $(crypto_pwhash_src) $(crypto_scalarmult_src) \
$(crypto_secretbox_src) $(crypto_shorthash_src) $(crypto_sign_src) \
$(crypto_stream_src) $(crypto_verify_src) $(randombytes_src) $(sodium_src)
LOCAL_MODULE := sodium
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
-DPACKAGE_NAME=\"libsodium\" -DPACKAGE_TARNAME=\"libsodium\" \
-DPACKAGE_VERSION=\"1.0.1\" -DPACKAGE_STRING=\"libsodium\ 1.0.1\" \
-DPACKAGE_BUGREPORT=\"https://github.com/jedisct1/libsodium/issues\" \
-DPACKAGE_URL=\"https://github.com/jedisct1/libsodium\" \
-DPACKAGE=\"libsodium\" -DVERSION=\"1.0.1\" -DSTDC_HEADERS=1 \
-DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 \
-DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 \
-DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 \
-D__EXTENSIONS__=1 -D_ALL_SOURCE=1 -D_GNU_SOURCE=1 \
-D_POSIX_PTHREAD_SEMANTICS=1 -D_TANDEM_SOURCE=1 \
-DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_MMINTRIN_H=1 \
-DHAVE_EMMINTRIN_H=1 -DHAVE_PMMINTRIN_H=1 -DHAVE_TMMINTRIN_H=1 \
-DHAVE_SYS_MMAN_H=1 -DNATIVE_LITTLE_ENDIAN=1 \
-DHAVE_WEAK_SYMBOLS=1 -DHAVE_ARC4RANDOM=1 -DHAVE_ARC4RANDOM_BUF=1 \
-DHAVE_MLOCK=1 -DHAVE_MPROTECT=1 -DHAVE_POSIX_MEMALIGN=1
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libsodium/src/libsodium/,$(SODIUM_SOURCE))
include $(BUILD_STATIC_LIBRARY)
########################################################
## libevent
########################################################
@@ -59,10 +126,10 @@ set_src = set/allocation.c set/inspection.c set/ipv4_set.c set/ipv6_set.c \
IPSET_SOURCE := general.c $(bdd_src) $(map_src) $(set_src)
LOCAL_MODULE := libipset
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks/libipset/include \
-I$(LOCAL_PATH)/shadowsocks/libcork/include
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libipset/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include
LOCAL_SRC_FILES := $(addprefix shadowsocks/libipset/,$(IPSET_SOURCE))
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libipset/,$(IPSET_SOURCE))
include $(BUILD_STATIC_LIBRARY)
@@ -86,10 +153,29 @@ pthreads_src := pthreads/thread.c
CORK_SOURCE := $(cli_src) $(core_src) $(ds_src) $(posix_src) $(pthreads_src)
LOCAL_MODULE := libcork
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks/libcork/include \
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
-DCORK_API=CORK_LOCAL
LOCAL_SRC_FILES := $(addprefix shadowsocks/libcork/,$(CORK_SOURCE))
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libcork/,$(CORK_SOURCE))
include $(BUILD_STATIC_LIBRARY)
########################################################
## libudns
########################################################
include $(CLEAR_VARS)
UDNS_SOURCES := udns_dn.c udns_dntosp.c udns_parse.c udns_resolver.c udns_init.c \
udns_misc.c udns_XtoX.c \
udns_rr_a.c udns_rr_ptr.c udns_rr_mx.c udns_rr_txt.c udns_bl.c \
udns_rr_srv.c udns_rr_naptr.c udns_codes.c udns_jran.c
LOCAL_MODULE := libudns
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libudns \
-DHAVE_DECL_INET_NTOP
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libudns/,$(UDNS_SOURCES))
include $(BUILD_STATIC_LIBRARY)
@@ -143,44 +229,51 @@ LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/pdnsd
include $(BUILD_EXECUTABLE)
########################################################
## shadowsocks local library
## shadowsocks-libev local library
########################################################
include $(CLEAR_VARS)
SHADOWSOCKS_SOURCES := local.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c acl.c
SHADOWSOCKS_SOURCES := local.c cache.c udprelay.c encrypt.c utils.c netutils.c json.c jconf.c acl.c
LOCAL_MODULE := ss-local
LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES))
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL \
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \
-I$(LOCAL_PATH)/libev/ \
-I$(LOCAL_PATH)/openssl/include \
-I$(LOCAL_PATH)/shadowsocks/libcork/include \
-I$(LOCAL_PATH)/shadowsocks/libipset/include
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
-I$(LOCAL_PATH)/shadowsocks-libev/libipset/include
LOCAL_STATIC_LIBRARIES := libev libcrypto libipset libcork
LOCAL_STATIC_LIBRARIES := libev libcrypto libipset libcork libudns libsodium
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
########################################################
## shadowsocks tunnel
## shadowsocks-libev tunnel
########################################################
include $(CLEAR_VARS)
SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c
SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c netutils.c json.c jconf.c
LOCAL_MODULE := ss-tunnel
LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES))
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H -DSSTUNNEL_JNI \
-I$(LOCAL_PATH)/libev/ \
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include \
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
-I$(LOCAL_PATH)/openssl/include
LOCAL_STATIC_LIBRARIES := libev libcrypto
LOCAL_STATIC_LIBRARIES := libev libcrypto libsodium libcork libudns
LOCAL_LDLIBS := -llog
+4 -2
View File
@@ -59,7 +59,8 @@ static void
ev_arc4random_buf(void *buf, size_t n)
{
#if defined(_EVENT_HAVE_ARC4RANDOM_BUF) && !defined(__APPLE__)
return arc4random_buf(buf, n);
arc4random_buf(buf, n);
return;
#else
unsigned char *b = buf;
@@ -71,7 +72,8 @@ ev_arc4random_buf(void *buf, size_t n)
* trickery.)
*/
if (arc4random_buf != NULL) {
return arc4random_buf(buf, n);
arc4random_buf(buf, n);
return;
}
#endif
/* Make sure that we start out with b at a 4-byte alignment; plenty
@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
#define OPENSSL_VERSION_NUMBER 0x1000103fL
#define OPENSSL_VERSION_NUMBER 0x100010afL
#ifdef OPENSSL_FIPS
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1c-fips 10 May 2012"
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j-fips 15 Oct 2014"
#else
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1c 10 May 2012"
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j 15 Oct 2014"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
+8
View File
@@ -0,0 +1,8 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/action_export"
android:title="@string/action_export"
android:showAsAction="never" />
<item android:id="@+id/action_import"
android:title="@string/action_import"
android:showAsAction="never" />
</menu>
+16 -5
View File
@@ -10,13 +10,13 @@
<string name="profile">配置文件</string>
<string name="profile_summary">配置文件名称</string>
<string name="proxy">服务器</string>
<string name="proxy_summary">您的影梭服务器的地址</string>
<string name="proxy_summary">远程服务器的地址</string>
<string name="remote_port">远程端口</string>
<string name="remote_port_summary">您的影梭服务器的端口号</string>
<string name="remote_port_summary">远程服务器的端口号</string>
<string name="port">本地端口</string>
<string name="port_summary">您的影梭客户端的端口号</string>
<string name="port_summary">本地客户端的端口号</string>
<string name="sitekey">密码</string>
<string name="sitekey_summary">您的影梭服务器的密码</string>
<string name="sitekey_summary">远程服务器的密码</string>
<string name="enc_method">加密方法</string>
<string name="feature_cat">功能设置</string>
<string name="http_proxy">HTTP 代理服务器</string>
@@ -47,7 +47,7 @@
<string name="service_failed">无法连接远程服务器</string>
<string name="stop">停止服务</string>
<string name="stopping">正在关闭...</string>
<string name="vpn_error">后台服务启动失败:\"%s\"。</string>
<string name="vpn_error">后台服务启动失败:%s</string>
<string name="ok_iknow">确定</string>
<string name="port_alert">端口号应大于1024</string>
<string name="port_empty">端口号不能为空</string>
@@ -69,6 +69,9 @@
<string name="flushing">刷新中...</string>
<string name="add_profile">添加配置文件</string>
<string name="enable_nat">启用 NAT 模式.</string>
<string name="disable_nat">禁用 NAT 模式.</string>
<string name="udp_dns">UDP 转发</string>
<string name="udp_dns_summary">由远程服务器转发 UDP 协议的数据包</string>
@@ -85,4 +88,12 @@
<item>绕过局域网及中国大陆地址</item>
</string-array>
<string name="action_export">导出至剪贴板</string>
<string name="action_import">从剪贴板导入</string>
<string name="action_export_msg">导出成功</string>
<string name="action_export_err">导出失败</string>
<string name="action_import_msg">导入成功</string>
<string name="action_import_err">导入失败</string>
<string name="error">错误</string>
</resources>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -4,6 +4,7 @@
<color name="title_background">#ff5e5e5e</color>
<color name="dialog_title_background">#17170443</color>
<color name="white">#FFFFFF</color>
<color name="black">#000000</color>
<color name="grey1">#646464</color>
<color name="grey2">#c8c8c8</color>
@@ -11,4 +12,4 @@
<color name="md__transparent">#00000000</color>
<color name="md__defaultBackground">#FF555555</color>
</resources>
</resources>
View File
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Executable → Regular
+14 -5
View File
@@ -14,13 +14,13 @@
<string name="profile">Profile</string>
<string name="profile_summary">Profile name</string>
<string name="proxy">Server</string>
<string name="proxy_summary">Hostname or IP Address of your Shadowsocks server</string>
<string name="proxy_summary">Hostname or IP of the remote server</string>
<string name="remote_port">Remote Port</string>
<string name="remote_port_summary">Port number of your Shadowsocks server</string>
<string name="remote_port_summary">Port number of the remote server</string>
<string name="port">Local Port</string>
<string name="port_summary">Port number of your Shadowsocks client</string>
<string name="port_summary">Port number of the local server</string>
<string name="sitekey">Password</string>
<string name="sitekey_summary">Password of your Shadowsocks server</string>
<string name="sitekey_summary">Password of the remote server</string>
<string name="enc_method">Encrypt Method</string>
<!-- feature category -->
@@ -58,7 +58,10 @@
<string name="service_failed">Failed to connect the remote server</string>
<string name="stop">Stop the service</string>
<string name="stopping">Shutting down...</string>
<string name="vpn_error">Error: \"%s\".</string>
<string name="vpn_error">%s</string>
<string name="enable_nat">Turn on NAT mode.</string>
<string name="disable_nat">Turn off NAT mode.</string>
<string name="error">ERROR</string>
<!-- alert category -->
<string name="ok_iknow">OK</string>
@@ -84,6 +87,12 @@
<string name="flush_dnscache">Flush DNS Cache</string>
<string name="flushing">Flushing</string>
<string name="add_profile">Add Profile</string>
<string name="action_export">Export to Clipboard</string>
<string name="action_import">Import from Clipboard</string>
<string name="action_export_msg">Successfully export!</string>
<string name="action_export_err">Failed to export.</string>
<string name="action_import_msg">Successfully import!</string>
<string name="action_import_err">Failed to import.</string>
<!-- profile -->
<string name="add_profile_dialog">Add this Shadowsocks Profile?</string>
+15 -4
View File
@@ -29,10 +29,10 @@
<item name="android:actionModeBackground">@drawable/cab_background_top_shadow</item>
<item name="android:actionModeSplitBackground">@drawable/cab_background_bottom_shadow</item>
<item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Shadow</item>
<!-- Light.DarkActionBar specific -->
<!-- Light.DarkActionBar specific -->
<item name="android:actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
</style>
<style name="ActionBar.Solid.Shadow" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
@@ -51,6 +51,14 @@
<item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
</style>
<style name="m_textAppearanceSmallPopupMenu" parent="@android:style/TextAppearance.Holo.Widget.PopupMenu.Small">
<item name="android:textColor">@android:color/white</item>
</style>
<style name="m_textAppearanceLargePopupMenu" parent="@android:style/TextAppearance.Holo.Widget.PopupMenu.Large">
<item name="android:textColor">@android:color/white</item>
</style>
<style name="DropDownListView.Shadow" parent="@android:style/Widget.Holo.ListView.DropDown">
<item name="android:listSelector">@drawable/selectable_background_shadow</item>
</style>
@@ -77,6 +85,9 @@
<style name="Theme.Shadow.Widget" parent="@android:style/Theme.Holo">
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
</style>
</resources>
</resources>
@@ -40,6 +40,8 @@
package com.github.shadowsocks
import android.app.{Activity, ProgressDialog}
import android.content.ClipboardManager
import android.content.ClipData
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
@@ -47,6 +49,8 @@ import android.graphics.{Bitmap, PixelFormat}
import android.os.Bundle
import android.os.Handler
import android.preference.PreferenceManager
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
@@ -115,7 +119,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
var appsLoaded: Boolean = false
def loadApps(context: Context): Array[ProxiedApp] = {
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val proxiedAppString = prefs.getString(Key.proxied, "")
val proxiedApps = proxiedAppString.split('|').sortWith(_ < _)
@@ -218,12 +222,64 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
}
}
protected override def onOptionsItemSelected(item: MenuItem): Boolean = {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE).asInstanceOf[ClipboardManager]
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
item.getItemId match {
case R.id.action_export =>
val bypass = prefs.getBoolean(Key.isBypassApps, false)
val proxiedAppString = prefs.getString(Key.proxied, "")
val clip = ClipData.newPlainText(Key.proxied, bypass + " " + proxiedAppString)
clipboard.setPrimaryClip(clip)
Toast.makeText(this, R.string.action_export_msg, Toast.LENGTH_SHORT).show()
return true
case R.id.action_import =>
if (clipboard.hasPrimaryClip) {
val clipdata = clipboard.getPrimaryClip
val label = clipdata.getDescription.getLabel
if (label == Key.proxied) {
val proxiedAppSequence = clipdata.getItemAt(0).getText
if (proxiedAppSequence != null) {
val proxiedAppString = proxiedAppSequence.toString
if (!proxiedAppString.isEmpty) {
val array = proxiedAppString.split(" ")
val bypass = array(0).toBoolean
val apps = if (array.size > 1) array(1) else ""
prefs.edit.putBoolean(Key.isBypassApps, bypass).commit()
prefs.edit.putString(Key.proxied, apps).commit()
Toast.makeText(this, R.string.action_import_msg, Toast.LENGTH_SHORT).show()
// Restart activity
val intent = getIntent
finish()
startActivity(intent)
return true
}
}
}
}
Toast.makeText(this, R.string.action_import_err, Toast.LENGTH_SHORT).show()
return false
case android.R.id.home =>
navigateUpTo(getParentActivityIntent)
return true
}
super.onOptionsItemSelected(item)
}
protected override def onCreateOptionsMenu(menu: Menu): Boolean = {
val inflater = getMenuInflater()
inflater.inflate(R.menu.app_manager_menu, menu)
return super.onCreateOptionsMenu(menu)
}
protected override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
handler = new Handler()
getActionBar.setTitle(R.string.proxied_help)
val actionBar = getActionBar()
actionBar.setTitle(R.string.proxied_help)
actionBar.setDisplayHomeAsUpEnabled(true)
this.setContentView(R.layout.layout_apps)
this.overlay = View.inflate(this, R.layout.overlay, null).asInstanceOf[TextView]
getWindowManager.addView(overlay, new
@@ -239,7 +295,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
ImageLoader.getInstance().init(config)
val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
bypassSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener {
def onCheckedChanged(button: CompoundButton, checked: Boolean) {
prefs.edit().putBoolean(Key.isBypassApps, checked).commit()
@@ -261,7 +317,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
def saveAppSettings(context: Context) {
if (apps == null) return
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val proxiedApps = new StringBuilder
apps.foreach(app =>
if (app.proxied) {
@@ -49,8 +49,8 @@ import android.content.Context
trait BaseService {
@volatile var state = State.INIT
@volatile var callbackCount = 0
@volatile private var state = State.INIT
@volatile private var callbackCount = 0
final val callbacks = new RemoteCallbackList[IShadowsocksServiceCallback]
@@ -100,6 +100,12 @@ trait BaseService {
def getTag: String
def getContext: Context
def getCallbackCount(): Int = {
callbackCount
}
def getState(): Int = {
state
}
def changeState(s: Int) {
changeState(s, null)
}
@@ -40,6 +40,7 @@ package com.github.shadowsocks
import java.util
import java.io.{OutputStream, InputStream, ByteArrayInputStream, ByteArrayOutputStream, IOException, FileOutputStream}
import java.util.Locale
import android.app.backup.BackupManager
import android.app.{Activity, AlertDialog, ProgressDialog}
@@ -51,9 +52,11 @@ import android.net.{Uri, VpnService}
import android.os._
import android.preference._
import android.util.{DisplayMetrics, Log}
import android.view.View.OnLongClickListener
import android.view._
import android.webkit.{WebView, WebViewClient}
import android.widget._
import com.github.mrengineer13.snackbar._
import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback}
import com.github.shadowsocks.database._
import com.github.shadowsocks.preferences.{PasswordEditTextPreference, ProfileEditTextPreference, SummaryEditTextPreference}
@@ -62,12 +65,10 @@ import com.google.android.gms.ads.{AdRequest, AdSize, AdView}
import com.google.android.gms.analytics.HitBuilders
import com.google.zxing.integration.android.IntentIntegrator
import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import de.keyboardsurfer.android.widget.crouton.{Configuration, Crouton, Style}
import net.simonvt.menudrawer.MenuDrawer
import scala.collection.mutable.{ArrayBuffer, ListBuffer}
import scala.concurrent.ops._
import scala.ref.WeakReference
class ProfileIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int)
extends BaseImageDownloader(context, connectTimeout, readTimeout) {
@@ -204,7 +205,6 @@ class Shadowsocks
// Update the UI
if (switchButton != null) switchButton.setEnabled(true)
if (State.isAvailable(bgService.getState)) {
Crouton.cancelAllCroutons()
setPreferenceEnabled(enabled = true)
} else {
changeSwitch(checked = true)
@@ -321,12 +321,12 @@ class Shadowsocks
}
}
private def crash_recovery() {
private def crashRecovery() {
val cmd = new ArrayBuffer[String]()
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "redsocks", "tun2socks")) {
cmd.append("chmod 666 %s%s-nat.pid".format(Path.BASE, task))
cmd.append("chmod 666 %s%s-vpn.pid".format(Path.BASE, task))
cmd.append("chmod 666 %s%s-nat.pid".formatLocal(Locale.ENGLISH, Path.BASE, task))
cmd.append("chmod 666 %s%s-vpn.pid".formatLocal(Locale.ENGLISH, Path.BASE, task))
}
Console.runRootCommand(cmd.toArray)
cmd.clear()
@@ -335,17 +335,17 @@ class Shadowsocks
try {
val pid_nat = scala.io.Source.fromFile(Path.BASE + task + "-nat.pid").mkString.trim.toInt
val pid_vpn = scala.io.Source.fromFile(Path.BASE + task + "-vpn.pid").mkString.trim.toInt
cmd.append("kill -9 %d".format(pid_nat))
cmd.append("kill -9 %d".format(pid_vpn))
cmd.append("kill -9 %d".formatLocal(Locale.ENGLISH, pid_nat))
cmd.append("kill -9 %d".formatLocal(Locale.ENGLISH, pid_vpn))
Process.killProcess(pid_nat)
Process.killProcess(pid_vpn)
} catch {
case e: Throwable => Log.e(Shadowsocks.TAG, "unable to kill " + task)
}
cmd.append("rm -f %s%s-nat.pid".format(Path.BASE, task))
cmd.append("rm -f %s%s-nat.conf".format(Path.BASE, task))
cmd.append("rm -f %s%s-vpn.pid".format(Path.BASE, task))
cmd.append("rm -f %s%s-vpn.conf".format(Path.BASE, task))
cmd.append("rm -f %s%s-nat.pid".formatLocal(Locale.ENGLISH, Path.BASE, task))
cmd.append("rm -f %s%s-nat.conf".formatLocal(Locale.ENGLISH, Path.BASE, task))
cmd.append("rm -f %s%s-vpn.pid".formatLocal(Locale.ENGLISH, Path.BASE, task))
cmd.append("rm -f %s%s-vpn.conf".formatLocal(Locale.ENGLISH, Path.BASE, task))
}
Console.runCommand(cmd.toArray)
Console.runRootCommand(cmd.toArray)
@@ -366,7 +366,7 @@ class Shadowsocks
def isTextEmpty(s: String, msg: String): Boolean = {
if (s == null || s.length <= 0) {
Crouton.makeText(this, msg, Style.ALERT).show()
new SnackBar.Builder(this).withMessage(msg).withStyle(SnackBar.Style.ALERT).show()
return true
}
false
@@ -499,13 +499,30 @@ class Shadowsocks
getActionBar.setDisplayShowTitleEnabled(false)
getActionBar.setDisplayShowCustomEnabled(true)
getActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
title.setOnLongClickListener(new OnLongClickListener {
override def onLongClick(v: View): Boolean = {
if (Utils.isLollipopOrAbove && bgService != null
&& (bgService.getState == State.INIT || bgService.getState == State.STOPPED)) {
val natEnabled = status.getBoolean(Key.isNAT, false)
status.edit().putBoolean(Key.isNAT, !natEnabled).commit()
if (!natEnabled) {
Toast.makeText(getBaseContext, R.string.enable_nat, Toast.LENGTH_LONG).show()
} else {
Toast.makeText(getBaseContext, R.string.disable_nat, Toast.LENGTH_LONG).show()
}
true
} else {
false
}
}
})
// Register broadcast receiver
registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS))
// Bind to the service
spawn {
val isRoot = Console.isRoot
val isRoot = (!Utils.isLollipopOrAbove || status.getBoolean(Key.isNAT, false)) && Console.isRoot
handler.post(new Runnable {
override def run() {
status.edit.putBoolean(Key.isRoot, isRoot).commit()
@@ -575,6 +592,9 @@ class Shadowsocks
h.postDelayed(new Runnable() {
def run() {
val integrator = new IntentIntegrator(Shadowsocks.this)
val list = new java.util.ArrayList(IntentIntegrator.TARGET_ALL_KNOWN)
list.add("tw.com.quickmark")
integrator.setTargetApplications(list)
integrator.initiateScan()
h.sendEmptyMessage(0)
}
@@ -652,7 +672,7 @@ class Shadowsocks
if (!profile.isDefined) return false
new AlertDialog.Builder(this)
.setMessage(String.format(getString(R.string.remove_profile), profile.get.name))
.setMessage(String.format(Locale.ENGLISH, getString(R.string.remove_profile), profile.get.name))
.setCancelable(false)
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
override def onClick(dialog: DialogInterface, i: Int) = dialog.cancel()
@@ -667,7 +687,7 @@ class Shadowsocks
currentProfile = profileManager.load(profileId)
menuAdapter.updateList(getMenuList, currentProfile.id)
sendBroadcast(new Intent(Action.UPDATE_FRAGMENT))
updatePreferenceScreen()
dialog.dismiss()
}
@@ -807,7 +827,6 @@ class Shadowsocks
override def onDestroy() {
super.onDestroy()
deattachService()
Crouton.cancelAllCroutons()
unregisterReceiver(preferenceReceiver)
new BackupManager(this).dataChanged()
if (handler != null) {
@@ -820,18 +839,17 @@ class Shadowsocks
val ab = new ArrayBuffer[String]
ab.append("mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system")
for (executable <- Shadowsocks.EXECUTABLES) {
ab.append("cp %s%s /system/bin/".format(Path.BASE, executable))
ab.append("cp %s%s /system/bin/".formatLocal(Locale.ENGLISH, Path.BASE, executable))
ab.append("chmod 755 /system/bin/" + executable)
ab.append("chown root:shell /system/bin/" + executable)
}
ab.append("mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system")
Console.runRootCommand(ab.toArray)
}
def reset() {
crash_recovery()
crashRecovery()
copyAssets(System.getABI)
@@ -907,12 +925,12 @@ class Shadowsocks
try {
val port: Int = Integer.valueOf(text)
if (!low && port <= 1024) {
Crouton.makeText(this, R.string.port_alert, Style.ALERT).show()
new SnackBar.Builder(this).withMessageId(R.string.port_alert).withStyle(SnackBar.Style.ALERT).show()
return false
}
} catch {
case ex: Exception =>
Crouton.makeText(this, R.string.port_alert, Style.ALERT).show()
new SnackBar.Builder(this).withMessageId(R.string.port_alert).withStyle(SnackBar.Style.ALERT).show()
return false
}
true
@@ -956,7 +974,7 @@ class Shadowsocks
}
new AlertDialog.Builder(this)
.setTitle(getString(R.string.about_title).format(versionName))
.setTitle(getString(R.string.about_title).formatLocal(Locale.ENGLISH, versionName))
.setCancelable(false)
.setNegativeButton(getString(R.string.ok_iknow), new DialogInterface.OnClickListener() {
override def onClick(dialog: DialogInterface, id: Int) {
@@ -994,15 +1012,12 @@ class Shadowsocks
case State.STOPPED =>
clearDialog()
changeSwitch(checked = false)
Crouton.cancelAllCroutons()
if (m != null) {
val style = new Style.Builder().setBackgroundColorValue(Style.holoRedLight).build()
val config = new Configuration.Builder()
.setDuration(Configuration.DURATION_LONG)
.build()
Crouton
.makeText(Shadowsocks.this, getString(R.string.vpn_error).format(m), style)
.setConfiguration(config)
new SnackBar.Builder(Shadowsocks.this)
.withMessage(getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m))
.withActionMessageId(R.string.error)
.withStyle(SnackBar.Style.ALERT)
.withDuration(SnackBar.LONG_SNACK)
.show()
}
setPreferenceEnabled(enabled = true)
@@ -41,14 +41,15 @@ package com.github.shadowsocks
import java.io.File
import java.lang.reflect.{InvocationTargetException, Method}
import java.util.Locale
import android.app.{Notification, NotificationManager, PendingIntent, Service}
import android.app._
import android.content._
import android.content.pm.{PackageInfo, PackageManager}
import android.net.{Network, ConnectivityManager}
import android.os._
import android.support.v4.app.NotificationCompat
import android.util.Log
import android.util.{SparseArray, Log}
import android.widget.Toast
import com.github.shadowsocks.aidl.Config
import com.github.shadowsocks.utils._
@@ -66,12 +67,15 @@ class ShadowsocksNatService extends Service with BaseService {
val CMD_IPTABLES_RETURN = " -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN"
val CMD_IPTABLES_DNAT_ADD_SOCKS = " -t nat -A OUTPUT -p tcp " +
"-j DNAT --to-destination 127.0.0.1:8123"
val DNS_PORT = 8153
private val mStartForegroundSignature = Array[Class[_]](classOf[Int], classOf[Notification])
private val mStopForegroundSignature = Array[Class[_]](classOf[Boolean])
private val mSetForegroundSignature = Array[Class[_]](classOf[Boolean])
private val mSetForegroundArgs = new Array[AnyRef](1)
private val mStartForegroundArgs = new Array[AnyRef](2)
private val mStopForegroundArgs = new Array[AnyRef](1)
var lockReceiver: BroadcastReceiver = null
var closeReceiver: BroadcastReceiver = null
var connReceiver: BroadcastReceiver = null
var notificationManager: NotificationManager = null
@@ -82,32 +86,61 @@ class ShadowsocksNatService extends Service with BaseService {
private var mSetForeground: Method = null
private var mStartForeground: Method = null
private var mStopForeground: Method = null
private var mSetForegroundArgs = new Array[AnyRef](1)
private var mStartForegroundArgs = new Array[AnyRef](2)
private var mStopForegroundArgs = new Array[AnyRef](1)
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def setDnsForAllNetwork(dns: String) {
private val dnsAddressCache = new SparseArray[String]
def getNetId(network: Network): Int = {
network.getClass.getDeclaredField("netId").get(network).asInstanceOf[Int]
}
def restoreDnsForAllNetwork() {
val manager = getSystemService(Context.CONNECTIVITY_SERVICE).asInstanceOf[ConnectivityManager]
val networks = manager.getAllNetworks
val cmdBuf = new ArrayBuffer[String]()
networks.foreach(network => {
val networkInfo = manager.getNetworkInfo(network)
if (networkInfo.isAvailable) {
val netId = network.getClass.getDeclaredField("netId").get(network).asInstanceOf[Int]
cmdBuf.append("ndc resolver setnetdns %d \"\" %s".format(netId, dns))
val netId = getNetId(network)
val oldDns = dnsAddressCache.get(netId)
if (oldDns != null) {
cmdBuf.append("ndc resolver setnetdns %d \"\" %s".formatLocal(Locale.ENGLISH, netId, oldDns))
dnsAddressCache.remove(netId)
}
})
Console.runRootCommand(cmdBuf.toArray)
if (cmdBuf.nonEmpty) Console.runRootCommand(cmdBuf.toArray)
}
def setupDns() = {
def setDnsForAllNetwork(dns: String) {
val manager = getSystemService(Context.CONNECTIVITY_SERVICE).asInstanceOf[ConnectivityManager]
val networks = manager.getAllNetworks
if (networks == null) return
val cmdBuf = new ArrayBuffer[String]()
networks.foreach(network => {
val networkInfo = manager.getNetworkInfo(network)
if (networkInfo == null) return
if (networkInfo.isConnected) {
val netId = getNetId(network)
val curDnsList = manager.getLinkProperties(network).getDnsServers
if (curDnsList != null) {
import scala.collection.JavaConverters._
val curDns = curDnsList.asScala.map(ip => ip.getHostAddress).mkString(" ")
if (curDns != dns) {
dnsAddressCache.put(netId, curDns)
cmdBuf.append("ndc resolver setnetdns %d \"\" %s".formatLocal(Locale.ENGLISH, netId, dns))
}
}
}
})
if (cmdBuf.nonEmpty) Console.runRootCommand(cmdBuf.toArray)
}
def setupDns() {
setDnsForAllNetwork("127.0.0.1")
}
def resetDns() = {
setDnsForAllNetwork("114.114.114.114 8.8.8.8 208.67.222.222")
restoreDnsForAllNetwork()
}
def flushDns() {
@@ -119,7 +152,7 @@ class ShadowsocksNatService extends Service with BaseService {
val networkInfo = manager.getNetworkInfo(network)
if (networkInfo.isAvailable) {
val netId = network.getClass.getDeclaredField("netId").get(network).asInstanceOf[Int]
cmdBuf.append("ndc resolver flushnet %d".format(netId))
cmdBuf.append("ndc resolver flushnet %d".formatLocal(Locale.ENGLISH, netId))
}
})
Console.runRootCommand(cmdBuf.toArray)
@@ -159,7 +192,7 @@ class ShadowsocksNatService extends Service with BaseService {
}
val conf = ConfigUtils
.SHADOWSOCKS.format(config.proxy, config.remotePort, config.localPort,
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, config.proxy, config.remotePort, config.localPort,
config.sitekey, config.encMethod, 10)
ConfigUtils.printToFile(new File(Path.BASE + "ss-local-nat.conf"))(p => {
p.println(conf)
@@ -168,6 +201,7 @@ class ShadowsocksNatService extends Service with BaseService {
val cmd = new ArrayBuffer[String]
cmd += (Path.BASE + "ss-local"
, "-b" , "127.0.0.1"
, "-t" , "600"
, "-c" , Path.BASE + "ss-local-nat.conf"
, "-f" , Path.BASE + "ss-local-nat.pid")
@@ -183,41 +217,37 @@ class ShadowsocksNatService extends Service with BaseService {
def startTunnel() {
if (config.isUdpDns) {
val conf = ConfigUtils
.SHADOWSOCKS.format(config.proxy, config.remotePort, 8153,
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, config.proxy, config.remotePort, 8153,
config.sitekey, config.encMethod, 10)
ConfigUtils.printToFile(new File(Path.BASE + "ss-tunnel-nat.conf"))(p => {
p.println(conf)
})
val cmd = new ArrayBuffer[String]
cmd += (Path.BASE + "ss-tunnel" , "-u"
, "-b" , "127.0.0.1"
, "-L" , "8.8.8.8:53"
, "-c" , Path.BASE + "ss-tunnel-nat.conf"
, "-f" , Path.BASE + "ss-tunnel-nat.pid")
cmd += (Path.BASE + "ss-tunnel"
, "-u"
, "-t" , "10"
, "-b" , "127.0.0.1"
, "-L" , "8.8.8.8:53"
, "-c" , Path.BASE + "ss-tunnel-nat.conf"
, "-f" , Path.BASE + "ss-tunnel-nat.pid")
if (Utils.isLollipopOrAbove) {
cmd += ("-l" , "53")
} else {
cmd += ("-l" , "8153")
}
cmd += ("-l" , "8153")
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
if (Utils.isLollipopOrAbove) {
Console.runRootCommand(cmd.mkString(" "))
} else {
Console.runCommand(cmd.mkString(" "))
}
Console.runCommand(cmd.mkString(" "))
} else {
val conf = ConfigUtils
.SHADOWSOCKS.format(config.proxy, config.remotePort, 8163,
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, config.proxy, config.remotePort, 8163,
config.sitekey, config.encMethod, 10)
ConfigUtils.printToFile(new File(Path.BASE + "ss-tunnel-nat.conf"))(p => {
p.println(conf)
})
val cmdBuf = new ArrayBuffer[String]
cmdBuf += (Path.BASE + "ss-tunnel"
, "-u"
, "-t" , "10"
, "-b" , "127.0.0.1"
, "-l" , "8163"
, "-L" , "8.8.8.8:53"
@@ -230,13 +260,17 @@ class ShadowsocksNatService extends Service with BaseService {
}
def startDnsDaemon() {
val conf = if (Utils.isLollipopOrAbove) {
ConfigUtils
.PDNSD_BYPASS.format("127.0.0.1", 53, Path.BASE + "pdnsd-nat.pid", getString(R.string.exclude), 8163)
val conf = if (config.route == Route.BYPASS_CHN) {
val reject = ConfigUtils.getRejectList(getContext, application)
val blackList = ConfigUtils.getBlackList(getContext, application)
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
Path.BASE + "pdnsd-nat.pid", reject, blackList, 8163)
} else {
ConfigUtils
.PDNSD_BYPASS.format("127.0.0.1", 8153, Path.BASE + "pdnsd-nat.pid", getString(R.string.exclude), 8163)
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
Path.BASE + "pdnsd-nat.pid", 8163)
}
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-nat.conf"))(p => {
p.println(conf)
})
@@ -244,11 +278,7 @@ class ShadowsocksNatService extends Service with BaseService {
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
if (Utils.isLollipopOrAbove) {
Console.runRootCommand(cmd)
} else {
Console.runCommand(cmd)
}
Console.runCommand(cmd)
}
@@ -265,9 +295,9 @@ class ShadowsocksNatService extends Service with BaseService {
}
def startRedsocksDaemon() {
val conf = ConfigUtils.REDSOCKS.format(config.localPort)
val conf = ConfigUtils.REDSOCKS.formatLocal(Locale.ENGLISH, config.localPort)
val cmd = Path.BASE + "redsocks -p %sredsocks-nat.pid -c %sredsocks-nat.conf"
.format(Path.BASE, Path.BASE)
.formatLocal(Locale.ENGLISH, Path.BASE, Path.BASE)
ConfigUtils.printToFile(new File(Path.BASE + "redsocks-nat.conf"))(p => {
p.println(conf)
})
@@ -299,7 +329,7 @@ class ShadowsocksNatService extends Service with BaseService {
}
}
def notifyForegroundAlert(title: String, info: String) {
def notifyForegroundAlert(title: String, info: String, visible: Boolean) {
val openIntent = new Intent(this, classOf[Shadowsocks])
openIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
val contentIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
@@ -317,6 +347,11 @@ class ShadowsocksNatService extends Service with BaseService {
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.stop),
actionIntent)
if (visible)
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT)
else
builder.setPriority(NotificationCompat.PRIORITY_MIN)
startForegroundCompat(1, builder.build)
}
@@ -360,7 +395,7 @@ class ShadowsocksNatService extends Service with BaseService {
val cmd = new ArrayBuffer[String]()
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "redsocks")) {
cmd.append("chmod 666 %s%s-nat.pid".format(Path.BASE, task))
cmd.append("chmod 666 %s%s-nat.pid".formatLocal(Locale.ENGLISH, Path.BASE, task))
}
Console.runRootCommand(cmd.toArray)
cmd.clear()
@@ -368,13 +403,13 @@ class ShadowsocksNatService extends Service with BaseService {
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "redsocks")) {
try {
val pid = scala.io.Source.fromFile(Path.BASE + task + "-nat.pid").mkString.trim.toInt
cmd.append("kill -9 %d".format(pid))
cmd.append("kill -9 %d".formatLocal(Locale.ENGLISH, pid))
Process.killProcess(pid)
} catch {
case e: Throwable => Log.e(TAG, "unable to kill " + task)
}
cmd.append("rm -f %s%s-nat.pid".format(Path.BASE, task))
cmd.append("rm -f %s%s-nat.conf".format(Path.BASE, task))
cmd.append("rm -f %s%s-nat.pid".formatLocal(Locale.ENGLISH, Path.BASE, task))
cmd.append("rm -f %s%s-nat.conf".formatLocal(Locale.ENGLISH, Path.BASE, task))
}
Console.runRootCommand(cmd.toArray)
@@ -385,20 +420,19 @@ class ShadowsocksNatService extends Service with BaseService {
val init_sb = new ArrayBuffer[String]
val http_sb = new ArrayBuffer[String]
init_sb.append("ulimit -n 4096")
init_sb.append(Utils.getIptables + " -t nat -F OUTPUT")
val cmd_bypass = Utils.getIptables + CMD_IPTABLES_RETURN
if (!InetAddressUtils.isIPv6Address(config.proxy.toUpperCase)) {
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-d " + config.proxy))
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d " + config.proxy))
}
init_sb.append(cmd_bypass.replace("0.0.0.0", "127.0.0.1"))
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid))
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 127.0.0.1"))
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-m owner --uid-owner " + myUid))
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport 53"))
if (!Utils.isLollipopOrAbove) {
init_sb.append(Utils.getIptables
+ " -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:" + DNS_PORT)
}
init_sb.append(Utils.getIptables
+ " -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:" + 8153)
if (config.isGlobalProxy || config.isBypassApps) {
http_sb.append(Utils.getIptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
@@ -467,21 +501,46 @@ class ShadowsocksNatService extends Service with BaseService {
config = c
// register connection receiver
if (Utils.isLollipopOrAbove) initConnectionReceiver()
// register close receiver
val filter = new IntentFilter()
filter.addAction(Intent.ACTION_SHUTDOWN)
filter.addAction(Action.CLOSE)
closeReceiver = new BroadcastReceiver() {
def onReceive(p1: Context, p2: Intent) {
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT)
def onReceive(context: Context, intent: Intent) {
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
stopRunner()
}
}
registerReceiver(closeReceiver, filter)
if (Utils.isLollipopOrAbove) {
val screenFilter = new IntentFilter()
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
screenFilter.addAction(Intent.ACTION_USER_PRESENT)
lockReceiver = new BroadcastReceiver() {
def onReceive(context: Context, intent: Intent) {
if (getState == State.CONNECTED) {
val action = intent.getAction
if (action == Intent.ACTION_SCREEN_OFF) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), false)
} else if (action == Intent.ACTION_SCREEN_ON) {
val keyGuard = getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
if (!keyGuard.inKeyguardRestrictedInputMode) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
}
} else if (action == Intent.ACTION_USER_PRESENT) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
}
}
}
}
registerReceiver(lockReceiver, screenFilter)
}
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(TAG)
@@ -510,10 +569,6 @@ class ShadowsocksNatService extends Service with BaseService {
// Clean up
killProcesses()
// Set DNS
if (Utils.isLollipopOrAbove) setupDns()
flushDns()
var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) {
@@ -528,8 +583,12 @@ class ShadowsocksNatService extends Service with BaseService {
}
if (resolved && handleConnection) {
// Set DNS
flushDns()
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).format(config.profileName))
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
changeState(State.CONNECTED)
} else {
changeState(State.STOPPED, getString(R.string.service_failed))
@@ -549,8 +608,12 @@ class ShadowsocksNatService extends Service with BaseService {
unregisterReceiver(closeReceiver)
closeReceiver = null
}
if (Utils.isLollipopOrAbove) {
destroyConnectionReceiver()
if (lockReceiver != null) {
unregisterReceiver(lockReceiver)
lockReceiver = null
}
}
// send event
@@ -564,7 +627,7 @@ class ShadowsocksNatService extends Service with BaseService {
killProcesses()
// stop the service if no callback registered
if (callbackCount == 0) {
if (getCallbackCount == 0) {
stopSelf()
}
@@ -50,14 +50,17 @@ import com.github.shadowsocks.aidl.IShadowsocksService
class ShadowsocksRunnerActivity extends Activity {
lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
private lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
private lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE)
val handler = new Handler()
val connection = new ServiceConnection {
override def onServiceConnected(name: ComponentName, service: IBinder) {
bgService = IShadowsocksService.Stub.asInterface(service)
handler.postDelayed(new Runnable() {
override def run() = startBackgroundService()
override def run() {
if (bgService != null) startBackgroundService()
}
}, 1000)
}
override def onServiceDisconnected(name: ComponentName) {
@@ -72,10 +75,10 @@ class ShadowsocksRunnerActivity extends Activity {
def isVpnEnabled: Boolean = {
if (vpnEnabled < 0) {
vpnEnabled = if (!Console.isRoot) {
1
} else {
vpnEnabled = if ((!Utils.isLollipopOrAbove || status.getBoolean(Key.isNAT, false)) && Console.isRoot) {
0
} else {
1
}
}
if (vpnEnabled == 1) true else false
@@ -40,6 +40,7 @@
package com.github.shadowsocks
import java.io.File
import java.util.Locale
import android.app._
import android.content._
@@ -107,7 +108,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
val conf = ConfigUtils
.SHADOWSOCKS.format(config.proxy, config.remotePort, config.localPort,
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, config.proxy, config.remotePort, config.localPort,
config.sitekey, config.encMethod, 10)
ConfigUtils.printToFile(new File(Path.BASE + "ss-local-vpn.conf"))(p => {
p.println(conf)
@@ -115,9 +116,10 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val cmd = new ArrayBuffer[String]
cmd +=(Path.BASE + "ss-local", "-u"
, "-b", "127.0.0.1"
, "-c", Path.BASE + "ss-local-vpn.conf"
, "-f", Path.BASE + "ss-local-vpn.pid")
, "-b" , "127.0.0.1"
, "-t" , "600"
, "-c" , Path.BASE + "ss-local-vpn.conf"
, "-f" , Path.BASE + "ss-local-vpn.pid")
if (Utils.isLollipopOrAbove && config.route != Route.ALL) {
cmd += "--acl"
@@ -130,18 +132,20 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def startDnsTunnel() = {
val conf = ConfigUtils
.SHADOWSOCKS.format(config.proxy, config.remotePort, 8163,
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, config.proxy, config.remotePort, 8163,
config.sitekey, config.encMethod, 10)
ConfigUtils.printToFile(new File(Path.BASE + "ss-tunnel-vpn.conf"))(p => {
p.println(conf)
})
val cmd = new ArrayBuffer[String]
cmd +=(Path.BASE + "ss-tunnel"
, "-b", "127.0.0.1"
, "-l", "8163"
, "-L", "8.8.8.8:53"
, "-c", Path.BASE + "ss-tunnel-vpn.conf"
, "-f", Path.BASE + "ss-tunnel-vpn.pid")
, "-u"
, "-t" , "10"
, "-b" , "127.0.0.1"
, "-l" , "8163"
, "-L" , "8.8.8.8:53"
, "-c" , Path.BASE + "ss-tunnel-vpn.conf"
, "-f" , Path.BASE + "ss-tunnel-vpn.pid")
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
Console.runCommand(cmd.mkString(" "))
@@ -149,10 +153,14 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def startDnsDaemon() {
val conf = {
if (Utils.isLollipopOrAbove) {
ConfigUtils.PDNSD_BYPASS.format("0.0.0.0", 8153, Path.BASE + "pdnsd-vpn.pid", getString(R.string.exclude), 8163)
if (Utils.isLollipopOrAbove && config.route == Route.BYPASS_CHN) {
val reject = ConfigUtils.getRejectList(getContext, application)
val blackList = ConfigUtils.getBlackList(getContext, application)
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
Path.BASE + "pdnsd-vpn.pid", reject, blackList, 8163)
} else {
ConfigUtils.PDNSD_LOCAL.format("0.0.0.0", 8163)
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
Path.BASE + "pdnsd-vpn.pid", 8163)
}
}
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-vpn.conf"))(p => {
@@ -182,10 +190,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
builder
.setSession(config.profileName)
.setMtu(VPN_MTU)
.addAddress(PRIVATE_VLAN.format("1"), 24)
.addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24)
.addDnsServer("8.8.8.8")
if (Utils.isLollipopOrAbove) {
builder.allowFamily(android.system.OsConstants.AF_INET6)
if (!config.isGlobalProxy) {
val apps = AppManager.getProxiedApps(this, config.proxiedAppString)
val pkgSet: mutable.HashSet[String] = new mutable.HashSet[String]
@@ -312,12 +323,12 @@ class ShadowsocksVpnService extends VpnService with BaseService {
+ "--tunmtu %d "
+ "--loglevel 3 "
+ "--pid %stun2socks-vpn.pid")
.format(PRIVATE_VLAN.format("2"), config.localPort, fd, VPN_MTU, Path.BASE)
.formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "2"), config.localPort, fd, VPN_MTU, Path.BASE)
if (config.isUdpDns)
cmd += " --enable-udprelay"
else
cmd += " --dnsgw %s:8153".format(PRIVATE_VLAN.format("1"))
cmd += " --dnsgw %s:8153".formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"))
if (Utils.isLollipopOrAbove) {
cmd += " --fake-proc"
@@ -469,7 +480,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
// stop the service if no callback registered
if (callbackCount == 0) {
if (getCallbackCount == 0) {
stopSelf()
}
@@ -40,7 +40,7 @@
package com.github.shadowsocks.utils
import android.content.{SharedPreferences, Context}
import com.github.shadowsocks.ShadowsocksApplication
import com.github.shadowsocks.{R, ShadowsocksApplication}
import com.google.android.gms.tagmanager.Container
import com.github.kevinsawicki.http.HttpRequest
import com.github.shadowsocks.aidl.Config
@@ -61,36 +61,6 @@ object ConfigUtils {
" port = %d;" +
" type = socks5;" +
"}"
val PDNSD =
"""
|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 = "google-servers";
| ip = 8.8.8.8, 8.8.4.4;
| 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_LOCAL =
"""
@@ -98,14 +68,14 @@ object ConfigUtils {
| perm_cache = 2048;
| cache_dir = "/data/data/com.github.shadowsocks";
| server_ip = %s;
| server_port = 8153;
| server_port = %d;
| 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";
| pid_file = %s;
|}
|
|server {
@@ -153,6 +123,8 @@ object ConfigUtils {
|server {
| label = "local-server";
| ip = 127.0.0.1;
| uptest = none;
| preset = on;
| port = %d;
| timeout = 5;
|}
@@ -166,6 +138,51 @@ object ConfigUtils {
|}
""".stripMargin
val PDNSD_DIRECT =
"""
|global {
| perm_cache = 2048;
| cache_dir = "/data/data/com.github.shadowsocks";
| server_ip = %s;
| server_port = %d;
| query_method = tcp_only;
| run_ipv4 = on;
| min_ttl = 15m;
| max_ttl = 1w;
| timeout = 10;
| daemon = on;
| pid_file = "%s";
|}
|
|server {
| label = "china-servers";
| ip = 223.5.5.5, 114.114.114.114;
| timeout = 2;
| reject = %s;
| reject_policy = fail;
| reject_recursively = on;
| exclude = %s;
| policy = included;
| uptest = none;
| preset = on;
|}
|
|server {
| label = "local-server";
| ip = 127.0.0.1;
| port = %d;
| timeout = 3;
|}
|
|rr {
| name=localhost;
| reverse=on;
| a=127.0.0.1;
| owner=localhost;
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|}
""".stripMargin
def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) {
val p = new java.io.PrintWriter(f)
try {
@@ -180,6 +197,28 @@ object ConfigUtils {
if (holder != null) holder.refresh()
}
def getRejectList(context: Context, app: ShadowsocksApplication): String = {
val default = context.getString(R.string.reject)
try {
val container = app.containerHolder.getContainer
val update = container.getString("reject")
if (update == null || update.isEmpty) default else update
} catch {
case ex: Exception => default
}
}
def getBlackList(context: Context, app: ShadowsocksApplication): String = {
val default = context.getString(R.string.black_list)
try {
val container = app.containerHolder.getContainer
val update = container.getString("black_list")
if (update == null || update.isEmpty) default else update
} catch {
case ex: Exception => default
}
}
def getPublicConfig(context: Context, container: Container, config: Config): Config = {
val url = container.getString("proxy_url")
val sig = Utils.getSignature(context)
@@ -65,6 +65,7 @@ object Key {
val proxied = "Proxyed"
val isNAT = "isNAT"
val isRoot = "isRoot"
val status = "status"
val proxyedApps = "proxyedApps"
@@ -52,17 +52,21 @@ object Parser {
if (uri.getScheme == Scheme.SS) {
val encoded = data.replace(Scheme.SS + "://", "")
val content = new String(Base64.decode(encoded, Base64.NO_PADDING), "UTF-8")
val info = content.split('@')
val encinfo = info(0).split(':')
val serverinfo = info(1).split(':')
val methodIdx = content.indexOf(':')
val passwordIdx = content.lastIndexOf('@')
val hostIdx = content.lastIndexOf(':')
val method = content.substring(0, methodIdx)
val password = content.substring(methodIdx + 1, passwordIdx)
val host = content.substring(passwordIdx + 1, hostIdx)
val port = content.substring(hostIdx + 1)
val profile = new Profile
profile.name = serverinfo(0)
profile.host = serverinfo(0)
profile.remotePort = serverinfo(1).toInt
profile.name = host
profile.host = host
profile.remotePort = port.toInt
profile.localPort = 1080
profile.method = encinfo(0)
profile.password = encinfo(1)
profile.method = method.toLowerCase
profile.password = password
return Some(profile)
}
} catch {