-
Notifications
You must be signed in to change notification settings - Fork 38
Description
Hi @craiciu, I experienced a bug in a case when running NDP code.
Here is the scenario, I have a message of two packets, the first packet gets payload trimmed, the second packet arrives at the receiver. The cut-payloaded packet of the first packet arrives at the receiver first, the second packet arrives at the receiver later. The receiver generates an NACK for the first packet with pull_no of 2, the receiver then generates an ACK for the second packet, and a PULL packet for the second packet with pull_no of 3; However, due to the multi-path, the PULL packet arrives at the sender earlier than the NACK packet; The PULL packet would first increase the _last_pull to be 3 in the function NdpSrc::pull_packets, because there is not any packet in the retransmission queue, nothing happens. The NACK packet arrives later and also call pull_packets function, because _last_pull has already increased to 3, the NACK packet would not trigger a retransmission. At the end, only timeout can help this packet gets retransmitted. However, as the code already erased the timer when process NACK packet. There is not any timer at retransmit_packet function, thus, no packets get retransmitted even timeout kicks in. At the end, this message never gets finished.
To fix this bug, below is the new function of NdpSrc::pull_packets. Does the change make sense to you?
void NdpSrc::pull_packets(NdpPull::seq_t pull_no, NdpPull::seq_t pacer_no) {
// Pull number is cumulative both to allow for lost pulls and to
// reduce reverse-path RTT - if one pull is delayed on one path, a
// pull that gets there faster on another path can supercede it
if(pull_no !=0 && pull_no <= _last_pull){
send_packet(pacer_no);
}else{
while (_last_pull < pull_no) {
send_packet(pacer_no);
_last_pull++;
}
}
}