mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 22:25:20 +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
|
### 4. Privacy Features
|
||||||
- **Message Padding**: Obscures message length
|
- **Message Padding**: Obscures message length
|
||||||
- **Cover Traffic**: Optional dummy messages
|
|
||||||
- **Timing Obfuscation**: Randomized delays
|
- **Timing Obfuscation**: Randomized delays
|
||||||
- **Emergency Wipe**: Triple-tap to clear all data
|
- **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
|
- **Decentralized Mesh Network**: Automatic peer discovery and multi-hop message relay over Bluetooth LE
|
||||||
- **Privacy First**: No accounts, no phone numbers, no persistent identifiers
|
- **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)
|
- **Private Message End-to-End Encryption**: [Noise Protocol](http://noiseprotocol.org)
|
||||||
- **Store & Forward**: Messages cached for offline peers and delivered when they reconnect
|
- **Store & Forward**: Messages cached for offline peers and delivered when they reconnect
|
||||||
- **IRC-Style Commands**: Familiar `/slap`, `/msg`, `/who` style interface
|
- **IRC-Style Commands**: Familiar `/slap`, `/msg`, `/who` style interface
|
||||||
|
|||||||
@@ -638,13 +638,6 @@ class BluetoothMeshService: NSObject {
|
|||||||
// Noise session state tracking for lazy handshakes
|
// Noise session state tracking for lazy handshakes
|
||||||
private var noiseSessionStates: [String: LazyHandshakeState] = [:]
|
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
|
// MARK: - Connection State
|
||||||
|
|
||||||
// Connection state tracking
|
// Connection state tracking
|
||||||
@@ -1719,7 +1712,6 @@ class BluetoothMeshService: NSObject {
|
|||||||
// Invalidate other timers
|
// Invalidate other timers
|
||||||
scanDutyCycleTimer?.invalidate()
|
scanDutyCycleTimer?.invalidate()
|
||||||
batteryMonitorTimer?.invalidate()
|
batteryMonitorTimer?.invalidate()
|
||||||
coverTrafficTimer?.invalidate()
|
|
||||||
bloomFilterResetTimer?.invalidate()
|
bloomFilterResetTimer?.invalidate()
|
||||||
aggregationTimer?.invalidate()
|
aggregationTimer?.invalidate()
|
||||||
cleanupTimer?.invalidate()
|
cleanupTimer?.invalidate()
|
||||||
@@ -1963,14 +1955,6 @@ class BluetoothMeshService: NSObject {
|
|||||||
|
|
||||||
// Setup battery optimizer
|
// Setup battery optimizer
|
||||||
setupBatteryOptimizer()
|
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
|
// MARK: - Consolidated Timer Management
|
||||||
@@ -3668,11 +3652,6 @@ class BluetoothMeshService: NSObject {
|
|||||||
// Parse the message
|
// Parse the message
|
||||||
if let message = BitchatMessage.fromBinaryPayload(decryptedPayload) {
|
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
|
// Check if this is a favorite/unfavorite notification
|
||||||
if message.content.hasPrefix("SYSTEM:FAVORITED") || message.content.hasPrefix("SYSTEM:UNFAVORITED") {
|
if message.content.hasPrefix("SYSTEM:FAVORITED") || message.content.hasPrefix("SYSTEM:UNFAVORITED") {
|
||||||
let parts = message.content.split(separator: ":")
|
let parts = message.content.split(separator: ":")
|
||||||
@@ -6209,85 +6188,6 @@ extension BluetoothMeshService: CBPeripheralManagerDelegate {
|
|||||||
category: SecureLogger.session, level: .debug)
|
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) {
|
private func updatePeerLastSeen(_ peerID: String) {
|
||||||
peerLastSeenTimestamps.set(peerID, value: Date())
|
peerLastSeenTimestamps.set(peerID, value: Date())
|
||||||
|
|||||||
Reference in New Issue
Block a user