From 5835a756cedb62dea18f8f6e76092b652d9b511e Mon Sep 17 00:00:00 2001 From: albexk Date: Tue, 5 Dec 2023 13:47:12 +0300 Subject: [PATCH] Add onError callback to handle errors in protocol threads --- .../amnezia/vpn/protocol/openvpn/OpenVpn.kt | 20 ++++++++++--------- .../vpn/protocol/openvpn/OpenVpnClient.kt | 16 ++++++--------- .../protocolApi/src/main/kotlin/Protocol.kt | 4 +++- .../src/org/amnezia/vpn/AmneziaVpnService.kt | 11 +++++----- .../vpn/protocol/wireguard/Wireguard.kt | 4 ++-- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpn.kt b/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpn.kt index cf55aebc..d363fbeb 100644 --- a/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpn.kt +++ b/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpn.kt @@ -11,8 +11,8 @@ import net.openvpn.ovpn3.ClientAPI_Config import org.amnezia.vpn.protocol.BadConfigException import org.amnezia.vpn.protocol.Protocol import org.amnezia.vpn.protocol.ProtocolState +import org.amnezia.vpn.protocol.ProtocolState.DISCONNECTED import org.amnezia.vpn.protocol.Statistics -import org.amnezia.vpn.protocol.VpnException import org.amnezia.vpn.protocol.VpnStartException import org.amnezia.vpn.util.net.InetNetwork import org.amnezia.vpn.util.net.getLocalNetworks @@ -53,8 +53,8 @@ open class OpenVpn : Protocol() { return Statistics.EMPTY_STATISTICS } - override fun initialize(context: Context, state: MutableStateFlow) { - super.initialize(context, state) + override fun initialize(context: Context, state: MutableStateFlow, onError: (String) -> Unit) { + super.initialize(context, state, onError) loadSharedLibrary(context, "ovpn3") this.context = context scope = CoroutineScope(Dispatchers.IO) @@ -64,11 +64,12 @@ open class OpenVpn : Protocol() { val configBuilder = OpenVpnConfig.Builder() openVpnClient = OpenVpnClient( - configBuilder, - state, - { ipv6 -> getLocalNetworks(context, ipv6) }, - makeEstablish(configBuilder, vpnBuilder), - protect + configBuilder = configBuilder, + state = state, + getLocalNetworks = { ipv6 -> getLocalNetworks(context, ipv6) }, + establish = makeEstablish(configBuilder, vpnBuilder), + protect = protect, + onError = onError ) try { @@ -92,7 +93,8 @@ open class OpenVpn : Protocol() { scope.launch { val status = client.connect() if (status.error) { - throw VpnException("OpenVpn connect() error: ${status.status}: ${status.message}") + state.value = DISCONNECTED + onError("OpenVpn connect() error: ${status.status}: ${status.message}") } } } diff --git a/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpnClient.kt b/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpnClient.kt index 17a06df6..c02a4360 100644 --- a/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpnClient.kt +++ b/client/android/openvpn/src/main/kotlin/org/amnezia/vpn/protocol/openvpn/OpenVpnClient.kt @@ -14,7 +14,6 @@ import net.openvpn.ovpn3.ClientAPI_TransportStats import org.amnezia.vpn.protocol.ProtocolState import org.amnezia.vpn.protocol.ProtocolState.CONNECTED import org.amnezia.vpn.protocol.ProtocolState.DISCONNECTED -import org.amnezia.vpn.protocol.VpnStartException import org.amnezia.vpn.util.Log import org.amnezia.vpn.util.net.InetNetwork import org.amnezia.vpn.util.net.parseInetAddress @@ -27,7 +26,8 @@ class OpenVpnClient( private val state: MutableStateFlow, private val getLocalNetworks: (Boolean) -> List, private val establish: () -> Int, - private val protect: (Int) -> Boolean + private val protect: (Int) -> Boolean, + private val onError: (String) -> Unit ) : ClientAPI_OpenVPNClient() { /************************************************************************** @@ -368,15 +368,11 @@ class OpenVpnClient( "COMPRESSION_ENABLED", "WARN" -> Log.w(TAG, "$name: $info") "CONNECTED" -> state.value = CONNECTED "DISCONNECTED" -> state.value = DISCONNECTED - "CONNECTION_TIMEOUT" -> { - Log.w(TAG, "$name: $info") - state.value = DISCONNECTED - // todo: test it - throw VpnStartException("Connection timeout") - } } - if (event.error) Log.e(TAG, "OpenVpn ERROR: $name: $info") - if (event.fatal) Log.e(TAG, "OpenVpn FATAL: $name: $info") + if (event.error || event.fatal) { + state.value = DISCONNECTED + onError("OpenVpn ${if (event.error) "ERROR" else "FATAL"}: $name: $info") + } } // Callback for logging. diff --git a/client/android/protocolApi/src/main/kotlin/Protocol.kt b/client/android/protocolApi/src/main/kotlin/Protocol.kt index 4b0fff47..57bded46 100644 --- a/client/android/protocolApi/src/main/kotlin/Protocol.kt +++ b/client/android/protocolApi/src/main/kotlin/Protocol.kt @@ -30,9 +30,11 @@ abstract class Protocol { abstract val statistics: Statistics protected lateinit var state: MutableStateFlow + protected lateinit var onError: (String) -> Unit - open fun initialize(context: Context, state: MutableStateFlow) { + open fun initialize(context: Context, state: MutableStateFlow, onError: (String) -> Unit) { this.state = state + this.onError = onError } abstract fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) diff --git a/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt b/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt index 3624d977..77b19463 100644 --- a/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt +++ b/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt @@ -345,18 +345,19 @@ class AmneziaVpnService : VpnService() { "openvpn" -> OpenVpn() "cloak" -> Cloak() else -> throw IllegalArgumentException("Protocol '$protocolName' not found") - }.apply { initialize(applicationContext, protocolState) } + }.apply { initialize(applicationContext, protocolState, ::onError) } .also { protocolCache[protocolName] = it } /** * Utils methods */ - @MainThread private fun onError(msg: String) { Log.e(TAG, msg) - clientMessenger.send { - ServiceEvent.ERROR.packToMessage { - putString(ERROR_MSG, msg) + mainScope.launch { + clientMessenger.send { + ServiceEvent.ERROR.packToMessage { + putString(ERROR_MSG, msg) + } } } } diff --git a/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt b/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt index 21423f38..227de63e 100644 --- a/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt +++ b/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt @@ -78,8 +78,8 @@ open class Wireguard : Protocol() { } } - override fun initialize(context: Context, state: MutableStateFlow) { - super.initialize(context, state) + override fun initialize(context: Context, state: MutableStateFlow, onError: (String) -> Unit) { + super.initialize(context, state, onError) loadSharedLibrary(context, "wg-go") }