PERFORCE change 195421 for review
Catalin Nicutar
cnicutar at FreeBSD.org
Mon Jun 27 14:35:49 UTC 2011
http://p4web.freebsd.org/@@195421?ac=10
Change 195421 by cnicutar at 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 */
};
/*
More information about the p4-projects
mailing list