Commit 9857e427 authored by Max Lv's avatar Max Lv

enable NAT mode on 5.0 again

parent 2f84c74d
...@@ -15,7 +15,7 @@ rm -rf assets/armeabi-v7a ...@@ -15,7 +15,7 @@ rm -rf assets/armeabi-v7a
rm -rf assets/x86 rm -rf assets/x86
mkdir -p assets/armeabi-v7a mkdir -p assets/armeabi-v7a
mkdir -p assets/x86 mkdir -p assets/x86
for app in pdnsd redsocks ss-local ss-tunnel tun2socks for app in iptables pdnsd redsocks ss-local ss-tunnel tun2socks
do do
try mv libs/armeabi-v7a/$app assets/armeabi-v7a/ try mv libs/armeabi-v7a/$app assets/armeabi-v7a/
try mv libs/x86/$app assets/x86/ try mv libs/x86/$app assets/x86/
......
...@@ -300,13 +300,13 @@ openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \ ...@@ -300,13 +300,13 @@ openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \
include $(openssl_subdirs) include $(openssl_subdirs)
# Iptables # Iptables
# LOCAL_PATH := $(ROOT_PATH) LOCAL_PATH := $(ROOT_PATH)
# iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \ iptables_subdirs := $(addprefix $(LOCAL_PATH)/iptables/,$(addsuffix /Android.mk, \
# iptables \ iptables \
# extensions \ extensions \
# libiptc \ libiptc \
# )) ))
# include $(iptables_subdirs) include $(iptables_subdirs)
# Import cpufeatures # Import cpufeatures
$(call import-module,android/cpufeatures) $(call import-module,android/cpufeatures)
...@@ -123,7 +123,7 @@ object Shadowsocks { ...@@ -123,7 +123,7 @@ object Shadowsocks {
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.isAutoConnect)
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL, Executable.TUN2SOCKS) val EXECUTABLES = Array(Executable.IPTABLES, Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL, Executable.TUN2SOCKS)
// Helper functions // Helper functions
def updateListPreference(pref: Preference, value: String) { def updateListPreference(pref: Preference, value: String) {
...@@ -335,21 +335,24 @@ class Shadowsocks ...@@ -335,21 +335,24 @@ class Shadowsocks
Console.runCommand(ab.toArray) Console.runCommand(ab.toArray)
if (!Utils.isLollipopOrAbove) { {
ab.clear() ab.clear()
ab.append("kill -9 `cat /data/data/com.github.shadowsocks/redsocks.pid`") ab.append("kill -9 `cat /data/data/com.github.shadowsocks/redsocks.pid`")
ab.append("rm /data/data/com.github.shadowsocks/redsocks.conf") ab.append("rm /data/data/com.github.shadowsocks/redsocks.conf")
ab.append("rm /data/data/com.github.shadowsocks/redsocks.pid") ab.append("rm /data/data/com.github.shadowsocks/redsocks.pid")
ab.append("kill -9 `cat /data/data/com.github.shadowsocks/ss-tunnel.pid`")
ab.append("rm /data/data/com.github.shadowsocks/ss-tunnel.conf")
ab.append("rm /data/data/com.github.shadowsocks/ss-tunnel.pid")
ab.append("kill -9 `cat /data/data/com.github.shadowsocks/pdnsd.pid`") ab.append("kill -9 `cat /data/data/com.github.shadowsocks/pdnsd.pid`")
ab.append("rm /data/data/com.github.shadowsocks/pdnsd.pid") ab.append("rm /data/data/com.github.shadowsocks/pdnsd.pid")
ab.append("rm /data/data/com.github.shadowsocks/pdnsd.conf") ab.append("rm /data/data/com.github.shadowsocks/pdnsd.conf")
ab.append("rm /data/data/com.github.shadowsocks/pdnsd.cache") ab.append("rm /data/data/com.github.shadowsocks/pdnsd.cache")
ab.append(Utils.getIptables + " -t nat -F OUTPUT")
Console.runRootCommand(ab.toArray) Console.runRootCommand(ab.toArray)
Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT")
} }
} }
...@@ -506,7 +509,7 @@ class Shadowsocks ...@@ -506,7 +509,7 @@ class Shadowsocks
// Bind to the service // Bind to the service
spawn { spawn {
val isRoot = !Utils.isLollipopOrAbove && Console.isRoot val isRoot = Console.isRoot
handler.post(new Runnable { handler.post(new Runnable {
override def run() { override def run() {
status.edit.putBoolean(Key.isRoot, isRoot).commit() status.edit.putBoolean(Key.isRoot, isRoot).commit()
...@@ -776,7 +779,7 @@ class Shadowsocks ...@@ -776,7 +779,7 @@ class Shadowsocks
if (pref != null) { if (pref != null) {
if (Seq(Key.isGlobalProxy, Key.proxyedApps) if (Seq(Key.isGlobalProxy, Key.proxyedApps)
.contains(name)) { .contains(name)) {
pref.setEnabled(enabled && (Utils.isLollipopOrAbove || !isVpnEnabled)) pref.setEnabled(enabled && (!isVpnEnabled))
} else { } else {
pref.setEnabled(enabled) pref.setEnabled(enabled)
} }
......
...@@ -46,8 +46,10 @@ import java.util.{Timer, TimerTask} ...@@ -46,8 +46,10 @@ import java.util.{Timer, TimerTask}
import android.app.{Notification, NotificationManager, PendingIntent, Service} import android.app.{Notification, NotificationManager, PendingIntent, Service}
import android.content._ import android.content._
import android.content.pm.{PackageInfo, PackageManager} import android.content.pm.{PackageInfo, PackageManager}
import android.net.ConnectivityManager
import android.os._ import android.os._
import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationCompat
import android.support.v4.net.ConnectivityManagerCompat
import android.util.Log import android.util.Log
import com.github.shadowsocks.aidl.Config import com.github.shadowsocks.aidl.Config
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
...@@ -71,7 +73,8 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -71,7 +73,8 @@ class ShadowsocksNatService extends Service with BaseService {
private val mStopForegroundSignature = Array[Class[_]](classOf[Boolean]) private val mStopForegroundSignature = Array[Class[_]](classOf[Boolean])
private val mSetForegroundSignature = Array[Class[_]](classOf[Boolean]) private val mSetForegroundSignature = Array[Class[_]](classOf[Boolean])
var receiver: BroadcastReceiver = null var closeReceiver: BroadcastReceiver = null
var conReceiver: BroadcastReceiver = null
var notificationManager: NotificationManager = null var notificationManager: NotificationManager = null
var config: Config = null var config: Config = null
var apps: Array[ProxiedApp] = null var apps: Array[ProxiedApp] = null
...@@ -91,6 +94,34 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -91,6 +94,34 @@ class ShadowsocksNatService extends Service with BaseService {
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication] private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def setDns(dns: String) {
val manager = getSystemService(Context.CONNECTIVITY_SERVICE).asInstanceOf[ConnectivityManager]
val networks = manager.getAllNetworks
val cmdBuf = new ArrayBuffer[String]()
networks.foreach(network => {
val networkInfo = manager.getNetworkInfo(network)
if (networkInfo.isAvailable) {
val netId = network.getClass.getDeclaredField("netId").get(network).asInstanceOf[Int]
cmdBuf.append("ndc resolver setnetdns %d \"\" %s".format(netId, dns))
}
})
Console.runRootCommand(cmdBuf.toArray)
}
def initConnectionReceiver() {
val filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
conReceiver = new BroadcastReceiver {
override def onReceive(context: Context, intent: Intent): Unit = {
setDns("127.0.0.1")
}
}
registerReceiver(conReceiver, filter)
}
def resetDns() = {
setDns("8.8.8.8 208.67.222.222 114.114.114.114")
}
def startShadowsocksDaemon() { def startShadowsocksDaemon() {
if (config.route != Route.ALL) { if (config.route != Route.ALL) {
val acl: Array[String] = config.route match { val acl: Array[String] = config.route match {
...@@ -135,13 +166,24 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -135,13 +166,24 @@ class ShadowsocksNatService extends Service with BaseService {
val cmd = new ArrayBuffer[String] val cmd = new ArrayBuffer[String]
cmd += (Path.BASE + "ss-tunnel" , "-u" cmd += (Path.BASE + "ss-tunnel" , "-u"
, "-b" , "127.0.0.1" , "-b" , "127.0.0.1"
, "-l" , "8153"
, "-L" , "8.8.8.8:53" , "-L" , "8.8.8.8:53"
, "-c" , Path.BASE + "ss-tunnel.json" , "-c" , Path.BASE + "ss-tunnel.json"
, "-f" , Path.BASE + "ss-tunnel.pid") , "-f" , Path.BASE + "ss-tunnel.pid")
if (Utils.isLollipopOrAbove) {
cmd += ("-l" , "53")
} else {
cmd += ("-l" , "8153")
}
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" ")) if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
if (Utils.isLollipopOrAbove) {
Console.runRootCommand(cmd.mkString(" "))
} else {
Console.runCommand(cmd.mkString(" ")) Console.runCommand(cmd.mkString(" "))
}
} else { } else {
val conf = ConfigUtils val conf = ConfigUtils
.SHADOWSOCKS.format(config.proxy, config.remotePort, 8163, .SHADOWSOCKS.format(config.proxy, config.remotePort, 8163,
...@@ -163,17 +205,28 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -163,17 +205,28 @@ class ShadowsocksNatService extends Service with BaseService {
} }
def startDnsDaemon() { def startDnsDaemon() {
val conf = ConfigUtils val conf = if (Utils.isLollipopOrAbove) {
.PDNSD_BYPASS.format("127.0.0.1", getString(R.string.exclude), 8163) ConfigUtils
.PDNSD_BYPASS.format("127.0.0.1", 53, getString(R.string.exclude), 8163)
} else {
ConfigUtils
.PDNSD_BYPASS.format("127.0.0.1", 8153, getString(R.string.exclude), 8163)
}
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => { ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
p.println(conf) p.println(conf)
}) })
val cmd = Path.BASE + "pdnsd -c " + Path.BASE + "pdnsd.conf" val cmd = Path.BASE + "pdnsd -c " + Path.BASE + "pdnsd.conf"
if (BuildConfig.DEBUG) Log.d(TAG, cmd) if (BuildConfig.DEBUG) Log.d(TAG, cmd)
if (Utils.isLollipopOrAbove) {
Console.runRootCommand(cmd)
} else {
Console.runCommand(cmd) Console.runCommand(cmd)
} }
}
def getVersionName: String = { def getVersionName: String = {
var version: String = null var version: String = null
try { try {
...@@ -195,7 +248,7 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -195,7 +248,7 @@ class ShadowsocksNatService extends Service with BaseService {
}) })
if (BuildConfig.DEBUG) Log.d(TAG, cmd) if (BuildConfig.DEBUG) Log.d(TAG, cmd)
Console.runCommand(cmd); Console.runCommand(cmd)
} }
/** Called when the activity is first created. */ /** Called when the activity is first created. */
...@@ -280,15 +333,19 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -280,15 +333,19 @@ class ShadowsocksNatService extends Service with BaseService {
} }
def killProcesses() { def killProcesses() {
val cmd = new ArrayBuffer[String]()
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "redsocks")) { for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "redsocks")) {
try { try {
val pid = scala.io.Source.fromFile(Path.BASE + task + ".pid").mkString.trim.toInt val pid = scala.io.Source.fromFile(Path.BASE + task + ".pid").mkString.trim.toInt
Process.killProcess(pid) Process.killProcess(pid)
cmd.append("kill -9 %d".format(pid))
cmd.append("rm -rf %s%s.pid", Path.BASE, task)
Log.d(TAG, "kill pid: " + pid) Log.d(TAG, "kill pid: " + pid)
} catch { } catch {
case e: Throwable => Log.e(TAG, "unable to kill " + task, e) case e: Throwable => Log.e(TAG, "unable to kill " + task, e)
} }
} }
Console.runRootCommand(cmd.toArray)
Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT") Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT")
} }
...@@ -308,9 +365,13 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -308,9 +365,13 @@ class ShadowsocksNatService extends Service with BaseService {
} }
init_sb.append(cmd_bypass.replace("0.0.0.0", "127.0.0.1")) init_sb.append(cmd_bypass.replace("0.0.0.0", "127.0.0.1"))
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid)) init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid))
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport 53"))
if (!Utils.isLollipopOrAbove) {
init_sb.append(Utils.getIptables init_sb.append(Utils.getIptables
+ " -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:" + DNS_PORT) + " -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:" + DNS_PORT)
}
if (config.isGlobalProxy || config.isBypassApps) { if (config.isGlobalProxy || config.isBypassApps) {
http_sb.append(Utils.getIptables + CMD_IPTABLES_DNAT_ADD_SOCKS) http_sb.append(Utils.getIptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
} }
...@@ -382,13 +443,15 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -382,13 +443,15 @@ class ShadowsocksNatService extends Service with BaseService {
val filter = new IntentFilter() val filter = new IntentFilter()
filter.addAction(Intent.ACTION_SHUTDOWN) filter.addAction(Intent.ACTION_SHUTDOWN)
filter.addAction(Action.CLOSE) filter.addAction(Action.CLOSE)
receiver = new BroadcastReceiver() { closeReceiver = new BroadcastReceiver() {
def onReceive(p1: Context, p2: Intent) { def onReceive(p1: Context, p2: Intent) {
stopRunner() stopRunner()
} }
} }
registerReceiver(receiver, filter) registerReceiver(closeReceiver, filter)
// register connection receiver
if (Utils.isLollipopOrAbove) initConnectionReceiver()
// send event // send event
application.tracker.send(new HitBuilders.EventBuilder() application.tracker.send(new HitBuilders.EventBuilder()
...@@ -468,10 +531,17 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -468,10 +531,17 @@ class ShadowsocksNatService extends Service with BaseService {
stopSelf() stopSelf()
} }
// clean up context // clean up recevier
if (receiver != null) { if (closeReceiver != null) {
unregisterReceiver(receiver) unregisterReceiver(closeReceiver)
receiver = null closeReceiver = null
}
if (Utils.isLollipopOrAbove) {
if (conReceiver != null) {
unregisterReceiver(conReceiver)
conReceiver = null
}
resetDns()
} }
stopForegroundCompat(1) stopForegroundCompat(1)
......
...@@ -72,7 +72,7 @@ class ShadowsocksRunnerActivity extends Activity { ...@@ -72,7 +72,7 @@ class ShadowsocksRunnerActivity extends Activity {
def isVpnEnabled: Boolean = { def isVpnEnabled: Boolean = {
if (vpnEnabled < 0) { if (vpnEnabled < 0) {
vpnEnabled = if (Utils.isLollipopOrAbove || !Console.isRoot) { vpnEnabled = if (!Console.isRoot) {
1 1
} else { } else {
0 0
......
...@@ -151,7 +151,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -151,7 +151,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def startDnsDaemon() { def startDnsDaemon() {
val conf = { val conf = {
if (Utils.isLollipopOrAbove) { if (Utils.isLollipopOrAbove) {
ConfigUtils.PDNSD_BYPASS.format("0.0.0.0", getString(R.string.exclude), 8163) ConfigUtils.PDNSD_BYPASS.format("0.0.0.0", 8153, getString(R.string.exclude), 8163)
} else { } else {
ConfigUtils.PDNSD_LOCAL.format("0.0.0.0", 8163) ConfigUtils.PDNSD_LOCAL.format("0.0.0.0", 8163)
} }
......
...@@ -130,7 +130,7 @@ object ConfigUtils { ...@@ -130,7 +130,7 @@ object ConfigUtils {
| perm_cache = 2048; | perm_cache = 2048;
| cache_dir = "/data/data/com.github.shadowsocks"; | cache_dir = "/data/data/com.github.shadowsocks";
| server_ip = %s; | server_ip = %s;
| server_port = 8153; | server_port = %d;
| query_method = tcp_only; | query_method = tcp_only;
| run_ipv4 = on; | run_ipv4 = on;
| min_ttl = 15m; | min_ttl = 15m;
......
...@@ -45,76 +45,70 @@ import java.util ...@@ -45,76 +45,70 @@ import java.util
object Console { object Console {
private var shell: Shell.Interactive = null private def openShell(): Shell.Interactive = {
private var rootShell: Shell.Interactive = null
private def openShell() {
if (shell == null) {
val builder = new Builder() val builder = new Builder()
shell = builder builder
.useSH() .useSH()
.setWatchdogTimeout(10) .setWatchdogTimeout(10)
.open(new OnCommandResultListener { .open()
override def onCommandResult(commandCode: Int, exitCode: Int,
output: util.List[String]) {
if (exitCode < 0) {
shell.close()
shell = null
}
}
})
}
} }
private def openRootShell() { private def openRootShell(context: String): Shell.Interactive = {
if (rootShell == null) {
val builder = new Builder() val builder = new Builder()
rootShell = builder builder
.setShell(SU.shell(0, "u:r:untrusted_app:s0")) .setShell(SU.shell(0, context))
.setWantSTDERR(true) .setWantSTDERR(true)
.setWatchdogTimeout(10) .setWatchdogTimeout(10)
.open() .open()
} }
}
def runCommand(command: String) { def runCommand(command: String) {
runCommand(Array(command)) runCommand(Array(command))
} }
def runCommand(commands: Array[String]) { def runCommand(commands: Array[String]) {
if (shell == null) { val shell = openShell()
openShell() shell.addCommand(commands, 0, new OnCommandResultListener {
override def onCommandResult(commandCode: Int, exitCode: Int,
output: util.List[String]) {
if (exitCode < 0) {
shell.close()
} }
val ts = shell }
ts.addCommand(commands) })
ts.waitForIdle() shell.waitForIdle()
shell.close()
} }
def runRootCommand(command: String): String = runRootCommand(Array(command)) def runRootCommand(command: String): String = runRootCommand(Array(command))
def runRootCommand(command: String, context: String): String = runRootCommand(Array(command), context)
def runRootCommand(commands: Array[String]): String = runRootCommand(commands, "u:r:init_shell:s0")
def runRootCommand(commands: Array[String]): String = { def runRootCommand(commands: Array[String], context: String): String = {
if (!isRoot) { if (!isRoot) {
return null return null
} }
if (rootShell == null) { val shell = openRootShell(context)
openRootShell()
}
val ts = rootShell
val sb = new StringBuilder val sb = new StringBuilder
ts.addCommand(commands, 0, new OnCommandResultListener { shell.addCommand(commands, 0, new OnCommandResultListener {
override def onCommandResult(commandCode: Int, exitCode: Int, override def onCommandResult(commandCode: Int, exitCode: Int,
output: util.List[String]) { output: util.List[String]) {
if (exitCode < 0) { if (exitCode < 0) {
rootShell.close() shell.close()
rootShell = null
} else { } else {
import scala.collection.JavaConversions._ import scala.collection.JavaConversions._
output.foreach(line => sb.append(line).append('\n')) output.foreach(line => sb.append(line).append('\n'))
} }
} }
}) })
if (ts.waitForIdle()) sb.toString() if (shell.waitForIdle()) {
else null shell.close()
sb.toString()
}
else {
shell.close()
null
}
} }
def isRoot: Boolean = SU.available() def isRoot: Boolean = SU.available()
......
...@@ -68,8 +68,8 @@ object Utils { ...@@ -68,8 +68,8 @@ object Utils {
val DEFAULT_SHELL: String = "/system/bin/sh" val DEFAULT_SHELL: String = "/system/bin/sh"
val DEFAULT_ROOT: String = "/system/bin/su" val DEFAULT_ROOT: String = "/system/bin/su"
val ALTERNATIVE_ROOT: String = "/system/xbin/su" val ALTERNATIVE_ROOT: String = "/system/xbin/su"
val DEFAULT_IPTABLES: String = "/system/bin/iptables" val DEFAULT_IPTABLES: String = "/data/data/com.github.shadowsocks/iptables"
val ALTERNATIVE_IPTABLES: String = "/data/data/com.github.shadowsocks/iptables" val ALTERNATIVE_IPTABLES: String = "/system/bin/iptables"
val TIME_OUT: Int = -99 val TIME_OUT: Int = -99
var initialized: Boolean = false var initialized: Boolean = false
var hasRedirectSupport: Int = -1 var hasRedirectSupport: Int = -1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment