Skip to content

Commit

Permalink
Add connection checking for WG/AWG via logs (#1056)
Browse files Browse the repository at this point in the history
  • Loading branch information
albexk authored Sep 9, 2024
1 parent 9cab51f commit 46058f6
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ open class OpenVpn : Protocol() {
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()

openVpnClient = OpenVpnClient(
Expand Down
2 changes: 1 addition & 1 deletion client/android/protocolApi/src/main/kotlin/Protocol.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ abstract class Protocol {

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()

Expand Down
7 changes: 6 additions & 1 deletion client/android/src/org/amnezia/vpn/AmneziaVpnService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.cancel
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.drop
Expand Down Expand Up @@ -111,6 +112,10 @@ open class AmneziaVpnService : VpnService() {
get() = clientMessengers.any { it.value.name == ACTIVITY_MESSENGER_NAME }

private val connectionExceptionHandler = CoroutineExceptionHandler { _, e ->
connectionJob?.cancel()
connectionJob = null
disconnectionJob?.cancel()
disconnectionJob = null
protocolState.value = DISCONNECTED
when (e) {
is IllegalArgumentException,
Expand Down Expand Up @@ -531,7 +536,7 @@ open class AmneziaVpnService : VpnService() {
protocolState.value = DISCONNECTING

disconnectionJob = connectionScope.launch {
connectionJob?.join()
connectionJob?.cancelAndJoin()
connectionJob = null

vpnProto?.protocol?.stopVpn()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package org.amnezia.vpn.protocol.wireguard

import android.net.VpnService.Builder
import java.io.IOException
import java.util.Locale
import java.util.TreeMap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.amnezia.awg.GoBackend
import org.amnezia.vpn.protocol.Protocol
import org.amnezia.vpn.protocol.ProtocolState.CONNECTED
Expand Down Expand Up @@ -79,12 +84,44 @@ open class Wireguard : Protocol() {
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 startTime = System.currentTimeMillis()
start(wireguardConfig, vpnBuilder, protect)
waitForConnection(startTime)
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 {
val configDataJson = config.getJSONObject("wireguard_config_data")
val configData = parseConfigData(configDataJson.getString("config"))
Expand Down
2 changes: 1 addition & 1 deletion client/android/xray/src/main/kotlin/Xray.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Log.w(TAG, "XRay already running")
return
Expand Down

0 comments on commit 46058f6

Please sign in to comment.