Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6841848a3 | ||
|
|
52cb15069c | ||
|
|
70ed2189b1 | ||
|
|
aeee9c2fac | ||
|
|
70dc8e9995 | ||
|
|
558a39ec14 | ||
|
|
5f95cccce4 | ||
|
|
55f25d3272 | ||
|
|
93273cbc44 | ||
|
|
c0514ee169 | ||
|
|
06d736b22d |
+3
-3
@@ -11,14 +11,14 @@ before_install:
|
||||
- sudo apt-get install ccache
|
||||
- export NDK_CCACHE=ccache
|
||||
- export ARCH=`uname -m`
|
||||
- wget http://dl.google.com/android/android-sdk_r23-linux.tgz
|
||||
- tar xf android-sdk_r23-linux.tgz
|
||||
- wget http://dl.google.com/android/android-sdk_r23.0.2-linux.tgz
|
||||
- tar xf android-sdk_r23.0.2-linux.tgz
|
||||
- wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2
|
||||
- tar xf android-ndk-r9d-linux-${ARCH}.tar.bz2
|
||||
- export ANDROID_NDK=`pwd`/android-ndk-r9d
|
||||
- export ANDROID_HOME=`pwd`/android-sdk-linux
|
||||
- export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
|
||||
- echo "y" | android update sdk --filter tools,platform-tools,build-tools-20.0.0,android-19,extra-google-m2repository --no-ui --no-https -a
|
||||
- echo "y" | android update sdk --filter tools,platform-tools,build-tools-21.0.1,android-21,extra-google-m2repository --no-ui --no-https -a
|
||||
- echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
|
||||
script:
|
||||
- ./build-ndk.sh
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ rm -rf src/main/assets/armeabi-v7a
|
||||
rm -rf src/main/assets/x86
|
||||
mkdir -p src/main/assets/armeabi-v7a
|
||||
mkdir -p src/main/assets/x86
|
||||
for app in pdnsd redsocks
|
||||
for app in pdnsd redsocks iptables
|
||||
do
|
||||
try mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/
|
||||
try mv libs/x86/$app src/main/assets/x86/
|
||||
|
||||
@@ -4,7 +4,7 @@ import android.Dependencies.{apklib,aar}
|
||||
|
||||
android.Plugin.androidBuild
|
||||
|
||||
platformTarget in Android := "android-19"
|
||||
platformTarget in Android := "android-21"
|
||||
|
||||
name := "shadowsocks"
|
||||
|
||||
|
||||
+7
-7
@@ -335,13 +335,13 @@ openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \
|
||||
include $(openssl_subdirs)
|
||||
|
||||
# Iptables
|
||||
# LOCAL_PATH := $(ROOT_PATH)
|
||||
# iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \
|
||||
# iptables \
|
||||
# extensions \
|
||||
# libiptc \
|
||||
# ))
|
||||
# include $(iptables_subdirs)
|
||||
LOCAL_PATH := $(ROOT_PATH)
|
||||
iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \
|
||||
iptables \
|
||||
extensions \
|
||||
libiptc \
|
||||
))
|
||||
include $(iptables_subdirs)
|
||||
|
||||
# Import cpufeatures
|
||||
$(call import-module,android/cpufeatures)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.github.shadowsocks"
|
||||
android:versionCode="74"
|
||||
android:versionName="2.2.6">
|
||||
android:versionCode="76"
|
||||
android:versionName="2.3.1">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="16"
|
||||
android:targetSdkVersion="19"/>
|
||||
android:targetSdkVersion="21"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -89,8 +89,9 @@ object AppManager {
|
||||
case a => {
|
||||
val uid = a.uid
|
||||
val userName = uid.toString
|
||||
val packageName = a.packageName
|
||||
val proxied = proxiedApps.binarySearch(userName) >= 0
|
||||
new ProxiedApp(uid, userName, proxied)
|
||||
new ProxiedApp(uid, packageName, proxied)
|
||||
}
|
||||
}.toArray
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ object Shadowsocks {
|
||||
val FEATRUE_PREFS = Array(Key.isGFWList, Key.isGlobalProxy, Key.proxyedApps, Key.isTrafficStat,
|
||||
Key.isUdpDns, Key.isAutoConnect)
|
||||
|
||||
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS)
|
||||
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.IPTABLES)
|
||||
|
||||
// Helper functions
|
||||
def updateListPreference(pref: Preference, value: String) {
|
||||
@@ -496,7 +496,7 @@ class Shadowsocks
|
||||
|
||||
// Bind to the service
|
||||
spawn {
|
||||
val isRoot = Console.isRoot
|
||||
val isRoot = Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP && Console.isRoot
|
||||
handler.post(new Runnable {
|
||||
override def run() {
|
||||
status.edit.putBoolean(Key.isRoot, isRoot).commit()
|
||||
@@ -755,7 +755,6 @@ class Shadowsocks
|
||||
}
|
||||
|
||||
private def setPreferenceEnabled(enabled: Boolean) {
|
||||
val isRoot = status.getBoolean(Key.isRoot, false)
|
||||
for (name <- Shadowsocks.PROXY_PREFS) {
|
||||
val pref = findPreference(name)
|
||||
if (pref != null) {
|
||||
@@ -767,7 +766,7 @@ class Shadowsocks
|
||||
if (pref != null) {
|
||||
if (Seq(Key.isGlobalProxy, Key.isTrafficStat, Key.proxyedApps)
|
||||
.contains(name)) {
|
||||
pref.setEnabled(enabled && isRoot)
|
||||
pref.setEnabled(enabled && (!isVpnEnabled || Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP))
|
||||
} else {
|
||||
pref.setEnabled(enabled)
|
||||
}
|
||||
@@ -827,10 +826,6 @@ class Shadowsocks
|
||||
|
||||
copyAssets(System.getABI)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 20) {
|
||||
copyToSystem()
|
||||
}
|
||||
|
||||
val ab = new ArrayBuffer[String]
|
||||
for (executable <- Shadowsocks.EXECUTABLES) {
|
||||
ab.append("chmod 755 " + Path.BASE + executable)
|
||||
@@ -879,8 +874,8 @@ class Shadowsocks
|
||||
|
||||
def isVpnEnabled: Boolean = {
|
||||
if (vpnEnabled < 0) {
|
||||
vpnEnabled = if (Build.VERSION.SDK_INT
|
||||
>= Build.VERSION_CODES.ICE_CREAM_SANDWICH && !status.getBoolean(Key.isRoot, false)) {
|
||||
vpnEnabled = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
|
||||
|| !status.getBoolean(Key.isRoot, false)) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
|
||||
@@ -46,7 +46,6 @@ import java.util.{Timer, TimerTask}
|
||||
import android.app.{Notification, NotificationManager, PendingIntent, Service}
|
||||
import android.content._
|
||||
import android.content.pm.{PackageInfo, PackageManager}
|
||||
import android.graphics.Color
|
||||
import android.net.TrafficStats
|
||||
import android.os._
|
||||
import android.support.v4.app.NotificationCompat
|
||||
@@ -150,22 +149,15 @@ class ShadowsocksNatService extends Service with BaseService {
|
||||
Core.sstunnel(cmd.toArray)
|
||||
} else {
|
||||
val conf = {
|
||||
if (config.isGFWList)
|
||||
ConfigUtils.PDNSD_BYPASS.format("127.0.0.1", getString(R.string.exclude))
|
||||
else
|
||||
ConfigUtils.PDNSD.format("127.0.0.1")
|
||||
ConfigUtils.PDNSD.format("127.0.0.1")
|
||||
}
|
||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
|
||||
p.println(conf)
|
||||
})
|
||||
|
||||
val args = "pdnsd -c " + Path.BASE + "pdnsd.conf"
|
||||
val cmd = Path.BASE + args
|
||||
|
||||
val cmd = if (Build.VERSION.SDK_INT >= 20) {
|
||||
"/system/bin/" + args
|
||||
} else {
|
||||
Path.BASE + args
|
||||
}
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
||||
Console.runRootCommand(cmd)
|
||||
}
|
||||
@@ -190,11 +182,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
||||
ConfigUtils.printToFile(new File(Path.BASE + "redsocks.conf"))(p => {
|
||||
p.println(conf)
|
||||
})
|
||||
val cmd = if (Build.VERSION.SDK_INT >= 20) {
|
||||
"/system/bin/" + args
|
||||
} else {
|
||||
Path.BASE + args
|
||||
}
|
||||
val cmd = Path.BASE + args
|
||||
Console.runRootCommand(cmd)
|
||||
}
|
||||
|
||||
@@ -333,10 +321,6 @@ class ShadowsocksNatService extends Service with BaseService {
|
||||
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid))
|
||||
|
||||
if (config.isGFWList) {
|
||||
// Bypass DNS in China
|
||||
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 114.114.114.114"))
|
||||
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 114.114.115.115"))
|
||||
|
||||
if (!isACLEnabled)
|
||||
{
|
||||
val chn_list: Array[String] = getResources.getStringArray(R.array.chn_list)
|
||||
|
||||
@@ -72,8 +72,8 @@ class ShadowsocksRunnerActivity extends Activity {
|
||||
|
||||
def isVpnEnabled: Boolean = {
|
||||
if (vpnEnabled < 0) {
|
||||
vpnEnabled = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH
|
||||
&& !Console.isRoot) {
|
||||
vpnEnabled = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
|
||||
|| !Console.isRoot) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
|
||||
@@ -55,6 +55,7 @@ import com.google.android.gms.analytics.HitBuilders
|
||||
import org.apache.commons.net.util.SubnetUtils
|
||||
import org.apache.http.conn.util.InetAddressUtils
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.concurrent.ops._
|
||||
|
||||
@@ -74,12 +75,28 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
|
||||
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
|
||||
|
||||
def isACLEnabled: Boolean = {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
def isByass(net: SubnetUtils): Boolean = {
|
||||
val info = net.getInfo
|
||||
info.isInRange(config.proxy) || info.isInRange("114.114.114.114") || info.isInRange("114.114.115.115")
|
||||
info.isInRange(config.proxy)
|
||||
}
|
||||
|
||||
def startShadowsocksDaemon() {
|
||||
|
||||
if (isACLEnabled && config.isGFWList) {
|
||||
val chn_list: Array[String] = getResources.getStringArray(R.array.chn_list_full)
|
||||
ConfigUtils.printToFile(new File(Path.BASE + "chn.acl"))(p => {
|
||||
chn_list.foreach(item => p.println(item))
|
||||
})
|
||||
}
|
||||
|
||||
val cmd = new ArrayBuffer[String]
|
||||
cmd += ("ss-local" , "-u"
|
||||
, "-b" , "127.0.0.1"
|
||||
@@ -88,17 +105,35 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
, "-l" , config.localPort.toString
|
||||
, "-k" , config.sitekey
|
||||
, "-m" , config.encMethod
|
||||
, "-f" , (Path.BASE + "ss-local.pid"))
|
||||
, "-f" , Path.BASE + "ss-local.pid")
|
||||
|
||||
if (config.isGFWList && isACLEnabled) {
|
||||
cmd += "--acl"
|
||||
cmd += (Path.BASE + "chn.acl")
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||
Core.sslocal(cmd.toArray)
|
||||
}
|
||||
|
||||
def startDnsTunnel() = {
|
||||
val cmd = new ArrayBuffer[String]
|
||||
cmd += ("ss-tunnel"
|
||||
, "-b" , "127.0.0.1"
|
||||
, "-l" , "8163"
|
||||
, "-L" , "8.8.8.8:53"
|
||||
, "-s" , config.proxy
|
||||
, "-p" , config.remotePort.toString
|
||||
, "-k" , config.sitekey
|
||||
, "-m" , config.encMethod
|
||||
, "-f" , Path.BASE + "ss-tunnel.pid")
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||
Core.sstunnel(cmd.toArray)
|
||||
}
|
||||
|
||||
def startDnsDaemon() {
|
||||
val conf = {
|
||||
if (config.isGFWList)
|
||||
ConfigUtils.PDNSD_BYPASS.format("0.0.0.0", getString(R.string.exclude))
|
||||
else
|
||||
ConfigUtils.PDNSD.format("0.0.0.0")
|
||||
ConfigUtils.PDNSD_LOCAL.format("0.0.0.0", 8163)
|
||||
}
|
||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
|
||||
p.println(conf)
|
||||
@@ -129,11 +164,36 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
.addAddress(PRIVATE_VLAN.format("1"), 24)
|
||||
.addDnsServer("8.8.8.8")
|
||||
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (!config.isGlobalProxy) {
|
||||
val apps = AppManager.getProxiedApps(this, config.proxiedAppString)
|
||||
val pkgSet: mutable.HashSet[String] = new mutable.HashSet[String]
|
||||
for (app <- apps) {
|
||||
if (app.proxied) {
|
||||
pkgSet.add(app.name)
|
||||
}
|
||||
}
|
||||
for (pkg <- pkgSet) {
|
||||
if (!config.isBypassApps) {
|
||||
builder.addAllowedApplication(pkg)
|
||||
} else {
|
||||
builder.addDisallowedApplication(pkg)
|
||||
}
|
||||
}
|
||||
|
||||
if (config.isBypassApps) {
|
||||
builder.addDisallowedApplication(this.getPackageName)
|
||||
}
|
||||
} else {
|
||||
builder.addDisallowedApplication(this.getPackageName)
|
||||
}
|
||||
}
|
||||
|
||||
if (InetAddressUtils.isIPv6Address(config.proxy)) {
|
||||
builder.addRoute("0.0.0.0", 0)
|
||||
} else if (config.isGFWList) {
|
||||
} else if (!isACLEnabled && config.isGFWList) {
|
||||
val gfwList = {
|
||||
if (Build.VERSION.SDK_INT == 19) {
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
|
||||
getResources.getStringArray(R.array.simple_list)
|
||||
} else {
|
||||
getResources.getStringArray(R.array.gfw_list)
|
||||
@@ -147,24 +207,28 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
for (i <- 1 to 254) {
|
||||
if (i != 26 && i != 127) {
|
||||
val addr = i.toString + ".0.0.0"
|
||||
val cidr = addr + "/8"
|
||||
val net = new SubnetUtils(cidr)
|
||||
if (isACLEnabled) {
|
||||
builder.addRoute("0.0.0.0", 0)
|
||||
} else {
|
||||
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)) {
|
||||
if (!InetAddress.getByName(addr).isSiteLocalAddress) {
|
||||
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)) {
|
||||
if (!InetAddress.getByName(subAddr).isSiteLocalAddress) {
|
||||
builder.addRoute(subAddr, 16)
|
||||
if (!isByass(net)) {
|
||||
if (!InetAddress.getByName(addr).isSiteLocalAddress) {
|
||||
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)) {
|
||||
if (!InetAddress.getByName(subAddr).isSiteLocalAddress) {
|
||||
builder.addRoute(subAddr, 16)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +279,10 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
def handleConnection: Boolean = {
|
||||
startVpn()
|
||||
startShadowsocksDaemon()
|
||||
if (!config.isUdpDns) startDnsDaemon()
|
||||
if (!config.isUdpDns) {
|
||||
startDnsDaemon()
|
||||
startDnsTunnel()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
@@ -243,13 +310,15 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
}
|
||||
|
||||
def killProcesses() {
|
||||
val ab = new ArrayBuffer[String]
|
||||
|
||||
ab.append("kill -9 `cat " + Path.BASE + "ss-local.pid`")
|
||||
ab.append("kill -9 `cat " + Path.BASE + "tun2socks.pid`")
|
||||
ab.append("kill -15 `cat " + Path.BASE + "pdnsd.pid`")
|
||||
|
||||
Console.runCommand(ab.toArray)
|
||||
for (task <- Array("ss-local", "ss-tunnel", "tun2socks", "pdnsd")) {
|
||||
try {
|
||||
val pid = scala.io.Source.fromFile(Path.BASE + task + ".pid").mkString.trim.toInt
|
||||
Process.killProcess(pid)
|
||||
Log.d(TAG, "kill pid: " + pid)
|
||||
} catch {
|
||||
case e: Throwable => Log.e(TAG, "unable to kill " + task, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def startRunner(c: Config) {
|
||||
|
||||
@@ -92,6 +92,38 @@ object ConfigUtils {
|
||||
|}
|
||||
""".stripMargin
|
||||
|
||||
val PDNSD_LOCAL =
|
||||
"""
|
||||
|global {
|
||||
| perm_cache = 2048;
|
||||
| cache_dir = "/data/data/com.github.shadowsocks";
|
||||
| server_ip = %s;
|
||||
| server_port = 8153;
|
||||
| query_method = tcp_only;
|
||||
| run_ipv4 = on;
|
||||
| min_ttl = 15m;
|
||||
| max_ttl = 1w;
|
||||
| timeout = 10;
|
||||
| daemon = on;
|
||||
| pid_file = "/data/data/com.github.shadowsocks/pdnsd.pid";
|
||||
|}
|
||||
|
|
||||
|server {
|
||||
| label = "local";
|
||||
| ip = 127.0.0.1;
|
||||
| port = %d;
|
||||
| timeout = 5;
|
||||
|}
|
||||
|
|
||||
|rr {
|
||||
| name=localhost;
|
||||
| reverse=on;
|
||||
| a=127.0.0.1;
|
||||
| owner=localhost;
|
||||
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||
|}
|
||||
""".stripMargin
|
||||
|
||||
val PDNSD_BYPASS =
|
||||
"""
|
||||
|global {
|
||||
|
||||
Reference in New Issue
Block a user