https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=283649
Gleb Smirnoff <gleb...@freebsd.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|New |In Progress --- Comment #4 from Gleb Smirnoff <gleb...@freebsd.org> --- Here the connection state that leads to a bogus packet: TF_FASTRECOVERY is set snd_wnd = 384 snd_cwnd quite large snd_nxt == snd_una SACK state: sack_bytes_rexmit 1448 sacked_bytes 124528 lost_bytes 0 In this state we start with sendwin=0 at line 262, then it is set to snd_wnd at line 277. We enter the fast recovery block and tcp_compute_pipe() returns us large negative -121632 at line 301. Subtracting large negative from small positive ends in large cwin. At this point we totally forget that we have small snd_wnd. So whatever branch for the len calculation we take in the rest of recovery block, we may overcommit snd_wnd. So, I'm 90% sure that regression comes from 7dc78150c730e90fa2afdaba3aa645932b30c429 this chunk: @@ -292,10 +294,13 @@ tcp_default_output(struct tcpcb *tp) if ((tp->t_flags & TF_SACK_PERMIT) && (IN_FASTRECOVERY(tp->t_flags) || SEQ_LT(tp->snd_nxt, tp->snd_max)) && (p = tcp_sack_output(tp, &sack_bytes_rxmt))) { - uint32_t cwin; + int32_t cwin; - cwin = - imax(min(tp->snd_wnd, tp->snd_cwnd) - sack_bytes_rxmt, 0); + if (IN_FASTRECOVERY(tp->t_flags)) { + cwin = imax(sendwin - tcp_compute_pipe(tp), 0); + } else { + cwin = imax(sendwin - off, 0); + } /* Do not retransmit SACK segments beyond snd_recover */ if (SEQ_GT(p->end, tp->snd_recover)) { /* -- You are receiving this mail because: You are the assignee for the bug.