Allow repeaters to restrict Flooded REQ, ANON_REQ, and RESPONSE packets - #2797
Allow repeaters to restrict Flooded REQ, ANON_REQ, and RESPONSE packets#2797netprince17 wants to merge 24 commits into
Conversation
|
Should we use the same flood max setting for these requests too? |
|
What’s wrong with requests? I don’t write anything on the channels myself - I only try to get into repeaters or check the telemetry. I don’t like writing because it’s not always reliable; not everyone replies. I’ve noticed a strong push to limit the number of hops. This affects people who live in mountain valleys, like me (or dense mesh). Sometimes, to get a signal through to a bigger town only about 20 km away, we need 8-10 hops. |
Thanks for the comment... there is not anything inherently wrong with flooded requests, just like there is not anything inherently wrong with flooded advertisements. In this case, a few users have setup automations which flood the network with flooded requests and flooded replies every minute or two. If it were up to me, I would set the defaults max-hops on flooded requests and flooded responses to 8 to match the new default on flooded adverts, but considering there may be unforeseen consequences, leaving the default set to 64 keeps the current behavior by default. |
Every login, also with direct path, results in an flood response. And this response is mostly Unscoped. So you get 28, 34 hops away responses and so on. I don't think that it would find the destination after 28 hops. Normally you are logging max 2-3 hops away to repeaters, more is not comfortable |
Replants the fork onto meshcore-dev repeater-v1.17.0 (727fc05), 390 commits on from the previous base e8d3c53. Conflict surface was three hunks in two files; everything else auto-merged. RadioLibWrappers.h: additive collision only. Kept 1.17's USE_CC310_HW_CRYPTO include and PacketMillis struct alongside our NUM_NOISE_FLOOR_SAMPLES define. The median noise-floor estimator in the .cpp auto-merged intact and 1.17's calcMaxPacketMillis is preserved. MyMesh.cpp constructor: kept both 1.17's recv_pkt_region init and our forward-filter counters. MyMesh.cpp / MyMesh.h, the substantive one: up to 1.16 mainline overrode filterRecvFloodPacket() purely to compute recv_pkt_region, and the fork's stage 2 and 3 were appended to that function. 1.17 moved the region logic into a new MyMesh::onRecvPacket() override and dropped the old override. Re-added filterRecvFloodPacket() as a fork-only override carrying just the filter stages, and dropped our now-duplicated region block -- mainline's onRecvPacket() sets recv_pkt_region before Mesh::onRecvPacket() calls the filter, so the value is already in place. Hook semantics are unchanged: still flood-only, still ahead of the dedup mark, so a dropped copy stays unmarked. The hasSeen() to wasSeen()/markSeen() split in 1.17 does not affect the fork, as all marking happens after our hook. flood_max/_unscoped/_advert deduplicated cleanly: the fork's fold-in of PR meshcore-dev#2797 and mainline's own copy are the same code with the same defaults (64/64/8), so they merged as identical rather than doubling up. Builds clean on all three release-matrix envs: RAK_4631_repeater (flash 58.2%, RAM 14.8%), Heltec_v3_repeater, SenseCap_Solar_repeater. Fork CLI surface verified unchanged at 13 fwd.* commands, all present in the flashed binary. NOT yet verified on hardware. The /com_prefs to /prefs.json migration and the filter's runtime behaviour both still need a bench run before any deployment.
The fork carries meshcore-dev#2933 (usrflo's median noise-floor estimator) ahead of mainline merging it. Nothing in the repo said so, and the commit that applied it (a028adc) is authored by this fork with the provenance only in its message body -- easy to lose track of, and easy to mistake for fork-original work. Records for each carried patch: who wrote it upstream, which PR, why we are not waiting, and what has to happen to drop it again. Also notes meshcore-dev#2797 as resolved, since 1.17 landed it and the replant deduplicated the fork copy automatically. Calls out that meshcore-dev#2842 is a competing fix for the same root cause, roughly thirty times the size, and that if it is the one that lands this is not a clean revert -- it rewrites the estimator our patch touches, so the bench stimulus has to be re-run against its clamp defaults rather than assumed equivalent. Explicitly: do not re-submit meshcore-dev#2933 upstream under fork authorship.
FAQ: Fixed instructions on wiping and resetting nrf52 devices
RadioLibWrapper::setTxPower() called setOutputPower() and nothing else. On
LR2021 that writes the PA config and TxParams, which are standby-only commands,
and it never re-arms the receiver.
This only affects LR2021 boards. recvRaw() has:
#if defined(USE_LR2021)
state = STATE_RX; // LR2021 stays in Rx after readData
#else
state = STATE_IDLE; // need another startReceive()
#endif
so on SX126x the next recvRaw() re-arms Rx anyway and the write is harmless,
while on LR2021 startReceive() is never called again on its own. A 'set tx'
issued while the radio was listening could therefore stop reception until the
next reboot. Observed a few times on an LR2021 repeater; recovery required a
power cycle.
Dispatcher's stuck-radio check does not catch it: isInRecvMode() reports the
wrapper's own `state` flag rather than the chip's actual mode, so it still
believes the radio is in Rx, and it only raises ERR_EVENT_STARTRX_TIMEOUT
without attempting recovery.
Fix: on LR2021, drop to standby via idle() before writing the PA config and let
checkRecv() re-arm Rx - the same pattern resetAGC() and
applySideDetectorConfig() already use. Other radios are left untouched.
Affects meshtracker_x1 and meshnology_w12 (both USE_LR2021).
Tested on hardware with an LR2021 repeater: six consecutive 'set tx' changes
(15/18/21/14/19/14), after which the radio kept receiving and forwarding
traffic (rawrx/rxpkts increasing, no missed IRQs). Noise-floor sampling also
kept updating, which only happens while state == STATE_RX.
Show a small lightning-bolt icon to the left of the battery indicator on the ui-new home screen while the device is externally powered, and a plug icon once the battery reads full. The bolt/plug sits beside the battery so the fill bar stays clean and uninterrupted. When a buzzer is present, the mute icon shifts one slot further left so the two never overlap. Charging state is derived from board.isExternalPowered(), so this works on any board that reports external power (e.g. the nRF52 VBUS-detect path). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Boards without a charge-complete signal only infer "full" from voltage, and a real pack rarely reads the full BATT_MAX_MILLIVOLTS (4.2V), so the plug icon was effectively never shown. Treat "full" as a high band (>= 95%) so the plug appears when the battery is charged rather than requiring an exact 100%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
An unconfigured slot has an all-zero secret, so it matches null-key group traffic (a sender with an unset PSK). The zero-key MAC validates against the empty slot and the foreign message is delivered as if it belonged to that channel — every node with a free slot is a null-key sink. Skip empty slots.
Several table entries share an address and not every driver verifies a chip ID: INA226::begin() only checks that the address ACKs, so an SHT4x at 0x44 was also registered as an INA226 and reported junk current on a second channel. Mark the address consumed once a driver initializes it so later entries cannot re-claim the same device.
Grove and other Bosch modules strap SDO high, so the 0x76-only table never initialized them. Add an alternate-address entry per Bosch sensor; the bus scan still gates every probe, and all four drivers verify a chip ID before claiming an address. Each sensor type has a single static driver instance, so skip an entry whose query is already active: the alternate address is a fallback, not a second device.
MAX_CLIENTS is defined in both src/helpers/ClientACL.h and examples/simple_repeater/MyMesh.h. Appears it was centralised in the former header file some time ago. Both are included in some places and, depending on which order they're in, either value can win. This change drops the duplicate entry from the repeater firmware and bumps the central limit up to 32 (per the original repeater firmware value). Changes: - Remove MAX_CLIENTS from repeater MyMesh.h - Increase MAX_CLIENTS limit in ClientACL.h to 32
2bc567e to
0679dbe
Compare
|
A suggestion : adding flood.max.advert.repeater Adverts from a repeater are not needed for message transport and don't need to go as far as other adverts. |
In our meshcore region, we are receiving a large number of flooded request, flooded anonymous request, and flooded response packets. We think this is probably from people using automation which is not quite configured properly. There are more flooded anonymous request and flooded response packets than flooded advertisement packets. I have monitored the packets using the 'Rx Log' tool, as well as using the pyMC:Console.
This patch allows the repeater owner to configure a maximum number of hops for flooded request, flooded anonymous request, and flooded response packets using the CLI.
set flood.max.response 8
set flood.max.request 8
set flood.max.anon.request 8
All options default to 64, so no changes to the default repeater behavior.
This patch was modeled after the recent flood.max.advert addition to meshcore found here:
74adda6
I have been testing this patch for several days on two repeaters. Using the test repeaters, I can still log-in to further away repeaters, less than the configured 8 hops away.
Dropping these packets will likely prevent logging-in to repeaters/rooms that are further away than the configured hops. There may be other consequences of preventing flooded request, anon request, and response packets further away than the configured hops, but I have not found any other downside yet.