fix(router): never forward control packets to the engine

MeshCore never relays control packets: the direct high-bit discovery
subset is explicitly released and any other control payload hits the
switch default that does not flood-route unknown types. Mark control
packets do-not-retransmit unconditionally instead of only when discovery
is enabled, so a repeater with discovery disabled no longer forwards
control/discovery traffic.
This commit is contained in:
agessaman
2026-07-13 20:40:22 -07:00
parent 62ad7424c2
commit 059065ce9c
2 changed files with 21 additions and 1 deletions
+8 -1
View File
@@ -475,10 +475,17 @@ class PacketRouter:
# as routing hashes and log bogus duplicate rows.
elif payload_type == ControlHandler.payload_type():
# MeshCore never relays control packets: the direct high-bit discovery
# subset is explicitly released (Mesh.cpp), and any other control
# payload hits the switch default that does not flood-route unknown
# types. Mark do-not-retransmit unconditionally so a repeater with
# discovery disabled still does not forward control/discovery traffic
# to the engine. Discovery responses are injected as their own TX, so
# this does not suppress them.
packet.mark_do_not_retransmit()
# Process control/discovery packet
if self.daemon.discovery_helper:
await self.daemon.discovery_helper.control_handler(packet)
packet.mark_do_not_retransmit()
# Deliver to companions via daemon (frame servers push PUSH_CODE_CONTROL_DATA 0x8E)
deliver = getattr(self.daemon, "deliver_control_data", None)
if deliver:
+13
View File
@@ -546,6 +546,19 @@ class TestPacketRouterRoutingBranches(unittest.IsolatedAsyncioTestCase):
daemon.deliver_control_data.assert_awaited_once()
daemon.repeater_handler.assert_awaited_once()
async def test_route_control_marks_do_not_retransmit_when_discovery_disabled(self):
"""With discovery disabled (discovery_helper is None), control packets must
still be marked do-not-retransmit so the engine does not relay them. MeshCore
never forwards control packets regardless of whether discovery is enabled."""
daemon = _make_daemon()
daemon.discovery_helper = None
daemon.deliver_control_data = AsyncMock()
router = PacketRouter(daemon)
pkt = _make_packet(ControlHandler.payload_type())
pkt.path_len = 0
await router._route_packet(pkt)
pkt.mark_do_not_retransmit.assert_called_once()
async def test_route_advert_delivers_to_helpers_and_engine(self):
daemon = _make_daemon()
daemon.advert_helper = MagicMock()