mirror of
https://github.com/wgtunnel/android.git
synced 2026-07-03 14:07:49 +02:00
fix: lockdown mode not fully cleaning up hev bridge
This commit is contained in:
+49
-48
@@ -29,60 +29,61 @@ class AndroidTunnelNotificationService(private val notificationService: Notifica
|
||||
|
||||
val context = notificationService.context
|
||||
|
||||
val formattedLines = tunnelNotificationLines.values.map { line ->
|
||||
val status = line.displayState.asLocalizedString(context)
|
||||
context.getString(
|
||||
R.string.notification_tunnel_status_format,
|
||||
line.name,
|
||||
status,
|
||||
)
|
||||
}
|
||||
val formattedLines =
|
||||
tunnelNotificationLines.values.map { line ->
|
||||
val status = line.displayState.asLocalizedString(context)
|
||||
context.getString(R.string.notification_tunnel_status_format, line.name, status)
|
||||
}
|
||||
|
||||
val description = formattedLines.joinToString("\n")
|
||||
|
||||
val actions = if (tunnelNotificationLines.size == 1) {
|
||||
val tunnelId = tunnelNotificationLines.keys.first()
|
||||
listOf(
|
||||
notificationService.createNotificationAction(
|
||||
notificationAction = NotificationAction.TUNNEL_OFF,
|
||||
extraId = tunnelId,
|
||||
val actions =
|
||||
if (tunnelNotificationLines.size == 1) {
|
||||
val tunnelId = tunnelNotificationLines.keys.first()
|
||||
listOf(
|
||||
notificationService.createNotificationAction(
|
||||
notificationAction = NotificationAction.TUNNEL_OFF,
|
||||
extraId = tunnelId,
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
listOf(
|
||||
notificationService.createNotificationAction(
|
||||
notificationAction = NotificationAction.STOP_ALL,
|
||||
extraId = null,
|
||||
} else {
|
||||
listOf(
|
||||
notificationService.createNotificationAction(
|
||||
notificationAction = NotificationAction.STOP_ALL,
|
||||
extraId = null,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val title =
|
||||
when (channel) {
|
||||
is NotificationChannels.Tunnel.VPN -> context.getString(R.string.vpn)
|
||||
is NotificationChannels.Tunnel.Proxy -> context.getString(R.string.proxy)
|
||||
}
|
||||
|
||||
val style =
|
||||
if (tunnelNotificationLines.size > 1) {
|
||||
NotificationCompat.InboxStyle()
|
||||
.setBigContentTitle(title)
|
||||
.setSummaryText(
|
||||
"${tunnelNotificationLines.size} ${context.getString(R.string.tunnels).lowercase()}"
|
||||
)
|
||||
.also { inboxStyle -> formattedLines.forEach { inboxStyle.addLine(it) } }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val notification =
|
||||
notificationService.createNotification(
|
||||
channel = channel,
|
||||
title = title,
|
||||
description = description,
|
||||
actions = actions,
|
||||
onGoing = true,
|
||||
onlyAlertOnce = true,
|
||||
groupKey = groupKey,
|
||||
style = style,
|
||||
)
|
||||
}
|
||||
|
||||
val title = when (channel) {
|
||||
is NotificationChannels.Tunnel.VPN -> context.getString(R.string.vpn)
|
||||
is NotificationChannels.Tunnel.Proxy -> context.getString(R.string.proxy)
|
||||
}
|
||||
|
||||
val style = if (tunnelNotificationLines.size > 1) {
|
||||
NotificationCompat.InboxStyle()
|
||||
.setBigContentTitle(title)
|
||||
.setSummaryText("${tunnelNotificationLines.size} ${context.getString(R.string.tunnels).lowercase()}")
|
||||
.also { inboxStyle ->
|
||||
formattedLines.forEach { inboxStyle.addLine(it) }
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val notification = notificationService.createNotification(
|
||||
channel = channel,
|
||||
title = title,
|
||||
description = description,
|
||||
actions = actions,
|
||||
onGoing = true,
|
||||
onlyAlertOnce = true,
|
||||
groupKey = groupKey,
|
||||
style = style,
|
||||
)
|
||||
|
||||
notificationService.show(notificationId, notification)
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.zaneschepke.tunnel.util.RootShellException
|
||||
import com.zaneschepke.tunnel.util.buildResolvedPeers
|
||||
import com.zaneschepke.tunnel.util.exponentialBackoffForever
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -208,7 +209,7 @@ internal class TunnelActor(
|
||||
|
||||
try {
|
||||
cmd.cmds?.forEach { cmd ->
|
||||
withTimeout(3_000) {
|
||||
withTimeout(3_000.milliseconds) {
|
||||
withContext(Dispatchers.IO) { RootShell.run(cmd) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,8 @@ class TunnelBackend(
|
||||
}
|
||||
|
||||
override suspend fun stop(id: Int): Result<Unit> = runCatching {
|
||||
// TODO need a clean localized message for this passed by provider
|
||||
// TODO need a clean localized message for this passed by provider, but this error should
|
||||
// never happen
|
||||
val runtime =
|
||||
actor.state.value.byTunnelId[id]
|
||||
?: throw BackendException.InternalError(
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.zaneschepke.tunnel.backend
|
||||
|
||||
import android.net.TrafficStats
|
||||
import com.zaneschepke.tunnel.ProxyBackend
|
||||
import com.zaneschepke.tunnel.Tunnel
|
||||
import com.zaneschepke.tunnel.VpnBackend
|
||||
import com.zaneschepke.tunnel.model.BackendMode
|
||||
import com.zaneschepke.tunnel.model.ProxyConfig
|
||||
import com.zaneschepke.tunnel.service.VpnService
|
||||
import com.zaneschepke.tunnel.service.VpnService.Companion.HEV_BRIDGE_TRAFFIC_TAG
|
||||
import com.zaneschepke.tunnel.state.EngineStartResult
|
||||
import com.zaneschepke.tunnel.state.EngineState
|
||||
import com.zaneschepke.tunnel.state.NativeTunnelStatus
|
||||
@@ -135,29 +137,45 @@ internal class WireGuardTunnelEngine(
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun getAvailablePort(): Int {
|
||||
ServerSocket(0).use { socket ->
|
||||
socket.reuseAddress = true
|
||||
return socket.localPort
|
||||
fun getAvailablePort(): Int {
|
||||
TrafficStats.setThreadStatsTag(HEV_BRIDGE_TRAFFIC_TAG)
|
||||
|
||||
try {
|
||||
ServerSocket(0).use {
|
||||
return it.localPort
|
||||
}
|
||||
} finally {
|
||||
TrafficStats.clearThreadStatsTag()
|
||||
}
|
||||
}
|
||||
|
||||
// omit peer endpoint while boostrapping
|
||||
// omit peer endpoint while bootstrapping
|
||||
private fun rewriteDynamicEndpoint(peer: PeerSection): PeerSection {
|
||||
return peer.copy(endpoint = null)
|
||||
}
|
||||
|
||||
override fun stop(handle: Int, mode: BackendMode) {
|
||||
when (mode) {
|
||||
is BackendMode.Proxy -> {
|
||||
ProxyBackend.awgTurnProxyTunnelOff(handle)
|
||||
}
|
||||
is BackendMode.Vpn -> {
|
||||
VpnBackend.awgTurnOff(handle)
|
||||
}
|
||||
is BackendMode.Proxy.Standard -> stopProxyTunnel(handle)
|
||||
is BackendMode.Vpn -> stopVpnTunnel(handle)
|
||||
is BackendMode.Proxy.KillSwitchPrimary -> stopKillSwitchPrimaryTunnel(handle)
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopKillSwitchPrimaryTunnel(handle: Int) {
|
||||
ProxyBackend.awgTurnProxyTunnelOff(handle)
|
||||
val service = serviceHolder.getVpnService()
|
||||
service.stopHevSocks5Bridge()
|
||||
}
|
||||
|
||||
private fun stopProxyTunnel(handle: Int) {
|
||||
ProxyBackend.awgTurnProxyTunnelOff(handle)
|
||||
}
|
||||
|
||||
private fun stopVpnTunnel(handle: Int) {
|
||||
VpnBackend.awgTurnOff(handle)
|
||||
}
|
||||
|
||||
private fun startVpnTunnel(tunnel: Tunnel, ifName: String, config: Config): Int {
|
||||
|
||||
val service = serviceHolder.getVpnService()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.zaneschepke.tunnel.service
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.TrafficStats
|
||||
import android.os.Build
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.system.OsConstants
|
||||
@@ -105,6 +106,7 @@ class VpnService : android.net.VpnService(), KillSwitch, SocketProtector {
|
||||
|
||||
private fun startHevBridge(port: Int, pass: String): Job {
|
||||
val job = serviceScope.launch {
|
||||
TrafficStats.setThreadStatsTag(HEV_BRIDGE_TRAFFIC_TAG)
|
||||
try {
|
||||
val vpnFd = fd ?: throw IOException("No VPN interface fd available")
|
||||
|
||||
@@ -145,6 +147,8 @@ class VpnService : android.net.VpnService(), KillSwitch, SocketProtector {
|
||||
Timber.e("Timed out waiting for SOCKS5 proxy to be ready")
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Failed to start HEV bridge")
|
||||
} finally {
|
||||
TrafficStats.clearThreadStatsTag()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +286,7 @@ class VpnService : android.net.VpnService(), KillSwitch, SocketProtector {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val HEV_BRIDGE_TRAFFIC_TAG = 0xF00D
|
||||
private const val LOCKDOWN_SESSION_NAME = "Lockdown"
|
||||
private const val LOCALHOST = "127.0.0.1"
|
||||
private const val IPV4_INTERFACE_ADDRESS = "10.0.0.1"
|
||||
|
||||
Reference in New Issue
Block a user