tcp: fix cwnd restricted SACK retransmission loop

While doing the initial SACK retransmission segment while heavily cwnd
constrained, tcp_ouput can erroneously send out the entire sendbuffer
again. This may happen after an retransmission timeout, which resets
snd_nxt to snd_una while the SACK scoreboard is still populated.

Reviewed By:		tuexen, #transport
PR:			264257
PR:			263445
PR:			260393
MFC after:		3 days
Sponsored by:		NetApp, Inc.
Differential Revision:	https://reviews.freebsd.org/D36637
This commit is contained in:
Richard Scheffenegger 2022-09-22 12:55:25 +02:00
parent 2f72ee987d
commit a743fc8826

View File

@ -415,7 +415,7 @@ tcp_default_output(struct tcpcb *tp)
else {
int32_t cwin;
/*
/*
* We are inside of a SACK recovery episode and are
* sending new data, having retransmitted all the
* data possible in the scoreboard.
@ -431,8 +431,8 @@ tcp_default_output(struct tcpcb *tp)
* of len is bungled by the optimizer.
*/
if (len > 0) {
cwin = tp->snd_cwnd -
(tp->snd_nxt - tp->snd_recover) -
cwin = tp->snd_cwnd - imax(0, (int32_t)
(tp->snd_nxt - tp->snd_recover)) -
sack_bytes_rxmt;
if (cwin < 0)
cwin = 0;