svn commit: r242601 - head/sys/netinet

Andre Oppermann andre at FreeBSD.org
Mon Nov 5 09:13:07 UTC 2012


Author: andre
Date: Mon Nov  5 09:13:06 2012
New Revision: 242601
URL: http://svnweb.freebsd.org/changeset/base/242601

Log:
  Back out r242262.  The simplified window change/update logic wasn't
  complete and ready for production use.
  
  PR:	kern/173309

Modified:
  head/sys/netinet/tcp_input.c

Modified: head/sys/netinet/tcp_input.c
==============================================================================
--- head/sys/netinet/tcp_input.c	Mon Nov  5 07:44:00 2012	(r242600)
+++ head/sys/netinet/tcp_input.c	Mon Nov  5 09:13:06 2012	(r242601)
@@ -1727,7 +1727,7 @@ tcp_do_segment(struct mbuf *m, struct tc
 			 * Pull snd_wl1 up to prevent seq wrap relative to
 			 * th_seq.
 			 */
-			tp->snd_wl1 = th->th_seq + tlen;
+			tp->snd_wl1 = th->th_seq;
 			/*
 			 * Pull rcv_up up to prevent seq wrap relative to
 			 * rcv_nxt.
@@ -2340,6 +2340,7 @@ tcp_do_segment(struct mbuf *m, struct tc
 		if (tlen == 0 && (thflags & TH_FIN) == 0)
 			(void) tcp_reass(tp, (struct tcphdr *)0, 0,
 			    (struct mbuf *)0);
+		tp->snd_wl1 = th->th_seq - 1;
 		/* FALLTHROUGH */
 
 	/*
@@ -2650,10 +2651,12 @@ process_ACK:
 
 		SOCKBUF_LOCK(&so->so_snd);
 		if (acked > so->so_snd.sb_cc) {
+			tp->snd_wnd -= so->so_snd.sb_cc;
 			sbdrop_locked(&so->so_snd, (int)so->so_snd.sb_cc);
 			ourfinisacked = 1;
 		} else {
 			sbdrop_locked(&so->so_snd, acked);
+			tp->snd_wnd -= acked;
 			ourfinisacked = 0;
 		}
 		/* NB: sowwakeup_locked() does an implicit unlock. */
@@ -2743,56 +2746,24 @@ step6:
 	INP_WLOCK_ASSERT(tp->t_inpcb);
 
 	/*
-	 * Window update acceptance logic.  We have to be careful not
-	 * to accept window updates from old segments in the presence
-	 * of reordering or duplication.
-	 *
-	 * A window update is valid when:
-	 *  - the segment ACK's new data.
-	 *  - the segment carries new data and its ACK is current.
-	 *  - the segment matches the current SEQ and ACK but increases
-	 *    the window.  This is the escape from persist mode, if there
-	 *    data to be sent.
-	 *
-	 * XXXAO: The presence of new SACK information would allow to
-	 * accept window updates during retransmits.  We don't have an
-	 * easy way to test for that the moment.
-	 *
-	 * NB: The other side isn't allowed to shrink the window when
-	 * not sending or acking new data.  This behavior is strongly
-	 * discouraged by RFC793, section 3.7, page 42 anyways.
-	 *
-	 * XXXAO: tiwin >= minmss to avoid jitter?
+	 * Update window information.
+	 * Don't look at window if no ACK: TAC's send garbage on first SYN.
 	 */
-        if ((thflags & TH_ACK) && tiwin != tp->snd_wnd &&
-	    (SEQ_GT(th->th_ack, tp->snd_wl2) ||
-	     (th->th_ack == tp->snd_wl2 &&
-	      (SEQ_GT(th->th_seq + tlen, tp->snd_wl1) ||
-	      (th->th_seq == tp->snd_wl1 && tlen == 0 && tiwin > tp->snd_wnd))))) {
-#if 0
-		char *s;
-		if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
-			log(LOG_DEBUG, "%s; %s: window update %lu -> %lu\n",
-			    s, __func__, tp->snd_wnd, tiwin);
-			free(s, M_TCPLOG);
-		}
-#endif
-		/* Keep track of pure window updates. */
-		if (th->th_seq == tp->snd_wl1 && tlen == 0 &&
-		    tiwin > tp->snd_wnd)
+	if ((thflags & TH_ACK) &&
+	    (SEQ_LT(tp->snd_wl1, th->th_seq) ||
+	    (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
+	     (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+		/* keep track of pure window updates */
+		if (tlen == 0 &&
+		    tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
 			TCPSTAT_INC(tcps_rcvwinupd);
-		/*
-		 * When the new window is larger, nudge output
-		 * as we may be able to send more data.
-		 */
-		if (tiwin > tp->snd_wnd)
-			needoutput = 1;
 		tp->snd_wnd = tiwin;
+		tp->snd_wl1 = th->th_seq;
+		tp->snd_wl2 = th->th_ack;
 		if (tp->snd_wnd > tp->max_sndwnd)
 			tp->max_sndwnd = tp->snd_wnd;
+		needoutput = 1;
 	}
-	if (SEQ_GT(th->th_ack, tp->snd_wl2))
-		tp->snd_wl2 = th->th_ack;
 
 	/*
 	 * Process segments with URG.
@@ -2912,8 +2883,6 @@ dodata:							/* XXX */
 			thflags = tcp_reass(tp, th, &tlen, m);
 			tp->t_flags |= TF_ACKNOW;
 		}
-		if (SEQ_GT(th->th_seq, tp->snd_wl1))
-			tp->snd_wl1 = th->th_seq + tlen;
 		if (tlen > 0 && (tp->t_flags & TF_SACK_PERMIT))
 			tcp_update_sack_list(tp, save_start, save_start + tlen);
 #if 0


More information about the svn-src-all mailing list