mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 17:25:20 +00:00
Guard BLE link state lookups on BLE queue (#805)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
@@ -1514,6 +1514,22 @@ extension BLEService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Safely fetch the current direct-link state for a peer using the BLE queue.
|
||||||
|
private func linkState(for peerID: PeerID) -> (hasPeripheral: Bool, hasCentral: Bool) {
|
||||||
|
let computeState = { () -> (Bool, Bool) in
|
||||||
|
let peripheralUUID = self.peerToPeripheralUUID[peerID]
|
||||||
|
let hasPeripheral = peripheralUUID.flatMap { self.peripherals[$0]?.isConnected } ?? false
|
||||||
|
let hasCentral = self.centralToPeerID.values.contains(peerID)
|
||||||
|
return (hasPeripheral, hasCentral)
|
||||||
|
}
|
||||||
|
|
||||||
|
if DispatchQueue.getSpecific(key: bleQueueKey) != nil {
|
||||||
|
return computeState()
|
||||||
|
} else {
|
||||||
|
return bleQueue.sync { computeState() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func configureNoiseServiceCallbacks(for service: NoiseEncryptionService) {
|
private func configureNoiseServiceCallbacks(for service: NoiseEncryptionService) {
|
||||||
service.onPeerAuthenticated = { [weak self] peerID, fingerprint in
|
service.onPeerAuthenticated = { [weak self] peerID, fingerprint in
|
||||||
let peerID = PeerID(str: peerID)
|
let peerID = PeerID(str: peerID)
|
||||||
@@ -2458,15 +2474,15 @@ extension BLEService {
|
|||||||
// Track if this is a new or reconnected peer
|
// Track if this is a new or reconnected peer
|
||||||
var isNewPeer = false
|
var isNewPeer = false
|
||||||
var isReconnectedPeer = false
|
var isReconnectedPeer = false
|
||||||
|
let directLinkState = linkState(for: peerID)
|
||||||
|
|
||||||
collectionsQueue.sync(flags: .barrier) {
|
collectionsQueue.sync(flags: .barrier) {
|
||||||
// Check if we have an actual BLE connection to this peer
|
// Check if we have an actual BLE connection to this peer
|
||||||
let peripheralUUID = peerToPeripheralUUID[peerID]
|
let hasPeripheralConnection = directLinkState.hasPeripheral
|
||||||
let hasPeripheralConnection = peripheralUUID != nil && peripherals[peripheralUUID!]?.isConnected == true
|
|
||||||
|
|
||||||
// Check if this peer is subscribed to us as a central
|
// Check if this peer is subscribed to us as a central
|
||||||
// Note: We can't identify which specific central is which peer without additional mapping
|
// Note: We can't identify which specific central is which peer without additional mapping
|
||||||
let hasCentralSubscription = centralToPeerID.values.contains(peerID)
|
let hasCentralSubscription = directLinkState.hasCentral
|
||||||
|
|
||||||
// Direct announces arrive with full TTL (no prior hop)
|
// Direct announces arrive with full TTL (no prior hop)
|
||||||
let isDirectAnnounce = (packet.ttl == messageTTL)
|
let isDirectAnnounce = (packet.ttl == messageTTL)
|
||||||
@@ -2698,12 +2714,8 @@ extension BLEService {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Determine if we have a direct link to the sender
|
// Determine if we have a direct link to the sender
|
||||||
let hasDirectLink: Bool = collectionsQueue.sync {
|
let directLink = linkState(for: peerID)
|
||||||
let perUUID = peerToPeripheralUUID[peerID]
|
let hasDirectLink = directLink.hasPeripheral || directLink.hasCentral
|
||||||
let perConnected = perUUID != nil && peripherals[perUUID!]?.isConnected == true
|
|
||||||
let hasCentral = centralToPeerID.values.contains(peerID)
|
|
||||||
return perConnected || hasCentral
|
|
||||||
}
|
|
||||||
|
|
||||||
let pathTag = hasDirectLink ? "direct" : "mesh"
|
let pathTag = hasDirectLink ? "direct" : "mesh"
|
||||||
SecureLogger.debug("💬 [\(senderNickname)] TTL:\(packet.ttl) (\(pathTag)): \(String(content.prefix(50)))\(content.count > 50 ? "..." : "")", category: .session)
|
SecureLogger.debug("💬 [\(senderNickname)] TTL:\(packet.ttl) (\(pathTag)): \(String(content.prefix(50)))\(content.count > 50 ? "..." : "")", category: .session)
|
||||||
@@ -3046,6 +3058,11 @@ extension BLEService {
|
|||||||
private func checkPeerConnectivity() {
|
private func checkPeerConnectivity() {
|
||||||
let now = Date()
|
let now = Date()
|
||||||
var disconnectedPeers: [String] = []
|
var disconnectedPeers: [String] = []
|
||||||
|
let peerIDsForLinkState: [PeerID] = collectionsQueue.sync { Array(peers.keys) }
|
||||||
|
var cachedLinkStates: [PeerID: (hasPeripheral: Bool, hasCentral: Bool)] = [:]
|
||||||
|
for peerID in peerIDsForLinkState {
|
||||||
|
cachedLinkStates[peerID] = linkState(for: peerID)
|
||||||
|
}
|
||||||
|
|
||||||
var removedOfflineCount = 0
|
var removedOfflineCount = 0
|
||||||
collectionsQueue.sync(flags: .barrier) {
|
collectionsQueue.sync(flags: .barrier) {
|
||||||
@@ -3054,9 +3071,9 @@ extension BLEService {
|
|||||||
let retention: TimeInterval = peer.isVerifiedNickname ? TransportConfig.bleReachabilityRetentionVerifiedSeconds : TransportConfig.bleReachabilityRetentionUnverifiedSeconds
|
let retention: TimeInterval = peer.isVerifiedNickname ? TransportConfig.bleReachabilityRetentionVerifiedSeconds : TransportConfig.bleReachabilityRetentionUnverifiedSeconds
|
||||||
if peer.isConnected && age > TransportConfig.blePeerInactivityTimeoutSeconds {
|
if peer.isConnected && age > TransportConfig.blePeerInactivityTimeoutSeconds {
|
||||||
// Check if we still have an active BLE connection to this peer
|
// Check if we still have an active BLE connection to this peer
|
||||||
let hasPeripheralConnection = peerToPeripheralUUID[peerID] != nil &&
|
let state = cachedLinkStates[peerID] ?? (hasPeripheral: false, hasCentral: false)
|
||||||
peripherals[peerToPeripheralUUID[peerID]!]?.isConnected == true
|
let hasPeripheralConnection = state.hasPeripheral
|
||||||
let hasCentralConnection = centralToPeerID.values.contains(peerID)
|
let hasCentralConnection = state.hasCentral
|
||||||
|
|
||||||
// If direct link is gone, mark as not connected (retain entry for reachability)
|
// If direct link is gone, mark as not connected (retain entry for reachability)
|
||||||
if !hasPeripheralConnection && !hasCentralConnection {
|
if !hasPeripheralConnection && !hasCentralConnection {
|
||||||
|
|||||||
Reference in New Issue
Block a user