Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7de0275
Deprecate forwarding for invalid hop_start
DivineOmega Jan 29, 2026
fdf06e1
Add pre-hop packet drop policy
DivineOmega Jan 29, 2026
c9d52cd
Log ignored rebroadcasts for pre-hop packets
DivineOmega Jan 29, 2026
92019ec
Respect pre-hop policy ALLOW in routing gates
DivineOmega Jan 29, 2026
09d8ca5
Exempt local packets from pre-hop drop policy
DivineOmega Jan 29, 2026
e2f329e
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
thebentern Jan 29, 2026
6d601ca
Format pre-hop log line
DivineOmega Jan 29, 2026
707685c
Add MODERN_ONLY rebroadcast mode for pre-hop packets
DivineOmega Jan 29, 2026
7e8096b
Simplify implementation for drop packet only behaviour
DivineOmega Jan 30, 2026
8a84830
Revert formatting-only changes
DivineOmega Jan 30, 2026
bd815c4
Match ReliableRouter EOF formatting
DivineOmega Jan 30, 2026
8fb8db3
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
thebentern Jan 30, 2026
4514dac
Make pre-hop drop a build-time flag
DivineOmega Jan 30, 2026
325cbee
Rework to compile/build flag MESHTASTIC_PREHOP_DROP
DivineOmega Jan 30, 2026
a052e80
Set MESHTASTIC_PREHOP_DROP off by default
DivineOmega Jan 30, 2026
41a09d3
Inline pre-hop hop_start validity check
DivineOmega Jan 30, 2026
d767cfb
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
thebentern Jan 30, 2026
3d6277d
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
thebentern Jan 30, 2026
b28a1f2
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
DivineOmega Jan 31, 2026
2b1ea98
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
DivineOmega Feb 2, 2026
4f6cd74
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
DivineOmega Feb 4, 2026
d7acf98
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
DivineOmega Feb 5, 2026
5b0015b
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
thebentern Feb 5, 2026
d4bfa52
Merge branch 'develop' into deprecate-packets-with-invalid-hopstart
DivineOmega Feb 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Configuration
// -----------------------------------------------------------------------------

// Pre-hop drop handling (compile-time flag).
#ifndef MESHTASTIC_PREHOP_DROP
#define MESHTASTIC_PREHOP_DROP 0
#endif

/// Convert a preprocessor name into a quoted string
#define xstr(s) ystr(s)
#define ystr(s) #s
Expand Down
34 changes: 34 additions & 0 deletions src/mesh/NodeDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,25 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
return delta;
}

HopStartStatus classifyHopStart(const meshtastic_MeshPacket &p)
{
// Guard against invalid values.
if (p.hop_start < p.hop_limit)
return HopStartStatus::INVALID;

if (p.hop_start == 0) {
// Firmware prior to 2.3.0 (585805c) lacked a hop_start field. Firmware version 2.5.0 (bf34329) introduced a
// bitfield that is always present. Use the presence of the bitfield to determine if the origin's firmware
// version is guaranteed to have hop_start populated. Note that this can only be done for decoded packets as
// the bitfield is encrypted under the channel encryption key.
if (p.which_payload_variant == meshtastic_MeshPacket_decoded_tag && p.decoded.has_bitfield)
return HopStartStatus::VALID;
return HopStartStatus::MISSING_OR_UNKNOWN;
}

return HopStartStatus::VALID;
}

int8_t getHopsAway(const meshtastic_MeshPacket &p, int8_t defaultIfUnknown)
{
// Firmware prior to 2.3.0 (585805c) lacked a hop_start field. Firmware version 2.5.0 (bf34329) introduced a
Expand Down Expand Up @@ -1672,6 +1691,21 @@ size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
#include "MeshModule.h"
#include "Throttle.h"

static constexpr uint32_t HOPSTART_DROP_LOG_INTERVAL_MS = 15000;

void logHopStartDrop(const meshtastic_MeshPacket &p, const char *context)
{
static uint32_t lastLogMs = 0;
if (Throttle::isWithinTimespanMs(lastLogMs, HOPSTART_DROP_LOG_INTERVAL_MS)) {
return;
}
lastLogMs = millis();
const bool decoded = (p.which_payload_variant == meshtastic_MeshPacket_decoded_tag);
const bool hasBitfield = decoded && p.decoded.has_bitfield;
LOG_DEBUG("Drop packet (%s): hop_start invalid/missing (from=0x%x id=%u hop_start=%u hop_limit=%u decoded=%d has_bitfield=%d)",
context ? context : "unknown", p.from, p.id, p.hop_start, p.hop_limit, decoded, hasBitfield);
}

/** Update position info for this node based on received position data
*/
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
Expand Down
21 changes: 21 additions & 0 deletions src/mesh/NodeDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,27 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p);
/// Returns defaultIfUnknown if the number of hops couldn't be determined.
int8_t getHopsAway(const meshtastic_MeshPacket &p, int8_t defaultIfUnknown = -1);

enum class HopStartStatus : uint8_t { VALID = 0, MISSING_OR_UNKNOWN, INVALID };

/// Classify hop_start validity for forwarding decisions.
HopStartStatus classifyHopStart(const meshtastic_MeshPacket &p);

inline bool shouldDropPacketForPreHop(const meshtastic_MeshPacket &p)
{
#if !MESHTASTIC_PREHOP_DROP
(void)p;
return false;
#else
if (isFromUs(&p)) {
return false; // local-originated packets should never be dropped by pre-hop drop policy
}
return classifyHopStart(p) != HopStartStatus::VALID;
#endif
}

/// Rate-limited debug log when hop_start is invalid/missing and packet is dropped.
void logHopStartDrop(const meshtastic_MeshPacket &p, const char *context);

enum LoadFileResult {
// Successfully opened the file
LOAD_SUCCESS = 1,
Expand Down
6 changes: 6 additions & 0 deletions src/mesh/Router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,12 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
return;
}

if (shouldDropPacketForPreHop(*p)) {
logHopStartDrop(*p, "pre-hop drop");
packetPool.release(p);
return;
}

if (shouldFilterReceived(p)) {
LOG_DEBUG("Incoming msg was filtered from 0x%x", p->from);
packetPool.release(p);
Expand Down
Loading