Commit 6678fd95 authored by Mygod's avatar Mygod

Revert "Replace NAT mode with local SOCKS5 mode. #1441"

This reverts commit 7fb19c40.
parent 7fb19c40
...@@ -9,6 +9,14 @@ ...@@ -9,6 +9,14 @@
path = mobile/src/main/jni/libancillary path = mobile/src/main/jni/libancillary
url = https://github.com/shadowsocks/libancillary.git url = https://github.com/shadowsocks/libancillary.git
branch = shadowsocks-android branch = shadowsocks-android
[submodule "mobile/src/main/jni/libevent"]
path = mobile/src/main/jni/libevent
url = https://github.com/shadowsocks/libevent.git
branch = shadowsocks-android
[submodule "mobile/src/main/jni/redsocks"]
path = mobile/src/main/jni/redsocks
url = https://github.com/shadowsocks/redsocks.git
branch = shadowsocks-android
[submodule "mobile/src/main/jni/mbedtls"] [submodule "mobile/src/main/jni/mbedtls"]
path = mobile/src/main/jni/mbedtls path = mobile/src/main/jni/mbedtls
url = https://github.com/ARMmbed/mbedtls url = https://github.com/ARMmbed/mbedtls
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
android:required="false"/> android:required="false"/>
<uses-feature android:name="android.software.leanback" <uses-feature android:name="android.software.leanback"
android:required="false"/> android:required="false"/>
<uses-feature android:name="android.hardware.camera" <uses-feature android:name="android.hardware.camera"
android:required="false"/> android:required="false"/>
<uses-sdk <uses-sdk
...@@ -109,7 +109,7 @@ ...@@ -109,7 +109,7 @@
</activity> </activity>
<service <service
android:name=".ShadowsocksLocalService" android:name=".ShadowsocksNatService"
android:process=":bg" android:process=":bg"
android:exported="false"> android:exported="false">
</service> </service>
......
...@@ -78,6 +78,32 @@ LOCAL_SRC_FILES := $(addprefix libsodium/src/libsodium/,$(SODIUM_SOURCE)) ...@@ -78,6 +78,32 @@ LOCAL_SRC_FILES := $(addprefix libsodium/src/libsodium/,$(SODIUM_SOURCE))
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
########################################################
## libevent
########################################################
include $(CLEAR_VARS)
LIBEVENT_SOURCES := \
buffer.c \
bufferevent.c bufferevent_filter.c \
bufferevent_pair.c bufferevent_ratelim.c \
bufferevent_sock.c epoll.c \
epoll_sub.c evdns.c event.c \
event_tagging.c evmap.c \
evrpc.c evthread.c \
evthread_pthread.c evutil.c \
evutil_rand.c http.c \
listener.c log.c poll.c \
select.c signal.c strlcpy.c
LOCAL_MODULE := event
LOCAL_SRC_FILES := $(addprefix libevent/, $(LIBEVENT_SOURCES))
LOCAL_CFLAGS := -O2 -D_EVENT_HAVE_ARC4RANDOM -I$(LOCAL_PATH)/libevent \
-I$(LOCAL_PATH)/libevent/include \
include $(BUILD_STATIC_LIBRARY)
######################################################## ########################################################
## libancillary ## libancillary
######################################################## ########################################################
...@@ -174,6 +200,28 @@ LOCAL_SRC_FILES := \ ...@@ -174,6 +200,28 @@ LOCAL_SRC_FILES := \
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
########################################################
## redsocks
########################################################
include $(CLEAR_VARS)
REDSOCKS_SOURCES := base.c http-connect.c \
log.c md5.c socks5.c \
base64.c http-auth.c http-relay.c main.c \
parser.c redsocks.c socks4.c utils.c
LOCAL_STATIC_LIBRARIES := libevent
LOCAL_MODULE := redsocks
LOCAL_SRC_FILES := $(addprefix redsocks/, $(REDSOCKS_SOURCES))
LOCAL_CFLAGS := -O2 -std=gnu99 -DUSE_IPTABLES \
-I$(LOCAL_PATH)/redsocks \
-I$(LOCAL_PATH)/libevent/include \
-I$(LOCAL_PATH)/libevent
include $(BUILD_SHARED_EXECUTABLE)
######################################################## ########################################################
## shadowsocks-libev local ## shadowsocks-libev local
######################################################## ########################################################
......
Subproject commit 359ca847a649b9c318f9217c0755484d98ecb779
Subproject commit 274334f14839431ae003774d99c3d1de337afff4
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
<!-- misc --> <!-- misc -->
<string name="profile">Profile</string> <string name="profile">Profile</string>
<string name="profile_summary">Switch to another profile or add new profiles</string> <string name="profile_summary">Switch to another profile or add new profiles</string>
<string name="local">SOCKS5 mode</string> <string name="nat">NAT mode (deprecated)</string>
<string name="local_summary">Enable SOCKS5 proxy mode instead of VPN mode to work with AFWall+ or Orbot</string> <string name="nat_summary">Use NAT mode instead of VPN mode. Requires ROOT permission.</string>
<string name="remote_dns">Remote DNS</string> <string name="remote_dns">Remote DNS</string>
<string name="stat_summary">Sent: \t\t\t\t\t%3$s\t↑\t%1$s/s\nReceived: \t%4$s\t↓\t%2$s/s</string> <string name="stat_summary">Sent: \t\t\t\t\t%3$s\t↑\t%1$s/s\nReceived: \t%4$s\t↓\t%2$s/s</string>
<string name="stat_profiles">%1$s↑\t%2$s↓</string> <string name="stat_profiles">%1$s↑\t%2$s↓</string>
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
<string name="route_entry_gfwlist">GFW List</string> <string name="route_entry_gfwlist">GFW List</string>
<string name="route_entry_chinalist">China List</string> <string name="route_entry_chinalist">China List</string>
<string name="proxied_apps">Per-App Proxy</string> <string name="proxied_apps">Per-App Proxy</string>
<string name="proxied_apps_summary">Set proxy for selected apps</string> <string name="proxied_apps_summary">Set proxy for selected apps, requires NAT mode under Android 4.x</string>
<string name="proxied_apps_summary_v21">Set proxy for selected apps</string> <string name="proxied_apps_summary_v21">Set proxy for selected apps</string>
<string name="on">On</string> <string name="on">On</string>
<string name="bypass_apps">Bypass Mode</string> <string name="bypass_apps">Bypass Mode</string>
...@@ -57,10 +57,12 @@ ...@@ -57,10 +57,12 @@
<!-- notification category --> <!-- notification category -->
<string name="service_vpn">VPN Service</string> <string name="service_vpn">VPN Service</string>
<string name="service_local">SOCKS5 Service</string> <string name="service_nat">NAT Service</string>
<string name="forward_success">Shadowsocks started.</string> <string name="forward_success">Shadowsocks started.</string>
<string name="invalid_server">Invalid server name</string> <string name="invalid_server">Invalid server name</string>
<string name="service_failed">Failed to connect the remote server</string> <string name="service_failed">Failed to connect the remote server</string>
<string name="nat_deprecated">WARNING: NAT mode has been deprecated since Android 5.0</string>
<string name="nat_no_root">NAT mode requires ROOT permission</string>
<string name="switch_to_vpn">Switch to VPN mode</string> <string name="switch_to_vpn">Switch to VPN mode</string>
<string name="stop">Stop</string> <string name="stop">Stop</string>
<string name="stopping">Shutting down…</string> <string name="stopping">Shutting down…</string>
...@@ -122,7 +124,7 @@ ...@@ -122,7 +124,7 @@
<string name="received">Received:</string> <string name="received">Received:</string>
<string name="connecting">Connecting…</string> <string name="connecting">Connecting…</string>
<string name="vpn_connected">Connected, tap to check connection</string> <string name="vpn_connected">Connected, tap to check connection</string>
<string name="local_connected">Connected</string> <string name="nat_connected">Connected</string>
<string name="not_connected">Not connected</string> <string name="not_connected">Not connected</string>
<!-- acl --> <!-- acl -->
......
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
android:summary="@string/tcp_fastopen_summary" android:summary="@string/tcp_fastopen_summary"
android:title="TCP Fast Open"/> android:title="TCP Fast Open"/>
<SwitchPreference android:key="isNAT" <SwitchPreference android:key="isNAT"
android:title="@string/local" android:title="@string/nat"
android:summary="@string/local_summary"/> android:summary="@string/nat_summary"/>
</PreferenceScreen> </PreferenceScreen>
...@@ -117,7 +117,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe ...@@ -117,7 +117,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
if (state == State.CONNECTING) fabProgressCircle.beginFinalAnimation() if (state == State.CONNECTING) fabProgressCircle.beginFinalAnimation()
else fabProgressCircle.postDelayed(hideCircle, 1000) else fabProgressCircle.postDelayed(hideCircle, 1000)
fab.setImageResource(R.drawable.ic_start_connected) fab.setImageResource(R.drawable.ic_start_connected)
statusText.setText(if (app.isLocalEnabled) R.string.local_connected else R.string.vpn_connected) statusText.setText(if (app.isNatEnabled) R.string.nat_connected else R.string.vpn_connected)
case State.STOPPING => case State.STOPPING =>
fab.setImageResource(R.drawable.ic_start_busy) fab.setImageResource(R.drawable.ic_start_busy)
if (state == State.CONNECTED) fabProgressCircle.show() // ignore for stopped if (state == State.CONNECTED) fabProgressCircle.show() // ignore for stopped
...@@ -128,6 +128,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe ...@@ -128,6 +128,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
if (m != null) { if (m != null) {
val snackbar = Snackbar.make(findViewById(R.id.snackbar), val snackbar = Snackbar.make(findViewById(R.id.snackbar),
getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m), Snackbar.LENGTH_LONG) getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m), Snackbar.LENGTH_LONG)
if (m == getString(R.string.nat_no_root)) addDisableNatToSnackbar(snackbar)
snackbar.show() snackbar.show()
Log.e(TAG, "Error to start VPN service: " + m) Log.e(TAG, "Error to start VPN service: " + m)
} }
...@@ -156,9 +157,16 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe ...@@ -156,9 +157,16 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
override def onServiceConnected() { override def onServiceConnected() {
changeState(bgService.getState) changeState(bgService.getState)
if (Build.VERSION.SDK_INT >= 21 && app.isNatEnabled) {
val snackbar = Snackbar.make(findViewById(R.id.snackbar), R.string.nat_deprecated, Snackbar.LENGTH_LONG)
addDisableNatToSnackbar(snackbar)
snackbar.show()
}
} }
override def onServiceDisconnected(): Unit = changeState(State.IDLE) override def onServiceDisconnected(): Unit = changeState(State.IDLE)
private def addDisableNatToSnackbar(snackbar: Snackbar) = snackbar.setAction(R.string.switch_to_vpn, (_ =>
if (state == State.STOPPED) app.dataStore.isNAT = false): View.OnClickListener)
override def binderDied(): Unit = handler.post(() => { override def binderDied(): Unit = handler.post(() => {
detachService() detachService()
...@@ -292,7 +300,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe ...@@ -292,7 +300,7 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
fab = findViewById(R.id.fab).asInstanceOf[FloatingActionButton] fab = findViewById(R.id.fab).asInstanceOf[FloatingActionButton]
fabProgressCircle = findViewById(R.id.fabProgressCircle).asInstanceOf[FABProgressCircle] fabProgressCircle = findViewById(R.id.fabProgressCircle).asInstanceOf[FABProgressCircle]
fab.setOnClickListener(_ => if (state == State.CONNECTED) Utils.stopSsService(this) else Utils.ThrowableFuture { fab.setOnClickListener(_ => if (state == State.CONNECTED) Utils.stopSsService(this) else Utils.ThrowableFuture {
if (app.isLocalEnabled) Utils.startSsService(this) else { if (app.isNatEnabled) Utils.startSsService(this) else {
val intent = VpnService.prepare(this) val intent = VpnService.prepare(this)
if (intent != null) startActivityForResult(intent, REQUEST_CONNECT) if (intent != null) startActivityForResult(intent, REQUEST_CONNECT)
else handler.post(() => onActivityResult(REQUEST_CONNECT, Activity.RESULT_OK, null)) else handler.post(() => onActivityResult(REQUEST_CONNECT, Activity.RESULT_OK, null))
......
...@@ -66,7 +66,7 @@ class ProfileConfigFragment extends PreferenceFragment with OnMenuItemClickListe ...@@ -66,7 +66,7 @@ class ProfileConfigFragment extends PreferenceFragment with OnMenuItemClickListe
findPreference(Key.password).setSummary("\u2022" * 32) findPreference(Key.password).setSummary("\u2022" * 32)
} }
isProxyApps = findPreference(Key.proxyApps).asInstanceOf[SwitchPreference] isProxyApps = findPreference(Key.proxyApps).asInstanceOf[SwitchPreference]
isProxyApps.setEnabled(Utils.isLollipopOrAbove || app.isLocalEnabled) isProxyApps.setEnabled(Utils.isLollipopOrAbove || app.isNatEnabled)
isProxyApps.setOnPreferenceClickListener(_ => { isProxyApps.setOnPreferenceClickListener(_ => {
startActivity(new Intent(getActivity, classOf[AppManager])) startActivity(new Intent(getActivity, classOf[AppManager]))
isProxyApps.setChecked(true) isProxyApps.setChecked(true)
......
...@@ -85,7 +85,7 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient { ...@@ -85,7 +85,7 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient {
protected def attachService(callback: IShadowsocksServiceCallback.Stub = null) { protected def attachService(callback: IShadowsocksServiceCallback.Stub = null) {
this.callback = callback this.callback = callback
if (bgService == null) { if (bgService == null) {
val s = if (app.isLocalEnabled) classOf[ShadowsocksLocalService] else classOf[ShadowsocksVpnService] val s = if (app.isNatEnabled) classOf[ShadowsocksNatService] else classOf[ShadowsocksVpnService]
val intent = new Intent(this, s) val intent = new Intent(this, s)
intent.setAction(Action.SERVICE) intent.setAction(Action.SERVICE)
......
...@@ -66,8 +66,8 @@ class ShadowsocksApplication extends Application { ...@@ -66,8 +66,8 @@ class ShadowsocksApplication extends Application {
lazy val profileManager = new ProfileManager(dbHelper) lazy val profileManager = new ProfileManager(dbHelper)
lazy val dataStore = new OrmLitePreferenceDataStore(dbHelper) lazy val dataStore = new OrmLitePreferenceDataStore(dbHelper)
def isLocalEnabled: Boolean = dataStore.isNAT def isNatEnabled: Boolean = dataStore.isNAT
def isVpnEnabled: Boolean = !isLocalEnabled def isVpnEnabled: Boolean = !isNatEnabled
// send event // send event
def track(category: String, action: String): Unit = tracker.send(new HitBuilders.EventBuilder() def track(category: String, action: String): Unit = tracker.send(new HitBuilders.EventBuilder()
...@@ -156,7 +156,7 @@ class ShadowsocksApplication extends Application { ...@@ -156,7 +156,7 @@ class ShadowsocksApplication extends Application {
if (Build.VERSION.SDK_INT >= 26) getSystemService(classOf[NotificationManager]).createNotificationChannels(List( if (Build.VERSION.SDK_INT >= 26) getSystemService(classOf[NotificationManager]).createNotificationChannels(List(
new NotificationChannel("service-vpn", getText(R.string.service_vpn), NotificationManager.IMPORTANCE_MIN), new NotificationChannel("service-vpn", getText(R.string.service_vpn), NotificationManager.IMPORTANCE_MIN),
new NotificationChannel("service-local", getText(R.string.service_local), NotificationManager.IMPORTANCE_LOW) new NotificationChannel("service-nat", getText(R.string.service_nat), NotificationManager.IMPORTANCE_LOW)
)) ))
} }
...@@ -165,9 +165,15 @@ class ShadowsocksApplication extends Application { ...@@ -165,9 +165,15 @@ class ShadowsocksApplication extends Application {
for (task <- Executable.EXECUTABLES) { for (task <- Executable.EXECUTABLES) {
cmd.append("killall lib%s.so".formatLocal(Locale.ENGLISH, task)) cmd.append("killall lib%s.so".formatLocal(Locale.ENGLISH, task))
cmd.append("rm -f %1$s/%2$s-local.conf %1$s/%2$s-vpn.conf" cmd.append("rm -f %1$s/%2$s-nat.conf %1$s/%2$s-vpn.conf"
.formatLocal(Locale.ENGLISH, getFilesDir.getAbsolutePath, task)) .formatLocal(Locale.ENGLISH, getFilesDir.getAbsolutePath, task))
} }
if (app.isNatEnabled) {
cmd.append("iptables -t nat -F OUTPUT")
cmd.append("echo done")
val result = Shell.SU.run(cmd.toArray)
if (result != null && !result.isEmpty) return // fallback to SH
}
Shell.SH.run(cmd.toArray) Shell.SH.run(cmd.toArray)
} }
......
...@@ -32,22 +32,32 @@ import com.github.shadowsocks.ShadowsocksApplication.app ...@@ -32,22 +32,32 @@ import com.github.shadowsocks.ShadowsocksApplication.app
import com.github.shadowsocks.acl.{Acl, AclSyncJob} import com.github.shadowsocks.acl.{Acl, AclSyncJob}
import com.github.shadowsocks.database.Profile import com.github.shadowsocks.database.Profile
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
import eu.chainfire.libsuperuser.Shell
import scala.collection.JavaConversions._ import scala.collection.JavaConversions._
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
class ShadowsocksLocalService extends BaseService { class ShadowsocksNatService extends BaseService {
val TAG = "ShadowsocksLocalService" val TAG = "ShadowsocksNatService"
val CMD_IPTABLES_DNAT_ADD_SOCKS =
"iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination 127.0.0.1:8123"
val myUid: Int = android.os.Process.myUid()
var sslocalProcess: GuardedProcess = _ var sslocalProcess: GuardedProcess = _
var sstunnelProcess: GuardedProcess = _
var redsocksProcess: GuardedProcess = _
var overtureProcess: GuardedProcess = _
var su: Shell.Interactive = _
def startShadowsocksDaemon() { def startShadowsocksDaemon() {
val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so", val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so",
"-b", "127.0.0.1", "-b", "127.0.0.1",
"-l", profile.localPort.toString, "-l", profile.localPort.toString,
"-t", "600", "-t", "600",
"-c", buildShadowsocksConfig("ss-local-local.conf")) "-c", buildShadowsocksConfig("ss-local-nat.conf"))
if (TcpFastOpen.sendEnabled) cmd += "--fast-open" if (TcpFastOpen.sendEnabled) cmd += "--fast-open"
...@@ -62,11 +72,45 @@ class ShadowsocksLocalService extends BaseService { ...@@ -62,11 +72,45 @@ class ShadowsocksLocalService extends BaseService {
sslocalProcess = new GuardedProcess(cmd: _*).start() sslocalProcess = new GuardedProcess(cmd: _*).start()
} }
def startDNSTunnel() {
val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-tunnel.so",
"-t", "10",
"-b", "127.0.0.1",
"-l", (profile.localPort + 63).toString,
"-L", profile.remoteDns.split(",").head.trim + ":53",
"-c", buildShadowsocksConfig("ss-tunnel-nat.conf"))
if (profile.udpdns) cmd.append("-u")
sstunnelProcess = new GuardedProcess(cmd: _*).start()
}
def startDnsDaemon() {
overtureProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/liboverture.so",
"-c", buildOvertureConfig("overture-nat.conf"))
.start()
}
def startRedsocksDaemon() {
IOUtils.writeString(new File(getFilesDir, "redsocks-nat.conf"),
ConfigUtils.REDSOCKS.formatLocal(Locale.ENGLISH, profile.localPort))
redsocksProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/libredsocks.so",
"-c", "redsocks-nat.conf").start()
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
def handleConnection() { def handleConnection() {
startRedsocksDaemon()
startShadowsocksDaemon() startShadowsocksDaemon()
if (!profile.udpdns)
startDnsDaemon()
else
startDNSTunnel()
setupIptables()
} }
def onBind(intent: Intent): IBinder = { def onBind(intent: Intent): IBinder = {
...@@ -83,8 +127,71 @@ class ShadowsocksLocalService extends BaseService { ...@@ -83,8 +127,71 @@ class ShadowsocksLocalService extends BaseService {
sslocalProcess.destroy() sslocalProcess.destroy()
sslocalProcess = null sslocalProcess = null
} }
if (sstunnelProcess != null) {
sstunnelProcess.destroy()
sstunnelProcess = null
}
if (redsocksProcess != null) {
redsocksProcess.destroy()
redsocksProcess = null
}
if (overtureProcess != null) {
overtureProcess.destroy()
overtureProcess = null
}
su.addCommand("iptables -t nat -F OUTPUT")
}
def setupIptables() {
val init_sb = new ArrayBuffer[String]
val http_sb = new ArrayBuffer[String]
init_sb.append("ulimit -n 4096")
init_sb.append("iptables -t nat -F OUTPUT")
val cmd_bypass = "iptables -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN"
if (!InetAddress.getByName(profile.host.toUpperCase).isInstanceOf[Inet6Address]) {
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d " + profile.host))
}
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 127.0.0.1"))
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-m owner --uid-owner " + myUid))
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport 53"))
init_sb.append("iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:"
+ (profile.localPort + 53))
if (!profile.proxyApps || profile.bypass) {
http_sb.append(CMD_IPTABLES_DNAT_ADD_SOCKS)
}
if (profile.proxyApps) {
val uidMap = getPackageManager.getInstalledApplications(0).map(ai => ai.packageName -> ai.uid).toMap
for (pn <- profile.individual.split('\n')) uidMap.get(pn) match {
case Some(uid) =>
if (!profile.bypass) {
http_sb.append(CMD_IPTABLES_DNAT_ADD_SOCKS
.replace("-t nat", "-t nat -m owner --uid-owner " + uid))
} else {
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + uid))
}
case _ => // probably removed package, ignore
}
}
su.addCommand((init_sb ++ http_sb).toArray)
} }
override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = if (su == null) {
su = new Shell.Builder().useSU().setWantSTDERR(true).setWatchdogTimeout(10).open((_, exitCode, _) =>
if (exitCode == 0) super.onStartCommand(intent, flags, startId) else {
if (su != null) {
su.close()
su = null
}
super.stopRunner(stopService = true, getString(R.string.nat_no_root))
})
Service.START_NOT_STICKY
} else super.onStartCommand(intent, flags, startId)
override def connect() { override def connect() {
super.connect() super.connect()
...@@ -104,7 +211,7 @@ class ShadowsocksLocalService extends BaseService { ...@@ -104,7 +211,7 @@ class ShadowsocksLocalService extends BaseService {
changeState(State.CONNECTED) changeState(State.CONNECTED)
} }
override def createNotification() = new ShadowsocksNotification(this, profile.name, "service-local", true) override def createNotification() = new ShadowsocksNotification(this, profile.name, "service-nat", true)
override def stopRunner(stopService: Boolean, msg: String = null) { override def stopRunner(stopService: Boolean, msg: String = null) {
...@@ -116,6 +223,9 @@ class ShadowsocksLocalService extends BaseService { ...@@ -116,6 +223,9 @@ class ShadowsocksLocalService extends BaseService {
// reset NAT // reset NAT
killProcesses() killProcesses()
su.close()
su = null
super.stopRunner(stopService, msg) super.stopRunner(stopService, msg)
} }
} }
...@@ -46,7 +46,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext { ...@@ -46,7 +46,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
} }
def startBackgroundService() { def startBackgroundService() {
if (app.isLocalEnabled) { if (app.isNatEnabled) {
Utils.startSsService(this) Utils.startSsService(this)
finish() finish()
} else { } else {
......
...@@ -33,7 +33,7 @@ import android.view.View.MeasureSpec ...@@ -33,7 +33,7 @@ import android.view.View.MeasureSpec
import android.view.{Gravity, View, Window} import android.view.{Gravity, View, Window}
import android.widget.Toast import android.widget.Toast
import com.github.shadowsocks.ShadowsocksApplication.app import com.github.shadowsocks.ShadowsocksApplication.app
import com.github.shadowsocks.{BuildConfig, ShadowsocksLocalService, ShadowsocksVpnService} import com.github.shadowsocks.{BuildConfig, ShadowsocksNatService, ShadowsocksVpnService}
import org.xbill.DNS._ import org.xbill.DNS._
import scala.collection.JavaConversions._ import scala.collection.JavaConversions._
...@@ -138,7 +138,7 @@ object Utils { ...@@ -138,7 +138,7 @@ object Utils {
def startSsService(context: Context) { def startSsService(context: Context) {
val intent = val intent =
new Intent(context, if (app.dataStore.isNAT) classOf[ShadowsocksLocalService] else classOf[ShadowsocksVpnService]) new Intent(context, if (app.dataStore.isNAT) classOf[ShadowsocksNatService] else classOf[ShadowsocksVpnService])
if (Build.VERSION.SDK_INT >= 26) context.startForegroundService(intent) else context.startService(intent) if (Build.VERSION.SDK_INT >= 26) context.startForegroundService(intent) else context.startService(intent)
} }
def reloadSsService(context: Context): Unit = context.sendBroadcast(new Intent(Action.RELOAD)) def reloadSsService(context: Context): Unit = context.sendBroadcast(new Intent(Action.RELOAD))
......
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