Skip to content

Commit

Permalink
Add ExpectedExceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
Mygod committed Jul 24, 2019
1 parent c44dfc4 commit 6a65886
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 16 deletions.
11 changes: 4 additions & 7 deletions core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand Down
18 changes: 13 additions & 5 deletions core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -67,10 +68,14 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
conn.doOutput = true

val proxies = conn.useCancellable {
outputStream.bufferedWriter().use {
it.write("sig=" + Base64.encodeToString(mdg.digest(), Base64.DEFAULT))
try {
outputStream.bufferedWriter().use {
it.write("sig=" + Base64.encodeToString(mdg.digest(), Base64.DEFAULT))
}
inputStream.bufferedReader().readText()
} catch (e: IOException) {
throw BaseService.ExpectedExceptionWrapper(e)
}
inputStream.bufferedReader().readText()
}.split('|').toMutableList()
proxies.shuffle()
val proxy = proxies.first().split(':')
Expand All @@ -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()
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down Expand Up @@ -91,7 +92,11 @@ class LocalDnsServer(private val localResolver: suspend (String) -> Array<InetAd

suspend fun start(listen: SocketAddress) = DatagramChannel.open().run {
configureBlocking(false)
socket().bind(listen)
try {
socket().bind(listen)
} catch (e: BindException) {
throw BaseService.ExpectedExceptionWrapper(e)
}
monitor.register(this, SelectionKey.OP_READ) { handlePacket(this) }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}

Expand Down

0 comments on commit 6a65886

Please sign in to comment.