Upon receiving ACK/reply directly, only update next-hop if we’re the *sole* relayer (#7859)

This commit is contained in:
GUVWAF 2025-09-06 13:23:43 +02:00 committed by GitHub
parent f26e657577
commit 4594ae474e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 36 additions and 15 deletions

View File

@ -74,10 +74,11 @@ void NextHopRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtast
if (p->from != 0) {
meshtastic_NodeInfoLite *origTx = nodeDB->getMeshNode(p->from);
if (origTx) {
// Either relayer of ACK was also a relayer of the packet, or we were the relayer and the ACK came directly from
// the destination
// Either relayer of ACK was also a relayer of the packet, or we were the *only* relayer and the ACK came directly
// from the destination
if (wasRelayer(p->relay_node, p->decoded.request_id, p->to) ||
(wasRelayer(ourRelayID, p->decoded.request_id, p->to) && p->hop_start != 0 && p->hop_start == p->hop_limit)) {
(p->hop_start != 0 && p->hop_start == p->hop_limit &&
wasSoleRelayer(ourRelayID, p->decoded.request_id, p->to))) {
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;

View File

@ -294,7 +294,7 @@ void PacketHistory::insert(const PacketRecord &r)
/* Check if a certain node was a relayer of a packet in the history given an ID and sender
* @return true if node was indeed a relayer, false if not */
bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender)
bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender, bool *wasSole)
{
if (!initOk()) {
LOG_ERROR("PacketHistory - wasRelayer: NOT INITIALIZED!");
@ -322,27 +322,42 @@ bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const N
found->sender, found->id, found->next_hop, millis() - found->rxTimeMsec, found->relayed_by[0], found->relayed_by[1],
found->relayed_by[2], relayer);
#endif
return wasRelayer(relayer, *found);
return wasRelayer(relayer, *found, wasSole);
}
/* 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, const PacketRecord &r)
bool PacketHistory::wasRelayer(const uint8_t relayer, const PacketRecord &r, bool *wasSole)
{
for (uint8_t i = 0; i < NUM_RELAYERS; i++) {
bool found = false;
bool other_present = false;
for (uint8_t i = 0; i < NUM_RELAYERS; ++i) {
if (r.relayed_by[i] == relayer) {
#if VERBOSE_PACKET_HISTORY
LOG_DEBUG("Packet History - was rel.PR.: s=%08x id=%08x rls=%02x %02x %02x / rl=%02x? YES", r.sender, r.id,
r.relayed_by[0], r.relayed_by[1], r.relayed_by[2], relayer);
#endif
return true;
found = true;
} else if (r.relayed_by[i] != 0) {
other_present = true;
}
}
if (wasSole) {
*wasSole = (found && !other_present);
}
#if VERBOSE_PACKET_HISTORY
LOG_DEBUG("Packet History - was rel.PR.: s=%08x id=%08x rls=%02x %02x %02x / rl=%02x? NO", r.sender, r.id, r.relayed_by[0],
r.relayed_by[1], r.relayed_by[2], relayer);
#endif
return false;
return found;
}
// Check if a certain node was the *only* relayer of a packet in the history given an ID and sender
bool PacketHistory::wasSoleRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender)
{
bool wasSole = false;
wasRelayer(relayer, id, sender, &wasSole);
return wasSole;
}
// Remove a relayer from the list of relayers of a packet in the history given an ID and sender

View File

@ -34,8 +34,9 @@ class PacketHistory
void insert(const PacketRecord &r); // Insert or replace a packet record in the history
/* Check if a certain node was a relayer of a packet in the history given iterator
* If wasSole is not nullptr, it will be set to true if the relayer was the only relayer of that packet
* @return true if node was indeed a relayer, false if not */
bool wasRelayer(const uint8_t relayer, const PacketRecord &r);
bool wasRelayer(const uint8_t relayer, const PacketRecord &r, bool *wasSole = nullptr);
PacketHistory(const PacketHistory &); // non construction-copyable
PacketHistory &operator=(const PacketHistory &); // non copyable
@ -54,8 +55,12 @@ class PacketHistory
bool *weWereNextHop = nullptr);
/* Check if a certain node was a relayer of a packet in the history given an ID and sender
* If wasSole is not nullptr, it will be set to true if the relayer was the only relayer of that packet
* @return true if node was indeed a relayer, false if not */
bool wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
bool wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender, bool *wasSole = nullptr);
// Check if a certain node was the *only* relayer of a packet in the history given an ID and sender
bool wasSoleRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
// 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);