Correctly set up the initial TCP congestion window in all cases,
by not including the SYN bit sequence space in cwnd related calculations. Snd_und is adjusted explicitly in all cases, outside the cwnd update, instead. This fixes an off-by-one conformance issue with regular TCP sessions not using Appropriate Byte Counting (RFC3465), sending one more packet during the initial window than expected. PR: 235256 Reviewed by: tuexen (mentor), rgrimes (mentor) Approved by: tuexen (mentor), rgrimes (mentor) MFC after: 3 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D19000
This commit is contained in:
parent
bb85a467ce
commit
f8d5656acd
@ -1470,7 +1470,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos)
|
||||
{
|
||||
int thflags, acked, ourfinisacked, needoutput = 0, sack_changed;
|
||||
int rstreason, todrop, win;
|
||||
int rstreason, todrop, win, incforsyn = 0;
|
||||
uint32_t tiwin;
|
||||
uint16_t nsegs;
|
||||
char *s;
|
||||
@ -2374,12 +2374,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
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);
|
||||
@ -2399,6 +2393,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
cc_conn_init(tp);
|
||||
tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp));
|
||||
}
|
||||
/*
|
||||
* Account for the ACK of our SYN prior to
|
||||
* regular ACK processing below, except for
|
||||
* simultaneous SYN, which is handled later.
|
||||
*/
|
||||
if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN))
|
||||
incforsyn = 1;
|
||||
/*
|
||||
* If segment contains data or ACK, will call tcp_reass()
|
||||
* later; if not, do so now to pass queued data to user.
|
||||
@ -2693,6 +2694,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
process_ACK:
|
||||
INP_WLOCK_ASSERT(tp->t_inpcb);
|
||||
|
||||
/*
|
||||
* Adjust for the SYN bit in sequence space,
|
||||
* but don't account for it in cwnd calculations.
|
||||
* This is for the SYN_RECEIVED, non-simultaneous
|
||||
* SYN case. SYN_SENT and simultaneous SYN are
|
||||
* treated elsewhere.
|
||||
*/
|
||||
if (incforsyn)
|
||||
tp->snd_una++;
|
||||
acked = BYTES_THIS_ACK(tp, th);
|
||||
KASSERT(acked >= 0, ("%s: acked unexepectedly negative "
|
||||
"(tp->snd_una=%u, th->th_ack=%u, tp=%p, m=%p)", __func__,
|
||||
|
@ -9326,11 +9326,6 @@ bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
|
||||
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++;
|
||||
}
|
||||
/*
|
||||
* Make transitions: SYN-RECEIVED -> ESTABLISHED SYN-RECEIVED* ->
|
||||
@ -9353,6 +9348,13 @@ bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
if (!IS_FASTOPEN(tp->t_flags))
|
||||
cc_conn_init(tp);
|
||||
}
|
||||
/*
|
||||
* Account for the ACK of our SYN prior to
|
||||
* regular ACK processing below, except for
|
||||
* simultaneous SYN, which is handled later.
|
||||
*/
|
||||
if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN))
|
||||
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.
|
||||
|
@ -6540,12 +6540,6 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
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);
|
||||
@ -6563,6 +6557,13 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
if (!IS_FASTOPEN(tp->t_flags))
|
||||
cc_conn_init(tp);
|
||||
}
|
||||
/*
|
||||
* Account for the ACK of our SYN prior to
|
||||
* regular ACK processing below, except for
|
||||
* simultaneous SYN, which is handled later.
|
||||
*/
|
||||
if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN))
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user