Add connection checking for WG/AWG via logs (#1056)
This commit is contained in:
parent
9cab51fb00
commit
46058f614e
5 changed files with 47 additions and 5 deletions
|
@ -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(
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue