mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-08 14:33:23 +00:00
feat: implement reconnection in AWG by turning the VPN off and on (#2046)
This commit is contained in:
@@ -93,7 +93,7 @@ open class OpenVpn : Protocol() {
|
|||||||
openVpnClient = null
|
openVpnClient = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reconnectVpn(vpnBuilder: Builder) {
|
override fun reconnectVpn(vpnBuilder: Builder, protect: (Int) -> Boolean) {
|
||||||
openVpnClient?.let {
|
openVpnClient?.let {
|
||||||
it.establish = makeEstablish(vpnBuilder)
|
it.establish = makeEstablish(vpnBuilder)
|
||||||
it.reconnect(0)
|
it.reconnect(0)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ abstract class Protocol {
|
|||||||
|
|
||||||
abstract fun stopVpn()
|
abstract fun stopVpn()
|
||||||
|
|
||||||
abstract fun reconnectVpn(vpnBuilder: Builder)
|
abstract fun reconnectVpn(vpnBuilder: Builder, protect: (Int) -> Boolean)
|
||||||
|
|
||||||
protected fun ProtocolConfig.Builder.configSplitTunneling(config: JSONObject) {
|
protected fun ProtocolConfig.Builder.configSplitTunneling(config: JSONObject) {
|
||||||
if (!allowSplitTunneling) {
|
if (!allowSplitTunneling) {
|
||||||
|
|||||||
@@ -565,7 +565,7 @@ open class AmneziaVpnService : VpnService() {
|
|||||||
protocolState.value = RECONNECTING
|
protocolState.value = RECONNECTING
|
||||||
|
|
||||||
connectionJob = connectionScope.launch {
|
connectionJob = connectionScope.launch {
|
||||||
vpnProto?.protocol?.reconnectVpn(Builder())
|
vpnProto?.protocol?.reconnectVpn(Builder(), ::protect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.amnezia.vpn.protocol.Protocol
|
|||||||
import org.amnezia.vpn.protocol.ProtocolState.CONNECTED
|
import org.amnezia.vpn.protocol.ProtocolState.CONNECTED
|
||||||
import org.amnezia.vpn.protocol.ProtocolState.DISCONNECTED
|
import org.amnezia.vpn.protocol.ProtocolState.DISCONNECTED
|
||||||
import org.amnezia.vpn.protocol.Statistics
|
import org.amnezia.vpn.protocol.Statistics
|
||||||
|
import org.amnezia.vpn.protocol.VpnException
|
||||||
import org.amnezia.vpn.protocol.VpnStartException
|
import org.amnezia.vpn.protocol.VpnStartException
|
||||||
import org.amnezia.vpn.util.LibraryLoader.loadSharedLibrary
|
import org.amnezia.vpn.util.LibraryLoader.loadSharedLibrary
|
||||||
import org.amnezia.vpn.util.Log
|
import org.amnezia.vpn.util.Log
|
||||||
@@ -27,6 +28,7 @@ private const val TAG = "Wireguard"
|
|||||||
open class Wireguard : Protocol() {
|
open class Wireguard : Protocol() {
|
||||||
|
|
||||||
private var tunnelHandle: Int = -1
|
private var tunnelHandle: Int = -1
|
||||||
|
private var config: WireguardConfig? = null // save config for reconnect
|
||||||
protected open val ifName: String = "amn0"
|
protected open val ifName: String = "amn0"
|
||||||
private lateinit var scope: CoroutineScope
|
private lateinit var scope: CoroutineScope
|
||||||
private var statusJob: Job? = null
|
private var statusJob: Job? = null
|
||||||
@@ -61,6 +63,7 @@ open class Wireguard : Protocol() {
|
|||||||
override suspend 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)
|
||||||
start(wireguardConfig, vpnBuilder, protect)
|
start(wireguardConfig, vpnBuilder, protect)
|
||||||
|
this.config = wireguardConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun parseConfig(config: JSONObject): WireguardConfig {
|
protected open fun parseConfig(config: JSONObject): WireguardConfig {
|
||||||
@@ -133,8 +136,13 @@ open class Wireguard : Protocol() {
|
|||||||
configData.optStringOrNull("I5")?.let { setI5(it) }
|
configData.optStringOrNull("I5")?.let { setI5(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun start(config: WireguardConfig, vpnBuilder: Builder, protect: (Int) -> Boolean) {
|
private fun start(
|
||||||
if (tunnelHandle != -1) {
|
config: WireguardConfig,
|
||||||
|
vpnBuilder: Builder,
|
||||||
|
protect: (Int) -> Boolean,
|
||||||
|
stopExistingVpn: Boolean = false
|
||||||
|
) {
|
||||||
|
if (!stopExistingVpn && tunnelHandle != -1) {
|
||||||
Log.w(TAG, "Tunnel already up")
|
Log.w(TAG, "Tunnel already up")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -142,6 +150,9 @@ open class Wireguard : Protocol() {
|
|||||||
buildVpnInterface(config, vpnBuilder)
|
buildVpnInterface(config, vpnBuilder)
|
||||||
|
|
||||||
vpnBuilder.establish().use { tunFd ->
|
vpnBuilder.establish().use { tunFd ->
|
||||||
|
if (stopExistingVpn && tunnelHandle != -1) {
|
||||||
|
turnOffVpn()
|
||||||
|
}
|
||||||
if (tunFd == null) {
|
if (tunFd == null) {
|
||||||
throw VpnStartException("Create VPN interface: permission not granted or revoked")
|
throw VpnStartException("Create VPN interface: permission not granted or revoked")
|
||||||
}
|
}
|
||||||
@@ -198,20 +209,25 @@ open class Wireguard : Protocol() {
|
|||||||
return lastHandshake
|
return lastHandshake
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun stopVpn() {
|
private fun turnOffVpn() {
|
||||||
if (tunnelHandle == -1) {
|
|
||||||
Log.w(TAG, "Tunnel already down")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
statusJob?.cancel()
|
statusJob?.cancel()
|
||||||
statusJob = null
|
statusJob = null
|
||||||
val handleToClose = tunnelHandle
|
val handleToClose = tunnelHandle
|
||||||
tunnelHandle = -1
|
tunnelHandle = -1
|
||||||
GoBackend.awgTurnOff(handleToClose)
|
GoBackend.awgTurnOff(handleToClose)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopVpn() {
|
||||||
|
if (tunnelHandle == -1) {
|
||||||
|
Log.w(TAG, "Tunnel already down")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
turnOffVpn()
|
||||||
state.value = DISCONNECTED
|
state.value = DISCONNECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reconnectVpn(vpnBuilder: Builder) {
|
override fun reconnectVpn(vpnBuilder: Builder, protect: (Int) -> Boolean) {
|
||||||
state.value = CONNECTED
|
val config = this.config ?: throw VpnException("Reconnect config is empty")
|
||||||
|
start(config, vpnBuilder, protect, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ class Xray : Protocol() {
|
|||||||
state.value = DISCONNECTED
|
state.value = DISCONNECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reconnectVpn(vpnBuilder: Builder) {
|
override fun reconnectVpn(vpnBuilder: Builder, protect: (Int) -> Boolean) {
|
||||||
state.value = CONNECTED
|
state.value = CONNECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user