mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-04 05:39:53 +00:00
bug #49533: start persist timer when unsent seg can't fit in window
This commit returns LwIP to previous behavior where if the next unsent
segment can't be sent due to the current send window, we start the
persist timer. This is done to engage window probing in the case that
the subsequent window update from the receiver is dropped, thus
preventing connection deadlock
This commit refines the previous logic to only target the following case:
1) Next unsent segment doesn't fit within the send window (not
congestion) and there is some room in the window
2) Unacked queue is empty (otherwise data is inflight and the RTO timer
will take care of any dropped window updates)
See commit d8f090a759
(which removed this
behavior) to reference the old logic. The old logic falsely started the
persit timer when the RTO timer was already running.
This commit is contained in:
parent
81a32e9b06
commit
f79eabd24b
@ -1033,6 +1033,24 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
lwip_ntohl(seg->tcphdr->seqno), pcb->lastack));
|
||||
}
|
||||
#endif /* TCP_CWND_DEBUG */
|
||||
/* Check if we need to start the persistent timer when the next unsent segment
|
||||
* does not fit within the remaining send window and RTO timer is not running (we
|
||||
* have no in-flight data). A traditional approach would fill the remaining window
|
||||
* with part of the unsent segment (which will engage zero-window probing upon
|
||||
* reception of the zero window update from the receiver). This ensures the
|
||||
* subsequent window update is reliably received. With the goal of being lightweight,
|
||||
* we avoid splitting the unsent segment and treat the window as already zero.
|
||||
*/
|
||||
if (seg != NULL &&
|
||||
lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd &&
|
||||
wnd > 0 && wnd == pcb->snd_wnd && pcb->unacked == NULL) {
|
||||
/* Start the persist timer */
|
||||
if (pcb->persist_backoff == 0) {
|
||||
pcb->persist_cnt = 0;
|
||||
pcb->persist_backoff = 1;
|
||||
}
|
||||
goto output_done;
|
||||
}
|
||||
/* data available and window allows it to be sent? */
|
||||
while (seg != NULL &&
|
||||
lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
|
||||
@ -1112,6 +1130,7 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
}
|
||||
seg = pcb->unsent;
|
||||
}
|
||||
output_done:
|
||||
#if TCP_OVERSIZE
|
||||
if (pcb->unsent == NULL) {
|
||||
/* last unsent has been removed, reset unsent_oversize */
|
||||
|
Loading…
Reference in New Issue
Block a user