Add connection checking for WG/AWG via logs (#1056)

This commit is contained in:
albexk 2024-09-09 22:08:06 +03:00 committed by GitHub
parent 9cab51fb00
commit 46058f614e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 47 additions and 5 deletions

View file

@ -58,7 +58,7 @@ open class OpenVpn : Protocol() {
scope = CoroutineScope(Dispatchers.IO) scope = CoroutineScope(Dispatchers.IO)
} }
override fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) { override suspend fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) {
val configBuilder = OpenVpnConfig.Builder() val configBuilder = OpenVpnConfig.Builder()
openVpnClient = OpenVpnClient( openVpnClient = OpenVpnClient(

View file

@ -42,7 +42,7 @@ abstract class Protocol {
protected abstract fun internalInit() protected abstract fun internalInit()
abstract fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) abstract suspend fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean)
abstract fun stopVpn() abstract fun stopVpn()

View file

@ -31,6 +31,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
@ -111,6 +112,10 @@ open class AmneziaVpnService : VpnService() {
get() = clientMessengers.any { it.value.name == ACTIVITY_MESSENGER_NAME } get() = clientMessengers.any { it.value.name == ACTIVITY_MESSENGER_NAME }
private val connectionExceptionHandler = CoroutineExceptionHandler { _, e -> private val connectionExceptionHandler = CoroutineExceptionHandler { _, e ->
connectionJob?.cancel()
connectionJob = null
disconnectionJob?.cancel()
disconnectionJob = null
protocolState.value = DISCONNECTED protocolState.value = DISCONNECTED
when (e) { when (e) {
is IllegalArgumentException, is IllegalArgumentException,
@ -531,7 +536,7 @@ open class AmneziaVpnService : VpnService() {
protocolState.value = DISCONNECTING protocolState.value = DISCONNECTING
disconnectionJob = connectionScope.launch { disconnectionJob = connectionScope.launch {
connectionJob?.join() connectionJob?.cancelAndJoin()
connectionJob = null connectionJob = null
vpnProto?.protocol?.stopVpn() vpnProto?.protocol?.stopVpn()

View file

@ -1,7 +1,12 @@
package org.amnezia.vpn.protocol.wireguard package org.amnezia.vpn.protocol.wireguard
import android.net.VpnService.Builder import android.net.VpnService.Builder
import java.io.IOException
import java.util.Locale
import java.util.TreeMap import java.util.TreeMap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.amnezia.awg.GoBackend import org.amnezia.awg.GoBackend
import org.amnezia.vpn.protocol.Protocol import org.amnezia.vpn.protocol.Protocol
import org.amnezia.vpn.protocol.ProtocolState.CONNECTED import org.amnezia.vpn.protocol.ProtocolState.CONNECTED
@ -79,12 +84,44 @@ open class Wireguard : Protocol() {
if (!isInitialized) loadSharedLibrary(context, "wg-go") if (!isInitialized) loadSharedLibrary(context, "wg-go")
} }
override fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) { override suspend fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) {
val wireguardConfig = parseConfig(config) val wireguardConfig = parseConfig(config)
val startTime = System.currentTimeMillis()
start(wireguardConfig, vpnBuilder, protect) start(wireguardConfig, vpnBuilder, protect)
waitForConnection(startTime)
state.value = CONNECTED state.value = CONNECTED
} }
private suspend fun waitForConnection(startTime: Long) {
Log.d(TAG, "Waiting for connection")
withContext(Dispatchers.IO) {
val time = String.format(Locale.ROOT,"%.3f", startTime / 1000.0)
try {
delay(1000)
var log = getLogcat(time)
Log.d(TAG, "First waiting log: $log")
// check that there is a connection log,
// to avoid infinite connection
if (!log.contains("Attaching to interface")) {
Log.w(TAG, "Logs do not contain a connection log")
return@withContext
}
while (!log.contains("Received handshake response")) {
delay(1000)
log = getLogcat(time)
}
} catch (e: IOException) {
Log.e(TAG, "Failed to get logcat: $e")
}
}
}
private fun getLogcat(time: String): String =
ProcessBuilder("logcat", "--buffer=main", "--format=raw", "*:S AmneziaWG/awg0", "-t", time)
.redirectErrorStream(true)
.start()
.inputStream.reader().readText()
protected open fun parseConfig(config: JSONObject): WireguardConfig { protected open fun parseConfig(config: JSONObject): WireguardConfig {
val configDataJson = config.getJSONObject("wireguard_config_data") val configDataJson = config.getJSONObject("wireguard_config_data")
val configData = parseConfigData(configDataJson.getString("config")) val configData = parseConfigData(configDataJson.getString("config"))

View file

@ -109,7 +109,7 @@ class Xray : Protocol() {
} }
} }
override fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) { override suspend fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) {
if (isRunning) { if (isRunning) {
Log.w(TAG, "XRay already running") Log.w(TAG, "XRay already running")
return return