Commit 7fdcee61 authored by Mygod's avatar Mygod

Suppress write errors to protect_path

parent fdff88e0
......@@ -29,6 +29,7 @@ import android.net.Network
import android.os.Build
import android.os.ParcelFileDescriptor
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
import com.github.shadowsocks.Core
import com.github.shadowsocks.VpnRequestActivity
......@@ -40,7 +41,6 @@ import com.github.shadowsocks.net.DnsResolverCompat
import com.github.shadowsocks.net.Subnet
import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.utils.Key
import com.github.shadowsocks.utils.closeQuietly
import com.github.shadowsocks.utils.int
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
......@@ -59,34 +59,42 @@ class VpnService : BaseVpnService(), BaseService.Interface {
private const val PRIVATE_VLAN4_ROUTER = "172.19.0.2"
private const val PRIVATE_VLAN6_CLIENT = "fdfe:dcba:9876::1"
private const val PRIVATE_VLAN6_ROUTER = "fdfe:dcba:9876::2"
private fun <T> FileDescriptor.use(block: (FileDescriptor) -> T) = try {
block(this)
} finally {
try {
Os.close(this)
} catch (_: ErrnoException) { }
}
}
private inner class ProtectWorker : ConcurrentLocalSocketListener("ShadowsocksVpnThread",
File(Core.deviceStorage.noBackupFilesDir, "protect_path")) {
override fun acceptInternal(socket: LocalSocket) {
socket.inputStream.read()
val fd = socket.ancillaryFileDescriptors!!.single()!!
try {
socket.outputStream.write(if (underlyingNetwork.let { network ->
if (network != null) try {
DnsResolverCompat.bindSocket(network, fd)
return@let true
} catch (e: IOException) {
when ((e.cause as? ErrnoException)?.errno) {
// also suppress ENONET (Machine is not on the network)
OsConstants.EPERM, 64 -> Timber.d(e)
else -> Timber.w(e)
}
return@let false
} catch (e: ReflectiveOperationException) {
check(Build.VERSION.SDK_INT < 23)
Timber.w(e)
}
protect(fd.int)
}) 0 else 1)
} finally {
fd.closeQuietly()
val success = socket.ancillaryFileDescriptors!!.single()!!.use { fd ->
underlyingNetwork.let { network ->
if (network != null) try {
DnsResolverCompat.bindSocket(network, fd)
return@let true
} catch (e: IOException) {
when ((e.cause as? ErrnoException)?.errno) {
// also suppress ENONET (Machine is not on the network)
OsConstants.EPERM, 64 -> Timber.d(e)
else -> Timber.w(e)
}
return@let false
} catch (e: ReflectiveOperationException) {
check(Build.VERSION.SDK_INT < 23)
Timber.w(e)
}
protect(fd.int)
}
}
try {
socket.outputStream.write(if (success) 0 else 1)
} catch (_: IOException) { } // ignore connection early close
}
}
......
......@@ -28,7 +28,6 @@ import android.graphics.BitmapFactory
import android.graphics.ImageDecoder
import android.net.Uri
import android.os.Build
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
import android.util.TypedValue
......@@ -66,10 +65,6 @@ val Throwable.readableMessage get() = localizedMessage ?: javaClass.name
private val getInt = FileDescriptor::class.java.getDeclaredMethod("getInt$")
val FileDescriptor.int get() = getInt.invoke(this) as Int
fun FileDescriptor.closeQuietly() = try {
Os.close(this)
} catch (_: ErrnoException) { }
private val parseNumericAddress by lazy @SuppressLint("SoonBlockedPrivateApi") {
InetAddress::class.java.getDeclaredMethod("parseNumericAddress", String::class.java).apply {
isAccessible = true
......
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