Move catch blocks to child classes

This reverts commit 07a48bc20b and f870093c94.
This commit is contained in:
Mygod
2017-12-06 16:07:37 -08:00
parent c50ef11b06
commit e19e629487
6 changed files with 36 additions and 63 deletions
@@ -25,75 +25,46 @@ import android.net.LocalSocket
import android.net.LocalSocketAddress
import android.util.Log
import com.github.shadowsocks.App.Companion.app
import com.github.shadowsocks.JniHelper
import java.io.File
import java.io.IOException
import java.util.concurrent.atomic.AtomicReference
abstract class LocalSocketListener(private val tag: String) : Thread() {
abstract class LocalSocketListener(protected val tag: String) : Thread() {
init {
setUncaughtExceptionHandler(app::track)
}
protected abstract val socketFile: File
private val localSocket = AtomicReference<LocalSocket?>()
private val serverSocket = AtomicReference<LocalServerSocket?>()
/**
* Inherited class do not need to close input/output streams as they will be closed automatically.
*/
protected abstract fun accept(socket: LocalSocket)
override fun run() {
JniHelper.unlink(socketFile.absolutePath)
Thread.sleep(1000) // trick to close the previous local socket safely
val serverSocket: LocalServerSocket? = try {
val ls = LocalSocket()
localSocket.set(ls)
ls.bind(LocalSocketAddress(socketFile.absolutePath, LocalSocketAddress.Namespace.FILESYSTEM))
LocalServerSocket(ls.fileDescriptor)
socketFile.delete()
try {
val localSocket = LocalSocket()
localSocket.bind(LocalSocketAddress(socketFile.absolutePath, LocalSocketAddress.Namespace.FILESYSTEM))
serverSocket.set(LocalServerSocket(localSocket.fileDescriptor))
} catch (e: IOException) {
Log.e(tag, "unable to bind", e)
null
return
}
while (true) {
val serverSocket = serverSocket.get() ?: return
try {
val socket = serverSocket?.accept() ?: break
try {
accept(socket)
} catch (e: Exception) {
Log.e(tag, "Error when recv traffic stat", e)
app.track(e)
}
try {
socket.close()
} catch (e: IOException) {
Log.e(tag, "Error when closing the local socket", e)
app.track(e)
}
serverSocket.accept()
} catch (e: IOException) {
Log.e(tag, "Error when accept socket", e)
app.track(e)
break
}
null
}?.use(this::accept)
}
try {
serverSocket?.close()
} catch (e: IOException) {
Log.e(tag, "Error when closing socket", e)
app.track(e)
}
Log.d(tag, "thread exit")
}
fun stopThread() {
val old = localSocket.getAndSet(null) ?: return
val old = serverSocket.getAndSet(null) ?: return
try {
old.close()
} catch (_: Exception) { } // ignore
@@ -21,6 +21,7 @@
package com.github.shadowsocks.bg
import android.net.LocalSocket
import android.util.Log
import com.github.shadowsocks.App.Companion.app
import java.io.File
import java.io.IOException
@@ -31,10 +32,15 @@ class TrafficMonitorThread : LocalSocketListener("TrafficMonitorThread") {
override val socketFile = File(app.filesDir, "/stat_path")
override fun accept(socket: LocalSocket) {
val buffer = ByteArray(16)
if (socket.inputStream.read(buffer) != 16) throw IOException("Unexpected traffic stat length")
val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN)
TrafficMonitor.update(stat.getLong(0), stat.getLong(8))
socket.outputStream.write(0)
try {
val buffer = ByteArray(16)
if (socket.inputStream.read(buffer) != 16) throw IOException("Unexpected traffic stat length")
val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN)
TrafficMonitor.update(stat.getLong(0), stat.getLong(8))
socket.outputStream.write(0)
} catch (e: Exception) {
Log.e(tag, "Error when recv traffic stat", e)
app.track(e)
}
}
}
@@ -55,13 +55,18 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
override val socketFile: File = File(filesDir, "protect_path")
override fun accept(socket: LocalSocket) {
socket.inputStream.read()
val fds = socket.ancillaryFileDescriptors
if (fds.isEmpty()) return
val fd = getInt.invoke(fds.first()) as Int
val ret = protect(fd)
JniHelper.close(fd) // Trick to close file decriptor
socket.outputStream.write(if (ret) 0 else 1)
try {
socket.inputStream.read()
val fds = socket.ancillaryFileDescriptors
if (fds.isEmpty()) return
val fd = getInt.invoke(fds.first()) as Int
val ret = protect(fd)
JniHelper.close(fd) // Trick to close file decriptor
socket.outputStream.write(if (ret) 0 else 1)
} catch (e: Exception) {
Log.e(tag, "Error when protect socket", e)
app.track(e)
}
}
}
class NullConnectionException : NullPointerException()