Skip to content

Fix replies dropped when flood.max.unscoped is low - #3106

Open
ViezeVingertjes wants to merge 2 commits into
meshcore-dev:devfrom
ViezeVingertjes:fix/scoped-reply-routing
Open

Fix replies dropped when flood.max.unscoped is low#3106
ViezeVingertjes wants to merge 2 commits into
meshcore-dev:devfrom
ViezeVingertjes:fix/scoped-reply-routing

Conversation

@ViezeVingertjes

@ViezeVingertjes ViezeVingertjes commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The repeater ignores the return path it already has, for logins only.
onPeerDataRecv checks client->out_path_len before falling back to flooding a REQ
reply. onAnonDataRecv never did: it only looked at reply_path_len, which
handleLoginReq does not set. A login arriving DIRECT is therefore always answered by
flooding, even when the repeater holds a valid out_path for that client.
simple_room_server already had this check; only the repeater was missing it.

Flooded replies go out un-scoped. A DIRECT request carries no transport codes, so
recv_pkt_region is NULL and sendFloodReply fell through to sendFlood(). Under
flood.max.unscoped=0 that reply dies at hop 0. Under the shipped default of 64 it
instead propagates across the whole mesh, which accounts for a lot of the REQ/RESP
flood traffic operators are seeing.

Changes

  • chooseReplyRoute(): a login arriving DIRECT replies via the client's stored
    out_path, matching what every other request type already does.
  • chooseReplyScope(): when the requester's scope cannot be determined, reply in the
    node's default Region instead of un-scoped. An un-scoped flood request is still
    answered un-scoped, so paths that work today are unchanged.
  • Both are pure functions in src/helpers/RoutingPolicy.h, alongside
    isFloodHopLimitExceeded() extracted from the copy in each firmware.
  • 14 unit tests in test/test_routing_policy/.

- Le Claude (mostly) 🤖

@ViezeVingertjes

ViezeVingertjes commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Verified on hardware: two Xiao ESP32-S3 + Wio SX1262 boards (repeater under test and a
companion client) with a third, unmodified repeater as the intermediate hop, all on
869.618 MHz / SF7 / BW62.5. The intermediate denies un-scoped floods, which is the
condition that triggers the bug. Client and repeater under test were kept out of direct
reach of each other so replies had to traverse the hop.

Each case was run twice: once against this branch with the fix reverted, once with it applied.

  • Reproduced without the fix. A DIRECT login makes the repeater answer with an un-scoped
    flood. The intermediate drops it at hop 0 and the client never receives a response. Happens
    both when the repeater has a stored out_path for the client and when it does not.
  • Fixed with the patch. With a stored out_path the reply is sent DIRECT along it. Without
    one, the reply is flooded with the default scope instead of un-scoped. The client receives
    the login response in both cases.

@IoTThinks

Copy link
Copy Markdown
Contributor

Does this PR help to resolve this issue? IoTThinks/EasySkyMesh#100
Thanks and have a nice day.

@ViezeVingertjes

ViezeVingertjes commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Does this PR help to resolve this issue? IoTThinks/EasySkyMesh#100 Thanks and have a nice day.

Hmm, doesnt seem related, this is fixing the repeater sending unscoped flood packets for the login, which are dropped over hops with denyf *, so people are unable to login.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants