fix: Use identity-based keying for fragmenters/reassemblers (MAC rotation immunity)
Critical fix for message delivery and Android MAC rotation support. **Problem:** - Fragmenters keyed by MAC address - Failed with "dev:" prefix mismatch - Would break on Android MAC rotation **Solution:** Use identity_hash for fragmenter/reassembler keys (with Protocol v1 MAC fallback). **Changes:** 1. Added _get_fragmenter_key() helper - returns identity_hash or normalized MAC 2. Updated _connect_to_peer() - creates fragmenters with identity keys 3. Updated BLEPeerInterface.processOutgoing() - looks up fragmenters with identity keys **Benefits:** - ✅ Fixes immediate "No fragmenter" bug - ✅ Survives Android MAC address rotation - ✅ Consistent with unified interface architecture - ✅ One fragmenter per peer identity (not per ephemeral MAC) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e7e9189983
commit
123bdc9200
1 changed files with 32 additions and 6 deletions
|
|
@ -1517,9 +1517,12 @@ class BLEInterface(Interface):
|
|||
self.peers[peer.address] = (client, time.time(), mtu)
|
||||
|
||||
# Create fragmenter for this peer's MTU
|
||||
# KEY CHANGE: Use identity_hash for keying (survives MAC rotation, fixes dev: prefix issue)
|
||||
frag_key = self._get_fragmenter_key(peer_identity, peer.address)
|
||||
with self.frag_lock:
|
||||
self.fragmenters[peer.address] = BLEFragmenter(mtu=mtu)
|
||||
self.reassemblers[peer.address] = BLEReassembler(timeout=self.connection_timeout)
|
||||
self.fragmenters[frag_key] = BLEFragmenter(mtu=mtu)
|
||||
self.reassemblers[frag_key] = BLEReassembler(timeout=self.connection_timeout)
|
||||
RNS.log(f"{self} created fragmenter/reassembler for peer (key: {frag_key[:16]})", RNS.LOG_DEBUG)
|
||||
|
||||
# Create or update unified peer interface with central connection
|
||||
self._spawn_or_update_peer_interface(
|
||||
|
|
@ -1633,6 +1636,27 @@ class BLEInterface(Interface):
|
|||
RNS.log(f"{self} failed to connect to {peer.name} ({peer.address}): "
|
||||
f"{error_type}: {e}, failures={peer.failed_connections}", RNS.LOG_WARNING)
|
||||
|
||||
def _get_fragmenter_key(self, peer_identity, peer_address):
|
||||
"""
|
||||
Compute fragmenter/reassembler dictionary key.
|
||||
|
||||
Uses identity_hash for Protocol v2 devices (survives MAC rotation),
|
||||
falls back to normalized MAC for Protocol v1 legacy devices.
|
||||
|
||||
Args:
|
||||
peer_identity: 16-byte peer identity (None for Protocol v1)
|
||||
peer_address: BLE MAC address (may have "dev:" prefix)
|
||||
|
||||
Returns:
|
||||
str: Identity hash (16 hex chars) or normalized MAC address
|
||||
"""
|
||||
if peer_identity:
|
||||
# Protocol v2: Use identity hash (immune to MAC rotation)
|
||||
return RNS.Identity.full_hash(peer_identity)[:16].hex()[:16]
|
||||
else:
|
||||
# Protocol v1 fallback: Use normalized MAC address
|
||||
return peer_address.replace("dev:", "")
|
||||
|
||||
def _spawn_or_update_peer_interface(self, address, name, peer_identity=None, client=None, mtu=None, connection_type="central"):
|
||||
"""
|
||||
Create or update a unified peer interface that can handle both central and peripheral connections.
|
||||
|
|
@ -2314,13 +2338,15 @@ class BLEPeerInterface(Interface):
|
|||
# Log packet transmission
|
||||
RNS.log(f"{self} TX: {len(data)} bytes to {self.peer_name}", RNS.LOG_DEBUG)
|
||||
|
||||
# Get fragmenter for this peer
|
||||
# Get fragmenter for this peer (using identity-based key for MAC rotation immunity)
|
||||
frag_key = self.parent_interface._get_fragmenter_key(self.peer_identity, self.peer_address)
|
||||
|
||||
with self.parent_interface.frag_lock:
|
||||
if self.peer_address not in self.parent_interface.fragmenters:
|
||||
RNS.log(f"No fragmenter for peer {self.peer_address}", RNS.LOG_WARNING)
|
||||
if frag_key not in self.parent_interface.fragmenters:
|
||||
RNS.log(f"No fragmenter for peer {self.peer_name} (key: {frag_key})", RNS.LOG_WARNING)
|
||||
return
|
||||
|
||||
fragmenter = self.parent_interface.fragmenters[self.peer_address]
|
||||
fragmenter = self.parent_interface.fragmenters[frag_key]
|
||||
|
||||
# Fragment the data
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue