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.

Reply via email to