mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-24 22:45:19 +00:00
Remove cover traffic functionality (#389)
- Remove cover traffic variables and timer - Remove cover traffic methods (startCoverTraffic, scheduleCoverTraffic, sendDummyMessage, generateDummyContent) - Remove cover traffic initialization in startSession() - Remove cover traffic check in handleReceivedPacket - Remove timer invalidation in reset() - Update README.md and AI_CONTEXT.md to remove cover traffic mentions Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
@@ -148,7 +148,6 @@ BitChat is a decentralized, peer-to-peer messaging application that works over B
|
||||
|
||||
### 4. Privacy Features
|
||||
- **Message Padding**: Obscures message length
|
||||
- **Cover Traffic**: Optional dummy messages
|
||||
- **Timing Obfuscation**: Randomized delays
|
||||
- **Emergency Wipe**: Triple-tap to clear all data
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ This project is released into the public domain. See the [LICENSE](LICENSE) file
|
||||
|
||||
- **Decentralized Mesh Network**: Automatic peer discovery and multi-hop message relay over Bluetooth LE
|
||||
- **Privacy First**: No accounts, no phone numbers, no persistent identifiers
|
||||
- **Cover Traffic**: Timing obfuscation and dummy messages for enhanced privacy
|
||||
- **Private Message End-to-End Encryption**: [Noise Protocol](http://noiseprotocol.org)
|
||||
- **Store & Forward**: Messages cached for offline peers and delivered when they reconnect
|
||||
- **IRC-Style Commands**: Familiar `/slap`, `/msg`, `/who` style interface
|
||||
|
||||
@@ -638,13 +638,6 @@ class BluetoothMeshService: NSObject {
|
||||
// Noise session state tracking for lazy handshakes
|
||||
private var noiseSessionStates: [String: LazyHandshakeState] = [:]
|
||||
|
||||
// MARK: - Cover Traffic
|
||||
|
||||
// Cover traffic for privacy
|
||||
private var coverTrafficTimer: Timer?
|
||||
private let coverTrafficPrefix = "☂DUMMY☂" // Prefix to identify dummy messages after decryption
|
||||
private var lastCoverTrafficTime = Date()
|
||||
|
||||
// MARK: - Connection State
|
||||
|
||||
// Connection state tracking
|
||||
@@ -1719,7 +1712,6 @@ class BluetoothMeshService: NSObject {
|
||||
// Invalidate other timers
|
||||
scanDutyCycleTimer?.invalidate()
|
||||
batteryMonitorTimer?.invalidate()
|
||||
coverTrafficTimer?.invalidate()
|
||||
bloomFilterResetTimer?.invalidate()
|
||||
aggregationTimer?.invalidate()
|
||||
cleanupTimer?.invalidate()
|
||||
@@ -1963,14 +1955,6 @@ class BluetoothMeshService: NSObject {
|
||||
|
||||
// Setup battery optimizer
|
||||
setupBatteryOptimizer()
|
||||
|
||||
// Start cover traffic for privacy (disabled by default for now)
|
||||
// TODO: Make this configurable in settings
|
||||
let coverTrafficEnabled = true
|
||||
if coverTrafficEnabled {
|
||||
SecureLogger.log("Cover traffic enabled", category: SecureLogger.security, level: .info)
|
||||
startCoverTraffic()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Consolidated Timer Management
|
||||
@@ -3668,11 +3652,6 @@ class BluetoothMeshService: NSObject {
|
||||
// Parse the message
|
||||
if let message = BitchatMessage.fromBinaryPayload(decryptedPayload) {
|
||||
|
||||
// Check if this is a dummy message for cover traffic
|
||||
if message.content.hasPrefix(self.coverTrafficPrefix) {
|
||||
return // Silently discard dummy messages
|
||||
}
|
||||
|
||||
// Check if this is a favorite/unfavorite notification
|
||||
if message.content.hasPrefix("SYSTEM:FAVORITED") || message.content.hasPrefix("SYSTEM:UNFAVORITED") {
|
||||
let parts = message.content.split(separator: ":")
|
||||
@@ -6209,85 +6188,6 @@ extension BluetoothMeshService: CBPeripheralManagerDelegate {
|
||||
category: SecureLogger.session, level: .debug)
|
||||
}
|
||||
|
||||
// MARK: - Cover Traffic
|
||||
|
||||
private func startCoverTraffic() {
|
||||
// Start cover traffic with random interval
|
||||
scheduleCoverTraffic()
|
||||
}
|
||||
|
||||
private func scheduleCoverTraffic() {
|
||||
// Random interval between 30-120 seconds
|
||||
let interval = TimeInterval.random(in: 30...120)
|
||||
|
||||
coverTrafficTimer?.invalidate()
|
||||
coverTrafficTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: false) { [weak self] _ in
|
||||
self?.sendDummyMessage()
|
||||
self?.scheduleCoverTraffic() // Schedule next dummy message
|
||||
}
|
||||
}
|
||||
|
||||
private func sendDummyMessage() {
|
||||
// Only send dummy messages if we have connected peers with established sessions
|
||||
let peersWithSessions = getAllConnectedPeerIDs().filter { peerID in
|
||||
return noiseService.hasEstablishedSession(with: peerID)
|
||||
}
|
||||
|
||||
guard !peersWithSessions.isEmpty else {
|
||||
SecureLogger.log("Cover traffic: No peers with established sessions, skipping dummy message",
|
||||
category: SecureLogger.security, level: .debug)
|
||||
return
|
||||
}
|
||||
|
||||
// Skip if battery is low
|
||||
if currentBatteryLevel < 0.2 {
|
||||
SecureLogger.log("Cover traffic: Battery low, skipping dummy message",
|
||||
category: SecureLogger.security, level: .debug)
|
||||
return
|
||||
}
|
||||
|
||||
// Pick a random peer with an established session to send to
|
||||
guard let randomPeer = peersWithSessions.randomElement() else { return }
|
||||
|
||||
// Generate random dummy content
|
||||
let dummyContent = generateDummyContent()
|
||||
|
||||
SecureLogger.log("Cover traffic: Sending dummy message to \(randomPeer)",
|
||||
category: SecureLogger.security, level: .info)
|
||||
|
||||
// Send as a private message so it's encrypted
|
||||
let recipientNickname = collectionsQueue.sync {
|
||||
return self.peerSessions[randomPeer]?.nickname ?? "unknown"
|
||||
}
|
||||
|
||||
sendPrivateMessage(dummyContent, to: randomPeer, recipientNickname: recipientNickname)
|
||||
}
|
||||
|
||||
private func generateDummyContent() -> String {
|
||||
// Generate realistic-looking dummy messages
|
||||
let templates = [
|
||||
"hey",
|
||||
"ok",
|
||||
"got it",
|
||||
"sure",
|
||||
"sounds good",
|
||||
"thanks",
|
||||
"np",
|
||||
"see you there",
|
||||
"on my way",
|
||||
"running late",
|
||||
"be there soon",
|
||||
"👍",
|
||||
"✓",
|
||||
"meeting at the usual spot",
|
||||
"confirmed",
|
||||
"roger that"
|
||||
]
|
||||
|
||||
// Prefix with dummy marker (will be encrypted)
|
||||
return coverTrafficPrefix + (templates.randomElement() ?? "ok")
|
||||
}
|
||||
|
||||
|
||||
private func updatePeerLastSeen(_ peerID: String) {
|
||||
peerLastSeenTimestamps.set(peerID, value: Date())
|
||||
|
||||
Reference in New Issue
Block a user