Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -2819,6 +2819,15 @@ tcp_newreno_partial_ack(tp, th); } else cc_post_recovery(tp, th); + } else if (IN_CONGRECOVERY(tp->t_flags)) { + if (SEQ_LT(th->th_ack, tp->snd_recover)) { + if (V_tcp_do_prr) { + tp->sackhint.delivered_data = BYTES_THIS_ACK(tp, th); + tp->snd_fack = th->th_ack; + tcp_prr_partialack(tp, th); + } + } else + cc_post_recovery(tp, th); } /* * If we reach this point, ACK is not a duplicate, @@ -3988,9 +3997,12 @@ * If there is going to be a SACK retransmission, adjust snd_cwnd * accordingly. */ - tp->snd_cwnd = imax(maxseg, tp->snd_nxt - tp->snd_recover + - tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg)); - tp->t_flags |= TF_ACKNOW; + if (IN_FASTRECOVERY(tp->t_flags)) { + tp->snd_cwnd = imax(maxseg, tp->snd_nxt - tp->snd_recover + + tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg)); + tp->t_flags |= TF_ACKNOW; + } else if (IN_CONGRECOVERY(tp->t_flags)) + tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); (void) tcp_output(tp); }