Commit 6a65886a authored by Mygod's avatar Mygod

Add ExpectedExceptions

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