Commit 6a65886a authored by Mygod's avatar Mygod

Add ExpectedExceptions

parent c44dfc4d
...@@ -37,13 +37,11 @@ import com.github.shadowsocks.aidl.IShadowsocksServiceCallback ...@@ -37,13 +37,11 @@ import com.github.shadowsocks.aidl.IShadowsocksServiceCallback
import com.github.shadowsocks.aidl.TrafficStats import com.github.shadowsocks.aidl.TrafficStats
import com.github.shadowsocks.core.R import com.github.shadowsocks.core.R
import com.github.shadowsocks.net.HostsFile import com.github.shadowsocks.net.HostsFile
import com.github.shadowsocks.plugin.PluginManager
import com.github.shadowsocks.preference.DataStore import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.utils.* import com.github.shadowsocks.utils.*
import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.FirebaseAnalytics
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.io.File import java.io.File
import java.net.BindException
import java.net.URL import java.net.URL
import java.net.UnknownHostException import java.net.UnknownHostException
import java.util.* import java.util.*
...@@ -66,6 +64,9 @@ object BaseService { ...@@ -66,6 +64,9 @@ object BaseService {
const val CONFIG_FILE = "shadowsocks.conf" const val CONFIG_FILE = "shadowsocks.conf"
const val CONFIG_FILE_UDP = "shadowsocks-udp.conf" const val CONFIG_FILE_UDP = "shadowsocks-udp.conf"
interface ExpectedException
class ExpectedExceptionWrapper(e: Exception) : Exception(e.localizedMessage, e), ExpectedException
class Data internal constructor(private val service: Interface) { class Data internal constructor(private val service: Interface) {
var state = State.Stopped var state = State.Stopped
var processes: GuardedProcessPool? = null var processes: GuardedProcessPool? = null
...@@ -360,11 +361,7 @@ object BaseService { ...@@ -360,11 +361,7 @@ object BaseService {
} catch (_: UnknownHostException) { } catch (_: UnknownHostException) {
stopRunner(false, getString(R.string.invalid_server)) stopRunner(false, getString(R.string.invalid_server))
} catch (exc: Throwable) { } catch (exc: Throwable) {
if (exc !is PluginManager.PluginNotFoundException && if (exc is ExpectedException) exc.printStackTrace() else printLog(exc)
exc !is BindException &&
exc !is VpnService.NullConnectionException) {
printLog(exc)
}
stopRunner(false, "${getString(R.string.service_failed)}: ${exc.readableMessage}") stopRunner(false, "${getString(R.string.service_failed)}: ${exc.readableMessage}")
} finally { } finally {
data.connectingJob = null data.connectingJob = null
......
...@@ -31,6 +31,7 @@ import com.github.shadowsocks.preference.DataStore ...@@ -31,6 +31,7 @@ import com.github.shadowsocks.preference.DataStore
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.net.URI import java.net.URI
import java.net.URISyntaxException
import java.util.* import java.util.*
object LocalDnsService { object LocalDnsService {
...@@ -47,7 +48,11 @@ object LocalDnsService { ...@@ -47,7 +48,11 @@ object LocalDnsService {
override suspend fun startProcesses(hosts: HostsFile) { override suspend fun startProcesses(hosts: HostsFile) {
super.startProcesses(hosts) super.startProcesses(hosts)
val profile = data.proxy!!.profile val profile = data.proxy!!.profile
val dns = URI("dns://${profile.remoteDns}") val dns = try {
URI("dns://${profile.remoteDns}")
} catch (e: URISyntaxException) {
throw BaseService.ExpectedExceptionWrapper(e)
}
LocalDnsServer(this::resolver, LocalDnsServer(this::resolver,
Socks5Endpoint(dns.host, if (dns.port < 0) 53 else dns.port), Socks5Endpoint(dns.host, if (dns.port < 0) 53 else dns.port),
DataStore.proxyAddress, DataStore.proxyAddress,
......
...@@ -37,6 +37,7 @@ import kotlinx.coroutines.CoroutineScope ...@@ -37,6 +37,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import java.io.IOException
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
import java.net.UnknownHostException import java.net.UnknownHostException
...@@ -67,10 +68,14 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro ...@@ -67,10 +68,14 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
conn.doOutput = true conn.doOutput = true
val proxies = conn.useCancellable { val proxies = conn.useCancellable {
try {
outputStream.bufferedWriter().use { outputStream.bufferedWriter().use {
it.write("sig=" + Base64.encodeToString(mdg.digest(), Base64.DEFAULT)) it.write("sig=" + Base64.encodeToString(mdg.digest(), Base64.DEFAULT))
} }
inputStream.bufferedReader().readText() inputStream.bufferedReader().readText()
} catch (e: IOException) {
throw BaseService.ExpectedExceptionWrapper(e)
}
}.split('|').toMutableList() }.split('|').toMutableList()
proxies.shuffle() proxies.shuffle()
val proxy = proxies.first().split(':') val proxy = proxies.first().split(':')
...@@ -86,8 +91,11 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro ...@@ -86,8 +91,11 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
// it's hard to resolve DNS on a specific interface so we'll do it here // it's hard to resolve DNS on a specific interface so we'll do it here
if (profile.host.parseNumericAddress() == null) { if (profile.host.parseNumericAddress() == null) {
profile.host = (hosts.resolve(profile.host).firstOrNull() ?: service.resolver(profile.host).firstOrNull()) profile.host = (hosts.resolve(profile.host).firstOrNull() ?: try {
?.hostAddress ?: throw UnknownHostException() service.resolver(profile.host).firstOrNull()
} catch (_: IOException) {
null
})?.hostAddress ?: throw UnknownHostException()
} }
} }
......
...@@ -90,7 +90,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { ...@@ -90,7 +90,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
} }
} }
inner class NullConnectionException : NullPointerException() { inner class NullConnectionException : NullPointerException(), BaseService.ExpectedException {
override fun getLocalizedMessage() = getString(R.string.reboot_required) override fun getLocalizedMessage() = getString(R.string.reboot_required)
} }
......
...@@ -22,6 +22,7 @@ package com.github.shadowsocks.net ...@@ -22,6 +22,7 @@ package com.github.shadowsocks.net
import android.util.Log import android.util.Log
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import com.github.shadowsocks.bg.BaseService
import com.github.shadowsocks.utils.printLog import com.github.shadowsocks.utils.printLog
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.xbill.DNS.* import org.xbill.DNS.*
...@@ -91,7 +92,11 @@ class LocalDnsServer(private val localResolver: suspend (String) -> Array<InetAd ...@@ -91,7 +92,11 @@ class LocalDnsServer(private val localResolver: suspend (String) -> Array<InetAd
suspend fun start(listen: SocketAddress) = DatagramChannel.open().run { suspend fun start(listen: SocketAddress) = DatagramChannel.open().run {
configureBlocking(false) configureBlocking(false)
try {
socket().bind(listen) socket().bind(listen)
} catch (e: BindException) {
throw BaseService.ExpectedExceptionWrapper(e)
}
monitor.register(this, SelectionKey.OP_READ) { handlePacket(this) } monitor.register(this, SelectionKey.OP_READ) { handlePacket(this) }
} }
......
...@@ -36,6 +36,7 @@ import androidx.core.os.bundleOf ...@@ -36,6 +36,7 @@ import androidx.core.os.bundleOf
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import com.github.shadowsocks.Core import com.github.shadowsocks.Core
import com.github.shadowsocks.Core.app import com.github.shadowsocks.Core.app
import com.github.shadowsocks.bg.BaseService
import com.github.shadowsocks.utils.printLog import com.github.shadowsocks.utils.printLog
import com.github.shadowsocks.utils.signaturesCompat import com.github.shadowsocks.utils.signaturesCompat
import java.io.File import java.io.File
...@@ -44,7 +45,8 @@ import java.io.FileNotFoundException ...@@ -44,7 +45,8 @@ import java.io.FileNotFoundException
object PluginManager { object PluginManager {
private const val TAG = "PluginManager" private const val TAG = "PluginManager"
class PluginNotFoundException(private val plugin: String) : FileNotFoundException(plugin) { class PluginNotFoundException(private val plugin: String) : FileNotFoundException(plugin),
BaseService.ExpectedException {
override fun getLocalizedMessage() = app.getString(com.github.shadowsocks.core.R.string.plugin_unknown, plugin) override fun getLocalizedMessage() = app.getString(com.github.shadowsocks.core.R.string.plugin_unknown, plugin)
} }
......
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