From 971b3f414fbbc18dbbfd77260cb33e4d626fa3a5 Mon Sep 17 00:00:00 2001 From: Matthias Wientapper Date: Wed, 7 Jan 2026 21:24:25 +0100 Subject: [PATCH 1/6] Limit flood advert packet forwarding, implements #1223 --- examples/simple_repeater/MyMesh.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 5ac99db0..459b4302 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -434,6 +434,14 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { return false; } } + // Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1) + // https://github.com/meshcore-dev/MeshCore/issues/1223 + double_t roll_dice = (double)rand() / RAND_MAX; + double_t forw_prob = pow(0.308, packet->path_len - 1); + if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood() && roll_dice > forw_prob) + return false; + + // all other packets return true; } From 6209ad12ce444f4a590b034097580d12a8b702ac Mon Sep 17 00:00:00 2001 From: Matthias Wientapper Date: Fri, 9 Jan 2026 20:47:09 +0100 Subject: [PATCH 2/6] Limit flood advert packet forwarding for roomservers as well --- examples/simple_room_server/MyMesh.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/simple_room_server/MyMesh.cpp b/examples/simple_room_server/MyMesh.cpp index 5451505a..59b9531c 100644 --- a/examples/simple_room_server/MyMesh.cpp +++ b/examples/simple_room_server/MyMesh.cpp @@ -276,7 +276,16 @@ uint32_t MyMesh::getDirectRetransmitDelay(const mesh::Packet *packet) { bool MyMesh::allowPacketForward(const mesh::Packet *packet) { if (_prefs.disable_fwd) return false; - if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false; + if (packet->isRouteFlood() && packet->path_len >= _prefs.flood_max) return false; + + // Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1) + // https://github.com/meshcore-dev/MeshCore/issues/1223 + double_t roll_dice = (double)rand() / RAND_MAX; + double_t forw_prob = pow(0.308, packet->path_len - 1); + if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood() && roll_dice > forw_prob) + return false; + + // all other packets return true; } From e24b5ff2630af2efe62894f7031cdf8543ae1074 Mon Sep 17 00:00:00 2001 From: Matthias Wientapper Date: Tue, 13 Jan 2026 23:06:27 +0100 Subject: [PATCH 3/6] Add cli config flood.advert.base 0 = forwarding flood adverts off 1 = forwarding flood adverts on (unrestricted) 0.308 (default) = prob. forwarding according to #1338 --- examples/simple_repeater/MyMesh.cpp | 3 ++- examples/simple_room_server/MyMesh.cpp | 3 ++- src/helpers/CommonCLI.cpp | 21 +++++++++++++++++++-- src/helpers/CommonCLI.h | 1 + 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 459b4302..231bfacd 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -437,7 +437,7 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { // Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1) // https://github.com/meshcore-dev/MeshCore/issues/1223 double_t roll_dice = (double)rand() / RAND_MAX; - double_t forw_prob = pow(0.308, packet->path_len - 1); + double_t forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood() && roll_dice > forw_prob) return false; @@ -878,6 +878,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc _prefs.tx_power_dbm = LORA_TX_POWER; _prefs.advert_interval = 1; // default to 2 minutes for NEW installs _prefs.flood_advert_interval = 12; // 12 hours + _prefs.flood_advert_base = 0.308f; _prefs.flood_max = 64; _prefs.interference_threshold = 0; // disabled diff --git a/examples/simple_room_server/MyMesh.cpp b/examples/simple_room_server/MyMesh.cpp index 59b9531c..fcb01b9b 100644 --- a/examples/simple_room_server/MyMesh.cpp +++ b/examples/simple_room_server/MyMesh.cpp @@ -281,7 +281,7 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { // Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1) // https://github.com/meshcore-dev/MeshCore/issues/1223 double_t roll_dice = (double)rand() / RAND_MAX; - double_t forw_prob = pow(0.308, packet->path_len - 1); + double_t forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood() && roll_dice > forw_prob) return false; @@ -624,6 +624,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc _prefs.disable_fwd = 1; _prefs.advert_interval = 1; // default to 2 minutes for NEW installs _prefs.flood_advert_interval = 12; // 12 hours + _prefs.flood_advert_base = 0.308f; _prefs.flood_max = 64; _prefs.interference_threshold = 0; // disabled #ifdef ROOM_PASSWORD diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index f3cba406..abca4073 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -83,7 +83,9 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 - // 290 + file.read((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290 + + // 294 // sanitise bad pref values _prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); @@ -111,6 +113,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { _prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1); _prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2); + _prefs->flood_advert_base = constrain(_prefs->flood_advert_base, 0, 1); + file.close(); } } @@ -170,7 +174,9 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 - // 290 + file.write((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290 + + // 294 file.close(); } @@ -401,6 +407,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch } else { sprintf(reply, "> %.3f", adc_mult); } + } else if (memcmp(config, "flood.advert.base", 17) == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(_prefs->flood_advert_base)); // Power management commands } else if (memcmp(config, "pwrmgt.support", 14) == 0) { #ifdef NRF52_POWER_MANAGEMENT @@ -678,6 +686,15 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch _prefs->adc_multiplier = 0.0f; strcpy(reply, "Error: unsupported by this board"); }; + } else if (memcmp(config, "flood.advert.base ", 18) == 0) { + float f = atof(&config[18]); + if((f > 0) || (f<1)) { + _prefs->flood_advert_base = f; + savePrefs(); + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error: base must be between 0 and 1"); + } } else { sprintf(reply, "unknown config: %s", config); } diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index 51013640..df96b644 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -41,6 +41,7 @@ struct NodePrefs { // persisted to file uint8_t flood_max; uint8_t interference_threshold; uint8_t agc_reset_interval; // secs / 4 + float flood_advert_base; // Bridge settings uint8_t bridge_enabled; // boolean uint16_t bridge_delay; // milliseconds (default 500 ms) From a678c4a9e60ee951c77de833bea64380eb5ecd60 Mon Sep 17 00:00:00 2001 From: mattzzw Date: Thu, 5 Mar 2026 08:21:15 +0100 Subject: [PATCH 4/6] Update src/helpers/CommonCLI.cpp Co-authored-by: Wessel --- src/helpers/CommonCLI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index abca4073..a57e8b88 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -688,7 +688,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch }; } else if (memcmp(config, "flood.advert.base ", 18) == 0) { float f = atof(&config[18]); - if((f > 0) || (f<1)) { + if(f >= 0 && f <= 1) { _prefs->flood_advert_base = f; savePrefs(); strcpy(reply, "OK"); From 7af69412200db903f597d76b8276b0b956ec0951 Mon Sep 17 00:00:00 2001 From: mattzzw Date: Thu, 5 Mar 2026 08:22:22 +0100 Subject: [PATCH 5/6] Update examples/simple_repeater/MyMesh.cpp Fix pow() and rand() are calculated for every forwarded packet, but we only need it for flood advert. Also fixes 'paket' typo. Co-authored-by: Wessel --- examples/simple_repeater/MyMesh.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 231bfacd..4b151043 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -436,12 +436,13 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { } // Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1) // https://github.com/meshcore-dev/MeshCore/issues/1223 - double_t roll_dice = (double)rand() / RAND_MAX; - double_t forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); - if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood() && roll_dice > forw_prob) - return false; + if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) { + double roll_dice = (double)rand() / RAND_MAX; + double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); + if (roll_dice > forw_prob) + return false; + } - // all other packets return true; } From 853ee62eb00adcd2408d191317b1bf74e9d36970 Mon Sep 17 00:00:00 2001 From: mattzzw Date: Thu, 5 Mar 2026 08:22:48 +0100 Subject: [PATCH 6/6] Update examples/simple_room_server/MyMesh.cpp Fix pow() and rand() are calculated for every forwarded packet, but we only need it for flood advert. Also fixes 'paket' typo. Co-authored-by: Wessel --- examples/simple_room_server/MyMesh.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/simple_room_server/MyMesh.cpp b/examples/simple_room_server/MyMesh.cpp index fcb01b9b..38f4845c 100644 --- a/examples/simple_room_server/MyMesh.cpp +++ b/examples/simple_room_server/MyMesh.cpp @@ -278,14 +278,15 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { if (_prefs.disable_fwd) return false; if (packet->isRouteFlood() && packet->path_len >= _prefs.flood_max) return false; - // Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1) + // Limit flood advert packet forwarding using a probabilistic reduction defined by P(h) = base^(hops-1) // https://github.com/meshcore-dev/MeshCore/issues/1223 - double_t roll_dice = (double)rand() / RAND_MAX; - double_t forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); - if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood() && roll_dice > forw_prob) - return false; + if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) { + double roll_dice = (double)rand() / RAND_MAX; + double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1); + if (roll_dice > forw_prob) + return false; + } - // all other packets return true; }