no signature in private message

This commit is contained in:
callebtc
2025-07-21 19:48:30 +02:00
parent bfb9a535ac
commit 0fb23f4c09
3 changed files with 90 additions and 6 deletions
@@ -64,7 +64,7 @@ class BluetoothMeshService(private val context: Context) {
// Wire up PacketProcessor reference for recursive handling in MessageHandler // Wire up PacketProcessor reference for recursive handling in MessageHandler
messageHandler.packetProcessor = packetProcessor messageHandler.packetProcessor = packetProcessor
// startPeriodicDebugLogging() startPeriodicDebugLogging()
} }
/** /**
@@ -491,7 +491,7 @@ class BluetoothMeshService(private val context: Context) {
if (encryptedPayload != null) { if (encryptedPayload != null) {
// Sign // Sign
val signature = securityManager.signPacket(encryptedPayload) // val signature = securityManager.signPacket(encryptedPayload)
val packet = BitchatPacket( val packet = BitchatPacket(
version = 1u, version = 1u,
@@ -500,7 +500,7 @@ class BluetoothMeshService(private val context: Context) {
recipientID = hexStringToByteArray(recipientPeerID), recipientID = hexStringToByteArray(recipientPeerID),
timestamp = System.currentTimeMillis().toULong(), timestamp = System.currentTimeMillis().toULong(),
payload = encryptedPayload, payload = encryptedPayload,
signature = signature, signature = null,
ttl = MAX_TTL ttl = MAX_TTL
) )
@@ -8,11 +8,20 @@ import android.util.Log
import com.bitchat.android.protocol.SpecialRecipients import com.bitchat.android.protocol.SpecialRecipients
import com.bitchat.android.model.RoutedPacket import com.bitchat.android.model.RoutedPacket
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.actor
/** /**
* Handles packet broadcasting to connected devices * Handles packet broadcasting to connected devices using actor pattern for serialization
*
* SERIALIZATION FIX: Uses Kotlin coroutine actor to serialize all packet broadcasting
* This prevents race conditions when multiple threads try to broadcast simultaneously
*/ */
class BluetoothPacketBroadcaster( class BluetoothPacketBroadcaster(
private val connectionScope: CoroutineScope, private val connectionScope: CoroutineScope,
@@ -25,6 +34,33 @@ class BluetoothPacketBroadcaster(
private const val CLEANUP_DELAY = 500L private const val CLEANUP_DELAY = 500L
} }
// Data class to hold broadcast request information
private data class BroadcastRequest(
val routed: RoutedPacket,
val gattServer: BluetoothGattServer?,
val characteristic: BluetoothGattCharacteristic?
)
// Actor scope for the broadcaster
private val broadcasterScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
// SERIALIZATION: Actor to serialize all broadcast operations
@OptIn(kotlinx.coroutines.ObsoleteCoroutinesApi::class)
private val broadcasterActor = broadcasterScope.actor<BroadcastRequest>(
capacity = Channel.UNLIMITED
) {
Log.d(TAG, "🎭 Created packet broadcaster actor")
try {
for (request in channel) {
Log.d(TAG, "Processing broadcast for packet type ${request.routed.packet.type} (serialized)")
broadcastSinglePacketInternal(request.routed, request.gattServer, request.characteristic)
Log.d(TAG, "Completed broadcast for packet type ${request.routed.packet.type}")
}
} finally {
Log.d(TAG, "🎭 Packet broadcaster actor terminated")
}
}
fun broadcastPacket( fun broadcastPacket(
routed: RoutedPacket, routed: RoutedPacket,
gattServer: BluetoothGattServer?, gattServer: BluetoothGattServer?,
@@ -54,12 +90,32 @@ class BluetoothPacketBroadcaster(
/** /**
* Broadcast single packet to connected devices with connection limit enforcement * Public entry point for broadcasting - submits request to actor for serialization
*/ */
fun broadcastSinglePacket( fun broadcastSinglePacket(
routed: RoutedPacket, routed: RoutedPacket,
gattServer: BluetoothGattServer?, gattServer: BluetoothGattServer?,
characteristic: BluetoothGattCharacteristic? characteristic: BluetoothGattCharacteristic?
) {
// Submit broadcast request to actor for serialized processing
broadcasterScope.launch {
try {
broadcasterActor.send(BroadcastRequest(routed, gattServer, characteristic))
} catch (e: Exception) {
Log.w(TAG, "Failed to send broadcast request to actor: ${e.message}")
// Fallback to direct processing if actor fails
broadcastSinglePacketInternal(routed, gattServer, characteristic)
}
}
}
/**
* Internal broadcast implementation - runs in serialized actor context
*/
private suspend fun broadcastSinglePacketInternal(
routed: RoutedPacket,
gattServer: BluetoothGattServer?,
characteristic: BluetoothGattCharacteristic?
) { ) {
val packet = routed.packet val packet = routed.packet
val data = packet.toBinaryData() ?: return val data = packet.toBinaryData() ?: return
@@ -177,4 +233,31 @@ class BluetoothPacketBroadcaster(
false false
} }
} }
/**
* Get debug information
*/
fun getDebugInfo(): String {
return buildString {
appendLine("=== Packet Broadcaster Debug Info ===")
appendLine("Broadcaster Scope Active: ${broadcasterScope.isActive}")
appendLine("Actor Channel Closed: ${broadcasterActor.isClosedForSend}")
appendLine("Connection Scope Active: ${connectionScope.isActive}")
}
}
/**
* Shutdown the broadcaster actor gracefully
*/
fun shutdown() {
Log.d(TAG, "Shutting down BluetoothPacketBroadcaster actor")
// Close the actor gracefully
broadcasterActor.close()
// Cancel the broadcaster scope
broadcasterScope.cancel()
Log.d(TAG, "BluetoothPacketBroadcaster shutdown complete")
}
} }
@@ -14,6 +14,7 @@ class FragmentManager {
companion object { companion object {
private const val TAG = "FragmentManager" private const val TAG = "FragmentManager"
private const val FRAGMENT_SIZE_THRESHOLD = 512 // 512 bytes
private const val MAX_FRAGMENT_SIZE = 500 // Match iOS/Rust for BLE compatibility (185 byte MTU limit) private const val MAX_FRAGMENT_SIZE = 500 // Match iOS/Rust for BLE compatibility (185 byte MTU limit)
private const val FRAGMENT_TIMEOUT = 30000L // 30 seconds private const val FRAGMENT_TIMEOUT = 30000L // 30 seconds
private const val CLEANUP_INTERVAL = 10000L // 10 seconds private const val CLEANUP_INTERVAL = 10000L // 10 seconds
@@ -39,7 +40,7 @@ class FragmentManager {
fun createFragments(packet: BitchatPacket): List<BitchatPacket> { fun createFragments(packet: BitchatPacket): List<BitchatPacket> {
val data = packet.toBinaryData() ?: return emptyList() val data = packet.toBinaryData() ?: return emptyList()
if (data.size <= MAX_FRAGMENT_SIZE) { if (data.size <= FRAGMENT_SIZE_THRESHOLD) {
return listOf(packet) // No fragmentation needed return listOf(packet) // No fragmentation needed
} }