From 2e3baa727d6ecdba0f50ad755b9ee601c0e006b9 Mon Sep 17 00:00:00 2001 From: Mygod Date: Fri, 20 Jan 2017 17:33:10 +0800 Subject: [PATCH] Move config files to files directory It looks nicer. Other changes btw: * Removes duplicated logcats from GuardedProcess; * local_port is moved to command line options since that's not sensitive; * pdnsd uses cache dir; * Refinements to Utils. --- mobile/src/main/jni/shadowsocks-libev | 2 +- .../com/github/shadowsocks/BaseService.scala | 8 +-- .../github/shadowsocks/GuardedProcess.scala | 12 ++-- .../shadowsocks/ShadowsocksApplication.scala | 6 +- .../shadowsocks/ShadowsocksNatService.scala | 65 +++++++------------ .../shadowsocks/ShadowsocksVpnService.scala | 65 ++++++++----------- .../shadowsocks/ShadowsocksVpnThread.scala | 10 +-- .../com/github/shadowsocks/acl/Acl.scala | 8 +-- .../github/shadowsocks/acl/AclSyncJob.scala | 6 +- .../github/shadowsocks/utils/IOUtils.scala | 2 + .../shadowsocks/utils/TcpFastOpen.scala | 3 +- .../utils/TrafficMonitorThread.scala | 6 +- .../com/github/shadowsocks/utils/Utils.scala | 42 +++--------- 13 files changed, 93 insertions(+), 142 deletions(-) diff --git a/mobile/src/main/jni/shadowsocks-libev b/mobile/src/main/jni/shadowsocks-libev index 19e222ba..4c3c0ce9 160000 --- a/mobile/src/main/jni/shadowsocks-libev +++ b/mobile/src/main/jni/shadowsocks-libev @@ -1 +1 @@ -Subproject commit 19e222bad8416f20b7694bff75f2cee72a70701e +Subproject commit 4c3c0ce9c33825949e289aa36f217d2de5af48c6 diff --git a/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala b/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala index 709ede02..8dfca684 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala @@ -20,7 +20,7 @@ package com.github.shadowsocks -import java.io.IOException +import java.io.{File, IOException} import java.net.InetAddress import java.util import java.util.concurrent.TimeUnit @@ -63,7 +63,6 @@ trait BaseService extends Service { private final val bandwidthListeners = new mutable.HashSet[IBinder]() // the binder is the real identifier lazy val handler = new Handler(getMainLooper) lazy val restartHanlder = new Handler(getMainLooper) - lazy val protectPath: String = getApplicationInfo.dataDir + "/protect_path" private val closeReceiver: BroadcastReceiver = (context: Context, _: Intent) => { Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show() @@ -320,18 +319,17 @@ trait BaseService extends Service { if (TcpFastOpen.sendEnabled) result += "--fast-open" result } - protected def buildShadowsocksConfig(file: String, localPortOffset: Int = 0): String = { + protected final def buildShadowsocksConfig(file: String): String = { val config = new JSONObject() .put("server", profile.host) .put("server_port", profile.remotePort) - .put("local_port", profile.localPort + localPortOffset) .put("password", profile.password) .put("method", profile.method) if (profile.auth) config.put("auth", true) if (pluginPath != null) config .put("plugin", Commandline.toString(buildPluginCommandLine())) .put("plugin_opts", plugin.toString) - IOUtils.writeString(file, config.toString) + IOUtils.writeString(new File(getFilesDir, file), config.toString) file } } diff --git a/mobile/src/main/scala/com/github/shadowsocks/GuardedProcess.scala b/mobile/src/main/scala/com/github/shadowsocks/GuardedProcess.scala index ca117acb..b995c8a7 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/GuardedProcess.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/GuardedProcess.scala @@ -27,6 +27,7 @@ import java.util.concurrent.Semaphore import android.util.Log import com.github.shadowsocks.utils.CloseUtils._ import com.github.shadowsocks.utils.Commandline +import com.github.shadowsocks.ShadowsocksApplication.app import scala.collection.JavaConversions._ import scala.collection.immutable.Stream @@ -41,7 +42,7 @@ class StreamLogger(is: InputStream, tag: String) extends Thread { /** * @author ayanamist@gmail.com */ -class GuardedProcess(cmd: Seq[String]) { +class GuardedProcess(cmd: String*) { private val TAG = classOf[GuardedProcess].getSimpleName @volatile private var guardThread: Thread = _ @@ -58,10 +59,13 @@ class GuardedProcess(cmd: Seq[String]) { try { var callback: () => Unit = null while (!isDestroyed) { - Log.i(TAG, "start process: " + Commandline.toString(cmd)) + if (BuildConfig.DEBUG) Log.d(TAG, "start process: " + Commandline.toString(cmd)) val startTime = currentTimeMillis - process = new ProcessBuilder(cmd).redirectErrorStream(true).start + process = new ProcessBuilder(cmd) + .redirectErrorStream(true) + .directory(app.getFilesDir) + .start() val is = process.getInputStream new StreamLogger(is, TAG).start() @@ -84,7 +88,7 @@ class GuardedProcess(cmd: Seq[String]) { } } catch { case _: InterruptedException => - Log.i(TAG, "thread interrupt, destroy process: " + Commandline.toString(cmd)) + if (BuildConfig.DEBUG) Log.d(TAG, "thread interrupt, destroy process: " + Commandline.toString(cmd)) process.destroy() case e: IOException => ioException = e } finally semaphore.release() diff --git a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala index f0d795cc..5d79a7c6 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala @@ -20,7 +20,7 @@ package com.github.shadowsocks -import java.io.{FileOutputStream, IOException} +import java.io.{File, FileOutputStream, IOException} import java.util import java.util.Locale import java.util.concurrent.TimeUnit @@ -184,7 +184,7 @@ class ShadowsocksApplication extends Application { for (task <- Executable.EXECUTABLES) { cmd.append("killall lib%s.so".formatLocal(Locale.ENGLISH, task)) cmd.append("rm -f %1$s/%2$s-nat.conf %1$s/%2$s-vpn.conf" - .formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir, task)) + .formatLocal(Locale.ENGLISH, getFilesDir.getAbsolutePath, task)) } if (app.isNatEnabled) { cmd.append("iptables -t nat -F OUTPUT") @@ -204,7 +204,7 @@ class ShadowsocksApplication extends Application { app.track(e) } if (files != null) for (file <- files) autoClose(assetManager.open("acl/" + file))(in => - autoClose(new FileOutputStream(getApplicationInfo.dataDir + '/' + file))(out => + autoClose(new FileOutputStream(new File(getFilesDir, file)))(out => IOUtils.copy(in, out))) editor.putInt(Key.currentVersionCode, BuildConfig.VERSION_CODE).apply() } diff --git a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 754c7a28..07279289 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -53,76 +53,59 @@ class ShadowsocksNatService extends BaseService { var su: Shell.Interactive = _ def startShadowsocksDaemon() { - val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so" - , "-b" , "127.0.0.1" - , "-t" , "600" - , "-P", getApplicationInfo.dataDir - , "-c" , buildShadowsocksConfig(getApplicationInfo.dataDir + "/ss-local-nat.conf")) + val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so", + "-b", "127.0.0.1", + "-l", profile.localPort.toString, + "-t", "600", + "-c", buildShadowsocksConfig("ss-local-nat.conf")) if (TcpFastOpen.sendEnabled) cmd += "--fast-open" if (profile.route != Acl.ALL) { cmd += "--acl" - cmd += Acl.getPath(profile.route) + cmd += Acl.getFile(profile.route).getAbsolutePath } - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - 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 + 53).toString - , "-L" , if (profile.remoteDns == null) "8.8.8.8:53" else profile.remoteDns + ":53" - , "-P", getApplicationInfo.dataDir - , "-c" , buildShadowsocksConfig(getApplicationInfo.dataDir + "/ss-tunnel-nat.conf", 63)) + val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-tunnel.so", + "-t", "10", + "-b", "127.0.0.1", + "-l", (profile.localPort + 63).toString, + "-L", if (profile.remoteDns == null) "8.8.8.8:53" else profile.remoteDns + ":53", + "-c", buildShadowsocksConfig("ss-tunnel-nat.conf")) if (profile.udpdns) cmd.append("-u") - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - - sstunnelProcess = new GuardedProcess(cmd).start() + sstunnelProcess = new GuardedProcess(cmd: _*).start() } def startDnsDaemon() { - val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0" - - val conf = profile.route match { + IOUtils.writeString(new File(getFilesDir, "pdnsd-nat.conf"), profile.route match { case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES => - ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getApplicationInfo.dataDir, + ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getCacheDir.getAbsolutePath, "127.0.0.1", profile.localPort + 53, "114.114.114.114, 223.5.5.5, 1.2.4.8", getBlackList, reject, profile.localPort + 63, reject) case Acl.CHINALIST => - ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getApplicationInfo.dataDir, + ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getCacheDir.getAbsolutePath, "127.0.0.1", profile.localPort + 53, "8.8.8.8, 8.8.4.4, 208.67.222.222", "", reject, profile.localPort + 63, reject) case _ => - ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "", getApplicationInfo.dataDir, + ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "", getCacheDir.getAbsolutePath, "127.0.0.1", profile.localPort + 53, profile.localPort + 63, reject) - } - - Utils.printToFile(new File(getApplicationInfo.dataDir + "/pdnsd-nat.conf"))(p => { - p.println(conf) }) - val cmd = Array(getApplicationInfo.nativeLibraryDir + "/libpdnsd.so", "-c", getApplicationInfo.dataDir + "/pdnsd-nat.conf") - - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - - pdnsdProcess = new GuardedProcess(cmd).start() + pdnsdProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/libpdnsd.so", "-c", "pdnsd-nat.conf") + .start() } def startRedsocksDaemon() { - val conf = ConfigUtils.REDSOCKS.formatLocal(Locale.ENGLISH, profile.localPort) - val cmd = Array(getApplicationInfo.nativeLibraryDir + "/libredsocks.so", "-c", getApplicationInfo.dataDir + "/redsocks-nat.conf") - Utils.printToFile(new File(getApplicationInfo.dataDir + "/redsocks-nat.conf"))(p => { - p.println(conf) - }) - - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - redsocksProcess = new GuardedProcess(cmd).start() + 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. */ diff --git a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index bf569cbe..e00458fc 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -34,7 +34,6 @@ import com.github.shadowsocks.acl.{Acl, AclSyncJob} import com.github.shadowsocks.database.Profile import com.github.shadowsocks.utils._ -import scala.collection.JavaConversions._ import scala.collection.mutable.ArrayBuffer class ShadowsocksVpnService extends VpnService with BaseService { @@ -163,65 +162,55 @@ class ShadowsocksVpnService extends VpnService with BaseService { } override protected def buildPluginCommandLine(): ArrayBuffer[String] = - super.buildPluginCommandLine() ++= Seq("-V", "-P", getApplicationInfo.dataDir) + super.buildPluginCommandLine() ++= Seq("-V", "-P", getFilesDir.getAbsolutePath) def startShadowsocksDaemon() { - val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so", "-V" - , "-b", "127.0.0.1" - , "-t", "600" - , "-P", getApplicationInfo.dataDir - , "-c", buildShadowsocksConfig(getApplicationInfo.dataDir + "/ss-local-vpn.conf", 0)) + val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so", + "-V", + "-b", "127.0.0.1", + "-l", profile.localPort.toString, + "-t", "600", + "-c", buildShadowsocksConfig("ss-local-vpn.conf")) if (profile.udpdns) cmd += "-u" if (profile.route != Acl.ALL) { cmd += "--acl" - cmd += Acl.getPath(profile.route) + cmd += Acl.getFile(profile.route).getAbsolutePath } if (TcpFastOpen.sendEnabled) cmd += "--fast-open" - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - - sslocalProcess = new GuardedProcess(cmd).start() + sslocalProcess = new GuardedProcess(cmd: _*).start() } - def startDnsTunnel() { - val cmd = Array[String](getApplicationInfo.nativeLibraryDir + "/libss-tunnel.so" - , "-V" - , "-t", "10" - , "-b", "127.0.0.1" - , "-L" , if (profile.remoteDns == null) "8.8.8.8:53" else profile.remoteDns + ":53" - , "-P", getApplicationInfo.dataDir - , "-c", buildShadowsocksConfig(getApplicationInfo.dataDir + "/ss-tunnel-vpn.conf", 63)) - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - sstunnelProcess = new GuardedProcess(cmd).start() - } + def startDnsTunnel(): Unit = + sstunnelProcess = new GuardedProcess(getApplicationInfo.nativeLibraryDir + "/libss-tunnel.so", + "-V", + "-t", "10", + "-b", "127.0.0.1", + "-l", (profile.localPort + 63).toString, + "-L" , if (profile.remoteDns == null) "8.8.8.8:53" else profile.remoteDns + ":53", + "-c", buildShadowsocksConfig("ss-tunnel-vpn.conf")).start() def startDnsDaemon() { val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0" - val protect = "protect = \"" + protectPath +"\";" - val conf = profile.route match { + IOUtils.writeString(new File(getFilesDir, "pdnsd-vpn.conf"), profile.route match { case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES => - ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, protect, getApplicationInfo.dataDir, + ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "protect = \"protect_path\";", getCacheDir.getAbsolutePath, "0.0.0.0", profile.localPort + 53, "114.114.114.114, 223.5.5.5, 1.2.4.8", getBlackList, reject, profile.localPort + 63, reject) case Acl.CHINALIST => - ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, protect, getApplicationInfo.dataDir, + ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "protect = \"protect_path\";", getCacheDir.getAbsolutePath, "0.0.0.0", profile.localPort + 53, "8.8.8.8, 8.8.4.4, 208.67.222.222", "", reject, profile.localPort + 63, reject) case _ => - ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, protect, getApplicationInfo.dataDir, + ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "protect = \"protect_path\";", getCacheDir.getAbsolutePath, "0.0.0.0", profile.localPort + 53, profile.localPort + 63, reject) - } - Utils.printToFile(new File(getApplicationInfo.dataDir + "/pdnsd-vpn.conf"))(p => { - p.println(conf) }) - val cmd = Array(getApplicationInfo.nativeLibraryDir + "/libpdnsd.so", "-c", getApplicationInfo.dataDir + "/pdnsd-vpn.conf") + val cmd = Array(getApplicationInfo.nativeLibraryDir + "/libpdnsd.so", "-c", "pdnsd-vpn.conf") - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - - pdnsdProcess = new GuardedProcess(cmd).start() + pdnsdProcess = new GuardedProcess(cmd: _*).start() } @SuppressLint(Array("NewApi")) @@ -281,7 +270,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { "--socks-server-addr", "127.0.0.1:" + profile.localPort, "--tunfd", fd.toString, "--tunmtu", VPN_MTU.toString, - "--sock-path", getApplicationInfo.dataDir + "/sock_path", + "--sock-path", "sock_path", "--loglevel", "3") if (profile.ipv6) @@ -293,9 +282,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { cmd += ("--dnsgw", "%s:%d".formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), profile.localPort + 53)) - if (BuildConfig.DEBUG) Log.d(TAG, Commandline.toString(cmd)) - - tun2socksProcess = new GuardedProcess(cmd).start(() => sendFd(fd)) + tun2socksProcess = new GuardedProcess(cmd: _*).start(() => sendFd(fd)) fd } @@ -305,7 +292,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { var tries = 1 while (tries < 5) { Thread.sleep(1000 * tries) - if (System.sendfd(fd, getApplicationInfo.dataDir + "/sock_path") != -1) { + if (System.sendfd(fd, new File(getFilesDir, "sock_path").getAbsolutePath) != -1) { return true } tries += 1 diff --git a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala index 63d7d25d..d34a60c0 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala @@ -32,11 +32,11 @@ object ShadowsocksVpnThread { val getInt: Method = classOf[FileDescriptor].getDeclaredMethod("getInt$") } -class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread { +class ShadowsocksVpnThread(service: ShadowsocksVpnService) extends Thread { import ShadowsocksVpnThread._ val TAG = "ShadowsocksVpnService" - lazy val PATH: String = vpnService.getApplicationInfo.dataDir + "/protect_path" + val protect = new File(service.getFilesDir, "protect_path") @volatile var isRunning: Boolean = true @volatile var serverSocket: LocalServerSocket = _ @@ -59,11 +59,11 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread { override def run() { - new File(PATH).delete() + protect.delete() try { val localSocket = new LocalSocket - localSocket.bind(new LocalSocketAddress(PATH, LocalSocketAddress.Namespace.FILESYSTEM)) + localSocket.bind(new LocalSocketAddress(protect.getAbsolutePath, LocalSocketAddress.Namespace.FILESYSTEM)) serverSocket = new LocalServerSocket(localSocket.getFileDescriptor) } catch { case e: IOException => @@ -89,7 +89,7 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread { if (fds.nonEmpty) { val fd = getInt.invoke(fds(0)).asInstanceOf[Int] - val ret = vpnService.protect(fd) + val ret = service.protect(fd) // Trick to close file decriptor System.jniclose(fd) diff --git a/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala b/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala index 715d11cb..676f09e4 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala @@ -1,6 +1,6 @@ package com.github.shadowsocks.acl -import java.io.FileNotFoundException +import java.io.{File, FileNotFoundException} import com.github.shadowsocks.ShadowsocksApplication.app import com.github.shadowsocks.utils.IOUtils @@ -83,7 +83,7 @@ class Acl { this.subnets ++= (if (bypass) proxySubnets else bypassSubnets) this } - final def fromId(id: String): Acl = fromSource(Source.fromFile(Acl.getPath(id))) + final def fromId(id: String): Acl = fromSource(Source.fromFile(Acl.getFile(id))) override def toString: String = { val result = new StringBuilder() @@ -128,7 +128,7 @@ object Acl { final val CHINALIST = "china-list" final val CUSTOM_RULES = "custom-rules" - def getPath(id: String): String = app.getApplicationInfo.dataDir + '/' + id + ".acl" + def getFile(id: String) = new File(app.getFilesDir, id + ".acl") def customRules: Acl = { val acl = new Acl() try acl.fromId(CUSTOM_RULES) catch { @@ -138,5 +138,5 @@ object Acl { acl.bypassHostnames.clear() // everything is bypassed acl } - def save(id: String, acl: Acl): Unit = IOUtils.writeString(getPath(id), acl.toString) + def save(id: String, acl: Acl): Unit = IOUtils.writeString(getFile(id), acl.toString) } diff --git a/mobile/src/main/scala/com/github/shadowsocks/acl/AclSyncJob.scala b/mobile/src/main/scala/com/github/shadowsocks/acl/AclSyncJob.scala index c5082f30..450ec903 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/acl/AclSyncJob.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/acl/AclSyncJob.scala @@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit import com.evernote.android.job.Job.{Params, Result} import com.evernote.android.job.{Job, JobRequest} -import com.github.shadowsocks.ShadowsocksApplication.app import com.github.shadowsocks.utils.IOUtils import scala.io.Source @@ -47,11 +46,10 @@ object AclSyncJob { class AclSyncJob(route: String) extends Job { override def onRunJob(params: Params): Result = { - val filename = route + ".acl" try { //noinspection JavaAccessorMethodCalledAsEmptyParen - IOUtils.writeString(app.getApplicationInfo.dataDir + '/' + filename, - Source.fromURL("https://shadowsocks.org/acl/android/v1/" + filename).mkString) + IOUtils.writeString(Acl.getFile(route), + Source.fromURL("https://shadowsocks.org/acl/android/v1/" + route + ".acl").mkString) Result.SUCCESS } catch { case e: IOException => diff --git a/mobile/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala b/mobile/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala index 3c4b4be1..993a4cf6 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala @@ -37,6 +37,8 @@ object IOUtils { } } + def writeString(file: File, content: String): Unit = + autoClose(new FileWriter(file))(writer => writer.write(content)) def writeString(file: String, content: String): Unit = autoClose(new FileWriter(file))(writer => writer.write(content)) diff --git a/mobile/src/main/scala/com/github/shadowsocks/utils/TcpFastOpen.scala b/mobile/src/main/scala/com/github/shadowsocks/utils/TcpFastOpen.scala index ffb7606c..80108f26 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/utils/TcpFastOpen.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/utils/TcpFastOpen.scala @@ -25,6 +25,7 @@ import java.io.File import eu.chainfire.libsuperuser.Shell import scala.collection.JavaConverters._ +import scala.io.Source /** * @author Mygod @@ -45,7 +46,7 @@ object TcpFastOpen { def sendEnabled: Boolean = { val file = new File("/proc/sys/net/ipv4/tcp_fastopen") - file.canRead && (Utils.readAllLines(file).toInt & 1) > 0 + file.canRead && (Source.fromFile(file).mkString.toInt & 1) > 0 } def enabled(value: Boolean): String = if (sendEnabled != value) { diff --git a/mobile/src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala b/mobile/src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala index 6efa39cf..0edb656f 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala @@ -32,7 +32,7 @@ import com.github.shadowsocks.ShadowsocksApplication.app class TrafficMonitorThread(context: Context) extends Thread { val TAG = "TrafficMonitorThread" - lazy val PATH: String = context.getApplicationInfo.dataDir + "/stat_path" + val stat = new File(context.getFilesDir, "/stat_path") @volatile var serverSocket: LocalServerSocket = _ @volatile var isRunning: Boolean = true @@ -55,11 +55,11 @@ class TrafficMonitorThread(context: Context) extends Thread { override def run() { - new File(PATH).delete() + stat.delete() try { val localSocket = new LocalSocket - localSocket.bind(new LocalSocketAddress(PATH, LocalSocketAddress.Namespace.FILESYSTEM)) + localSocket.bind(new LocalSocketAddress(stat.getAbsolutePath, LocalSocketAddress.Namespace.FILESYSTEM)) serverSocket = new LocalServerSocket(localSocket.getFileDescriptor) } catch { case e: IOException => diff --git a/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala b/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala index 20a9e14c..03e55b85 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala @@ -20,10 +20,8 @@ package com.github.shadowsocks.utils -import java.io.File import java.net._ import java.security.MessageDigest -import java.util.Scanner import android.content.pm.PackageManager import android.content.{Context, Intent} @@ -78,22 +76,6 @@ object Utils { toast } - def readAllLines(f: File): String = { - val scanner = new Scanner(f) - try { - scanner.useDelimiter("\\Z") - scanner.next() - } finally scanner.close() - } - def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) { - val p = new java.io.PrintWriter(f) - try { - op(p) - } finally { - p.close() - } - } - def resolve(host: String, addrType: Int): Option[String] = { try { val lookup = new Lookup(host, addrType) @@ -131,20 +113,16 @@ object Utils { /** * If there exists a valid IPv6 interface */ - def isIPv6Support: Boolean = { - try { - for (intf <- enumerationAsScalaIterator(NetworkInterface.getNetworkInterfaces)) - for (addr <- enumerationAsScalaIterator(intf.getInetAddresses)) - if (addr.isInstanceOf[Inet6Address] && !addr.isLoopbackAddress && !addr.isLinkLocalAddress) { - if (BuildConfig.DEBUG) Log.d(TAG, "IPv6 address detected") - return true - } - } catch { - case ex: Exception => - Log.e(TAG, "Failed to get interfaces' addresses.", ex) - app.track(ex) - } - false + def isIPv6Support: Boolean = try { + val result = NetworkInterface.getNetworkInterfaces.flatMap(_.getInetAddresses) + .count(addr => addr.isInstanceOf[Inet6Address] && !addr.isLoopbackAddress && !addr.isLinkLocalAddress) > 0 + if (result && BuildConfig.DEBUG) Log.d(TAG, "IPv6 address detected") + result + } catch { + case ex: Exception => + Log.e(TAG, "Failed to get interfaces' addresses.", ex) + app.track(ex) + false } def startSsService(context: Context) {