mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 23:45:19 +00:00
fix: sync own messages
This commit is contained in:
@@ -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}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user