Author: rscheff
Date: Thu May 21 19:46:11 2020
New Revision: 361342
URL: https://svnweb.freebsd.org/changeset/base/361342

Log:
  MFC r360477: 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, blanket)
  Approved by:  tuexen (mentor), rgrimes (mentor, blanket)
  MFC after:    3 weeks
  Sponsored by: NetApp, Inc.
  Differential Revision:        https://reviews.freebsd.org/D19000

Modified:
  stable/12/sys/netinet/tcp_input.c
  stable/12/sys/netinet/tcp_stacks/rack.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet/tcp_input.c
==============================================================================
--- stable/12/sys/netinet/tcp_input.c   Thu May 21 19:45:14 2020        
(r361341)
+++ stable/12/sys/netinet/tcp_input.c   Thu May 21 19:46:11 2020        
(r361342)
@@ -1519,7 +1519,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
     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;
@@ -2432,12 +2432,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
                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);
@@ -2458,6 +2452,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
                        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.
                 */
@@ -2751,6 +2752,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
 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__,

Modified: stable/12/sys/netinet/tcp_stacks/rack.c
==============================================================================
--- stable/12/sys/netinet/tcp_stacks/rack.c     Thu May 21 19:45:14 2020        
(r361341)
+++ stable/12/sys/netinet/tcp_stacks/rack.c     Thu May 21 19:46:11 2020        
(r361342)
@@ -5580,12 +5580,6 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, st
        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);
@@ -5603,6 +5597,13 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, st
                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.
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to