Commit 64b78846 authored by Mygod's avatar Mygod

Create class ConcurrentLocalSocketListener

parent 3997896a
...@@ -31,7 +31,7 @@ import java.nio.ByteOrder ...@@ -31,7 +31,7 @@ import java.nio.ByteOrder
class TrafficMonitor(statFile: File) : AutoCloseable { class TrafficMonitor(statFile: File) : AutoCloseable {
private val thread = object : LocalSocketListener("TrafficMonitor", statFile) { private val thread = object : LocalSocketListener("TrafficMonitor", statFile) {
override fun accept(socket: LocalSocket) = socket.use { override fun acceptInternal(socket: LocalSocket) {
val buffer = ByteArray(16) val buffer = ByteArray(16)
if (socket.inputStream.read(buffer) != 16) throw IOException("Unexpected traffic stat length") if (socket.inputStream.read(buffer) != 16) throw IOException("Unexpected traffic stat length")
val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN) val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN)
......
...@@ -34,14 +34,14 @@ import com.github.shadowsocks.Core ...@@ -34,14 +34,14 @@ import com.github.shadowsocks.Core
import com.github.shadowsocks.VpnRequestActivity import com.github.shadowsocks.VpnRequestActivity
import com.github.shadowsocks.acl.Acl import com.github.shadowsocks.acl.Acl
import com.github.shadowsocks.core.R import com.github.shadowsocks.core.R
import com.github.shadowsocks.net.ConcurrentLocalSocketListener
import com.github.shadowsocks.net.DefaultNetworkListener import com.github.shadowsocks.net.DefaultNetworkListener
import com.github.shadowsocks.net.LocalSocketListener
import com.github.shadowsocks.net.Subnet import com.github.shadowsocks.net.Subnet
import com.github.shadowsocks.preference.DataStore import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.utils.Key import com.github.shadowsocks.utils.Key
import com.github.shadowsocks.utils.parseNumericAddress import com.github.shadowsocks.utils.parseNumericAddress
import com.github.shadowsocks.utils.printLog import com.github.shadowsocks.utils.printLog
import kotlinx.coroutines.* import kotlinx.coroutines.delay
import java.io.Closeable import java.io.Closeable
import java.io.File import java.io.File
import java.io.FileDescriptor import java.io.FileDescriptor
...@@ -66,15 +66,9 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { ...@@ -66,15 +66,9 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
override fun close() = Os.close(fd) override fun close() = Os.close(fd)
} }
private inner class ProtectWorker : private inner class ProtectWorker : ConcurrentLocalSocketListener("ShadowsocksVpnThread",
LocalSocketListener("ShadowsocksVpnThread", File(Core.deviceStorage.noBackupFilesDir, "protect_path")), File(Core.deviceStorage.noBackupFilesDir, "protect_path")) {
CoroutineScope { override fun acceptInternal(socket: LocalSocket) {
private val job = SupervisorJob()
override val coroutineContext get() = Dispatchers.IO + job + CoroutineExceptionHandler { _, t -> printLog(t) }
override fun accept(socket: LocalSocket) {
launch {
socket.use {
socket.inputStream.read() socket.inputStream.read()
val fd = socket.ancillaryFileDescriptors!!.single()!! val fd = socket.ancillaryFileDescriptors!!.single()!!
CloseableFd(fd).use { CloseableFd(fd).use {
...@@ -91,14 +85,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { ...@@ -91,14 +85,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
} }
} }
} }
}
suspend fun shutdown() {
job.cancel()
close()
job.join()
}
}
inner class NullConnectionException : NullPointerException() { inner class NullConnectionException : NullPointerException() {
override fun getLocalizedMessage() = getString(R.string.reboot_required) override fun getLocalizedMessage() = getString(R.string.reboot_required)
} }
......
/*******************************************************************************
* *
* Copyright (C) 2019 by Max Lv <max.c.lv@gmail.com> *
* Copyright (C) 2019 by Mygod Studio <contact-shadowsocks-android@mygod.be> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
package com.github.shadowsocks.net
import android.net.LocalSocket
import com.github.shadowsocks.utils.printLog
import kotlinx.coroutines.*
import java.io.File
abstract class ConcurrentLocalSocketListener(name: String, socketFile: File) : LocalSocketListener(name, socketFile),
CoroutineScope {
private val job = SupervisorJob()
override val coroutineContext get() = Dispatchers.IO + job + CoroutineExceptionHandler { _, t -> printLog(t) }
override fun accept(socket: LocalSocket) {
launch { super.accept(socket) }
}
suspend fun shutdown() {
job.cancel()
close()
job.join()
}
}
...@@ -42,7 +42,8 @@ abstract class LocalSocketListener(name: String, socketFile: File) : Thread(name ...@@ -42,7 +42,8 @@ abstract class LocalSocketListener(name: String, socketFile: File) : Thread(name
/** /**
* Inherited class do not need to close input/output streams as they will be closed automatically. * Inherited class do not need to close input/output streams as they will be closed automatically.
*/ */
protected abstract fun accept(socket: LocalSocket) protected open fun accept(socket: LocalSocket) = socket.use { acceptInternal(socket) }
protected abstract fun acceptInternal(socket: LocalSocket)
final override fun run() = localSocket.use { final override fun run() = localSocket.use {
while (running) { while (running) {
try { try {
......
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