fix: sync own messages

This commit is contained in:
callebtc
2025-09-15 15:23:33 +02:00
parent 7061a96cce
commit ca51e66951
4 changed files with 41 additions and 10 deletions
@@ -51,7 +51,14 @@ class BluetoothConnectionManager(
}
}
if (peerID == myPeerID) return // Ignore messages from self
// Normally ignore messages from self, but accept local-only sync responses (TTL=0)
if (peerID == myPeerID) {
if (packet.ttl == 0u.toUByte()) {
Log.d(TAG, "Accepting self-sender packet with TTL=0 (likely SYNC response)")
} else {
return // Ignore non-sync self packets
}
}
delegate?.onPacketReceived(packet, peerID, device)
}
@@ -179,7 +179,7 @@ class MessageHandler(private val myPeerID: String) {
val packet = routed.packet
val peerID = routed.peerID ?: "unknown"
if (peerID == myPeerID) return false
if (peerID == myPeerID && routed.packet.ttl != 0u.toUByte()) return false
// Try to decode as iOS-compatible IdentityAnnouncement with TLV format
val announcement = IdentityAnnouncement.decode(packet.payload)
@@ -304,7 +304,8 @@ class MessageHandler(private val myPeerID: String) {
suspend fun handleMessage(routed: RoutedPacket) {
val packet = routed.packet
val peerID = routed.peerID ?: "unknown"
if (peerID == myPeerID) return
// IMPORTANT: Allow TTL=0 self packets (sync responses) to flow through
if (peerID == myPeerID && packet.ttl != 0u.toUByte()) return
val senderNickname = delegate?.getPeerNickname(peerID)
if (senderNickname != null) {
Log.d(TAG, "Received message from $senderNickname")
@@ -331,8 +332,9 @@ class MessageHandler(private val myPeerID: String) {
val peerID = routed.peerID ?: "unknown"
// Enforce: only accept public messages from verified peers we know
// EXCEPTION: allow our own messages (peerID == myPeerID), e.g. TTL=0 sync responses
val peerInfo = delegate?.getPeerInfo(peerID)
if (peerInfo == null || !peerInfo.isVerifiedNickname) {
if (peerID != myPeerID && (peerInfo == null || !peerInfo.isVerifiedNickname)) {
Log.w(TAG, "🚫 Dropping public message from unverified or unknown peer ${peerID.take(8)}...")
return
}
@@ -340,7 +342,7 @@ class MessageHandler(private val myPeerID: String) {
try {
// Parse message
val message = BitchatMessage(
sender = delegate?.getPeerNickname(peerID) ?: "unknown",
sender = if (peerID == myPeerID) (delegate?.getMyNickname() ?: myPeerID) else (delegate?.getPeerNickname(peerID) ?: "unknown"),
content = String(packet.payload, Charsets.UTF_8),
senderPeerID = peerID,
timestamp = Date(packet.timestamp.toLong())
@@ -44,10 +44,16 @@ class SecurityManager(private val encryptionService: EncryptionService, private
* Validate packet security (timestamp, replay attacks, duplicates, signatures)
*/
fun validatePacket(packet: BitchatPacket, peerID: String): Boolean {
// Skip validation for our own packets
// Allow our own packets only when they are local-only (TTL=0) — used by SYNC responses
if (peerID == myPeerID) {
Log.d(TAG, "Skipping validation for our own packet")
return false
val isLocalOnly = packet.ttl == 0u.toUByte()
if (isLocalOnly) {
Log.d(TAG, "Accepting self packet due to TTL=0 (SYNC/local-only)")
// Intentionally continue to duplicate detection to avoid showing duplicates
} else {
Log.d(TAG, "Dropping non-local self packet during validation")
return false
}
}
// Validate packet payload
@@ -156,8 +156,12 @@ class GossipSyncManager(
return GCSFilter.contains(sorted, v)
}
// Track what we send per original sender peerID (hex)
data class SentStats(var announce: Boolean = false, var msgCount: Int = 0)
val sentBySender = mutableMapOf<String, SentStats>()
// 1) Announcements: send latest per peerID if remote doesn't have them
for ((_, pair) in latestAnnouncementByPeer.entries) {
for ((senderHex, pair) in latestAnnouncementByPeer.entries) {
val (id, pkt) = pair
val idBytes = hexToBytes(id)
if (!mightContain(idBytes)) {
@@ -165,6 +169,7 @@ class GossipSyncManager(
val toSend = pkt.copy(ttl = 0u)
delegate?.sendPacketToPeer(fromPeerID, toSend)
Log.d(TAG, "Sent sync announce: Type ${toSend.type} from ${toSend.senderID.toHexString()} to $fromPeerID packet id ${idBytes.toHexString()}")
sentBySender.getOrPut(senderHex) { SentStats() }.apply { announce = true }
}
}
@@ -176,6 +181,17 @@ class GossipSyncManager(
val toSend = pkt.copy(ttl = 0u)
delegate?.sendPacketToPeer(fromPeerID, toSend)
Log.d(TAG, "Sent sync message: Type ${toSend.type} to $fromPeerID packet id ${idBytes.toHexString()}")
val senderHex = pkt.senderID.joinToString("") { b -> "%02x".format(b) }
sentBySender.getOrPut(senderHex) { SentStats() }.apply { msgCount += 1 }
}
}
// Summary log per sender (original packet senderID)
if (sentBySender.isEmpty()) {
Log.d(TAG, "SYNC_RESPONSE summary to $fromPeerID: nothing to send")
} else {
for ((senderHex, stats) in sentBySender) {
Log.d(TAG, "SYNC_RESPONSE summary to $fromPeerID for sender $senderHex: announce=${stats.announce}, messages=${stats.msgCount}")
}
}
}