diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -953,8 +953,17 @@ /* Send one or 2 segments based on how much new data was acked. */ if ((BYTES_THIS_ACK(tp, th) / maxseg) >= 2) num_segs = 2; - tp->snd_cwnd = (tp->sackhint.sack_bytes_rexmit + - (tp->snd_nxt - tp->snd_recover) + num_segs * maxseg); + if (V_tcp_do_newsack) { + tp->snd_cwnd = imax(tp->snd_nxt - th->th_ack + + tp->sackhint.sack_bytes_rexmit - + tp->sackhint.sacked_bytes - + tp->sackhint.lost_bytes, maxseg) + + num_segs * maxseg; + } else { + tp->snd_cwnd = (tp->sackhint.sack_bytes_rexmit + + imax(0, tp->snd_nxt - tp->snd_recover) + + num_segs * maxseg); + } if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; tp->t_flags |= TF_ACKNOW;