Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Jun 2011 14:35:48 GMT
From:      Catalin Nicutar <cnicutar@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 195421 for review
Message-ID:  <201106271435.p5REZmwX057382@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@195421?ac=10

Change 195421 by cnicutar@cnicutar_cronos on 2011/06/27 14:35:32

	When using UTO don't reset the connection if TCP_MAXRXTSHIFT
	retransmits are sent and the timeout has not been exceeded. If UTO
	is exceeded, drop the connection regardless of the number of
	retransmits performed.
	
	Add a field to tcpcb to record the starting time of retransmissions
	(and, implicitly, UTO).

Affected files ...

.. //depot/projects/soc2011/cnicutar_tcputo_8/src/sys/netinet/tcp_timer.c#3 edit
.. //depot/projects/soc2011/cnicutar_tcputo_8/src/sys/netinet/tcp_var.h#5 edit

Differences ...

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/sys/netinet/tcp_timer.c#3 (text+ko) ====

@@ -66,6 +66,9 @@
 #include <netinet/tcp_debug.h>
 #endif
 
+/* XXX-CN this will have to move */
+#define ticks_to_secs(t)        ((t) / hz)
+
 int	tcp_keepinit;
 SYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINIT, keepinit, CTLTYPE_INT|CTLFLAG_RW,
     &tcp_keepinit, 0, sysctl_msec_to_ticks, "I", "time to establish connection");
@@ -117,6 +120,7 @@
 	/* max idle time in persist */
 int	tcp_maxidle;
 
+
 /*
  * Tcp protocol timeout routine called every 500 ms.
  * Updates timestamps used for TCP
@@ -452,6 +456,7 @@
 	int rexmt;
 	int headlocked;
 	struct inpcb *inp;
+	int uto_left = 0;
 #ifdef TCPDEBUG
 	int ostate;
 
@@ -483,16 +488,49 @@
 	}
 	callout_deactivate(&tp->t_timers->tt_rexmt);
 	tcp_free_sackholes(tp);
+
+	if (tp->t_rxtshift == 0)
+		tp->t_suto = 0;
+
+	if ((tp->t_flags & TF_SND_UTO) || ((tp->t_flags & TF_RCV_UTO) &&
+	    tp->rcv_uto)) {
+		/* Using UTO for this connection. */
+		uto_left = max(tp->snd_uto, tp->rcv_uto);
+		if (tp->t_suto) {
+			uto_left -= ticks_to_secs(ticks - tp->t_suto);
+		}
+
+		/*
+		 * The user may choose a value that's less than TCP_MAXRXTSHIFT
+		 * retransmits.
+		 */
+		if (tp->t_rxtshift > TCP_MAXRXTSHIFT || uto_left <= 0) {
+			/* Before or after the retransmits, UTO was exceeded. */
+			TCPSTAT_INC(tcps_timeoutdrop);
+			tp = tcp_drop(tp, ETIMEDOUT);
+			goto out;
+		}
+	}
+	 
 	/*
 	 * Retransmission timer went off.  Message has not
 	 * been acked within retransmit interval.  Back off
 	 * to a longer retransmit interval and retransmit one segment.
 	 */
 	if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
-		tp->t_rxtshift = TCP_MAXRXTSHIFT;
-		TCPSTAT_INC(tcps_timeoutdrop);
-		tp = tcp_drop(tp, tp->t_softerror ?
-			      tp->t_softerror : ETIMEDOUT);
+		if (uto_left > 0) {
+			/*
+			 * Reset the timer for UTO; t_rxtshift will hint
+			 * that it's not a normal retransmit.
+			 */
+			callout_reset(&tp->t_timers->tt_rexmt, hz * uto_left,
+			    tcp_timer_rexmt, tp);
+		} else {
+			tp->t_rxtshift = TCP_MAXRXTSHIFT;
+			TCPSTAT_INC(tcps_timeoutdrop);
+			tp = tcp_drop(tp, tp->t_softerror ?
+				      tp->t_softerror : ETIMEDOUT);
+		}
 		goto out;
 	}
 	INP_INFO_WUNLOCK(&V_tcbinfo);
@@ -515,6 +553,7 @@
 		else
 		  tp->t_flags &= ~TF_WASFRECOVERY;
 		tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1));
+		tp->t_suto = ticks; /* Keep track of UTO start. */
 	}
 	TCPSTAT_INC(tcps_rexmttimeo);
 	if (tp->t_state == TCPS_SYN_SENT)
@@ -523,6 +562,9 @@
 		rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
 	TCPT_RANGESET(tp->t_rxtcur, rexmt,
 		      tp->t_rttmin, TCPTV_REXMTMAX);
+	if (uto_left) {
+		tp->t_rxtcur = min(tp->t_rxtcur, hz * uto_left);
+	}
 	/*
 	 * Disable rfc1323 if we haven't got any response to
 	 * our third SYN to work-around some broken terminal servers

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/sys/netinet/tcp_var.h#5 (text+ko) ====

@@ -200,13 +200,14 @@
 
 
 	void	*t_pspare2[6];		/* 2 CC / 4 TBD */
-	uint64_t _pad[8];		/* 5 UTO, 3 TBD (1-2 CC/RTT?) */
+	uint64_t _pad[7];		/* 4 UTO, 3 TBD (1-2 CC/RTT?) */
 
 	uint64_t	t_sndrexmitpack;/* retransmit packets sent */
 	uint64_t	t_rcvoopack;	/* out-of-order packets received */
 
 	uint64_t snd_uto;		/* sent timeout */
 	uint64_t rcv_uto;		/* received suggestion from peer */
+	uint64_t t_suto;		/* uto starting time */
 };
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106271435.p5REZmwX057382>