mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 20:45:19 +00:00
Fix session destruction race condition causing handshake delays
Root cause: When receiving a handshake initiation (32 bytes) from a peer with whom we already had an established session, the code would destroy the existing session to "help" the other side. This created a cascade: - Peer A completes handshake with Peer B - Peer A sends message, realizes no session, initiates handshake - Peer B destroys its working session to "help" - Peer B now has no session, initiates handshake - Both peers keep destroying each other's sessions Fix: - Never destroy an established session when receiving new handshake attempts - Add early check in handshake initiation to skip if session exists - Clear handshake rate limit timers when session already established This eliminates the delays and repeated handshakes seen in the logs.
This commit is contained in:
@@ -319,18 +319,11 @@ class NoiseSessionManager {
|
|||||||
var existingSession: NoiseSession? = nil
|
var existingSession: NoiseSession? = nil
|
||||||
|
|
||||||
if let existing = sessions[peerID] {
|
if let existing = sessions[peerID] {
|
||||||
// If we have an established session, we might need to help the other side complete theirs
|
// If we have an established session, reject new handshake attempts
|
||||||
if existing.isEstablished() {
|
if existing.isEstablished() {
|
||||||
// If this is a handshake initiation (32 bytes), the other side doesn't have a session
|
// Don't destroy our working session just because the other side is confused
|
||||||
// We should complete the handshake to help them establish their session
|
// They should detect the established session through successful message exchange
|
||||||
if message.count == 32 {
|
throw NoiseSessionError.alreadyEstablished
|
||||||
// Remove existing session and create new one
|
|
||||||
sessions.removeValue(forKey: peerID)
|
|
||||||
shouldCreateNew = true
|
|
||||||
} else {
|
|
||||||
// For other handshake messages, ignore if already established
|
|
||||||
throw NoiseSessionError.alreadyEstablished
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// If we're in the middle of a handshake and receive a new initiation,
|
// If we're in the middle of a handshake and receive a new initiation,
|
||||||
// reset and start fresh (the other side may have restarted)
|
// reset and start fresh (the other side may have restarted)
|
||||||
|
|||||||
@@ -3368,6 +3368,14 @@ extension BluetoothMeshService: CBPeripheralManagerDelegate {
|
|||||||
|
|
||||||
SecurityLogger.log("Initiating Noise handshake with \(peerID)", category: SecurityLogger.noise, level: .info)
|
SecurityLogger.log("Initiating Noise handshake with \(peerID)", category: SecurityLogger.noise, level: .info)
|
||||||
|
|
||||||
|
// Check if we already have an established session
|
||||||
|
if noiseService.hasEstablishedSession(with: peerID) {
|
||||||
|
SecurityLogger.log("Already have established session with \(peerID)", category: SecurityLogger.noise, level: .debug)
|
||||||
|
// Clear any lingering handshake attempt time
|
||||||
|
handshakeAttemptTimes.removeValue(forKey: peerID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we've recently tried to handshake with this peer
|
// Check if we've recently tried to handshake with this peer
|
||||||
if let lastAttempt = handshakeAttemptTimes[peerID],
|
if let lastAttempt = handshakeAttemptTimes[peerID],
|
||||||
Date().timeIntervalSince(lastAttempt) < handshakeTimeout {
|
Date().timeIntervalSince(lastAttempt) < handshakeTimeout {
|
||||||
|
|||||||
Reference in New Issue
Block a user