Index: sys/netinet/cc/cc_newreno.c =================================================================== --- sys/netinet/cc/cc_newreno.c +++ sys/netinet/cc/cc_newreno.c @@ -134,7 +134,7 @@ if (type == CC_ACK && !IN_RECOVERY(CCV(ccv, t_flags)) && (ccv->flags & CCF_CWND_LIMITED)) { u_int cw = CCV(ccv, snd_cwnd); - u_int incr = CCV(ccv, t_maxseg); + u_int incr = 0; /* * Regular in-order ACK, open the congestion window. @@ -169,7 +169,7 @@ ccv->flags &= ~CCF_ABC_SENTAWND; else incr = 0; - } else + } else if (ccv->bytes_this_ack > 0) incr = max((incr * incr / cw), 1); } else if (V_tcp_do_rfc3465) { /* @@ -188,7 +188,8 @@ CCV(ccv, t_maxseg)); else incr = min(ccv->bytes_this_ack, CCV(ccv, t_maxseg)); - } + } else if (ccv->bytes_this_ack > 0) + incr = CCV(ccv, t_maxseg); /* ABC is on by default, so incr equals 0 frequently. */ if (incr > 0) CCV(ccv, snd_cwnd) = min(cw + incr, Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -2396,12 +2396,6 @@ if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) { tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; - - /* - * Account for the ACK of our SYN prior to - * regular ACK processing below. - */ - tp->snd_una++; } if (tp->t_flags & TF_NEEDFIN) { tcp_state_change(tp, TCPS_FIN_WAIT_1); @@ -2421,6 +2415,12 @@ cc_conn_init(tp); tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); } + if (SEQ_GT(th->th_ack, tp->snd_una)) + /* + * Account for the ACK of our SYN prior to + * regular ACK processing below. + */ + tp->snd_una++; /* * If segment contains data or ACK, will call tcp_reass() * later; if not, do so now to pass queued data to user. Index: sys/netinet/tcp_stacks/rack.c =================================================================== --- sys/netinet/tcp_stacks/rack.c +++ sys/netinet/tcp_stacks/rack.c @@ -5433,6 +5433,7 @@ tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } + tp->snd_wnd = tiwin; /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later @@ -5440,7 +5441,6 @@ */ if ((thflags & TH_ACK) == 0) { if (IS_FASTOPEN(tp->t_flags)) { - tp->snd_wnd = tiwin; cc_conn_init(tp); } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, @@ -5452,7 +5452,6 @@ if ((tp->t_flags & (TF_RCVD_SCALE | TF_REQ_SCALE)) == (TF_RCVD_SCALE | TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; - tp->snd_wnd = tiwin; } /* * Make transitions: SYN-RECEIVED -> ESTABLISHED SYN-RECEIVED* -> @@ -5462,12 +5461,6 @@ if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) { tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; - - /* - * Account for the ACK of our SYN prior to - * regular ACK processing below. - */ - tp->snd_una++; } if (tp->t_flags & TF_NEEDFIN) { tcp_state_change(tp, TCPS_FIN_WAIT_1); @@ -5485,6 +5478,12 @@ if (!IS_FASTOPEN(tp->t_flags)) cc_conn_init(tp); } + if (SEQ_GT(th->th_ack, tp->snd_una)) + /* + * Account for the ACK of our SYN prior to + * regular ACK processing below. + */ + tp->snd_una++; /* * If segment contains data or ACK, will call tcp_reass() later; if * not, do so now to pass queued data to user.