fix(android): Handle case where connlibSessionPtr can be null in NetworkMonitor (#5496)

Connlib session pointer can be null if the service was shutdown before
the NetworkMonitor has stopped, causing a race condition.

Fixes #4758
This commit is contained in:
Jamil
2024-06-26 11:24:23 -07:00
committed by GitHub
parent f80e550c77
commit a097732f5d
3 changed files with 59 additions and 15 deletions

View File

@@ -18,20 +18,28 @@ class NetworkMonitor(private val tunnelService: TunnelService) : ConnectivityMan
linkProperties: LinkProperties,
) {
Log.d("NetworkMonitor", "OnLinkPropertiesChanged: $network: $linkProperties")
if (tunnelService.tunnelState != TunnelService.Companion.State.UP) {
tunnelService.tunnelState = TunnelService.Companion.State.UP
tunnelService.updateStatusNotification(TunnelStatusNotification.Connected)
// Acquire mutex lock
if (tunnelService.lock.tryLock()) {
if (tunnelService.tunnelState != TunnelService.Companion.State.UP) {
tunnelService.tunnelState = TunnelService.Companion.State.UP
tunnelService.updateStatusNotification(TunnelStatusNotification.Connected)
}
if (lastDns != linkProperties.dnsServers) {
lastDns = linkProperties.dnsServers
ConnlibSession.setDns(tunnelService.connlibSessionPtr!!, Gson().toJson(linkProperties.dnsServers))
}
if (lastNetwork != network) {
lastNetwork = network
ConnlibSession.reconnect(tunnelService.connlibSessionPtr!!)
}
// Release mutex lock
tunnelService.lock.unlock()
}
if (lastDns != linkProperties.dnsServers) {
lastDns = linkProperties.dnsServers
ConnlibSession.setDns(tunnelService.connlibSessionPtr!!, Gson().toJson(linkProperties.dnsServers))
}
if (lastNetwork != network) {
lastNetwork = network
ConnlibSession.reconnect(tunnelService.connlibSessionPtr!!)
}
super.onLinkPropertiesChanged(network, linkProperties)
}
}

View File

@@ -29,6 +29,7 @@ import dev.firezone.android.tunnel.model.Resource
import java.nio.file.Files
import java.nio.file.Paths
import java.util.UUID
import java.util.concurrent.locks.ReentrantLock
import javax.inject.Inject
@AndroidEntryPoint
@@ -51,6 +52,10 @@ class TunnelService : VpnService() {
private var _tunnelState: State = State.DOWN
private var networkCallback: NetworkMonitor? = null
// General purpose mutex lock for preventing network monitoring from calling connlib
// during shutdown.
val lock = ReentrantLock()
var startedByUser: Boolean = false
var connlibSessionPtr: Long? = null
@@ -131,6 +136,8 @@ class TunnelService : VpnService() {
Log.d(TAG, "onDisconnect: $error")
Firebase.crashlytics.log("onDisconnect: $error")
stopNetworkMonitoring()
// Clear any user tokens and actorNames
repo.clearToken()
repo.clearActorName()
@@ -209,19 +216,24 @@ class TunnelService : VpnService() {
fun disconnect() {
Log.d(TAG, "disconnect")
// Connlib should call onDisconnect() when it's done, with no error.
// Acquire mutex lock
lock.lock()
stopNetworkMonitoring()
connlibSessionPtr?.let {
ConnlibSession.disconnect(it)
}
shutdown()
// Release mutex lock
lock.unlock()
}
private fun shutdown() {
Log.d(TAG, "shutdown")
stopNetworkMonitoring()
connlibSessionPtr = null
stopSelf()
tunnelState = State.DOWN

View File

@@ -0,0 +1,24 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/aws" {
version = "5.55.0"
hashes = [
"h1:vChl08zNYLVzuSzfxz3wp3wNSx+vjwl/jPuyPbg59Ks=",
"zh:06fbb1cc4b61b9d6370d391bf7538aa6ef8b60b91c67d125a6be60a70b1d49f0",
"zh:1d52acd2184f379433a0fce2c29d5ed8fc7958d6a9d1b403310dcc36b2a3f626",
"zh:290bbce092f8836a1db530ac86d933cfea27d52b827639974a81bc48dfba8c34",
"zh:3531f2822c2de3ba837381c4ee4816c5b437fd204c07d659526a04d9154a65e8",
"zh:56d70db4c8c6c0ec1b665380b87726275f4ab3665b4b78ac86dc90e1010c0fe3",
"zh:8251d713c0b2c8c51b6858e51c70d083b484342ff9782a88c39e7eaa966c3da2",
"zh:9a7d1f7207e51382a7dd139dfd5786e7e905edf9bf89bbee4b59ad41365e87be",
"zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
"zh:a529c78dfc60063289524690af78794e99a768835b88e27cdfec15bc85439f7c",
"zh:b6da1843355db05c5d412126406fd97db2a6ff9edc166b81c1cea2994535b4eb",
"zh:bfc08cd23b1556b3287d1b28ac7f12c7d459471d97a0592bf2579ea68d11bae7",
"zh:c382088faf05894191636b57861069a21de10a5ff4eb8f7cc122e764ccf7a4a8",
"zh:e27f99f389921314ee428b24990d3a829057ce532b2beb33c69387458722edd9",
"zh:ef11285eedb45ffc3fb2ecdfefa206e64eb2760a87fff15c44dee42de9703436",
"zh:fedc4ebee0d6fe196691127004db5d1ff8bd22e3b667a74026bb92c607589b6c",
]
}