From 24ff7c0bfb66ccba382c6c6adf0161650e2db177 Mon Sep 17 00:00:00 2001 From: GUVWAF Date: Tue, 5 Nov 2024 21:27:10 +0100 Subject: [PATCH] Better checking for fallback to flooding --- src/mesh/NextHopRouter.cpp | 6 +++--- src/mesh/PacketHistory.cpp | 24 +++++++++++++++++++----- src/mesh/PacketHistory.h | 4 ++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/mesh/NextHopRouter.cpp b/src/mesh/NextHopRouter.cpp index 7d1568f4c..38cc0fe6d 100644 --- a/src/mesh/NextHopRouter.cpp +++ b/src/mesh/NextHopRouter.cpp @@ -18,7 +18,7 @@ ErrorCode NextHopRouter::send(meshtastic_MeshPacket *p) wasSeenRecently(p); // FIXME, move this to a sniffSent method p->next_hop = getNextHop(p->to, p->relay_node); // set the next hop - // LOG_DEBUG("Setting next hop for packet with dest %x to %x", p->to, p->next_hop); + LOG_DEBUG("Setting next hop for packet with dest %x to %x", p->to, p->next_hop); // If it's from us, ReliableRouter already handles retransmissions. If a next hop is set and hop limit is not 0, start // retransmissions @@ -62,8 +62,8 @@ void NextHopRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtast if (wasRelayer(p->relay_node, p->decoded.request_id, p->to) || (wasRelayer(ourRelayID, p->decoded.request_id, p->to) && p->relay_node == nodeDB->getLastByteOfNodeNum(p->from))) { - if (origTx->next_hop != p->relay_node) { - LOG_DEBUG("Update next hop of 0x%x to 0x%x based on ACK/reply", p->from, p->relay_node); + if (origTx->next_hop != p->relay_node) { // Not already set + LOG_INFO("Update next hop of 0x%x to 0x%x based on ACK/reply", p->from, p->relay_node); origTx->next_hop = p->relay_node; } } diff --git a/src/mesh/PacketHistory.cpp b/src/mesh/PacketHistory.cpp index 91e395d9c..8d3ae36fc 100644 --- a/src/mesh/PacketHistory.cpp +++ b/src/mesh/PacketHistory.cpp @@ -29,6 +29,7 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd r.rxTimeMsec = millis(); r.next_hop = p->next_hop; r.relayed_by[0] = p->relay_node; + LOG_INFO("Add relayed_by 0x%x for id=0x%x", p->relay_node, r.id); auto found = recentPackets.find(r); bool seenRecently = (found != recentPackets.end()); // found not equal to .end() means packet was seen recently @@ -48,10 +49,15 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd } if (seenRecently) { - // If it was seen with a next-hop not set to us, relayer is still the same and now it's NO_NEXT_HOP_PREFERENCE, it's a - // fallback to flooding, so we consider it unseen because we might need to handle it now - if (found->next_hop != NO_NEXT_HOP_PREFERENCE && found->next_hop != nodeDB->getLastByteOfNodeNum(nodeDB->getNodeNum()) && - found->relayed_by[0] == p->relay_node && p->next_hop == NO_NEXT_HOP_PREFERENCE) { + // If it was seen with a next-hop not set to us and now it's NO_NEXT_HOP_PREFERENCE, relayer relayed already before, it's + // a fallback to flooding. If we didn't already relay and the next-hop neither, consider it unseen because we might need + // to handle it now + uint8_t ourRelayID = nodeDB->getLastByteOfNodeNum(nodeDB->getNodeNum()); + if (found->sender != nodeDB->getNodeNum() && found->next_hop != NO_NEXT_HOP_PREFERENCE && + p->next_hop == NO_NEXT_HOP_PREFERENCE && found->next_hop != nodeDB->getLastByteOfNodeNum(nodeDB->getNodeNum()) && + p->relay_node != 0 && wasRelayer(p->relay_node, found) && !wasRelayer(ourRelayID, found) && + !wasRelayer(found->next_hop, found)) { + LOG_WARN("Fallback to flooding, consider unseen relay_node=0x%x", p->relay_node); seenRecently = false; } } @@ -113,11 +119,19 @@ bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const N return false; } + return wasRelayer(relayer, found); +} + +/* Check if a certain node was a relayer of a packet in the history given iterator + * @return true if node was indeed a relayer, false if not */ +bool PacketHistory::wasRelayer(const uint8_t relayer, std::unordered_set::iterator r) +{ for (uint8_t i = 0; i < NUM_RELAYERS; i++) { - if (found->relayed_by[i] == relayer) { + if (r->relayed_by[i] == relayer) { return true; } } + return false; } // Remove a relayer from the list of relayers of a packet in the history given an ID and sender diff --git a/src/mesh/PacketHistory.h b/src/mesh/PacketHistory.h index adde4b27d..aae5ebff1 100644 --- a/src/mesh/PacketHistory.h +++ b/src/mesh/PacketHistory.h @@ -52,6 +52,10 @@ class PacketHistory * @return true if node was indeed a relayer, false if not */ bool wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender); + /* Check if a certain node was a relayer of a packet in the history given iterator + * @return true if node was indeed a relayer, false if not */ + bool wasRelayer(const uint8_t relayer, std::unordered_set::iterator r); + // Remove a relayer from the list of relayers of a packet in the history given an ID and sender void removeRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender); }; \ No newline at end of file