Commit b682cb3a authored by chenhuaqing's avatar chenhuaqing

fixed restart

parent 0b81449f
......@@ -39,18 +39,23 @@ import kotlin.concurrent.thread
class GuardedProcessPool(private val onFatal: suspend (IOException) -> Unit) : CoroutineScope {
companion object {
private val pid by lazy {
Class.forName("java.lang.ProcessManager\$ProcessImpl").getDeclaredField("pid").apply { isAccessible = true }
Class.forName("java.lang.ProcessManager\$ProcessImpl").getDeclaredField("pid")
.apply { isAccessible = true }
}
}
private inner class Guard(private val cmd: List<String>) {
private inner class Guard(private val cmdSupplier: suspend () -> List<String>) {
private lateinit var process: Process
private lateinit var cmd: List<String>
private fun streamLogger(input: InputStream, logger: (String) -> Unit) = try {
input.bufferedReader().forEachLine(logger)
} catch (_: IOException) { } // ignore
} catch (_: IOException) {
} // ignore
fun start() {
suspend fun start() {
cmd = cmdSupplier.invoke()
Timber.i("start process: ${Commandline.toString(cmd)}")
process = ProcessBuilder(cmd).directory(Core.deviceStorage.noBackupFilesDir).start()
}
......@@ -74,7 +79,8 @@ class GuardedProcessPool(private val onFatal: suspend (IOException) -> Unit) : C
when {
exitCode == OsConstants.ECONNREFUSED -> throw IOException("connection refused by server")
SystemClock.elapsedRealtime() - startTime < 1000 -> throw IOException(
"$cmdName exits too fast (exit code: $exitCode)")
"$cmdName exits too fast (exit code: $exitCode)"
)
exitCode == 128 + OsConstants.SIGKILL -> Timber.w("$cmdName was killed")
else -> Timber.w(IOException("$cmdName unexpectedly exits with code $exitCode"))
}
......@@ -112,11 +118,15 @@ class GuardedProcessPool(private val onFatal: suspend (IOException) -> Unit) : C
override val coroutineContext = Dispatchers.Main.immediate + Job()
@MainThread
fun start(cmd: List<String>, onRestartCallback: (suspend () -> Unit)? = null) {
Timber.i("start process: ${Commandline.toString(cmd)}")
Guard(cmd).apply {
fun start(
cmdSupplier: suspend () -> List<String>,
onRestartCallback: (suspend () -> Unit)? = null
) {
Guard(cmdSupplier).apply {
launch {
start() // if start fails, IOException will be thrown directly
launch { looper(onRestartCallback) }
looper(onRestartCallback)
}
}
}
......
......@@ -59,10 +59,11 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
* Sensitive shadowsocks configuration file requires extra protection. It may be stored in encrypted storage or
* device storage, depending on which is currently available.
*/
fun start(service: BaseService.Interface, stat: File, configFile: File, mode: String, dnsRelay: Boolean = true) {
suspend fun start(service: BaseService.Interface, stat: File, configFile: File, mode: String, dnsRelay: Boolean = true) {
// setup traffic monitor path
trafficMonitor = TrafficMonitor(stat)
val cmdSupplier: suspend () -> List<String> = {
AuthManager.initAuthProfile(profile)
// init JSON config
this.configFile = configFile
val config = profile.toJson()
......@@ -116,6 +117,7 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
if (route != Acl.ALL) {
cmd += "--acl"
cmd += Acl.getFile(route).absolutePath
Timber.d("start vpn service with acl ${Acl.getFile(route).readText()}")
}
if (BuildConfig.DEBUG) {
......@@ -124,8 +126,10 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
cmd += "-v"
cmd += "-v"
}
cmd
}
service.data.processes!!.start(cmd)
service.data.processes!!.start(cmdSupplier)
}
fun scheduleUpdate() {
......
......@@ -224,7 +224,7 @@ class VpnService : BaseVpnService(), BaseService.Interface {
cmd += PRIVATE_VLAN6_ROUTER
}
cmd += "--enable-udprelay"
data.processes!!.start(cmd, onRestartCallback = {
data.processes!!.start(cmdSupplier = { cmd }, onRestartCallback = {
try {
sendFd(conn.fileDescriptor)
} catch (e: ErrnoException) {
......
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