Index: tcp_stacks/bbr.c =================================================================== --- tcp_stacks/bbr.c +++ tcp_stacks/bbr.c @@ -4975,6 +4975,15 @@ rsm->r_flags &= ~(BBR_ACKED | BBR_SACK_PASSED | BBR_WAS_SACKPASS); bbr_log_type_rsmclear(bbr, cts, rsm, old_flags, __LINE__); } else { + if ((tp->t_state < TCPS_ESTABLISHED) && + (rsm->r_start == tp->snd_una)) { + /* + * Special case for TCP FO. Where + * we sent more data beyond the snd_max. + * We don't mark that as lost and stop here. + */ + break; + } if ((rsm->r_flags & BBR_MARKED_LOST) == 0) { bbr->r_ctl.rc_lost += rsm->r_end - rsm->r_start; bbr->r_ctl.rc_lost_bytes += rsm->r_end - rsm->r_start; @@ -12315,7 +12324,8 @@ (tp->t_state == TCPS_SYN_SENT)) && SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN or SYN|ACK sent */ (tp->t_rxtshift == 0)) { /* not a retransmit */ - return (0); + len = 0; + goto just_return_nolock; } /* * Before sending anything check for a state update. For hpts @@ -14286,6 +14296,7 @@ (hw_tls == 0) && (len > 0) && ((flags & TH_RST) == 0) && + ((flags & TH_SYN) == 0) && (IN_RECOVERY(tp->t_flags) == 0) && (bbr->rc_in_persist == 0) && (tot_len < bbr->r_ctl.rc_pace_max_segs)) { Index: tcp_stacks/rack.c =================================================================== --- tcp_stacks/rack.c +++ tcp_stacks/rack.c @@ -12109,8 +12109,10 @@ ((tp->t_state == TCPS_SYN_RECEIVED) || (tp->t_state == TCPS_SYN_SENT)) && SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN or SYN|ACK sent */ - (tp->t_rxtshift == 0)) /* not a retransmit */ - return (0); + (tp->t_rxtshift == 0)) { /* not a retransmit */ + cwnd_to_use = rack->r_ctl.cwnd_to_use = tp->snd_cwnd; + goto just_return_nolock; + } /* * Determine length of data that should be transmitted, and flags * that will be used. If there is some data or critical controls Index: tcp_stacks/rack_bbr_common.c =================================================================== --- tcp_stacks/rack_bbr_common.c +++ tcp_stacks/rack_bbr_common.c @@ -466,7 +466,14 @@ uint32_t ctf_outstanding(struct tcpcb *tp) { - return(tp->snd_max - tp->snd_una); + uint32_t bytes_out; + + bytes_out = tp->snd_max - tp->snd_una; + if (tp->t_state < TCPS_ESTABLISHED) + bytes_out++; + if (tp->t_flags & TF_SENTFIN) + bytes_out++; + return (bytes_out); } uint32_t