mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 13:05:18 +00:00
Update NoiseRateLimiter to use Peer
This commit is contained in:
@@ -132,8 +132,8 @@ final class SecureNoiseSession: NoiseSession {
|
|||||||
// MARK: - Rate Limiter
|
// MARK: - Rate Limiter
|
||||||
|
|
||||||
final class NoiseRateLimiter {
|
final class NoiseRateLimiter {
|
||||||
private var handshakeTimestamps: [String: [Date]] = [:] // peerID -> timestamps
|
private var handshakeTimestamps: [Peer: [Date]] = [:] // Peer -> timestamps
|
||||||
private var messageTimestamps: [String: [Date]] = [:] // peerID -> timestamps
|
private var messageTimestamps: [Peer: [Date]] = [:] // Peer -> timestamps
|
||||||
|
|
||||||
// Global rate limiting
|
// Global rate limiting
|
||||||
private var globalHandshakeTimestamps: [Date] = []
|
private var globalHandshakeTimestamps: [Date] = []
|
||||||
@@ -141,7 +141,7 @@ final class NoiseRateLimiter {
|
|||||||
|
|
||||||
private let queue = DispatchQueue(label: "chat.bitchat.noise.ratelimit", attributes: .concurrent)
|
private let queue = DispatchQueue(label: "chat.bitchat.noise.ratelimit", attributes: .concurrent)
|
||||||
|
|
||||||
func allowHandshake(from peerID: String) -> Bool {
|
func allowHandshake(from peer: Peer) -> Bool {
|
||||||
return queue.sync(flags: .barrier) {
|
return queue.sync(flags: .barrier) {
|
||||||
let now = Date()
|
let now = Date()
|
||||||
let oneMinuteAgo = now.addingTimeInterval(-60)
|
let oneMinuteAgo = now.addingTimeInterval(-60)
|
||||||
@@ -154,23 +154,23 @@ final class NoiseRateLimiter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check per-peer rate limit
|
// Check per-peer rate limit
|
||||||
var timestamps = handshakeTimestamps[peerID] ?? []
|
var timestamps = handshakeTimestamps[peer] ?? []
|
||||||
timestamps = timestamps.filter { $0 > oneMinuteAgo }
|
timestamps = timestamps.filter { $0 > oneMinuteAgo }
|
||||||
|
|
||||||
if timestamps.count >= NoiseSecurityConstants.maxHandshakesPerMinute {
|
if timestamps.count >= NoiseSecurityConstants.maxHandshakesPerMinute {
|
||||||
SecureLogger.warning("Per-peer handshake rate limit exceeded for \(peerID): \(timestamps.count)/\(NoiseSecurityConstants.maxHandshakesPerMinute) per minute", category: .security)
|
SecureLogger.warning("Per-peer handshake rate limit exceeded for \(peer.id): \(timestamps.count)/\(NoiseSecurityConstants.maxHandshakesPerMinute) per minute", category: .security)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record new handshake
|
// Record new handshake
|
||||||
timestamps.append(now)
|
timestamps.append(now)
|
||||||
handshakeTimestamps[peerID] = timestamps
|
handshakeTimestamps[peer] = timestamps
|
||||||
globalHandshakeTimestamps.append(now)
|
globalHandshakeTimestamps.append(now)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func allowMessage(from peerID: String) -> Bool {
|
func allowMessage(from peer: Peer) -> Bool {
|
||||||
return queue.sync(flags: .barrier) {
|
return queue.sync(flags: .barrier) {
|
||||||
let now = Date()
|
let now = Date()
|
||||||
let oneSecondAgo = now.addingTimeInterval(-1)
|
let oneSecondAgo = now.addingTimeInterval(-1)
|
||||||
@@ -183,26 +183,26 @@ final class NoiseRateLimiter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check per-peer rate limit
|
// Check per-peer rate limit
|
||||||
var timestamps = messageTimestamps[peerID] ?? []
|
var timestamps = messageTimestamps[peer] ?? []
|
||||||
timestamps = timestamps.filter { $0 > oneSecondAgo }
|
timestamps = timestamps.filter { $0 > oneSecondAgo }
|
||||||
|
|
||||||
if timestamps.count >= NoiseSecurityConstants.maxMessagesPerSecond {
|
if timestamps.count >= NoiseSecurityConstants.maxMessagesPerSecond {
|
||||||
SecureLogger.warning("Per-peer message rate limit exceeded for \(peerID): \(timestamps.count)/\(NoiseSecurityConstants.maxMessagesPerSecond) per second", category: .security)
|
SecureLogger.warning("Per-peer message rate limit exceeded for \(peer.id): \(timestamps.count)/\(NoiseSecurityConstants.maxMessagesPerSecond) per second", category: .security)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record new message
|
// Record new message
|
||||||
timestamps.append(now)
|
timestamps.append(now)
|
||||||
messageTimestamps[peerID] = timestamps
|
messageTimestamps[peer] = timestamps
|
||||||
globalMessageTimestamps.append(now)
|
globalMessageTimestamps.append(now)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reset(for peerID: String) {
|
func reset(for peer: Peer) {
|
||||||
queue.async(flags: .barrier) {
|
queue.async(flags: .barrier) {
|
||||||
self.handshakeTimestamps.removeValue(forKey: peerID)
|
self.handshakeTimestamps.removeValue(forKey: peer)
|
||||||
self.messageTimestamps.removeValue(forKey: peerID)
|
self.messageTimestamps.removeValue(forKey: peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ final class NoiseEncryptionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rate limit
|
// Check rate limit
|
||||||
guard rateLimiter.allowHandshake(from: peerID) else {
|
guard rateLimiter.allowHandshake(from: Peer(str: peerID)) else {
|
||||||
SecureLogger.warning(.authenticationFailed(peerID: "Rate limited: \(peerID)"))
|
SecureLogger.warning(.authenticationFailed(peerID: "Rate limited: \(peerID)"))
|
||||||
throw NoiseSecurityError.rateLimitExceeded
|
throw NoiseSecurityError.rateLimitExceeded
|
||||||
}
|
}
|
||||||
@@ -429,7 +429,7 @@ final class NoiseEncryptionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rate limit
|
// Check rate limit
|
||||||
guard rateLimiter.allowHandshake(from: peerID) else {
|
guard rateLimiter.allowHandshake(from: Peer(str: peerID)) else {
|
||||||
SecureLogger.warning(.authenticationFailed(peerID: "Rate limited: \(peerID)"))
|
SecureLogger.warning(.authenticationFailed(peerID: "Rate limited: \(peerID)"))
|
||||||
throw NoiseSecurityError.rateLimitExceeded
|
throw NoiseSecurityError.rateLimitExceeded
|
||||||
}
|
}
|
||||||
@@ -463,7 +463,7 @@ final class NoiseEncryptionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rate limit
|
// Check rate limit
|
||||||
guard rateLimiter.allowMessage(from: peerID) else {
|
guard rateLimiter.allowMessage(from: Peer(str: peerID)) else {
|
||||||
throw NoiseSecurityError.rateLimitExceeded
|
throw NoiseSecurityError.rateLimitExceeded
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +485,7 @@ final class NoiseEncryptionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rate limit
|
// Check rate limit
|
||||||
guard rateLimiter.allowMessage(from: peerID) else {
|
guard rateLimiter.allowMessage(from: Peer(str: peerID)) else {
|
||||||
throw NoiseSecurityError.rateLimitExceeded
|
throw NoiseSecurityError.rateLimitExceeded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user