Avoid authentication callback queue starvation

This commit is contained in:
jack
2026-07-25 20:39:29 +02:00
committed by jack
parent 4ba895e4ce
commit aee5bee8e8
+16 -11
View File
@@ -192,8 +192,8 @@ final class NoiseEncryptionService {
// Add a handler for peer authentication // Add a handler for peer authentication
func addOnPeerAuthenticatedHandler(_ handler: @escaping (PeerID, String) -> Void) { func addOnPeerAuthenticatedHandler(_ handler: @escaping (PeerID, String) -> Void) {
serviceQueue.async(flags: .barrier) { [weak self] in serviceQueue.sync(flags: .barrier) {
self?.onPeerAuthenticatedHandlers.append(handler) onPeerAuthenticatedHandlers.append(handler)
} }
} }
@@ -213,8 +213,8 @@ final class NoiseEncryptionService {
get { nil } get { nil }
set { set {
guard let handler = newValue else { return } guard let handler = newValue else { return }
serviceQueue.async(flags: .barrier) { [weak self] in serviceQueue.sync(flags: .barrier) {
self?.onPeerAuthenticatedWithGenerationHandlers.append(handler) onPeerAuthenticatedWithGenerationHandlers.append(handler)
} }
} }
} }
@@ -877,25 +877,30 @@ final class NoiseEncryptionService {
// Calculate fingerprint // Calculate fingerprint
let fingerprint = remoteStaticKey.rawRepresentation.sha256Fingerprint() let fingerprint = remoteStaticKey.rawRepresentation.sha256Fingerprint()
// Store fingerprint mapping // Registering handlers is synchronous, and this barrier snapshots them
serviceQueue.sync(flags: .barrier) { // with the fingerprint update. Invoke the snapshot outside the queue:
// parallel Swift Testing workers must not block behind queued callback
// registration or allow a handler to re-enter serviceQueue.
let handlers: (
generationAware: [(PeerID, String, UUID) -> Void],
legacy: [(PeerID, String) -> Void]
) = serviceQueue.sync(flags: .barrier) {
peerFingerprints[peerID] = fingerprint peerFingerprints[peerID] = fingerprint
fingerprintToPeerID[fingerprint] = peerID fingerprintToPeerID[fingerprint] = peerID
return (onPeerAuthenticatedWithGenerationHandlers, onPeerAuthenticatedHandlers)
} }
// Log security event // Log security event
SecureLogger.info(.handshakeCompleted(peerID: peerID.id)) SecureLogger.info(.handshakeCompleted(peerID: peerID.id))
// Notify all handlers about authentication // Notify all handlers about authentication.
serviceQueue.async { [weak self] in handlers.generationAware.forEach { handler in
self?.onPeerAuthenticatedWithGenerationHandlers.forEach { handler in
handler(peerID, fingerprint, sessionGeneration) handler(peerID, fingerprint, sessionGeneration)
} }
self?.onPeerAuthenticatedHandlers.forEach { handler in handlers.legacy.forEach { handler in
handler(peerID, fingerprint) handler(peerID, fingerprint)
} }
} }
}
// MARK: - Session Maintenance // MARK: - Session Maintenance