Avoid authentication callback queue starvation

This commit is contained in:
jack
2026-07-12 11:57:13 -04:00
parent 0288404e26
commit 34961b9ad6
+19 -14
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,23 +877,28 @@ 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) }
} handlers.legacy.forEach { handler in
self?.onPeerAuthenticatedHandlers.forEach { handler in handler(peerID, fingerprint)
handler(peerID, fingerprint)
}
} }
} }