Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b272d7ab71 | ||
|
|
09d53033cb | ||
|
|
496c809186 | ||
|
|
b58ffb7a95 | ||
|
|
3512542043 | ||
|
|
0c940c8860 | ||
|
|
00253ea3f6 | ||
|
|
d836aafe40 | ||
|
|
60360e6a19 | ||
|
|
5939f2776c | ||
|
|
0cecc62035 | ||
|
|
7a6fbaca15 | ||
|
|
2a3ffd768c | ||
|
|
33b775ea5e | ||
|
|
0be4d39606 | ||
|
|
ee7e4c9711 | ||
|
|
c1c8ff309c | ||
|
|
8724bf325f | ||
|
|
20395ede5f | ||
|
|
336fa3b775 | ||
|
|
11bfef423a | ||
|
|
6e0534b00f | ||
|
|
bf960f1a64 | ||
|
|
b1e01d2158 | ||
|
|
f344eb783c | ||
|
|
5f6effba09 | ||
|
|
97cfd1f869 | ||
|
|
97bd714beb | ||
|
|
9a841e901c | ||
|
|
de7e516204 | ||
|
|
c31a5c1951 | ||
|
|
6c47c361f7 | ||
|
|
ddd37a3219 | ||
|
|
01125d53b3 | ||
|
|
9613d65303 | ||
|
|
a510b11187 | ||
|
|
051e600e59 | ||
|
|
fea9a6f919 | ||
|
|
c2c7cabbaf | ||
|
|
092d880c7d | ||
|
|
c208c4bf50 | ||
|
|
34af6aeef5 | ||
|
|
d9af2f93e0 | ||
|
|
aae068b7b2 | ||
|
|
7626c1117e | ||
|
|
1188b59b05 | ||
|
|
cbd46d0c95 | ||
|
|
8d02a1a6a4 | ||
|
|
9f67636464 | ||
|
|
abb97e16c4 | ||
|
|
541f8de2cf | ||
|
|
7c31f5e5b4 | ||
|
|
809f4c13e0 | ||
|
|
04725803e4 | ||
|
|
faad961804 | ||
|
|
2f7424d07b | ||
|
|
fd4015fac2 | ||
|
|
f2c39bd16e | ||
|
|
e849a9e2cb | ||
|
|
524d3b6fdc | ||
|
|
6f5db34a6f | ||
|
|
3c161be1e4 | ||
|
|
1c30fdb8f2 | ||
|
|
ce24ddb9ed | ||
|
|
17eaf25b4f | ||
|
|
f4b171a3d9 | ||
|
|
ae9622a1b3 | ||
|
|
44e1b9daa3 | ||
|
|
7a2c42626b | ||
|
|
adb979a111 | ||
|
|
1e23307f95 |
@@ -14,8 +14,8 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
|
|||||||
|
|
||||||
* JDK 1.7+
|
* JDK 1.7+
|
||||||
* SBT 0.13.0+
|
* SBT 0.13.0+
|
||||||
* Android SDK r21+
|
* Android SDK r24+
|
||||||
* Android NDK r9+
|
* Android NDK r10d+
|
||||||
|
|
||||||
### BUILD
|
### BUILD
|
||||||
|
|
||||||
@@ -58,6 +58,16 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
|
|||||||
sbt clean android:package-release
|
sbt clean android:package-release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## OPEN SOURCE LICENSES
|
||||||
|
|
||||||
|
* shadowsocks-libev: [GPLv3](https://github.com/shadowsocks/shadowsocks-libev/blob/master/LICENSE)
|
||||||
|
* tun2socks: [BSD](https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/badvpn/COPYING)
|
||||||
|
* redsocks: [APL 2.0](https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/redsocks/README)
|
||||||
|
* OpenSSL: [OpenSSL](https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/openssl/NOTICE)
|
||||||
|
* pdnsd: [GPLv3](https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/pdnsd/COPYING)
|
||||||
|
* libev: [GPLv2](https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/libev/LICENSE)
|
||||||
|
* libevent: [BSD](https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/libevent/LICENSE)
|
||||||
|
|
||||||
### LICENSE
|
### LICENSE
|
||||||
|
|
||||||
Copyright (C) 2014 Max Lv <max.c.lv@gmail.com>
|
Copyright (C) 2014 Max Lv <max.c.lv@gmail.com>
|
||||||
|
|||||||
@@ -31,9 +31,10 @@ libraryDependencies ++= Seq(
|
|||||||
"com.joanzapata.android" % "android-iconify" % "1.0.9",
|
"com.joanzapata.android" % "android-iconify" % "1.0.9",
|
||||||
"net.glxn.qrgen" % "android" % "2.0",
|
"net.glxn.qrgen" % "android" % "2.0",
|
||||||
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
|
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
|
||||||
"com.google.android.gms" % "play-services-base" % "6.5.87",
|
"com.google.android.gms" % "play-services-base" % "8.1.0",
|
||||||
"com.google.android.gms" % "play-services-ads" % "6.5.87",
|
"com.google.android.gms" % "play-services-ads" % "8.1.0",
|
||||||
"com.android.support" % "support-v4" % "21.0.3"
|
"com.google.android.gms" % "play-services-analytics" % "8.1.0",
|
||||||
|
"com.android.support" % "support-v4" % "23.0.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
@@ -52,5 +53,6 @@ proguardOptions in Android ++= Seq("-keep class android.support.v4.app.** { *; }
|
|||||||
"-keep class * extends com.j256.ormlite.** { *; }",
|
"-keep class * extends com.j256.ormlite.** { *; }",
|
||||||
"-keep class com.joanzapata.** { *; }",
|
"-keep class com.joanzapata.** { *; }",
|
||||||
"-keepattributes *Annotation*",
|
"-keepattributes *Annotation*",
|
||||||
|
"-dontwarn com.google.android.gms.internal.zzhu",
|
||||||
"-dontwarn org.xbill.**",
|
"-dontwarn org.xbill.**",
|
||||||
"-dontwarn com.actionbarsherlock.**")
|
"-dontwarn com.actionbarsherlock.**")
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ function try () {
|
|||||||
try pushd src/main
|
try pushd src/main
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
try $ANDROID_NDK_HOME/ndk-build clean
|
#try $ANDROID_NDK_HOME/ndk-build clean
|
||||||
try $ANDROID_NDK_HOME/ndk-build
|
try $ANDROID_NDK_HOME/ndk-build -j8
|
||||||
|
|
||||||
# copy executables
|
# copy executables
|
||||||
rm -rf assets/armeabi-v7a
|
rm -rf assets/armeabi-v7a
|
||||||
|
|||||||
+13
-9
@@ -24,6 +24,8 @@ def main():
|
|||||||
"0.0.0.0/8",
|
"0.0.0.0/8",
|
||||||
"10.0.0.0/8",
|
"10.0.0.0/8",
|
||||||
"100.64.0.0/10",
|
"100.64.0.0/10",
|
||||||
|
"112.124.47.0/24",
|
||||||
|
"114.114.114.0/24",
|
||||||
"127.0.0.0/8",
|
"127.0.0.0/8",
|
||||||
"169.254.0.0/16",
|
"169.254.0.0/16",
|
||||||
"172.16.0.0/12",
|
"172.16.0.0/12",
|
||||||
@@ -39,16 +41,18 @@ def main():
|
|||||||
]))
|
]))
|
||||||
china_list_set += internal_list
|
china_list_set += internal_list
|
||||||
|
|
||||||
# 取反
|
all = china_list_set
|
||||||
all = IPy.IPSet([IPy.IP("0.0.0.0/0")])
|
|
||||||
# 剔除所有孤立的C段
|
|
||||||
for ip in china_list_set:
|
|
||||||
all.discard(ip)
|
|
||||||
|
|
||||||
filter = itertools.ifilter(lambda x: len(x) <= 65536, all)
|
# 取反
|
||||||
for ip in filter:
|
# all = IPy.IPSet([IPy.IP("0.0.0.0/0")])
|
||||||
all.discard(ip)
|
# 剔除所有孤立的C段
|
||||||
all.add(IPy.IP(ip.strNormal(0)).make_net('255.255.0.0'))
|
# for ip in china_list_set:
|
||||||
|
# all.discard(ip)
|
||||||
|
|
||||||
|
# filter = itertools.ifilter(lambda x: len(x) <= 65536, all)
|
||||||
|
# for ip in filter:
|
||||||
|
# all.discard(ip)
|
||||||
|
# all.add(IPy.IP(ip.strNormal(0)).make_net('255.255.0.0'))
|
||||||
|
|
||||||
# 输出结果
|
# 输出结果
|
||||||
for ip in all:
|
for ip in all:
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
|
resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
|
||||||
|
|
||||||
addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.3.22")
|
addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.5.0")
|
||||||
|
|
||||||
resolvers += Resolver.sbtPluginRepo("snapshots")
|
resolvers += "Sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||||
|
|
||||||
addSbtPlugin("com.hanhuy.sbt" % "sbt-idea" % "1.7.0-SNAPSHOT")
|
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.7.0-SNAPSHOT")
|
||||||
|
|||||||
@@ -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="106"
|
android:versionCode="117"
|
||||||
android:versionName="2.6.8">
|
android:versionName="2.8.0">
|
||||||
|
|
||||||
<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"/>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ public class Config implements Parcelable {
|
|||||||
public boolean isBypassApps = false;
|
public boolean isBypassApps = false;
|
||||||
public boolean isTrafficStat = false;
|
public boolean isTrafficStat = false;
|
||||||
public boolean isUdpDns = false;
|
public boolean isUdpDns = false;
|
||||||
|
public boolean isAuth = false;
|
||||||
|
public boolean isIpv6 = false;
|
||||||
|
|
||||||
public String profileName = "Untitled";
|
public String profileName = "Untitled";
|
||||||
public String proxy = "127.0.0.1";
|
public String proxy = "127.0.0.1";
|
||||||
@@ -33,13 +35,15 @@ public class Config implements Parcelable {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public Config(boolean isGlobalProxy, boolean isGFWList, boolean isBypassApps,
|
public Config(boolean isGlobalProxy, boolean isGFWList, boolean isBypassApps,
|
||||||
boolean isTrafficStat, boolean isUdpDns, String profileName, String proxy, String sitekey,
|
boolean isTrafficStat, boolean isUdpDns, boolean isAuth, boolean isIpv6, String profileName, String proxy, String sitekey,
|
||||||
String encMethod, String proxiedAppString, String route, int remotePort, int localPort) {
|
String encMethod, String proxiedAppString, String route, int remotePort, int localPort) {
|
||||||
this.isGlobalProxy = isGlobalProxy;
|
this.isGlobalProxy = isGlobalProxy;
|
||||||
this.isGFWList = isGFWList;
|
this.isGFWList = isGFWList;
|
||||||
this.isBypassApps = isBypassApps;
|
this.isBypassApps = isBypassApps;
|
||||||
this.isTrafficStat = isTrafficStat;
|
this.isTrafficStat = isTrafficStat;
|
||||||
this.isUdpDns = isUdpDns;
|
this.isUdpDns = isUdpDns;
|
||||||
|
this.isAuth = isAuth;
|
||||||
|
this.isIpv6 = isIpv6;
|
||||||
this.profileName = profileName;
|
this.profileName = profileName;
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
this.sitekey = sitekey;
|
this.sitekey = sitekey;
|
||||||
@@ -60,6 +64,8 @@ public class Config implements Parcelable {
|
|||||||
isBypassApps = in.readInt() == 1;
|
isBypassApps = in.readInt() == 1;
|
||||||
isTrafficStat = in.readInt() == 1;
|
isTrafficStat = in.readInt() == 1;
|
||||||
isUdpDns = in.readInt() == 1;
|
isUdpDns = in.readInt() == 1;
|
||||||
|
isAuth = in.readInt() == 1;
|
||||||
|
isIpv6 = in.readInt() == 1;
|
||||||
profileName = in.readString();
|
profileName = in.readString();
|
||||||
proxy = in.readString();
|
proxy = in.readString();
|
||||||
sitekey = in.readString();
|
sitekey = in.readString();
|
||||||
@@ -80,6 +86,8 @@ public class Config implements Parcelable {
|
|||||||
out.writeInt(isBypassApps ? 1 : 0);
|
out.writeInt(isBypassApps ? 1 : 0);
|
||||||
out.writeInt(isTrafficStat ? 1 : 0);
|
out.writeInt(isTrafficStat ? 1 : 0);
|
||||||
out.writeInt(isUdpDns ? 1 : 0);
|
out.writeInt(isUdpDns ? 1 : 0);
|
||||||
|
out.writeInt(isAuth ? 1 : 0);
|
||||||
|
out.writeInt(isIpv6 ? 1 : 0);
|
||||||
out.writeString(profileName);
|
out.writeString(profileName);
|
||||||
out.writeString(proxy);
|
out.writeString(proxy);
|
||||||
out.writeString(sitekey);
|
out.writeString(sitekey);
|
||||||
|
|||||||
@@ -286,6 +286,17 @@ GNU General Public License for more details.</p>
|
|||||||
<p>You should have received a copy of the GNU General Public License
|
<p>You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
|
along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
|
||||||
|
|
||||||
|
<h3>Open Source Licenses</h3>
|
||||||
|
<ul>
|
||||||
|
<li>shadowsocks-libev: <a href="https://github.com/shadowsocks/shadowsocks-libev/blob/master/LICENSE">GPLv3</a></li>
|
||||||
|
<li>tun2socks: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/badvpn/COPYING">BSD</a></li>
|
||||||
|
<li>redsocks: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/redsocks/README">APL 2.0</a></li>
|
||||||
|
<li>OpenSSL: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/openssl/NOTICE">OpenSSL</a></li>
|
||||||
|
<li>pdnsd: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/pdnsd/COPYING">GPLv3</a></li>
|
||||||
|
<li>libev: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/libev/LICENSE">GPLv2</a></li>
|
||||||
|
<li>libevent: <a href="https://github.com/shadowsocks/shadowsocks-android/blob/master/src/main/jni/libevent/LICENSE">BSD</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
<!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
|
<!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
|
||||||
|
|||||||
@@ -45,4 +45,6 @@ public class System {
|
|||||||
|
|
||||||
public static native void exec(String cmd);
|
public static native void exec(String cmd);
|
||||||
public static native String getABI();
|
public static native String getABI();
|
||||||
|
public static native int sendfd(int fd);
|
||||||
|
public static native void jniclose(int fd);
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-9
@@ -110,6 +110,21 @@ LOCAL_CFLAGS := -O2 -I$(LOCAL_PATH)/libevent \
|
|||||||
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
## libancillary
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
ANCILLARY_SOURCE := fd_recv.c fd_send.c
|
||||||
|
|
||||||
|
LOCAL_MODULE := libancillary
|
||||||
|
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/libancillary
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(addprefix libancillary/, $(ANCILLARY_SOURCE))
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
## libipset
|
## libipset
|
||||||
########################################################
|
########################################################
|
||||||
@@ -234,13 +249,14 @@ include $(BUILD_EXECUTABLE)
|
|||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
SHADOWSOCKS_SOURCES := local.c cache.c udprelay.c encrypt.c utils.c netutils.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 android.c
|
||||||
|
|
||||||
LOCAL_MODULE := ss-local
|
LOCAL_MODULE := ss-local
|
||||||
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
|
||||||
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL \
|
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL \
|
||||||
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \
|
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \
|
||||||
-I$(LOCAL_PATH)/libev/ \
|
-I$(LOCAL_PATH)/libev \
|
||||||
|
-I$(LOCAL_PATH)/libancillary \
|
||||||
-I$(LOCAL_PATH)/openssl/include \
|
-I$(LOCAL_PATH)/openssl/include \
|
||||||
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
|
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
|
||||||
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||||
@@ -248,7 +264,7 @@ LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL \
|
|||||||
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
|
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
|
||||||
-I$(LOCAL_PATH)/shadowsocks-libev/libipset/include
|
-I$(LOCAL_PATH)/shadowsocks-libev/libipset/include
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := libev libcrypto libipset libcork libudns libsodium
|
LOCAL_STATIC_LIBRARIES := libev libcrypto libipset libcork libudns libsodium libancillary
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
@@ -260,20 +276,21 @@ include $(BUILD_EXECUTABLE)
|
|||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c netutils.c json.c jconf.c
|
SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c netutils.c json.c jconf.c android.c
|
||||||
|
|
||||||
LOCAL_MODULE := ss-tunnel
|
LOCAL_MODULE := ss-tunnel
|
||||||
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
|
||||||
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \
|
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \
|
||||||
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H -DSSTUNNEL_JNI \
|
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H -DSSTUNNEL_JNI \
|
||||||
-I$(LOCAL_PATH)/libev/ \
|
-I$(LOCAL_PATH)/libev \
|
||||||
|
-I$(LOCAL_PATH)/libancillary \
|
||||||
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
|
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
|
||||||
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
-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 \
|
||||||
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
|
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
|
||||||
-I$(LOCAL_PATH)/openssl/include
|
-I$(LOCAL_PATH)/openssl/include
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := libev libcrypto libsodium libcork libudns
|
LOCAL_STATIC_LIBRARIES := libev libcrypto libsodium libcork libudns libancillary
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
@@ -287,12 +304,13 @@ include $(CLEAR_VARS)
|
|||||||
|
|
||||||
LOCAL_MODULE:= system
|
LOCAL_MODULE:= system
|
||||||
|
|
||||||
LOCAL_SRC_FILES:= \
|
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/libancillary
|
||||||
system.cpp
|
|
||||||
|
LOCAL_SRC_FILES:= system.cpp
|
||||||
|
|
||||||
LOCAL_LDLIBS := -ldl -llog
|
LOCAL_LDLIBS := -ldl -llog
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := cpufeatures
|
LOCAL_STATIC_LIBRARIES := cpufeatures libancillary
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
@@ -309,7 +327,10 @@ LOCAL_CFLAGS += -DBADVPN_LITTLE_ENDIAN -DBADVPN_THREAD_SAFE
|
|||||||
LOCAL_CFLAGS += -DNDEBUG -DANDROID
|
LOCAL_CFLAGS += -DNDEBUG -DANDROID
|
||||||
# LOCAL_CFLAGS += -DTUN2SOCKS_JNI
|
# LOCAL_CFLAGS += -DTUN2SOCKS_JNI
|
||||||
|
|
||||||
|
LOCAL_STATIC_LIBRARIES := libancillary
|
||||||
|
|
||||||
LOCAL_C_INCLUDES:= \
|
LOCAL_C_INCLUDES:= \
|
||||||
|
$(LOCAL_PATH)/libancillary \
|
||||||
$(LOCAL_PATH)/badvpn/lwip/src/include/ipv4 \
|
$(LOCAL_PATH)/badvpn/lwip/src/include/ipv4 \
|
||||||
$(LOCAL_PATH)/badvpn/lwip/src/include/ipv6 \
|
$(LOCAL_PATH)/badvpn/lwip/src/include/ipv6 \
|
||||||
$(LOCAL_PATH)/badvpn/lwip/src/include \
|
$(LOCAL_PATH)/badvpn/lwip/src/include \
|
||||||
|
|||||||
@@ -71,9 +71,13 @@
|
|||||||
#include <generated/blog_channel_tun2socks.h>
|
#include <generated/blog_channel_tun2socks.h>
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
|
|
||||||
|
#include <ancillary.h>
|
||||||
|
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <structure/BAVL.h>
|
#include <structure/BAVL.h>
|
||||||
|
|
||||||
BAVL connections_tree;
|
BAVL connections_tree;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BAddr local_addr;
|
BAddr local_addr;
|
||||||
@@ -408,7 +412,6 @@ int main (int argc, char **argv)
|
|||||||
prctl(PR_SET_NAME, "com.github.shadowsocks");
|
prctl(PR_SET_NAME, "com.github.shadowsocks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// handle --help and --version
|
// handle --help and --version
|
||||||
if (options.help) {
|
if (options.help) {
|
||||||
print_version();
|
print_version();
|
||||||
@@ -490,11 +493,56 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
// use supplied file descriptor
|
// use supplied file descriptor
|
||||||
|
|
||||||
|
int sock, fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||||
|
BLog(BLOG_ERROR, "socket() failed: %s (socket sock = %d)\n", strerror(errno), sock);
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *path = "/data/data/com.github.shadowsocks/sock_path";
|
||||||
|
unlink(path);
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy(addr.sun_path, path, sizeof(addr.sun_path)-1);
|
||||||
|
|
||||||
|
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
||||||
|
BLog(BLOG_ERROR, "bind() failed: %s (sock = %d)\n", strerror(errno), sock);
|
||||||
|
close(sock);
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(sock, 5) == -1) {
|
||||||
|
BLog(BLOG_ERROR, "listen() failed: %s (sock = %d)\n", strerror(errno), sock);
|
||||||
|
close(sock);
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int sock2;
|
||||||
|
struct sockaddr_un remote;
|
||||||
|
int t = sizeof(remote);
|
||||||
|
if ((sock2 = accept(sock, (struct sockaddr *)&remote, &t)) == -1) {
|
||||||
|
BLog(BLOG_ERROR, "accept() failed: %s (sock = %d)\n", strerror(errno), sock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ancil_recv_fd(sock2, &fd)) {
|
||||||
|
BLog(BLOG_ERROR, "ancil_recv_fd: %s (sock = %d)\n", strerror(errno), sock2);
|
||||||
|
close(sock2);
|
||||||
|
} else {
|
||||||
|
close(sock2);
|
||||||
|
BLog(BLOG_INFO, "received fd = %d", fd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
|
|
||||||
struct BTap_init_data init_data;
|
struct BTap_init_data init_data;
|
||||||
init_data.dev_type = BTAP_DEV_TUN;
|
init_data.dev_type = BTAP_DEV_TUN;
|
||||||
init_data.init_type = BTAP_INIT_FD;
|
init_data.init_type = BTAP_INIT_FD;
|
||||||
init_data.init.fd.fd = options.tun_fd;
|
init_data.init.fd.fd = fd;
|
||||||
init_data.init.fd.mtu = options.tun_mtu;
|
init_data.init.fd.mtu = options.tun_mtu;
|
||||||
|
|
||||||
if (!BTap_Init2(&device, &ss, init_data, device_error_handler, NULL)) {
|
if (!BTap_Init2(&device, &ss, init_data, device_error_handler, NULL)) {
|
||||||
@@ -1724,6 +1772,9 @@ err_t listener_accept_func (void *arg, struct tcp_pcb *newpcb, err_t err)
|
|||||||
// set client not closed
|
// set client not closed
|
||||||
client->client_closed = 0;
|
client->client_closed = 0;
|
||||||
|
|
||||||
|
// enable TCP_NODELAY
|
||||||
|
tcp_nagle_disable(client->pcb);
|
||||||
|
|
||||||
// setup handler argument
|
// setup handler argument
|
||||||
tcp_arg(client->pcb, client);
|
tcp_arg(client->pcb, client);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
This library provide an easy interface to the black magic that can be done
|
||||||
|
on Unix domain sockets, like passing file descriptors from one process to
|
||||||
|
another.
|
||||||
|
|
||||||
|
Programs that uses this library should include the ancillary.h header file.
|
||||||
|
Nothing else is required.
|
||||||
|
|
||||||
|
All functions of this library require the following header:
|
||||||
|
|
||||||
|
#include <ancillary.h>
|
||||||
|
|
||||||
|
At this time, the only ancillary data defined by the Single Unix
|
||||||
|
Specification (v3) is file descriptors.
|
||||||
|
|
||||||
|
Passing file descriptors
|
||||||
|
|
||||||
|
int ancil_send_fd(socket, file_descriptor)
|
||||||
|
int socket: the Unix socket
|
||||||
|
int file_descriptor: the file descriptor
|
||||||
|
Return value: 0 for success, -1 for failure.
|
||||||
|
|
||||||
|
Sends one file descriptor on a socket.
|
||||||
|
In case of failure, errno is set; the possible values are the ones of the
|
||||||
|
sendmsg(2) system call.
|
||||||
|
|
||||||
|
|
||||||
|
int ancil_recv_fd(socket, file_descriptor)
|
||||||
|
int socket: the Unix socket
|
||||||
|
int *file_descriptor: pointer to the returned file descriptor
|
||||||
|
Return value: 0 for success, -1 for failure
|
||||||
|
|
||||||
|
Receives one file descriptor from a socket.
|
||||||
|
In case of success, the file descriptor is stored in the integer pointed
|
||||||
|
to by file_descriptor.
|
||||||
|
In case of failure, errno is set; the possible values are the ones of the
|
||||||
|
recvmsg(2) system call.
|
||||||
|
The behavior is undefined if the recv_fd does not match a send_fd* on the
|
||||||
|
other side.
|
||||||
|
|
||||||
|
|
||||||
|
int ancil_send_fds(socket, file_descriptors, num_file_descriptors)
|
||||||
|
int socket: the Unix socket
|
||||||
|
const int *file_descriptors: array of file descriptors
|
||||||
|
unsigned num_file_descriptors: number of file descriptors
|
||||||
|
Return value: 0 for success, -1 for failure
|
||||||
|
|
||||||
|
Sends several file descriptors on a socket.
|
||||||
|
In case of failure, errno is set; the possible values are the ones of the
|
||||||
|
sendmsg(2) system call.
|
||||||
|
The maximum number of file descriptors that can be sent using this
|
||||||
|
function is ANCIL_MAX_N_FDS; the behavior is undefined in case of
|
||||||
|
overflow, probably a stack corruption.
|
||||||
|
|
||||||
|
|
||||||
|
int ancil_recv_fds(socket, file_descriptors, num_file_descriptors)
|
||||||
|
int socket: the Unix socket
|
||||||
|
int *file_descriptors: return array of file descriptors
|
||||||
|
unsigned num_file_descriptors: number of file descriptors
|
||||||
|
Return value: number of received fd for success, -1 for failure
|
||||||
|
|
||||||
|
Receives several file descriptors from a socket, no more than
|
||||||
|
num_file_descriptors.
|
||||||
|
In case of success, the received file descriptors are stored in the array
|
||||||
|
pointed to by file_descriptors.
|
||||||
|
In case of failure, errno is set; the possible values are the ones of the
|
||||||
|
recvmsg(2) system call.
|
||||||
|
The maximum number of file descriptors that can be received using this
|
||||||
|
function is ANCIL_MAX_N_FDS; the behavior is undefined in case of
|
||||||
|
overflow, probably a stack corruption.
|
||||||
|
The behavior is undefined if the recv_fds does not match a send_fd* on
|
||||||
|
the other side, or if the number of received file descriptors is more than
|
||||||
|
num_file_descriptors.
|
||||||
|
|
||||||
|
|
||||||
|
int ancil_send_fds_with_buffer(socket, fds, num, buffer)
|
||||||
|
int socket: the Unix socket
|
||||||
|
const int *fds: array of file descriptors
|
||||||
|
unsigned num: number of file descriptors
|
||||||
|
void *buffer: buffer to hold the system data structures
|
||||||
|
Return value: 0 for success, -1 for failure
|
||||||
|
|
||||||
|
Sends several file descriptors on a socket.
|
||||||
|
In case of failure, errno is set; the possible values are the ones of the
|
||||||
|
sendmsg(2) system call.
|
||||||
|
The buffer argument must point to a memory area large enough to hold the
|
||||||
|
system data structures, see ANCIL_FD_BUFFER.
|
||||||
|
|
||||||
|
|
||||||
|
int ancil_send_fds_with_buffer(socket, fds, num, buffer)
|
||||||
|
int socket: the Unix socket
|
||||||
|
int *fds: return array of file descriptors
|
||||||
|
unsigned num: number of file descriptors
|
||||||
|
void *buffer: buffer to hold the system data structures
|
||||||
|
Return value: number of received fd for success, -1 for failure
|
||||||
|
|
||||||
|
Receives several file descriptors from a socket, no more than
|
||||||
|
num_file_descriptors.
|
||||||
|
In case of success, the received file descriptors are stored in the array
|
||||||
|
pointed to by file_descriptors.
|
||||||
|
In case of failure, errno is set; the possible values are the ones of the
|
||||||
|
recvmsg(2) system call.
|
||||||
|
The behavior is undefined if the recv_fds does not match a send_fd* on
|
||||||
|
the other side, or if the number of received file descriptors is more than
|
||||||
|
num_file_descriptors.
|
||||||
|
The buffer argument must point to a memory area large enough to hold the
|
||||||
|
system data structures, see ANCIL_FD_BUFFER.
|
||||||
|
|
||||||
|
|
||||||
|
ANCIL_MAX_N_FDS
|
||||||
|
|
||||||
|
Maximum number of file descriptors that can be sent with the sent_fds and
|
||||||
|
recv_fds functions. If you have to send more at once, use the
|
||||||
|
*_with_buffer versions. The value is enough to send "quite a few" file
|
||||||
|
descriptors.
|
||||||
|
|
||||||
|
|
||||||
|
ANCIL_FD_BUFFER(n)
|
||||||
|
int n: number of file descriptors
|
||||||
|
|
||||||
|
Expands to a structure data type large enough to hold the system data
|
||||||
|
structures for n file descriptors. So the address of a variable declared
|
||||||
|
of type ANCIL_FD_BUFFER(n) is suitable as the buffer argument for
|
||||||
|
*_with_buffer on n file descriptors.
|
||||||
|
To use this macro, you need <sys/types.h> and <sys/socket.h>. Bevare: with
|
||||||
|
Solaris, the _XPG4_2 macro must be defined before sys/socket is included.
|
||||||
|
|
||||||
|
|
||||||
|
Tuning the compilation
|
||||||
|
|
||||||
|
This library is designed to be included in projects, not installed in
|
||||||
|
/usr/lib. If your project does not use some of the functions, the
|
||||||
|
TUNE_OPTS variable in the Makefile allows not to build them. It is a list
|
||||||
|
of proprocessor options:
|
||||||
|
|
||||||
|
-DNDEBUG: turn assertions off (see assert(3))
|
||||||
|
-DSPARE_SEND_FDS: do not build ancil_send_fds
|
||||||
|
-DSPARE_SEND_FD: do not build ancil_send_fd
|
||||||
|
-DSPARE_RECV_FDS: do not build ancil_recv_fds
|
||||||
|
-DSPARE_RECV_FD: do not build ancil_recv_fd
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. The name of the author may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
###########################################################################
|
||||||
|
# libancillary - black magic on Unix domain sockets
|
||||||
|
# (C) Nicolas George
|
||||||
|
# Makefile - guess what
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# 3. The name of the author may not be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-Wall -g -O2
|
||||||
|
LDFLAGS=
|
||||||
|
LIBS=
|
||||||
|
AR=ar
|
||||||
|
RANLIB=ranlib
|
||||||
|
RM=rm
|
||||||
|
CP=cp
|
||||||
|
MKDIR=mkdir
|
||||||
|
TAR=tar
|
||||||
|
GZIP=gzip -9
|
||||||
|
|
||||||
|
NAME=libancillary
|
||||||
|
DISTRIBUTION=API COPYING Makefile ancillary.h fd_send.c fd_recv.c test.c
|
||||||
|
VERSION=0.9.1
|
||||||
|
|
||||||
|
OBJECTS=fd_send.o fd_recv.o
|
||||||
|
|
||||||
|
TUNE_OPTS=-DNDEBUG
|
||||||
|
#TUNE_OPTS=-DNDEBUG \
|
||||||
|
-DSPARE_SEND_FDS -DSPARE_SEND_FD -DSPARE_RECV_FDS -DSPARE_RECV_FD
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -c $(CFLAGS) $(TUNE_OPTS) $<
|
||||||
|
|
||||||
|
all: libancillary.a
|
||||||
|
|
||||||
|
libancillary.a: $(OBJECTS)
|
||||||
|
$(AR) cr $@ $(OBJECTS)
|
||||||
|
$(RANLIB) $@
|
||||||
|
|
||||||
|
fd_send.o: ancillary.h
|
||||||
|
fd_recv.o: ancillary.h
|
||||||
|
|
||||||
|
test: test.c libancillary.a
|
||||||
|
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) -L. test.c -lancillary $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) -f *.o *.a test
|
||||||
|
|
||||||
|
dist:
|
||||||
|
$(MKDIR) $(NAME)-$(VERSION)
|
||||||
|
$(CP) $(DISTRIBUTION) $(NAME)-$(VERSION)
|
||||||
|
$(TAR) -cf - $(NAME)-$(VERSION) | $(GZIP) > $(NAME)-$(VERSION).tar.gz
|
||||||
|
$(RM) -rf $(NAME)-$(VERSION)
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* libancillary - black magic on Unix domain sockets
|
||||||
|
* (C) Nicolas George
|
||||||
|
* ancillary.c - public header
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANCILLARY_H__
|
||||||
|
#define ANCILLARY_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Start of the readable part.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#define ANCIL_MAX_N_FDS 960
|
||||||
|
/*
|
||||||
|
* Maximum number of fds that can be sent or received using the "esay"
|
||||||
|
* functions; this is so that all can fit in one page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int
|
||||||
|
ancil_send_fds_with_buffer(int, const int *, unsigned, void *);
|
||||||
|
/*
|
||||||
|
* ancil_send_fds_with_buffer(sock, n_fds, fds, buffer)
|
||||||
|
*
|
||||||
|
* Sends the file descriptors in the array pointed by fds, of length n_fds
|
||||||
|
* on the socket sock.
|
||||||
|
* buffer is a writeable memory area large enough to hold the required data
|
||||||
|
* structures.
|
||||||
|
* Returns: -1 and errno in case of error, 0 in case of success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int
|
||||||
|
ancil_recv_fds_with_buffer(int, int *, unsigned, void *);
|
||||||
|
/*
|
||||||
|
* ancil_recv_fds_with_buffer(sock, n_fds, fds, buffer)
|
||||||
|
*
|
||||||
|
* Receives *n_fds file descriptors into the array pointed by fds
|
||||||
|
* from the socket sock.
|
||||||
|
* buffer is a writeable memory area large enough to hold the required data
|
||||||
|
* structures.
|
||||||
|
* Returns: -1 and errno in case of error, the actual number of received fd
|
||||||
|
* in case of success
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ANCIL_FD_BUFFER(n) \
|
||||||
|
struct { \
|
||||||
|
struct cmsghdr h; \
|
||||||
|
int fd[n]; \
|
||||||
|
}
|
||||||
|
/* ANCIL_FD_BUFFER(n)
|
||||||
|
*
|
||||||
|
* A structure type suitable to be used as buffer for n file descriptors.
|
||||||
|
* Requires <sys/socket.h>.
|
||||||
|
* Example:
|
||||||
|
* ANCIL_FD_BUFFER(42) buffer;
|
||||||
|
* ancil_recv_fds_with_buffer(sock, 42, my_fds, &buffer);
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int
|
||||||
|
ancil_send_fds(int, const int *, unsigned);
|
||||||
|
/*
|
||||||
|
* ancil_send_fds(sock, n_fds, fds)
|
||||||
|
*
|
||||||
|
* Sends the file descriptors in the array pointed by fds, of length n_fds
|
||||||
|
* on the socket sock.
|
||||||
|
* n_fds must not be greater than ANCIL_MAX_N_FDS.
|
||||||
|
* Returns: -1 and errno in case of error, 0 in case of success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int
|
||||||
|
ancil_recv_fds(int, int *, unsigned);
|
||||||
|
/*
|
||||||
|
* ancil_recv_fds(sock, n_fds, fds)
|
||||||
|
*
|
||||||
|
* Receives *n_fds file descriptors into the array pointed by fds
|
||||||
|
* from the socket sock.
|
||||||
|
* *n_fds must not be greater than ANCIL_MAX_N_FDS.
|
||||||
|
* Returns: -1 and errno in case of error, the actual number of received fd
|
||||||
|
* in case of success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
extern int
|
||||||
|
ancil_send_fd(int, int);
|
||||||
|
/* ancil_recv_fd(sock, fd);
|
||||||
|
*
|
||||||
|
* Sends the file descriptor fd on the socket sock.
|
||||||
|
* Returns : -1 and errno in case of error, 0 in case of success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int
|
||||||
|
ancil_recv_fd(int, int *);
|
||||||
|
/* ancil_send_fd(sock, &fd);
|
||||||
|
*
|
||||||
|
* Receives the file descriptor fd from the socket sock.
|
||||||
|
* Returns : -1 and errno in case of error, 0 in case of success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ANCILLARY_H__ */
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* libancillary - black magic on Unix domain sockets
|
||||||
|
* (C) Nicolas George
|
||||||
|
* fd_send.c - receiving file descriptors
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XPG4_2 /* Solaris sucks */
|
||||||
|
# define _XPG4_2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
# include <sys/param.h> /* FreeBSD sucks */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ancillary.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
ancil_recv_fds_with_buffer(int sock, int *fds, unsigned n_fds, void *buffer)
|
||||||
|
{
|
||||||
|
struct msghdr msghdr;
|
||||||
|
char nothing;
|
||||||
|
struct iovec nothing_ptr;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nothing_ptr.iov_base = ¬hing;
|
||||||
|
nothing_ptr.iov_len = 1;
|
||||||
|
msghdr.msg_name = NULL;
|
||||||
|
msghdr.msg_namelen = 0;
|
||||||
|
msghdr.msg_iov = ¬hing_ptr;
|
||||||
|
msghdr.msg_iovlen = 1;
|
||||||
|
msghdr.msg_flags = 0;
|
||||||
|
msghdr.msg_control = buffer;
|
||||||
|
msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds;
|
||||||
|
cmsg = CMSG_FIRSTHDR(&msghdr);
|
||||||
|
cmsg->cmsg_len = msghdr.msg_controllen;
|
||||||
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
|
cmsg->cmsg_type = SCM_RIGHTS;
|
||||||
|
for(i = 0; i < n_fds; i++)
|
||||||
|
((int *)CMSG_DATA(cmsg))[i] = -1;
|
||||||
|
|
||||||
|
if(recvmsg(sock, &msghdr, 0) < 0)
|
||||||
|
return(-1);
|
||||||
|
for(i = 0; i < n_fds; i++)
|
||||||
|
fds[i] = ((int *)CMSG_DATA(cmsg))[i];
|
||||||
|
n_fds = (msghdr.msg_controllen - sizeof(struct cmsghdr)) / sizeof(int);
|
||||||
|
return(n_fds);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SPARE_RECV_FDS
|
||||||
|
int
|
||||||
|
ancil_recv_fds(int sock, int *fd, unsigned n_fds)
|
||||||
|
{
|
||||||
|
ANCIL_FD_BUFFER(ANCIL_MAX_N_FDS) buffer;
|
||||||
|
|
||||||
|
assert(n_fds <= ANCIL_MAX_N_FDS);
|
||||||
|
return(ancil_recv_fds_with_buffer(sock, fd, n_fds, &buffer));
|
||||||
|
}
|
||||||
|
#endif /* SPARE_RECV_FDS */
|
||||||
|
|
||||||
|
#ifndef SPARE_RECV_FD
|
||||||
|
int
|
||||||
|
ancil_recv_fd(int sock, int *fd)
|
||||||
|
{
|
||||||
|
ANCIL_FD_BUFFER(1) buffer;
|
||||||
|
|
||||||
|
return(ancil_recv_fds_with_buffer(sock, fd, 1, &buffer) == 1 ? 0 : -1);
|
||||||
|
}
|
||||||
|
#endif /* SPARE_RECV_FD */
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* libancillary - black magic on Unix domain sockets
|
||||||
|
* (C) Nicolas George
|
||||||
|
* fd_send.c - sending file descriptors
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XPG4_2 /* Solaris sucks */
|
||||||
|
# define _XPG4_2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
# include <sys/param.h> /* FreeBSD sucks */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ancillary.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
ancil_send_fds_with_buffer(int sock, const int *fds, unsigned n_fds, void *buffer)
|
||||||
|
{
|
||||||
|
struct msghdr msghdr;
|
||||||
|
char nothing = '!';
|
||||||
|
struct iovec nothing_ptr;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nothing_ptr.iov_base = ¬hing;
|
||||||
|
nothing_ptr.iov_len = 1;
|
||||||
|
msghdr.msg_name = NULL;
|
||||||
|
msghdr.msg_namelen = 0;
|
||||||
|
msghdr.msg_iov = ¬hing_ptr;
|
||||||
|
msghdr.msg_iovlen = 1;
|
||||||
|
msghdr.msg_flags = 0;
|
||||||
|
msghdr.msg_control = buffer;
|
||||||
|
msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds;
|
||||||
|
cmsg = CMSG_FIRSTHDR(&msghdr);
|
||||||
|
cmsg->cmsg_len = msghdr.msg_controllen;
|
||||||
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
|
cmsg->cmsg_type = SCM_RIGHTS;
|
||||||
|
for(i = 0; i < n_fds; i++)
|
||||||
|
((int *)CMSG_DATA(cmsg))[i] = fds[i];
|
||||||
|
return(sendmsg(sock, &msghdr, 0) >= 0 ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SPARE_SEND_FDS
|
||||||
|
int
|
||||||
|
ancil_send_fds(int sock, const int *fds, unsigned n_fds)
|
||||||
|
{
|
||||||
|
ANCIL_FD_BUFFER(ANCIL_MAX_N_FDS) buffer;
|
||||||
|
|
||||||
|
assert(n_fds <= ANCIL_MAX_N_FDS);
|
||||||
|
return(ancil_send_fds_with_buffer(sock, fds, n_fds, &buffer));
|
||||||
|
}
|
||||||
|
#endif /* SPARE_SEND_FDS */
|
||||||
|
|
||||||
|
#ifndef SPARE_SEND_FD
|
||||||
|
int
|
||||||
|
ancil_send_fd(int sock, int fd)
|
||||||
|
{
|
||||||
|
ANCIL_FD_BUFFER(1) buffer;
|
||||||
|
|
||||||
|
return(ancil_send_fds_with_buffer(sock, &fd, 1, &buffer));
|
||||||
|
}
|
||||||
|
#endif /* SPARE_SEND_FD */
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* libancillary - black magic on Unix domain sockets
|
||||||
|
* (C) Nicolas George
|
||||||
|
* test.c - testing and example program
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include "ancillary.h"
|
||||||
|
|
||||||
|
void child_process(int sock)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int fds[3], nfds;
|
||||||
|
char b[] = "This is on the received fd!\n";
|
||||||
|
|
||||||
|
if(ancil_recv_fd(sock, &fd)) {
|
||||||
|
perror("ancil_recv_fd");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("Received fd: %d\n", fd);
|
||||||
|
}
|
||||||
|
write(fd, b, sizeof(b));
|
||||||
|
close(fd);
|
||||||
|
sleep(2);
|
||||||
|
|
||||||
|
nfds = ancil_recv_fds(sock, fds, 3);
|
||||||
|
if(nfds < 0) {
|
||||||
|
perror("ancil_recv_fds");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("Received %d/3 fds : %d %d %d.\n", nfds,
|
||||||
|
fds[0], fds[1], fds[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parent_process(int sock)
|
||||||
|
{
|
||||||
|
int fds[2] = { 1, 2 };
|
||||||
|
|
||||||
|
if(ancil_send_fd(sock, 1)) {
|
||||||
|
perror("ancil_send_fd");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("Sent fd.\n");
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
if(ancil_send_fds(sock, fds, 2)) {
|
||||||
|
perror("ancil_send_fds");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("Sent two fds.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int sock[2];
|
||||||
|
|
||||||
|
if(socketpair(PF_UNIX, SOCK_STREAM, 0, sock)) {
|
||||||
|
perror("socketpair");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("Established socket pair: (%d, %d)\n", sock[0], sock[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(fork()) {
|
||||||
|
case 0:
|
||||||
|
close(sock[0]);
|
||||||
|
child_process(sock[1]);
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
perror("fork");
|
||||||
|
exit(1);
|
||||||
|
default:
|
||||||
|
close(sock[1]);
|
||||||
|
parent_process(sock[0]);
|
||||||
|
wait(NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
Submodule src/main/jni/shadowsocks-libev updated: d53cd0c3fd...ad4fdeb364
@@ -5,8 +5,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <cpu-features.h>
|
#include <cpu-features.h>
|
||||||
|
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <ancillary.h>
|
||||||
|
|
||||||
#define LOGI(...) do { __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__); } while(0)
|
#define LOGI(...) do { __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__); } while(0)
|
||||||
#define LOGW(...) do { __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__); } while(0)
|
#define LOGW(...) do { __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__); } while(0)
|
||||||
#define LOGE(...) do { __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__); } while(0)
|
#define LOGE(...) do { __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__); } while(0)
|
||||||
@@ -36,9 +43,46 @@ void Java_com_github_shadowsocks_system_exec(JNIEnv *env, jobject thiz, jstring
|
|||||||
env->ReleaseStringUTFChars(cmd, str);
|
env->ReleaseStringUTFChars(cmd, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Java_com_github_shadowsocks_system_jniclose(JNIEnv *env, jobject thiz, jint fd) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
jint Java_com_github_shadowsocks_system_sendfd(JNIEnv *env, jobject thiz, jint tun_fd) {
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||||
|
LOGE("socket() failed: %s (socket fd = %d)\n", strerror(errno), fd);
|
||||||
|
return (jint)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy(addr.sun_path, "/data/data/com.github.shadowsocks/sock_path", sizeof(addr.sun_path)-1);
|
||||||
|
|
||||||
|
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
||||||
|
LOGE("connect() failed: %s (fd = %d)\n", strerror(errno), fd);
|
||||||
|
close(fd);
|
||||||
|
return (jint)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ancil_send_fd(fd, tun_fd)) {
|
||||||
|
LOGE("ancil_send_fd: %s", strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
return (jint)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *classPathName = "com/github/shadowsocks/System";
|
static const char *classPathName = "com/github/shadowsocks/System";
|
||||||
|
|
||||||
static JNINativeMethod method_table[] = {
|
static JNINativeMethod method_table[] = {
|
||||||
|
{ "jniclose", "(I)V",
|
||||||
|
(void*) Java_com_github_shadowsocks_system_jniclose },
|
||||||
|
{ "sendfd", "(I)I",
|
||||||
|
(void*) Java_com_github_shadowsocks_system_sendfd },
|
||||||
{ "exec", "(Ljava/lang/String;)V",
|
{ "exec", "(Ljava/lang/String;)V",
|
||||||
(void*) Java_com_github_shadowsocks_system_exec },
|
(void*) Java_com_github_shadowsocks_system_exec },
|
||||||
{ "getABI", "()Ljava/lang/String;",
|
{ "getABI", "()Ljava/lang/String;",
|
||||||
|
|||||||
@@ -77,6 +77,12 @@
|
|||||||
<string name="udp_dns">UDP 转发</string>
|
<string name="udp_dns">UDP 转发</string>
|
||||||
<string name="udp_dns_summary">由远程服务器转发 UDP 协议的数据包</string>
|
<string name="udp_dns_summary">由远程服务器转发 UDP 协议的数据包</string>
|
||||||
|
|
||||||
|
<string name="onetime_auth">一次性认证</string>
|
||||||
|
<string name="onetime_auth_summary">启用一次性认证(实验性)</string>
|
||||||
|
|
||||||
|
<string name="ipv6">IPv6 路由</string>
|
||||||
|
<string name="ipv6_summary">向远程服务器转发 IPv6 流量</string>
|
||||||
|
|
||||||
<!-- profile -->
|
<!-- profile -->
|
||||||
<string name="add_profile_dialog">为影梭添加此配置文件?</string>
|
<string name="add_profile_dialog">为影梭添加此配置文件?</string>
|
||||||
<string-array name="add_profile_methods">
|
<string-array name="add_profile_methods">
|
||||||
|
|||||||
@@ -85,7 +85,41 @@
|
|||||||
<item>101.0.0.0/8</item>
|
<item>101.0.0.0/8</item>
|
||||||
<item>102.0.0.0/7</item>
|
<item>102.0.0.0/7</item>
|
||||||
<item>104.0.0.0/5</item>
|
<item>104.0.0.0/5</item>
|
||||||
<item>112.0.0.0/5</item>
|
<item>112.0.0.0/10</item>
|
||||||
|
<item>112.64.0.0/11</item>
|
||||||
|
<item>112.96.0.0/12</item>
|
||||||
|
<item>112.112.0.0/13</item>
|
||||||
|
<item>112.120.0.0/14</item>
|
||||||
|
<item>112.124.0.0/19</item>
|
||||||
|
<item>112.124.32.0/21</item>
|
||||||
|
<item>112.124.40.0/22</item>
|
||||||
|
<item>112.124.44.0/23</item>
|
||||||
|
<item>112.124.46.0/24</item>
|
||||||
|
<item>112.124.48.0/20</item>
|
||||||
|
<item>112.124.64.0/18</item>
|
||||||
|
<item>112.124.128.0/17</item>
|
||||||
|
<item>112.125.0.0/16</item>
|
||||||
|
<item>112.126.0.0/15</item>
|
||||||
|
<item>112.128.0.0/9</item>
|
||||||
|
<item>113.0.0.0/8</item>
|
||||||
|
<item>114.0.0.0/10</item>
|
||||||
|
<item>114.64.0.0/11</item>
|
||||||
|
<item>114.96.0.0/12</item>
|
||||||
|
<item>114.112.0.0/15</item>
|
||||||
|
<item>114.114.0.0/18</item>
|
||||||
|
<item>114.114.64.0/19</item>
|
||||||
|
<item>114.114.96.0/20</item>
|
||||||
|
<item>114.114.112.0/23</item>
|
||||||
|
<item>114.114.115.0/24</item>
|
||||||
|
<item>114.114.116.0/22</item>
|
||||||
|
<item>114.114.120.0/21</item>
|
||||||
|
<item>114.114.128.0/17</item>
|
||||||
|
<item>114.115.0.0/16</item>
|
||||||
|
<item>114.116.0.0/14</item>
|
||||||
|
<item>114.120.0.0/13</item>
|
||||||
|
<item>114.128.0.0/9</item>
|
||||||
|
<item>115.0.0.0/8</item>
|
||||||
|
<item>116.0.0.0/6</item>
|
||||||
<item>120.0.0.0/6</item>
|
<item>120.0.0.0/6</item>
|
||||||
<item>124.0.0.0/7</item>
|
<item>124.0.0.0/7</item>
|
||||||
<item>126.0.0.0/8</item>
|
<item>126.0.0.0/8</item>
|
||||||
|
|||||||
@@ -321,6 +321,10 @@
|
|||||||
<item>43.239.0.0/19</item>
|
<item>43.239.0.0/19</item>
|
||||||
<item>43.239.32.0/20</item>
|
<item>43.239.32.0/20</item>
|
||||||
<item>43.239.48.0/22</item>
|
<item>43.239.48.0/22</item>
|
||||||
|
<item>43.239.116.0/22</item>
|
||||||
|
<item>43.239.120.0/22</item>
|
||||||
|
<item>43.239.172.0/22</item>
|
||||||
|
<item>43.239.176.0/22</item>
|
||||||
<item>43.240.0.0/22</item>
|
<item>43.240.0.0/22</item>
|
||||||
<item>43.240.48.0/22</item>
|
<item>43.240.48.0/22</item>
|
||||||
<item>43.240.56.0/21</item>
|
<item>43.240.56.0/21</item>
|
||||||
@@ -505,6 +509,154 @@
|
|||||||
<item>43.255.232.0/22</item>
|
<item>43.255.232.0/22</item>
|
||||||
<item>43.255.244.0/22</item>
|
<item>43.255.244.0/22</item>
|
||||||
<item>45.64.112.0/23</item>
|
<item>45.64.112.0/23</item>
|
||||||
|
<item>45.112.132.0/22</item>
|
||||||
|
<item>45.112.188.0/22</item>
|
||||||
|
<item>45.112.208.0/20</item>
|
||||||
|
<item>45.112.228.0/22</item>
|
||||||
|
<item>45.112.232.0/21</item>
|
||||||
|
<item>45.113.12.0/22</item>
|
||||||
|
<item>45.113.16.0/20</item>
|
||||||
|
<item>45.113.40.0/22</item>
|
||||||
|
<item>45.113.52.0/22</item>
|
||||||
|
<item>45.113.56.0/22</item>
|
||||||
|
<item>45.113.72.0/22</item>
|
||||||
|
<item>45.113.108.0/22</item>
|
||||||
|
<item>45.113.144.0/21</item>
|
||||||
|
<item>45.113.168.0/22</item>
|
||||||
|
<item>45.113.176.0/22</item>
|
||||||
|
<item>45.113.184.0/22</item>
|
||||||
|
<item>45.113.200.0/21</item>
|
||||||
|
<item>45.113.208.0/20</item>
|
||||||
|
<item>45.113.228.0/22</item>
|
||||||
|
<item>45.113.240.0/22</item>
|
||||||
|
<item>45.113.252.0/22</item>
|
||||||
|
<item>45.114.0.0/22</item>
|
||||||
|
<item>45.114.12.0/22</item>
|
||||||
|
<item>45.114.32.0/22</item>
|
||||||
|
<item>45.114.40.0/22</item>
|
||||||
|
<item>45.114.52.0/22</item>
|
||||||
|
<item>45.114.96.0/22</item>
|
||||||
|
<item>45.114.104.0/22</item>
|
||||||
|
<item>45.114.136.0/22</item>
|
||||||
|
<item>45.114.196.0/22</item>
|
||||||
|
<item>45.114.200.0/22</item>
|
||||||
|
<item>45.114.228.0/22</item>
|
||||||
|
<item>45.114.236.0/22</item>
|
||||||
|
<item>45.114.252.0/22</item>
|
||||||
|
<item>45.115.44.0/22</item>
|
||||||
|
<item>45.115.100.0/22</item>
|
||||||
|
<item>45.115.120.0/22</item>
|
||||||
|
<item>45.115.132.0/22</item>
|
||||||
|
<item>45.115.144.0/22</item>
|
||||||
|
<item>45.115.156.0/22</item>
|
||||||
|
<item>45.115.164.0/22</item>
|
||||||
|
<item>45.115.200.0/22</item>
|
||||||
|
<item>45.115.212.0/22</item>
|
||||||
|
<item>45.115.216.0/22</item>
|
||||||
|
<item>45.115.228.0/22</item>
|
||||||
|
<item>45.115.236.0/22</item>
|
||||||
|
<item>45.115.244.0/22</item>
|
||||||
|
<item>45.115.248.0/22</item>
|
||||||
|
<item>45.116.12.0/22</item>
|
||||||
|
<item>45.116.16.0/21</item>
|
||||||
|
<item>45.116.24.0/22</item>
|
||||||
|
<item>45.116.32.0/21</item>
|
||||||
|
<item>45.116.52.0/22</item>
|
||||||
|
<item>45.116.60.0/22</item>
|
||||||
|
<item>45.116.64.0/22</item>
|
||||||
|
<item>45.116.96.0/21</item>
|
||||||
|
<item>45.116.140.0/22</item>
|
||||||
|
<item>45.116.152.0/22</item>
|
||||||
|
<item>45.116.208.0/22</item>
|
||||||
|
<item>45.117.8.0/22</item>
|
||||||
|
<item>45.117.20.0/22</item>
|
||||||
|
<item>45.117.40.0/22</item>
|
||||||
|
<item>45.117.68.0/22</item>
|
||||||
|
<item>45.117.124.0/22</item>
|
||||||
|
<item>45.117.252.0/22</item>
|
||||||
|
<item>45.119.52.0/22</item>
|
||||||
|
<item>45.119.60.0/22</item>
|
||||||
|
<item>45.119.64.0/21</item>
|
||||||
|
<item>45.119.72.0/22</item>
|
||||||
|
<item>45.119.104.0/22</item>
|
||||||
|
<item>45.119.116.0/22</item>
|
||||||
|
<item>45.119.160.0/22</item>
|
||||||
|
<item>45.119.232.0/22</item>
|
||||||
|
<item>45.120.100.0/22</item>
|
||||||
|
<item>45.120.140.0/22</item>
|
||||||
|
<item>45.120.156.0/22</item>
|
||||||
|
<item>45.120.164.0/22</item>
|
||||||
|
<item>45.120.220.0/22</item>
|
||||||
|
<item>45.120.240.0/22</item>
|
||||||
|
<item>45.121.20.0/22</item>
|
||||||
|
<item>45.121.52.0/22</item>
|
||||||
|
<item>45.121.64.0/21</item>
|
||||||
|
<item>45.121.72.0/22</item>
|
||||||
|
<item>45.121.92.0/22</item>
|
||||||
|
<item>45.121.96.0/22</item>
|
||||||
|
<item>45.121.104.0/22</item>
|
||||||
|
<item>45.121.172.0/22</item>
|
||||||
|
<item>45.121.176.0/22</item>
|
||||||
|
<item>45.121.212.0/22</item>
|
||||||
|
<item>45.121.240.0/20</item>
|
||||||
|
<item>45.122.0.0/19</item>
|
||||||
|
<item>45.122.32.0/21</item>
|
||||||
|
<item>45.122.40.0/22</item>
|
||||||
|
<item>45.122.60.0/22</item>
|
||||||
|
<item>45.122.64.0/19</item>
|
||||||
|
<item>45.122.96.0/20</item>
|
||||||
|
<item>45.122.112.0/21</item>
|
||||||
|
<item>45.122.160.0/19</item>
|
||||||
|
<item>45.122.192.0/20</item>
|
||||||
|
<item>45.122.208.0/21</item>
|
||||||
|
<item>45.122.216.0/22</item>
|
||||||
|
<item>45.123.28.0/22</item>
|
||||||
|
<item>45.123.32.0/21</item>
|
||||||
|
<item>45.123.44.0/22</item>
|
||||||
|
<item>45.123.48.0/20</item>
|
||||||
|
<item>45.123.64.0/20</item>
|
||||||
|
<item>45.123.80.0/21</item>
|
||||||
|
<item>45.123.88.0/22</item>
|
||||||
|
<item>45.123.120.0/22</item>
|
||||||
|
<item>45.123.128.0/21</item>
|
||||||
|
<item>45.123.136.0/22</item>
|
||||||
|
<item>45.123.148.0/22</item>
|
||||||
|
<item>45.123.152.0/21</item>
|
||||||
|
<item>45.123.164.0/22</item>
|
||||||
|
<item>45.123.168.0/21</item>
|
||||||
|
<item>45.123.176.0/21</item>
|
||||||
|
<item>45.123.184.0/22</item>
|
||||||
|
<item>45.123.204.0/22</item>
|
||||||
|
<item>45.123.212.0/22</item>
|
||||||
|
<item>45.123.224.0/19</item>
|
||||||
|
<item>45.124.0.0/22</item>
|
||||||
|
<item>45.124.20.0/22</item>
|
||||||
|
<item>45.124.28.0/22</item>
|
||||||
|
<item>45.124.32.0/21</item>
|
||||||
|
<item>45.124.44.0/22</item>
|
||||||
|
<item>45.124.68.0/22</item>
|
||||||
|
<item>45.124.76.0/22</item>
|
||||||
|
<item>45.124.80.0/22</item>
|
||||||
|
<item>45.124.100.0/22</item>
|
||||||
|
<item>45.124.124.0/22</item>
|
||||||
|
<item>45.124.172.0/22</item>
|
||||||
|
<item>45.124.176.0/22</item>
|
||||||
|
<item>45.124.208.0/22</item>
|
||||||
|
<item>45.124.248.0/21</item>
|
||||||
|
<item>45.125.12.0/22</item>
|
||||||
|
<item>45.125.16.0/22</item>
|
||||||
|
<item>45.125.24.0/21</item>
|
||||||
|
<item>45.125.32.0/22</item>
|
||||||
|
<item>45.125.44.0/22</item>
|
||||||
|
<item>45.125.52.0/22</item>
|
||||||
|
<item>45.125.56.0/22</item>
|
||||||
|
<item>45.125.76.0/22</item>
|
||||||
|
<item>45.125.80.0/20</item>
|
||||||
|
<item>45.125.96.0/21</item>
|
||||||
|
<item>45.125.104.0/22</item>
|
||||||
|
<item>45.125.136.0/22</item>
|
||||||
|
<item>47.92.0.0/14</item>
|
||||||
|
<item>47.96.0.0/11</item>
|
||||||
<item>49.4.0.0/14</item>
|
<item>49.4.0.0/14</item>
|
||||||
<item>49.51.0.0/16</item>
|
<item>49.51.0.0/16</item>
|
||||||
<item>49.52.0.0/14</item>
|
<item>49.52.0.0/14</item>
|
||||||
@@ -803,7 +955,6 @@
|
|||||||
<item>103.30.96.0/22</item>
|
<item>103.30.96.0/22</item>
|
||||||
<item>103.30.148.0/22</item>
|
<item>103.30.148.0/22</item>
|
||||||
<item>103.30.200.0/22</item>
|
<item>103.30.200.0/22</item>
|
||||||
<item>103.30.216.0/22</item>
|
|
||||||
<item>103.30.228.0/22</item>
|
<item>103.30.228.0/22</item>
|
||||||
<item>103.30.236.0/22</item>
|
<item>103.30.236.0/22</item>
|
||||||
<item>103.31.0.0/22</item>
|
<item>103.31.0.0/22</item>
|
||||||
@@ -818,6 +969,8 @@
|
|||||||
<item>103.35.0.0/19</item>
|
<item>103.35.0.0/19</item>
|
||||||
<item>103.35.32.0/20</item>
|
<item>103.35.32.0/20</item>
|
||||||
<item>103.35.48.0/22</item>
|
<item>103.35.48.0/22</item>
|
||||||
|
<item>103.35.104.0/22</item>
|
||||||
|
<item>103.35.116.0/22</item>
|
||||||
<item>103.36.20.0/22</item>
|
<item>103.36.20.0/22</item>
|
||||||
<item>103.36.28.0/22</item>
|
<item>103.36.28.0/22</item>
|
||||||
<item>103.36.36.0/22</item>
|
<item>103.36.36.0/22</item>
|
||||||
@@ -1004,6 +1157,142 @@
|
|||||||
<item>103.50.224.0/20</item>
|
<item>103.50.224.0/20</item>
|
||||||
<item>103.50.240.0/21</item>
|
<item>103.50.240.0/21</item>
|
||||||
<item>103.50.248.0/22</item>
|
<item>103.50.248.0/22</item>
|
||||||
|
<item>103.52.40.0/22</item>
|
||||||
|
<item>103.52.72.0/21</item>
|
||||||
|
<item>103.52.80.0/21</item>
|
||||||
|
<item>103.52.96.0/21</item>
|
||||||
|
<item>103.52.104.0/22</item>
|
||||||
|
<item>103.52.160.0/21</item>
|
||||||
|
<item>103.52.172.0/22</item>
|
||||||
|
<item>103.52.176.0/22</item>
|
||||||
|
<item>103.52.184.0/22</item>
|
||||||
|
<item>103.52.196.0/22</item>
|
||||||
|
<item>103.53.4.0/22</item>
|
||||||
|
<item>103.53.64.0/21</item>
|
||||||
|
<item>103.53.92.0/22</item>
|
||||||
|
<item>103.53.100.0/22</item>
|
||||||
|
<item>103.53.124.0/22</item>
|
||||||
|
<item>103.53.128.0/20</item>
|
||||||
|
<item>103.53.144.0/22</item>
|
||||||
|
<item>103.53.160.0/22</item>
|
||||||
|
<item>103.53.180.0/22</item>
|
||||||
|
<item>103.53.204.0/22</item>
|
||||||
|
<item>103.53.208.0/22</item>
|
||||||
|
<item>103.53.216.0/22</item>
|
||||||
|
<item>103.53.236.0/22</item>
|
||||||
|
<item>103.53.248.0/22</item>
|
||||||
|
<item>103.54.8.0/22</item>
|
||||||
|
<item>103.54.48.0/22</item>
|
||||||
|
<item>103.54.60.0/22</item>
|
||||||
|
<item>103.54.160.0/21</item>
|
||||||
|
<item>103.54.212.0/22</item>
|
||||||
|
<item>103.54.228.0/22</item>
|
||||||
|
<item>103.54.240.0/22</item>
|
||||||
|
<item>103.55.24.0/22</item>
|
||||||
|
<item>103.55.80.0/22</item>
|
||||||
|
<item>103.55.120.0/22</item>
|
||||||
|
<item>103.55.152.0/22</item>
|
||||||
|
<item>103.55.172.0/22</item>
|
||||||
|
<item>103.55.204.0/22</item>
|
||||||
|
<item>103.55.208.0/22</item>
|
||||||
|
<item>103.55.228.0/22</item>
|
||||||
|
<item>103.55.236.0/22</item>
|
||||||
|
<item>103.55.240.0/22</item>
|
||||||
|
<item>103.56.8.0/22</item>
|
||||||
|
<item>103.56.16.0/21</item>
|
||||||
|
<item>103.56.32.0/22</item>
|
||||||
|
<item>103.56.52.0/22</item>
|
||||||
|
<item>103.56.56.0/21</item>
|
||||||
|
<item>103.56.72.0/21</item>
|
||||||
|
<item>103.56.100.0/22</item>
|
||||||
|
<item>103.56.104.0/22</item>
|
||||||
|
<item>103.56.140.0/22</item>
|
||||||
|
<item>103.56.152.0/22</item>
|
||||||
|
<item>103.56.184.0/22</item>
|
||||||
|
<item>103.56.200.0/22</item>
|
||||||
|
<item>103.56.216.0/22</item>
|
||||||
|
<item>103.57.12.0/22</item>
|
||||||
|
<item>103.57.52.0/22</item>
|
||||||
|
<item>103.57.56.0/22</item>
|
||||||
|
<item>103.57.76.0/22</item>
|
||||||
|
<item>103.57.108.0/22</item>
|
||||||
|
<item>103.57.136.0/22</item>
|
||||||
|
<item>103.57.196.0/22</item>
|
||||||
|
<item>103.58.24.0/22</item>
|
||||||
|
<item>103.58.182.0/23</item>
|
||||||
|
<item>103.59.76.0/22</item>
|
||||||
|
<item>103.59.100.0/22</item>
|
||||||
|
<item>103.59.112.0/20</item>
|
||||||
|
<item>103.59.128.0/22</item>
|
||||||
|
<item>103.59.148.0/22</item>
|
||||||
|
<item>103.59.164.0/22</item>
|
||||||
|
<item>103.59.216.0/22</item>
|
||||||
|
<item>103.60.32.0/22</item>
|
||||||
|
<item>103.60.44.0/22</item>
|
||||||
|
<item>103.60.164.0/22</item>
|
||||||
|
<item>103.60.228.0/22</item>
|
||||||
|
<item>103.60.236.0/22</item>
|
||||||
|
<item>103.61.60.0/22</item>
|
||||||
|
<item>103.61.104.0/22</item>
|
||||||
|
<item>103.61.140.0/22</item>
|
||||||
|
<item>103.61.152.0/21</item>
|
||||||
|
<item>103.61.160.0/22</item>
|
||||||
|
<item>103.61.172.0/22</item>
|
||||||
|
<item>103.61.176.0/22</item>
|
||||||
|
<item>103.61.184.0/21</item>
|
||||||
|
<item>103.62.24.0/22</item>
|
||||||
|
<item>103.62.52.0/22</item>
|
||||||
|
<item>103.62.72.0/21</item>
|
||||||
|
<item>103.62.80.0/21</item>
|
||||||
|
<item>103.62.88.0/22</item>
|
||||||
|
<item>103.62.96.0/19</item>
|
||||||
|
<item>103.62.128.0/21</item>
|
||||||
|
<item>103.62.156.0/22</item>
|
||||||
|
<item>103.62.160.0/19</item>
|
||||||
|
<item>103.62.192.0/22</item>
|
||||||
|
<item>103.62.204.0/22</item>
|
||||||
|
<item>103.62.208.0/20</item>
|
||||||
|
<item>103.62.224.0/22</item>
|
||||||
|
<item>103.63.32.0/19</item>
|
||||||
|
<item>103.63.64.0/20</item>
|
||||||
|
<item>103.63.80.0/21</item>
|
||||||
|
<item>103.63.88.0/22</item>
|
||||||
|
<item>103.63.140.0/22</item>
|
||||||
|
<item>103.63.144.0/22</item>
|
||||||
|
<item>103.63.152.0/22</item>
|
||||||
|
<item>103.63.160.0/20</item>
|
||||||
|
<item>103.63.176.0/21</item>
|
||||||
|
<item>103.63.184.0/22</item>
|
||||||
|
<item>103.63.192.0/20</item>
|
||||||
|
<item>103.63.208.0/22</item>
|
||||||
|
<item>103.63.240.0/20</item>
|
||||||
|
<item>103.192.0.0/19</item>
|
||||||
|
<item>103.192.48.0/21</item>
|
||||||
|
<item>103.192.56.0/22</item>
|
||||||
|
<item>103.192.84.0/22</item>
|
||||||
|
<item>103.192.88.0/21</item>
|
||||||
|
<item>103.192.96.0/20</item>
|
||||||
|
<item>103.192.112.0/22</item>
|
||||||
|
<item>103.192.128.0/20</item>
|
||||||
|
<item>103.192.144.0/22</item>
|
||||||
|
<item>103.192.164.0/22</item>
|
||||||
|
<item>103.192.188.0/22</item>
|
||||||
|
<item>103.192.208.0/21</item>
|
||||||
|
<item>103.192.216.0/22</item>
|
||||||
|
<item>103.192.252.0/22</item>
|
||||||
|
<item>103.193.40.0/21</item>
|
||||||
|
<item>103.193.120.0/21</item>
|
||||||
|
<item>103.193.140.0/22</item>
|
||||||
|
<item>103.193.144.0/21</item>
|
||||||
|
<item>103.193.160.0/22</item>
|
||||||
|
<item>103.193.188.0/22</item>
|
||||||
|
<item>103.193.192.0/22</item>
|
||||||
|
<item>103.193.212.0/22</item>
|
||||||
|
<item>103.193.216.0/21</item>
|
||||||
|
<item>103.193.224.0/20</item>
|
||||||
|
<item>103.193.240.0/22</item>
|
||||||
|
<item>103.194.16.0/22</item>
|
||||||
|
<item>103.194.230.0/23</item>
|
||||||
<item>103.224.40.0/21</item>
|
<item>103.224.40.0/21</item>
|
||||||
<item>103.224.60.0/22</item>
|
<item>103.224.60.0/22</item>
|
||||||
<item>103.224.80.0/22</item>
|
<item>103.224.80.0/22</item>
|
||||||
@@ -1096,6 +1385,7 @@
|
|||||||
<item>103.236.0.0/18</item>
|
<item>103.236.0.0/18</item>
|
||||||
<item>103.236.64.0/19</item>
|
<item>103.236.64.0/19</item>
|
||||||
<item>103.236.96.0/22</item>
|
<item>103.236.96.0/22</item>
|
||||||
|
<item>103.236.120.0/22</item>
|
||||||
<item>103.237.0.0/20</item>
|
<item>103.237.0.0/20</item>
|
||||||
<item>103.237.24.0/21</item>
|
<item>103.237.24.0/21</item>
|
||||||
<item>103.237.68.0/22</item>
|
<item>103.237.68.0/22</item>
|
||||||
@@ -1936,6 +2226,7 @@
|
|||||||
<item>166.111.0.0/16</item>
|
<item>166.111.0.0/16</item>
|
||||||
<item>167.139.0.0/16</item>
|
<item>167.139.0.0/16</item>
|
||||||
<item>167.189.0.0/16</item>
|
<item>167.189.0.0/16</item>
|
||||||
|
<item>167.220.244.0/22</item>
|
||||||
<item>168.160.0.0/16</item>
|
<item>168.160.0.0/16</item>
|
||||||
<item>169.254.0.0/16</item>
|
<item>169.254.0.0/16</item>
|
||||||
<item>171.8.0.0/13</item>
|
<item>171.8.0.0/13</item>
|
||||||
@@ -3363,7 +3654,6 @@
|
|||||||
<item>210.26.0.0/15</item>
|
<item>210.26.0.0/15</item>
|
||||||
<item>210.28.0.0/14</item>
|
<item>210.28.0.0/14</item>
|
||||||
<item>210.32.0.0/12</item>
|
<item>210.32.0.0/12</item>
|
||||||
<item>210.48.136.0/21</item>
|
|
||||||
<item>210.51.0.0/16</item>
|
<item>210.51.0.0/16</item>
|
||||||
<item>210.52.0.0/15</item>
|
<item>210.52.0.0/15</item>
|
||||||
<item>210.56.192.0/19</item>
|
<item>210.56.192.0/19</item>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -25,10 +25,14 @@
|
|||||||
|
|
||||||
<!-- feature category -->
|
<!-- feature category -->
|
||||||
<string name="feature_cat">Feature Settings</string>
|
<string name="feature_cat">Feature Settings</string>
|
||||||
|
<string name="ipv6">IPv6 Route</string>
|
||||||
|
<string name="ipv6_summary">Redirect IPv6 traffic to remote</string>
|
||||||
|
<string name="onetime_auth">One-time Authentication</string>
|
||||||
|
<string name="onetime_auth_summary">Enable one-time authentication (Experimental)</string>
|
||||||
<string name="http_proxy">HTTP Proxy</string>
|
<string name="http_proxy">HTTP Proxy</string>
|
||||||
<string name="http_proxy_summary">Local HTTP Proxy</string>
|
<string name="http_proxy_summary">Local HTTP Proxy</string>
|
||||||
<string name="dns_proxy">DNS Proxy</string>
|
<string name="dns_proxy">DNS Proxy</string>
|
||||||
<string name="dns_proxy_summary">Redirect DNS queries to remote server</string>
|
<string name="dns_proxy_summary">Redirect DNS queries to remote</string>
|
||||||
<string name="auto_set_gfwlist">CHN Route</string>
|
<string name="auto_set_gfwlist">CHN Route</string>
|
||||||
<string name="auto_set_gfwlist_summary">Bypass all sites located in China
|
<string name="auto_set_gfwlist_summary">Bypass all sites located in China
|
||||||
</string>
|
</string>
|
||||||
@@ -46,7 +50,7 @@
|
|||||||
<string name="traffic_stat">Traffic Stats</string>
|
<string name="traffic_stat">Traffic Stats</string>
|
||||||
<string name="traffic_stat_summary">Show traffic stats in notification bar</string>
|
<string name="traffic_stat_summary">Show traffic stats in notification bar</string>
|
||||||
<string name="udp_dns">UDP Forwarding</string>
|
<string name="udp_dns">UDP Forwarding</string>
|
||||||
<string name="udp_dns_summary">Forward UDP packets to remote server</string>
|
<string name="udp_dns_summary">Forward UDP packets to remote</string>
|
||||||
|
|
||||||
<!-- notification category -->
|
<!-- notification category -->
|
||||||
<string name="forward_success">Shadowsocks started.</string>
|
<string name="forward_success">Shadowsocks started.</string>
|
||||||
|
|||||||
@@ -58,6 +58,12 @@
|
|||||||
android:summary="@string/route_list_summary"
|
android:summary="@string/route_list_summary"
|
||||||
android:title="@string/route_list">
|
android:title="@string/route_list">
|
||||||
</com.github.shadowsocks.preferences.SummaryListPreference>
|
</com.github.shadowsocks.preferences.SummaryListPreference>
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="isIpv6"
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:summary="@string/ipv6_summary"
|
||||||
|
android:title="@string/ipv6">
|
||||||
|
</CheckBoxPreference>
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="isGlobalProxy"
|
android:key="isGlobalProxy"
|
||||||
@@ -78,6 +84,12 @@
|
|||||||
android:summary="@string/udp_dns_summary"
|
android:summary="@string/udp_dns_summary"
|
||||||
android:title="@string/udp_dns">
|
android:title="@string/udp_dns">
|
||||||
</CheckBoxPreference>
|
</CheckBoxPreference>
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="isAuth"
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:summary="@string/onetime_auth_summary"
|
||||||
|
android:title="@string/onetime_auth">
|
||||||
|
</CheckBoxPreference>
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="isAutoConnect"
|
android:key="isAutoConnect"
|
||||||
android:summary="@string/auto_connect_summary"
|
android:summary="@string/auto_connect_summary"
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ object Shadowsocks {
|
|||||||
val PROXY_PREFS = Array(Key.profileName, Key.proxy, Key.remotePort, Key.localPort, Key.sitekey,
|
val PROXY_PREFS = Array(Key.profileName, Key.proxy, Key.remotePort, Key.localPort, Key.sitekey,
|
||||||
Key.encMethod)
|
Key.encMethod)
|
||||||
val FEATRUE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps,
|
val FEATRUE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps,
|
||||||
Key.isUdpDns, Key.isAutoConnect)
|
Key.isUdpDns, Key.isAuth, Key.isIpv6, Key.isAutoConnect)
|
||||||
|
|
||||||
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL, Executable.TUN2SOCKS)
|
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL, Executable.TUN2SOCKS)
|
||||||
|
|
||||||
@@ -166,6 +166,8 @@ object Shadowsocks {
|
|||||||
case Key.route => updateListPreference(pref, profile.route)
|
case Key.route => updateListPreference(pref, profile.route)
|
||||||
case Key.isGlobalProxy => updateCheckBoxPreference(pref, profile.global)
|
case Key.isGlobalProxy => updateCheckBoxPreference(pref, profile.global)
|
||||||
case Key.isUdpDns => updateCheckBoxPreference(pref, profile.udpdns)
|
case Key.isUdpDns => updateCheckBoxPreference(pref, profile.udpdns)
|
||||||
|
case Key.isAuth => updateCheckBoxPreference(pref, profile.auth)
|
||||||
|
case Key.isIpv6 => updateCheckBoxPreference(pref, profile.ipv6)
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,6 +187,7 @@ class Shadowsocks
|
|||||||
// Variables
|
// Variables
|
||||||
var switchButton: Switch = null
|
var switchButton: Switch = null
|
||||||
var progressDialog: ProgressDialog = null
|
var progressDialog: ProgressDialog = null
|
||||||
|
var progressTag = -1
|
||||||
var state = State.INIT
|
var state = State.INIT
|
||||||
var prepared = false
|
var prepared = false
|
||||||
var currentProfile = new Profile
|
var currentProfile = new Profile
|
||||||
@@ -218,6 +221,11 @@ class Shadowsocks
|
|||||||
state = bgService.getState
|
state = bgService.getState
|
||||||
// set the listener
|
// set the listener
|
||||||
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
|
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
|
||||||
|
|
||||||
|
if (!status.getBoolean(getVersionName, false)) {
|
||||||
|
status.edit.putBoolean(getVersionName, true).commit()
|
||||||
|
recovery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def onServiceDisconnected(name: ComponentName) {
|
override def onServiceDisconnected(name: ComponentName) {
|
||||||
@@ -271,9 +279,10 @@ class Shadowsocks
|
|||||||
switchButton.setOnCheckedChangeListener(this)
|
switchButton.setOnCheckedChangeListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def showProgress(msg: String): Handler = {
|
private def showProgress(msg: Int): Handler = {
|
||||||
clearDialog()
|
clearDialog()
|
||||||
progressDialog = ProgressDialog.show(this, "", msg, true, false)
|
progressDialog = ProgressDialog.show(this, "", getString(msg), true, false)
|
||||||
|
progressTag = msg
|
||||||
new Handler {
|
new Handler {
|
||||||
override def handleMessage(msg: Message) {
|
override def handleMessage(msg: Message) {
|
||||||
clearDialog()
|
clearDialog()
|
||||||
@@ -397,7 +406,7 @@ class Shadowsocks
|
|||||||
}
|
}
|
||||||
|
|
||||||
def prepareStartService() {
|
def prepareStartService() {
|
||||||
showProgress(getString(R.string.connecting))
|
showProgress(R.string.connecting)
|
||||||
spawn {
|
spawn {
|
||||||
if (isVpnEnabled) {
|
if (isVpnEnabled) {
|
||||||
val intent = VpnService.prepare(this)
|
val intent = VpnService.prepare(this)
|
||||||
@@ -474,22 +483,16 @@ class Shadowsocks
|
|||||||
|
|
||||||
addPreferencesFromResource(R.xml.pref_all)
|
addPreferencesFromResource(R.xml.pref_all)
|
||||||
|
|
||||||
|
// Update the profile
|
||||||
|
if (!status.getBoolean(getVersionName, false)) {
|
||||||
|
currentProfile = profileManager.create()
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the profile
|
// Initialize the profile
|
||||||
currentProfile = {
|
currentProfile = {
|
||||||
profileManager.getProfile(settings.getInt(Key.profileId, -1)) getOrElse currentProfile
|
profileManager.getProfile(settings.getInt(Key.profileId, -1)) getOrElse currentProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the profile
|
|
||||||
if (!status.getBoolean(getVersionName, false)) {
|
|
||||||
val h = showProgress(getString(R.string.initializing))
|
|
||||||
status.edit.putBoolean(getVersionName, true).apply()
|
|
||||||
spawn {
|
|
||||||
reset()
|
|
||||||
currentProfile = profileManager.create()
|
|
||||||
h.sendEmptyMessage(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize drawer
|
// Initialize drawer
|
||||||
menuAdapter.setActiveId(settings.getInt(Key.profileId, -1))
|
menuAdapter.setActiveId(settings.getInt(Key.profileId, -1))
|
||||||
menuAdapter.setListener(this)
|
menuAdapter.setListener(this)
|
||||||
@@ -617,7 +620,7 @@ class Shadowsocks
|
|||||||
which match {
|
which match {
|
||||||
case 0 =>
|
case 0 =>
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
val h = showProgress(getString(R.string.loading))
|
val h = showProgress(R.string.loading)
|
||||||
h.postDelayed(new Runnable() {
|
h.postDelayed(new Runnable() {
|
||||||
def run() {
|
def run() {
|
||||||
val integrator = new IntentIntegrator(Shadowsocks.this)
|
val integrator = new IntentIntegrator(Shadowsocks.this)
|
||||||
@@ -641,7 +644,7 @@ class Shadowsocks
|
|||||||
def reloadProfile() {
|
def reloadProfile() {
|
||||||
drawer.closeMenu(true)
|
drawer.closeMenu(true)
|
||||||
|
|
||||||
val h = showProgress(getString(R.string.loading))
|
val h = showProgress(R.string.loading)
|
||||||
|
|
||||||
handler.postDelayed(new Runnable {
|
handler.postDelayed(new Runnable {
|
||||||
def run() {
|
def run() {
|
||||||
@@ -660,7 +663,7 @@ class Shadowsocks
|
|||||||
def addProfile(profile: Profile) {
|
def addProfile(profile: Profile) {
|
||||||
drawer.closeMenu(true)
|
drawer.closeMenu(true)
|
||||||
|
|
||||||
val h = showProgress(getString(R.string.loading))
|
val h = showProgress(R.string.loading)
|
||||||
|
|
||||||
handler.postDelayed(new Runnable {
|
handler.postDelayed(new Runnable {
|
||||||
def run() {
|
def run() {
|
||||||
@@ -679,7 +682,7 @@ class Shadowsocks
|
|||||||
def addProfile(id: Int) {
|
def addProfile(id: Int) {
|
||||||
drawer.closeMenu(true)
|
drawer.closeMenu(true)
|
||||||
|
|
||||||
val h = showProgress(getString(R.string.loading))
|
val h = showProgress(R.string.loading)
|
||||||
|
|
||||||
handler.postDelayed(new Runnable {
|
handler.postDelayed(new Runnable {
|
||||||
def run() {
|
def run() {
|
||||||
@@ -697,7 +700,7 @@ class Shadowsocks
|
|||||||
def updateProfile(id: Int) {
|
def updateProfile(id: Int) {
|
||||||
drawer.closeMenu(true)
|
drawer.closeMenu(true)
|
||||||
|
|
||||||
val h = showProgress(getString(R.string.loading))
|
val h = showProgress(R.string.loading)
|
||||||
|
|
||||||
handler.postDelayed(new Runnable {
|
handler.postDelayed(new Runnable {
|
||||||
def run() {
|
def run() {
|
||||||
@@ -916,10 +919,7 @@ class Shadowsocks
|
|||||||
Console.runRootCommand(ab.toArray)
|
Console.runRootCommand(ab.toArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
def reset() {
|
def install() {
|
||||||
|
|
||||||
crashRecovery()
|
|
||||||
|
|
||||||
copyAssets(System.getABI)
|
copyAssets(System.getABI)
|
||||||
|
|
||||||
val ab = new ArrayBuffer[String]
|
val ab = new ArrayBuffer[String]
|
||||||
@@ -927,12 +927,18 @@ class Shadowsocks
|
|||||||
ab.append("chmod 755 " + Path.BASE + executable)
|
ab.append("chmod 755 " + Path.BASE + executable)
|
||||||
}
|
}
|
||||||
Console.runCommand(ab.toArray)
|
Console.runCommand(ab.toArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
def reset() {
|
||||||
|
|
||||||
|
crashRecovery()
|
||||||
|
|
||||||
|
install()
|
||||||
}
|
}
|
||||||
|
|
||||||
private def recovery() {
|
private def recovery() {
|
||||||
val h = showProgress(getString(R.string.recovering))
|
|
||||||
serviceStop()
|
serviceStop()
|
||||||
|
val h = showProgress(R.string.recovering)
|
||||||
spawn {
|
spawn {
|
||||||
reset()
|
reset()
|
||||||
h.sendEmptyMessage(0)
|
h.sendEmptyMessage(0)
|
||||||
@@ -965,7 +971,7 @@ class Shadowsocks
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def flushDnsCache() {
|
private def flushDnsCache() {
|
||||||
val h = showProgress(getString(R.string.flushing))
|
val h = showProgress(R.string.flushing)
|
||||||
spawn {
|
spawn {
|
||||||
Utils.toggleAirplaneMode(getBaseContext)
|
Utils.toggleAirplaneMode(getBaseContext)
|
||||||
h.sendEmptyMessage(0)
|
h.sendEmptyMessage(0)
|
||||||
@@ -1083,6 +1089,7 @@ class Shadowsocks
|
|||||||
if (progressDialog != null) {
|
if (progressDialog != null) {
|
||||||
progressDialog.dismiss()
|
progressDialog.dismiss()
|
||||||
progressDialog = null
|
progressDialog = null
|
||||||
|
progressTag = -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1096,14 +1103,19 @@ class Shadowsocks
|
|||||||
if (progressDialog == null) {
|
if (progressDialog == null) {
|
||||||
progressDialog = ProgressDialog
|
progressDialog = ProgressDialog
|
||||||
.show(Shadowsocks.this, "", getString(R.string.connecting), true, true)
|
.show(Shadowsocks.this, "", getString(R.string.connecting), true, true)
|
||||||
|
progressTag = R.string.connecting
|
||||||
}
|
}
|
||||||
setPreferenceEnabled(enabled = false)
|
setPreferenceEnabled(enabled = false)
|
||||||
case State.CONNECTED =>
|
case State.CONNECTED =>
|
||||||
clearDialog()
|
if (progressTag == R.string.connecting) {
|
||||||
|
clearDialog()
|
||||||
|
}
|
||||||
changeSwitch(checked = true)
|
changeSwitch(checked = true)
|
||||||
setPreferenceEnabled(enabled = false)
|
setPreferenceEnabled(enabled = false)
|
||||||
case State.STOPPED =>
|
case State.STOPPED =>
|
||||||
clearDialog()
|
if (progressTag == R.string.stopping || progressTag == R.string.connecting) {
|
||||||
|
clearDialog()
|
||||||
|
}
|
||||||
changeSwitch(checked = false)
|
changeSwitch(checked = false)
|
||||||
if (m != null) {
|
if (m != null) {
|
||||||
new SnackBar.Builder(Shadowsocks.this)
|
new SnackBar.Builder(Shadowsocks.this)
|
||||||
@@ -1118,6 +1130,7 @@ class Shadowsocks
|
|||||||
if (progressDialog == null) {
|
if (progressDialog == null) {
|
||||||
progressDialog = ProgressDialog
|
progressDialog = ProgressDialog
|
||||||
.show(Shadowsocks.this, "", getString(R.string.stopping), true, true)
|
.show(Shadowsocks.this, "", getString(R.string.stopping), true, true)
|
||||||
|
progressTag = R.string.stopping
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,8 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
, "-c" , Path.BASE + "ss-local-nat.conf"
|
, "-c" , Path.BASE + "ss-local-nat.conf"
|
||||||
, "-f" , Path.BASE + "ss-local-nat.pid")
|
, "-f" , Path.BASE + "ss-local-nat.pid")
|
||||||
|
|
||||||
|
if (config.isAuth) cmd += "-A"
|
||||||
|
|
||||||
if (config.route != Route.ALL) {
|
if (config.route != Route.ALL) {
|
||||||
cmd += "--acl"
|
cmd += "--acl"
|
||||||
cmd += (Path.BASE + "acl.list")
|
cmd += (Path.BASE + "acl.list")
|
||||||
@@ -233,6 +235,8 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
|
|
||||||
cmd += ("-l" , "8153")
|
cmd += ("-l" , "8153")
|
||||||
|
|
||||||
|
if (config.isAuth) cmd += "-A"
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
|
|
||||||
Console.runCommand(cmd.mkString(" "))
|
Console.runCommand(cmd.mkString(" "))
|
||||||
@@ -254,6 +258,8 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
, "-c" , Path.BASE + "ss-tunnel-nat.conf"
|
, "-c" , Path.BASE + "ss-tunnel-nat.conf"
|
||||||
, "-f" , Path.BASE + "ss-tunnel-nat.pid")
|
, "-f" , Path.BASE + "ss-tunnel-nat.pid")
|
||||||
|
|
||||||
|
if (config.isAuth) cmdBuf += "-A"
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmdBuf.mkString(" "))
|
if (BuildConfig.DEBUG) Log.d(TAG, cmdBuf.mkString(" "))
|
||||||
Console.runCommand(cmdBuf.mkString(" "))
|
Console.runCommand(cmdBuf.mkString(" "))
|
||||||
}
|
}
|
||||||
@@ -265,10 +271,10 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
val reject = ConfigUtils.getRejectList(getContext, application)
|
val reject = ConfigUtils.getRejectList(getContext, application)
|
||||||
val blackList = ConfigUtils.getBlackList(getContext, application)
|
val blackList = ConfigUtils.getBlackList(getContext, application)
|
||||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
||||||
Path.BASE + "pdnsd-nat.pid", reject, blackList, 8163)
|
Path.BASE + "pdnsd-nat.pid", reject, blackList, 8163, "")
|
||||||
} else {
|
} else {
|
||||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
||||||
Path.BASE + "pdnsd-nat.pid", 8163)
|
Path.BASE + "pdnsd-nat.pid", 8163, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-nat.conf"))(p => {
|
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-nat.conf"))(p => {
|
||||||
|
|||||||
@@ -61,18 +61,17 @@ import scala.concurrent.ops._
|
|||||||
|
|
||||||
class ShadowsocksVpnService extends VpnService with BaseService {
|
class ShadowsocksVpnService extends VpnService with BaseService {
|
||||||
|
|
||||||
|
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
|
||||||
val TAG = "ShadowsocksVpnService"
|
val TAG = "ShadowsocksVpnService"
|
||||||
|
|
||||||
val VPN_MTU = 1500
|
val VPN_MTU = 1500
|
||||||
val PRIVATE_VLAN = "26.26.26.%s"
|
val PRIVATE_VLAN = "26.26.26.%s"
|
||||||
|
val PRIVATE_VLAN6 = "fdfe:dcba:9876::%s"
|
||||||
var conn: ParcelFileDescriptor = null
|
var conn: ParcelFileDescriptor = null
|
||||||
var notificationManager: NotificationManager = null
|
var notificationManager: NotificationManager = null
|
||||||
var receiver: BroadcastReceiver = null
|
var receiver: BroadcastReceiver = null
|
||||||
var apps: Array[ProxiedApp] = null
|
var apps: Array[ProxiedApp] = null
|
||||||
var config: Config = null
|
var config: Config = null
|
||||||
|
var vpnThread: ShadowsocksVpnThread = null
|
||||||
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
|
|
||||||
|
|
||||||
def isByass(net: SubnetUtils): Boolean = {
|
def isByass(net: SubnetUtils): Boolean = {
|
||||||
val info = net.getInfo
|
val info = net.getInfo
|
||||||
@@ -95,81 +94,70 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def startShadowsocksDaemon() {
|
override def onBind(intent: Intent): IBinder = {
|
||||||
|
val action = intent.getAction
|
||||||
if (Utils.isLollipopOrAbove && config.route != Route.ALL) {
|
if (VpnService.SERVICE_INTERFACE == action) {
|
||||||
val acl: Array[String] = config.route match {
|
return super.onBind(intent)
|
||||||
case Route.BYPASS_LAN => getResources.getStringArray(R.array.private_route)
|
} else if (Action.SERVICE == action) {
|
||||||
case Route.BYPASS_CHN => getResources.getStringArray(R.array.chn_route_full)
|
return binder
|
||||||
}
|
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "acl.list"))(p => {
|
|
||||||
acl.foreach(item => p.println(item))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
null
|
||||||
val conf = ConfigUtils
|
|
||||||
.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)
|
|
||||||
})
|
|
||||||
|
|
||||||
val cmd = new ArrayBuffer[String]
|
|
||||||
cmd +=(Path.BASE + "ss-local", "-u"
|
|
||||||
, "-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"
|
|
||||||
cmd += (Path.BASE + "acl.list")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
|
||||||
Console.runCommand(cmd.mkString(" "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def startDnsTunnel() = {
|
override def onCreate() {
|
||||||
val conf = ConfigUtils
|
|
||||||
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, config.proxy, config.remotePort, 8163,
|
super.onCreate()
|
||||||
config.sitekey, config.encMethod, 10)
|
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "ss-tunnel-vpn.conf"))(p => {
|
ConfigUtils.refresh(this)
|
||||||
p.println(conf)
|
|
||||||
})
|
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
|
||||||
val cmd = new ArrayBuffer[String]
|
.asInstanceOf[NotificationManager]
|
||||||
cmd +=(Path.BASE + "ss-tunnel"
|
|
||||||
, "-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(" "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def startDnsDaemon() {
|
override def onRevoke() {
|
||||||
val conf = {
|
stopRunner()
|
||||||
if (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.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
|
|
||||||
Path.BASE + "pdnsd-vpn.pid", 8163)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-vpn.conf"))(p => {
|
|
||||||
p.println(conf)
|
|
||||||
})
|
|
||||||
val cmd = Path.BASE + "pdnsd -c " + Path.BASE + "pdnsd-vpn.conf"
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
override def stopRunner() {
|
||||||
Console.runCommand(cmd)
|
|
||||||
|
if (vpnThread != null) {
|
||||||
|
vpnThread.stopThread()
|
||||||
|
vpnThread = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// channge the state
|
||||||
|
changeState(State.STOPPING)
|
||||||
|
|
||||||
|
// send event
|
||||||
|
application.tracker.send(new HitBuilders.EventBuilder()
|
||||||
|
.setCategory(TAG)
|
||||||
|
.setAction("stop")
|
||||||
|
.setLabel(getVersionName)
|
||||||
|
.build())
|
||||||
|
|
||||||
|
// reset VPN
|
||||||
|
killProcesses()
|
||||||
|
|
||||||
|
// close connections
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close()
|
||||||
|
conn = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop the service if no callback registered
|
||||||
|
if (getCallbackCount == 0) {
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up the context
|
||||||
|
if (receiver != null) {
|
||||||
|
unregisterReceiver(receiver)
|
||||||
|
receiver = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// channge the state
|
||||||
|
changeState(State.STOPPED)
|
||||||
}
|
}
|
||||||
|
|
||||||
def getVersionName: String = {
|
def getVersionName: String = {
|
||||||
@@ -184,195 +172,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
version
|
version
|
||||||
}
|
}
|
||||||
|
|
||||||
def startVpn() {
|
|
||||||
|
|
||||||
val builder = new Builder()
|
|
||||||
builder
|
|
||||||
.setSession(config.profileName)
|
|
||||||
.setMtu(VPN_MTU)
|
|
||||||
.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]
|
|
||||||
for (app <- apps) {
|
|
||||||
if (app.proxied) {
|
|
||||||
pkgSet.add(app.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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)) {
|
|
||||||
builder.addRoute("0.0.0.0", 0)
|
|
||||||
} else {
|
|
||||||
if (!Utils.isLollipopOrAbove) {
|
|
||||||
config.route match {
|
|
||||||
case Route.BYPASS_LAN =>
|
|
||||||
for (i <- 1 to 223) {
|
|
||||||
if (i != 26 && i != 127) {
|
|
||||||
val addr = i.toString + ".0.0.0"
|
|
||||||
val cidr = addr + "/8"
|
|
||||||
val net = new SubnetUtils(cidr)
|
|
||||||
|
|
||||||
if (!isByass(net) && !isPrivateA(i)) {
|
|
||||||
builder.addRoute(addr, 8)
|
|
||||||
} else {
|
|
||||||
for (j <- 0 to 255) {
|
|
||||||
val subAddr = i.toString + "." + j.toString + ".0.0"
|
|
||||||
val subCidr = subAddr + "/16"
|
|
||||||
val subNet = new SubnetUtils(subCidr)
|
|
||||||
if (!isByass(subNet) && !isPrivateB(i, j)) {
|
|
||||||
builder.addRoute(subAddr, 16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Route.BYPASS_CHN =>
|
|
||||||
val list = {
|
|
||||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
|
|
||||||
getResources.getStringArray(R.array.simple_route)
|
|
||||||
} else {
|
|
||||||
getResources.getStringArray(R.array.gfw_route)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list.foreach(cidr => {
|
|
||||||
val net = new SubnetUtils(cidr)
|
|
||||||
if (!isByass(net)) {
|
|
||||||
val addr = cidr.split('/')
|
|
||||||
builder.addRoute(addr(0), addr(1).toInt)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
case Route.ALL =>
|
|
||||||
for (i <- 1 to 223) {
|
|
||||||
if (i != 26 && i != 127) {
|
|
||||||
val addr = i.toString + ".0.0.0"
|
|
||||||
val cidr = addr + "/8"
|
|
||||||
val net = new SubnetUtils(cidr)
|
|
||||||
|
|
||||||
if (!isByass(net)) {
|
|
||||||
builder.addRoute(addr, 8)
|
|
||||||
} else {
|
|
||||||
for (j <- 0 to 255) {
|
|
||||||
val subAddr = i.toString + "." + j.toString + ".0.0"
|
|
||||||
val subCidr = subAddr + "/16"
|
|
||||||
val subNet = new SubnetUtils(subCidr)
|
|
||||||
if (!isByass(subNet)) {
|
|
||||||
builder.addRoute(subAddr, 16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (config.route == Route.ALL) {
|
|
||||||
builder.addRoute("0.0.0.0", 0)
|
|
||||||
} else {
|
|
||||||
val privateList = getResources.getStringArray(R.array.bypass_private_route)
|
|
||||||
privateList.foreach(cidr => {
|
|
||||||
val addr = cidr.split('/')
|
|
||||||
builder.addRoute(addr(0), addr(1).toInt)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.addRoute("8.8.0.0", 16)
|
|
||||||
|
|
||||||
try {
|
|
||||||
conn = builder.establish()
|
|
||||||
} catch {
|
|
||||||
case ex: IllegalStateException =>
|
|
||||||
changeState(State.STOPPED, ex.getMessage)
|
|
||||||
conn = null
|
|
||||||
case ex: Exception => conn = null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn == null) {
|
|
||||||
stopRunner()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val fd = conn.getFd
|
|
||||||
|
|
||||||
var cmd = (Path.BASE +
|
|
||||||
"tun2socks --netif-ipaddr %s "
|
|
||||||
+ "--netif-netmask 255.255.255.0 "
|
|
||||||
+ "--socks-server-addr 127.0.0.1:%d "
|
|
||||||
+ "--tunfd %d "
|
|
||||||
+ "--tunmtu %d "
|
|
||||||
+ "--loglevel 3 "
|
|
||||||
+ "--pid %stun2socks-vpn.pid")
|
|
||||||
.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".formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"))
|
|
||||||
|
|
||||||
if (Utils.isLollipopOrAbove) {
|
|
||||||
cmd += " --fake-proc"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
|
||||||
|
|
||||||
System.exec(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
|
||||||
def handleConnection: Boolean = {
|
|
||||||
startShadowsocksDaemon()
|
|
||||||
if (!config.isUdpDns) {
|
|
||||||
startDnsDaemon()
|
|
||||||
startDnsTunnel()
|
|
||||||
}
|
|
||||||
startVpn()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onBind(intent: Intent): IBinder = {
|
|
||||||
val action = intent.getAction
|
|
||||||
if (VpnService.SERVICE_INTERFACE == action) {
|
|
||||||
return super.onBind(intent)
|
|
||||||
} else if (Action.SERVICE == action) {
|
|
||||||
return binder
|
|
||||||
}
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
|
|
||||||
ConfigUtils.refresh(this)
|
|
||||||
|
|
||||||
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
|
|
||||||
.asInstanceOf[NotificationManager]
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onRevoke() {
|
|
||||||
stopRunner()
|
|
||||||
}
|
|
||||||
|
|
||||||
def killProcesses() {
|
def killProcesses() {
|
||||||
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "tun2socks")) {
|
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "tun2socks")) {
|
||||||
try {
|
try {
|
||||||
@@ -386,6 +185,9 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
|
|
||||||
override def startRunner(c: Config) {
|
override def startRunner(c: Config) {
|
||||||
|
|
||||||
|
vpnThread = new ShadowsocksVpnThread(this)
|
||||||
|
vpnThread.start()
|
||||||
|
|
||||||
config = c
|
config = c
|
||||||
|
|
||||||
// ensure the VPNService is prepared
|
// ensure the VPNService is prepared
|
||||||
@@ -458,40 +260,201 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def stopRunner() {
|
/** Called when the activity is first created. */
|
||||||
|
def handleConnection: Boolean = {
|
||||||
// channge the state
|
startShadowsocksDaemon()
|
||||||
changeState(State.STOPPING)
|
if (!config.isUdpDns) {
|
||||||
|
startDnsDaemon()
|
||||||
// send event
|
startDnsTunnel()
|
||||||
application.tracker.send(new HitBuilders.EventBuilder()
|
|
||||||
.setCategory(TAG)
|
|
||||||
.setAction("stop")
|
|
||||||
.setLabel(getVersionName)
|
|
||||||
.build())
|
|
||||||
|
|
||||||
// reset VPN
|
|
||||||
killProcesses()
|
|
||||||
|
|
||||||
// close connections
|
|
||||||
if (conn != null) {
|
|
||||||
conn.close()
|
|
||||||
conn = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop the service if no callback registered
|
val fd = startVpn()
|
||||||
if (getCallbackCount == 0) {
|
|
||||||
stopSelf()
|
if (fd != -1) {
|
||||||
|
var tries = 1
|
||||||
|
while (tries < 5) {
|
||||||
|
Thread.sleep(1000 * tries)
|
||||||
|
if (System.sendfd(fd) != -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
tries += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
def startShadowsocksDaemon() {
|
||||||
|
|
||||||
|
if (config.route != Route.ALL) {
|
||||||
|
val acl: Array[String] = config.route match {
|
||||||
|
case Route.BYPASS_LAN => getResources.getStringArray(R.array.private_route)
|
||||||
|
case Route.BYPASS_CHN => getResources.getStringArray(R.array.chn_route_full)
|
||||||
|
}
|
||||||
|
ConfigUtils.printToFile(new File(Path.BASE + "acl.list"))(p => {
|
||||||
|
acl.foreach(item => p.println(item))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up the context
|
val conf = ConfigUtils
|
||||||
if (receiver != null) {
|
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, config.proxy, config.remotePort, config.localPort,
|
||||||
unregisterReceiver(receiver)
|
config.sitekey, config.encMethod, 10)
|
||||||
receiver = null
|
ConfigUtils.printToFile(new File(Path.BASE + "ss-local-vpn.conf"))(p => {
|
||||||
|
p.println(conf)
|
||||||
|
})
|
||||||
|
|
||||||
|
val cmd = new ArrayBuffer[String]
|
||||||
|
cmd += (Path.BASE + "ss-local", "-V", "-u"
|
||||||
|
, "-b", "127.0.0.1"
|
||||||
|
, "-t", "600"
|
||||||
|
, "-c", Path.BASE + "ss-local-vpn.conf"
|
||||||
|
, "-f", Path.BASE + "ss-local-vpn.pid")
|
||||||
|
|
||||||
|
if (config.isAuth) cmd += "-A"
|
||||||
|
|
||||||
|
if (config.route != Route.ALL) {
|
||||||
|
cmd += "--acl"
|
||||||
|
cmd += (Path.BASE + "acl.list")
|
||||||
}
|
}
|
||||||
|
|
||||||
// channge the state
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
changeState(State.STOPPED)
|
Console.runCommand(cmd.mkString(" "))
|
||||||
|
}
|
||||||
|
|
||||||
|
def startDnsTunnel() = {
|
||||||
|
val conf = ConfigUtils
|
||||||
|
.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"
|
||||||
|
, "-V"
|
||||||
|
, "-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 (config.isAuth) cmd += "-A"
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
|
Console.runCommand(cmd.mkString(" "))
|
||||||
|
}
|
||||||
|
|
||||||
|
def startDnsDaemon() {
|
||||||
|
val ipv6 = if (config.isIpv6) "" else "reject = ::/0;"
|
||||||
|
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, "0.0.0.0", 8153,
|
||||||
|
Path.BASE + "pdnsd-vpn.pid", reject, blackList, 8163, ipv6)
|
||||||
|
} else {
|
||||||
|
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
|
||||||
|
Path.BASE + "pdnsd-vpn.pid", 8163, ipv6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-vpn.conf"))(p => {
|
||||||
|
p.println(conf)
|
||||||
|
})
|
||||||
|
val cmd = Path.BASE + "pdnsd -c " + Path.BASE + "pdnsd-vpn.conf"
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
||||||
|
Console.runCommand(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getContext = getBaseContext
|
||||||
|
|
||||||
|
def startVpn(): Int = {
|
||||||
|
|
||||||
|
val builder = new Builder()
|
||||||
|
builder
|
||||||
|
.setSession(config.profileName)
|
||||||
|
.setMtu(VPN_MTU)
|
||||||
|
.addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24)
|
||||||
|
.addDnsServer("8.8.8.8")
|
||||||
|
|
||||||
|
if (config.isIpv6) {
|
||||||
|
builder.addAddress(PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "1"), 126)
|
||||||
|
builder.addRoute("::", 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Utils.isLollipopOrAbove) {
|
||||||
|
|
||||||
|
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.packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (pkg <- pkgSet) {
|
||||||
|
if (!config.isBypassApps) {
|
||||||
|
builder.addAllowedApplication(pkg)
|
||||||
|
} else {
|
||||||
|
builder.addDisallowedApplication(pkg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.route == Route.ALL) {
|
||||||
|
builder.addRoute("0.0.0.0", 0)
|
||||||
|
} else {
|
||||||
|
val privateList = getResources.getStringArray(R.array.bypass_private_route)
|
||||||
|
privateList.foreach(cidr => {
|
||||||
|
val addr = cidr.split('/')
|
||||||
|
builder.addRoute(addr(0), addr(1).toInt)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.addRoute("8.8.0.0", 16)
|
||||||
|
|
||||||
|
try {
|
||||||
|
conn = builder.establish()
|
||||||
|
} catch {
|
||||||
|
case ex: IllegalStateException =>
|
||||||
|
changeState(State.STOPPED, ex.getMessage)
|
||||||
|
conn = null
|
||||||
|
case ex: Exception => conn = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn == null) {
|
||||||
|
stopRunner()
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
val fd = conn.getFd
|
||||||
|
|
||||||
|
var cmd = (Path.BASE +
|
||||||
|
"tun2socks --netif-ipaddr %s "
|
||||||
|
+ "--netif-netmask 255.255.255.0 "
|
||||||
|
+ "--socks-server-addr 127.0.0.1:%d "
|
||||||
|
+ "--tunfd %d "
|
||||||
|
+ "--tunmtu %d "
|
||||||
|
+ "--loglevel 3 "
|
||||||
|
+ "--pid %stun2socks-vpn.pid")
|
||||||
|
.formatLocal(Locale.ENGLISH,
|
||||||
|
PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "2"),
|
||||||
|
config.localPort, fd, VPN_MTU, Path.BASE)
|
||||||
|
|
||||||
|
if (config.isIpv6)
|
||||||
|
cmd += " --netif-ip6addr " + PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "2")
|
||||||
|
|
||||||
|
if (config.isUdpDns)
|
||||||
|
cmd += " --enable-udprelay"
|
||||||
|
else
|
||||||
|
cmd += " --dnsgw %s:8153".formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"))
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
||||||
|
|
||||||
|
Console.runCommand(cmd)
|
||||||
|
|
||||||
|
return fd
|
||||||
}
|
}
|
||||||
|
|
||||||
override def stopBackgroundService() {
|
override def stopBackgroundService() {
|
||||||
@@ -501,6 +464,4 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
override def getTag = TAG
|
override def getTag = TAG
|
||||||
|
|
||||||
override def getServiceMode = Mode.VPN
|
override def getServiceMode = Mode.VPN
|
||||||
|
|
||||||
override def getContext = getBaseContext
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Shadowsocks - A shadowsocks client for Android
|
||||||
|
* Copyright (C) 2015 <max.c.lv@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ___====-_ _-====___
|
||||||
|
* _--^^^#####// \\#####^^^--_
|
||||||
|
* _-^##########// ( ) \\##########^-_
|
||||||
|
* -############// |\^^/| \\############-
|
||||||
|
* _/############// (@::@) \\############\_
|
||||||
|
* /#############(( \\// ))#############\
|
||||||
|
* -###############\\ (oo) //###############-
|
||||||
|
* -#################\\ / VV \ //#################-
|
||||||
|
* -###################\\/ \//###################-
|
||||||
|
* _#/|##########/\######( /\ )######/\##########|\#_
|
||||||
|
* |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \|
|
||||||
|
* ` |/ V V ` V \#\| | | |/#/ V ' V V \| '
|
||||||
|
* ` ` ` ` / | | | | \ ' ' ' '
|
||||||
|
* ( | | | | )
|
||||||
|
* __\ | | | | /__
|
||||||
|
* (vvv(VVV)(VVV)vvv)
|
||||||
|
*
|
||||||
|
* HERE BE DRAGONS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.github.shadowsocks
|
||||||
|
|
||||||
|
import java.io.{File, FileDescriptor, IOException}
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
import android.net.{LocalServerSocket, LocalSocket, LocalSocketAddress}
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread {
|
||||||
|
|
||||||
|
val TAG = "ShadowsocksVpnService"
|
||||||
|
val PATH = "/data/data/com.github.shadowsocks/protect_path"
|
||||||
|
|
||||||
|
@volatile var isRunning: Boolean = true
|
||||||
|
@volatile var serverSocket: LocalServerSocket = null
|
||||||
|
|
||||||
|
def closeServerSocket() {
|
||||||
|
if (serverSocket != null) {
|
||||||
|
try {
|
||||||
|
serverSocket.close()
|
||||||
|
} catch {
|
||||||
|
case _: Exception => // ignore
|
||||||
|
}
|
||||||
|
serverSocket = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def stopThread() {
|
||||||
|
isRunning = false
|
||||||
|
closeServerSocket()
|
||||||
|
}
|
||||||
|
|
||||||
|
override def run(): Unit = {
|
||||||
|
|
||||||
|
try {
|
||||||
|
new File(PATH).delete()
|
||||||
|
} catch {
|
||||||
|
case _: Exception => // ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val localSocket = new LocalSocket
|
||||||
|
localSocket.bind(new LocalSocketAddress(PATH, LocalSocketAddress.Namespace.FILESYSTEM))
|
||||||
|
serverSocket = new LocalServerSocket(localSocket.getFileDescriptor)
|
||||||
|
} catch {
|
||||||
|
case e: IOException =>
|
||||||
|
Log.e(TAG, "unable to bind", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val pool = Executors.newFixedThreadPool(4)
|
||||||
|
|
||||||
|
while (isRunning) {
|
||||||
|
try {
|
||||||
|
val socket = serverSocket.accept()
|
||||||
|
|
||||||
|
pool.execute(new Runnable {
|
||||||
|
override def run() {
|
||||||
|
try {
|
||||||
|
val input = socket.getInputStream
|
||||||
|
val output = socket.getOutputStream
|
||||||
|
|
||||||
|
input.read()
|
||||||
|
|
||||||
|
val fds = socket.getAncillaryFileDescriptors
|
||||||
|
|
||||||
|
if (fds.length > 0) {
|
||||||
|
var ret = false
|
||||||
|
|
||||||
|
val getInt = classOf[FileDescriptor].getDeclaredMethod("getInt$")
|
||||||
|
val fd = getInt.invoke(fds(0)).asInstanceOf[Int]
|
||||||
|
ret = vpnService.protect(fd)
|
||||||
|
|
||||||
|
// Trick to close file decriptor
|
||||||
|
System.jniclose(fd)
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
output.write(0)
|
||||||
|
} else {
|
||||||
|
output.write(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
input.close()
|
||||||
|
output.close()
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
case e: Exception =>
|
||||||
|
Log.e(TAG, "Error when protect socket", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// close socket
|
||||||
|
try {
|
||||||
|
socket.close()
|
||||||
|
} catch {
|
||||||
|
case _: Exception => // ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
}})
|
||||||
|
} catch {
|
||||||
|
case e: IOException => {
|
||||||
|
Log.e(TAG, "Error when accept socket", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,7 +51,7 @@ object DBHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DBHelper(val context: Context)
|
class DBHelper(val context: Context)
|
||||||
extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 9) {
|
extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 11) {
|
||||||
|
|
||||||
lazy val profileDao: Dao[Profile, Int] = getDao(classOf[Profile])
|
lazy val profileDao: Dao[Profile, Int] = getDao(classOf[Profile])
|
||||||
|
|
||||||
@@ -62,14 +62,23 @@ class DBHelper(val context: Context)
|
|||||||
def onUpgrade(database: SQLiteDatabase, connectionSource: ConnectionSource, oldVersion: Int,
|
def onUpgrade(database: SQLiteDatabase, connectionSource: ConnectionSource, oldVersion: Int,
|
||||||
newVersion: Int) {
|
newVersion: Int) {
|
||||||
if (oldVersion != newVersion) {
|
if (oldVersion != newVersion) {
|
||||||
if (oldVersion < 8) {
|
if (oldVersion < 7) {
|
||||||
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN udpdns SMALLINT;")
|
|
||||||
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN route VARCHAR;")
|
|
||||||
} else if (oldVersion < 9) {
|
|
||||||
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN route VARCHAR;")
|
|
||||||
} else {
|
|
||||||
profileDao.executeRaw("DROP TABLE IF EXISTS 'profile';")
|
profileDao.executeRaw("DROP TABLE IF EXISTS 'profile';")
|
||||||
onCreate(database, connectionSource)
|
onCreate(database, connectionSource)
|
||||||
|
} else {
|
||||||
|
if (oldVersion < 8) {
|
||||||
|
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN udpdns SMALLINT;")
|
||||||
|
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN route VARCHAR;")
|
||||||
|
}
|
||||||
|
if (oldVersion < 9) {
|
||||||
|
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN route VARCHAR;")
|
||||||
|
}
|
||||||
|
if (oldVersion < 10) {
|
||||||
|
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN auth SMALLINT;")
|
||||||
|
}
|
||||||
|
if (oldVersion < 11) {
|
||||||
|
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN ipv6 SMALLINT;")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ class Profile {
|
|||||||
@DatabaseField
|
@DatabaseField
|
||||||
var udpdns: Boolean = false
|
var udpdns: Boolean = false
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
var auth: Boolean = false
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
var ipv6: Boolean = false
|
||||||
|
|
||||||
@DatabaseField(dataType = DataType.LONG_STRING)
|
@DatabaseField(dataType = DataType.LONG_STRING)
|
||||||
var individual: String = ""
|
var individual: String = ""
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
|
|||||||
edit.putBoolean(Key.isBypassApps, profile.bypass)
|
edit.putBoolean(Key.isBypassApps, profile.bypass)
|
||||||
edit.putBoolean(Key.isTrafficStat, profile.traffic)
|
edit.putBoolean(Key.isTrafficStat, profile.traffic)
|
||||||
edit.putBoolean(Key.isUdpDns, profile.udpdns)
|
edit.putBoolean(Key.isUdpDns, profile.udpdns)
|
||||||
|
edit.putBoolean(Key.isAuth, profile.auth)
|
||||||
|
edit.putBoolean(Key.isIpv6, profile.ipv6)
|
||||||
edit.putString(Key.profileName, profile.name)
|
edit.putString(Key.profileName, profile.name)
|
||||||
edit.putString(Key.proxy, profile.host)
|
edit.putString(Key.proxy, profile.host)
|
||||||
edit.putString(Key.sitekey, profile.password)
|
edit.putString(Key.sitekey, profile.password)
|
||||||
@@ -146,6 +148,8 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
|
|||||||
profile.bypass = settings.getBoolean(Key.isBypassApps, false)
|
profile.bypass = settings.getBoolean(Key.isBypassApps, false)
|
||||||
profile.traffic = settings.getBoolean(Key.isTrafficStat, false)
|
profile.traffic = settings.getBoolean(Key.isTrafficStat, false)
|
||||||
profile.udpdns = settings.getBoolean(Key.isUdpDns, false)
|
profile.udpdns = settings.getBoolean(Key.isUdpDns, false)
|
||||||
|
profile.auth = settings.getBoolean(Key.isAuth, false)
|
||||||
|
profile.ipv6 = settings.getBoolean(Key.isIpv6, false)
|
||||||
profile.name = settings.getString(Key.profileName, "default")
|
profile.name = settings.getString(Key.profileName, "default")
|
||||||
profile.host = settings.getString(Key.proxy, "127.0.0.1")
|
profile.host = settings.getString(Key.proxy, "127.0.0.1")
|
||||||
profile.password = settings.getString(Key.sitekey, "default")
|
profile.password = settings.getString(Key.sitekey, "default")
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ object ConfigUtils {
|
|||||||
| label = "local";
|
| label = "local";
|
||||||
| ip = 127.0.0.1;
|
| ip = 127.0.0.1;
|
||||||
| port = %d;
|
| port = %d;
|
||||||
| reject = ::/0;
|
| %s
|
||||||
| reject_policy = negate;
|
| reject_policy = negate;
|
||||||
| reject_recursively = on;
|
| reject_recursively = on;
|
||||||
| timeout = 5;
|
| timeout = 5;
|
||||||
@@ -159,8 +159,8 @@ object ConfigUtils {
|
|||||||
|
|
|
|
||||||
|server {
|
|server {
|
||||||
| label = "china-servers";
|
| label = "china-servers";
|
||||||
| ip = 223.5.5.5, 114.114.114.114;
|
| ip = 114.114.114.114, 112.124.47.27;
|
||||||
| timeout = 2;
|
| timeout = 4;
|
||||||
| reject = %s;
|
| reject = %s;
|
||||||
| reject_policy = fail;
|
| reject_policy = fail;
|
||||||
| reject_recursively = on;
|
| reject_recursively = on;
|
||||||
@@ -174,7 +174,9 @@ object ConfigUtils {
|
|||||||
| label = "local-server";
|
| label = "local-server";
|
||||||
| ip = 127.0.0.1;
|
| ip = 127.0.0.1;
|
||||||
| port = %d;
|
| port = %d;
|
||||||
| timeout = 3;
|
| %s
|
||||||
|
| reject_policy = negate;
|
||||||
|
| reject_recursively = on;
|
||||||
|}
|
|}
|
||||||
|
|
|
|
||||||
|rr {
|
|rr {
|
||||||
@@ -240,7 +242,7 @@ object ConfigUtils {
|
|||||||
val method = proxy(3).trim
|
val method = proxy(3).trim
|
||||||
|
|
||||||
new Config(config.isGlobalProxy, config.isGFWList, config.isBypassApps, config.isTrafficStat,
|
new Config(config.isGlobalProxy, config.isGFWList, config.isBypassApps, config.isTrafficStat,
|
||||||
config.isUdpDns, config.profileName, host, password, method, config.proxiedAppString, config.route, port,
|
config.isUdpDns, config.isAuth, config.isIpv6, config.profileName, host, password, method, config.proxiedAppString, config.route, port,
|
||||||
config.localPort)
|
config.localPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +252,8 @@ object ConfigUtils {
|
|||||||
val isBypassApps = settings.getBoolean(Key.isBypassApps, false)
|
val isBypassApps = settings.getBoolean(Key.isBypassApps, false)
|
||||||
val isTrafficStat = settings.getBoolean(Key.isTrafficStat, false)
|
val isTrafficStat = settings.getBoolean(Key.isTrafficStat, false)
|
||||||
val isUdpDns = settings.getBoolean(Key.isUdpDns, false)
|
val isUdpDns = settings.getBoolean(Key.isUdpDns, false)
|
||||||
|
val isAuth = settings.getBoolean(Key.isAuth, false)
|
||||||
|
val isIpv6 = settings.getBoolean(Key.isIpv6, false)
|
||||||
|
|
||||||
val profileName = settings.getString(Key.profileName, "default")
|
val profileName = settings.getString(Key.profileName, "default")
|
||||||
val proxy = settings.getString(Key.proxy, "127.0.0.1")
|
val proxy = settings.getString(Key.proxy, "127.0.0.1")
|
||||||
@@ -271,7 +275,7 @@ object ConfigUtils {
|
|||||||
}
|
}
|
||||||
val proxiedAppString = settings.getString(Key.proxied, "")
|
val proxiedAppString = settings.getString(Key.proxied, "")
|
||||||
|
|
||||||
new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, isUdpDns, profileName, proxy,
|
new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, isUdpDns, isAuth, isIpv6, profileName, proxy,
|
||||||
sitekey, encMethod, proxiedAppString, route, remotePort, localPort)
|
sitekey, encMethod, proxiedAppString, route, remotePort, localPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ object Key {
|
|||||||
val isBypassApps = "isBypassApps"
|
val isBypassApps = "isBypassApps"
|
||||||
val isTrafficStat = "isTrafficStat"
|
val isTrafficStat = "isTrafficStat"
|
||||||
val isUdpDns = "isUdpDns"
|
val isUdpDns = "isUdpDns"
|
||||||
|
val isAuth= "isAuth"
|
||||||
|
val isIpv6= "isIpv6"
|
||||||
|
|
||||||
val proxy = "proxy"
|
val proxy = "proxy"
|
||||||
val sitekey = "sitekey"
|
val sitekey = "sitekey"
|
||||||
|
|||||||
Reference in New Issue
Block a user