Skip to content
Open
Changes from all commits
Commits
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
41 changes: 30 additions & 11 deletions src/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,6 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
}

if (pkt->isRouteDirect() && pkt->getPathHashCount() > 0) {
// check for 'early received' ACK
if (pkt->getPayloadType() == PAYLOAD_TYPE_ACK) {
int i = 0;
uint32_t ack_crc;
memcpy(&ack_crc, &pkt->payload[i], 4); i += 4;
if (i <= pkt->payload_len) {
onAckRecv(pkt, ack_crc);
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this is a slight behavior change, and opens up one weird edge case: if a packet has the local node as part of the path and as the destination (i.e. the full path is something like A,B,C with a destination of B) then the packet won't be received early as retransmit logic takes priority here. I could restructure the code to avoid this situation, but it's a bit nonsensical in the first place and I'm not sure it's worth fixing.

if (self_id.isHashMatch(pkt->path, pkt->getPathHashSize()) && allowPacketForward(pkt)) {
if (pkt->getPayloadType() == PAYLOAD_TYPE_MULTIPART) {
return forwardMultipartDirect(pkt);
Expand All @@ -101,7 +91,36 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
return ACTION_RETRANSMIT_DELAYED(0, d); // Routed traffic is HIGHEST priority
}
}
return ACTION_RELEASE; // this node is NOT the next hop (OR this packet has already been forwarded), so discard.

// check if we're the destination or can otherwise receive this packet early - before the full path has been consumed
bool can_early_receive = false;
switch (pkt->getPayloadType()) {
case PAYLOAD_TYPE_ACK: {
int i = 0;
uint32_t ack_crc;
memcpy(&ack_crc, &pkt->payload[i], 4); i += 4;
if (i <= pkt->payload_len) {
can_early_receive = true;
}
break;
}

case PAYLOAD_TYPE_PATH:
case PAYLOAD_TYPE_REQ:
case PAYLOAD_TYPE_RESPONSE:
case PAYLOAD_TYPE_TXT_MSG:
case PAYLOAD_TYPE_ANON_REQ: {
// all of these payloads have the destination hash in the first byte
if (self_id.isHashMatch(pkt->payload, 1)) {
can_early_receive = true;
}
break;
}
}

if (!can_early_receive) {
return ACTION_RELEASE; // this node is NOT the next hop (OR this packet has already been forwarded), so discard.
}
}

if (pkt->isRouteFlood() && filterRecvFloodPacket(pkt)) return ACTION_RELEASE;
Expand Down