Deprecate/block packets with a missing/invalid hop_start value (pre-hop firmware) (related to issue #7369) (#9476)
* Deprecate forwarding for invalid hop_start * Add pre-hop packet drop policy * Log ignored rebroadcasts for pre-hop packets * Respect pre-hop policy ALLOW in routing gates * Exempt local packets from pre-hop drop policy * Format pre-hop log line * Add MODERN_ONLY rebroadcast mode for pre-hop packets * Simplify implementation for drop packet only behaviour * Revert formatting-only changes * Match ReliableRouter EOF formatting * Make pre-hop drop a build-time flag * Rework to compile/build flag MESHTASTIC_PREHOP_DROP * Set MESHTASTIC_PREHOP_DROP off by default * Inline pre-hop hop_start validity check --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com> Co-authored-by: Jord <650645+DivineOmega@users.noreply.github.com>
This commit is contained in:
co-authored by
GitHub
Ben Meadors
Jord
parent
e51e6cad84
commit
53c21eb30d
@@ -78,6 +78,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// Configuration
|
// 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
|
/// Convert a preprocessor name into a quoted string
|
||||||
#define xstr(s) ystr(s)
|
#define xstr(s) ystr(s)
|
||||||
#define ystr(s) #s
|
#define ystr(s) #s
|
||||||
|
|||||||
@@ -1646,6 +1646,25 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
|
|||||||
return delta;
|
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)
|
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
|
// Firmware prior to 2.3.0 (585805c) lacked a hop_start field. Firmware version 2.5.0 (bf34329) introduced a
|
||||||
@@ -1683,6 +1702,21 @@ size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
|
|||||||
#include "MeshModule.h"
|
#include "MeshModule.h"
|
||||||
#include "Throttle.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
|
/** Update position info for this node based on received position data
|
||||||
*/
|
*/
|
||||||
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
|
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
|
||||||
|
|||||||
@@ -114,6 +114,27 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p);
|
|||||||
/// Returns defaultIfUnknown if the number of hops couldn't be determined.
|
/// Returns defaultIfUnknown if the number of hops couldn't be determined.
|
||||||
int8_t getHopsAway(const meshtastic_MeshPacket &p, int8_t defaultIfUnknown = -1);
|
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 {
|
enum LoadFileResult {
|
||||||
// Successfully opened the file
|
// Successfully opened the file
|
||||||
LOAD_SUCCESS = 1,
|
LOAD_SUCCESS = 1,
|
||||||
|
|||||||
@@ -851,6 +851,12 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldDropPacketForPreHop(*p)) {
|
||||||
|
logHopStartDrop(*p, "pre-hop drop");
|
||||||
|
packetPool.release(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldFilterReceived(p)) {
|
if (shouldFilterReceived(p)) {
|
||||||
LOG_DEBUG("Incoming msg was filtered from 0x%x", p->from);
|
LOG_DEBUG("Incoming msg was filtered from 0x%x", p->from);
|
||||||
packetPool.release(p);
|
packetPool.release(p);
|
||||||
|
|||||||
Reference in New Issue
Block a user