tcp: Lowering initial RTO according to RFC 6298
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 16 Mar 2012 10:23:47 +0000 (18:23 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 16 Mar 2012 10:23:47 +0000 (18:23 +0800)
The SYN retransmit backoff is roughly according to the tcp_syn_backoff[]
as following:
                                      15s
tcp_syn_backoff[]     rexmt: 3 3 3 3 3 | 6 12 24 (ended at 57s)
tcp_syn_backoff_low[] rexmt: 1 2 4 4 4 | 8 16 16 (ended at 55s)

It is on by default and could be turned off by using sysctl
net.inet.tcp.low_rtobase

sys/netinet/tcp_input.c
sys/netinet/tcp_subr.c
sys/netinet/tcp_timer.c
sys/netinet/tcp_timer.h
sys/netinet/tcp_var.h

index 253c111..c83609e 100644 (file)
@@ -3208,5 +3208,15 @@ tcp_established(struct tcpcb *tp)
                 *  segment consisting of MSS bytes."
                 */
                tp->snd_cwnd = tp->t_maxseg;
+
+               /*
+                * RFC6298:
+                * "If the timer expires awaiting the ACK of a SYN segment
+                *  and the TCP implementation is using an RTO less than 3
+                *  seconds, the RTO MUST be re-initialized to 3 seconds
+                *  when data transmission begins"
+                */
+               if (tp->t_rxtcur < TCPTV_RTOBASE3)
+                       tp->t_rxtcur = TCPTV_RTOBASE3;
        }
 }
index 54d0679..eec53a1 100644 (file)
@@ -246,6 +246,10 @@ static int tcp_inflight_stab = 50;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, inflight_stab, CTLFLAG_RW,
     &tcp_inflight_stab, 0, "Slop in maximal packets / 10 (20 = 3 packets)");
 
+int tcp_low_rtobase = 1;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, low_rtobase, CTLFLAG_RW,
+    &tcp_low_rtobase, 0, "Lowering the Initial RTO (RFC 6298)");
+
 static MALLOC_DEFINE(M_TCPTEMP, "tcptemp", "TCP Templates for Keepalives");
 static struct malloc_pipe tcptemp_mpipe;
 
index 47edc9b..3b153da 100644 (file)
@@ -225,6 +225,9 @@ tcp_send_timermsg(struct tcpcb *tp, uint32_t task)
 int    tcp_syn_backoff[TCP_MAXRXTSHIFT + 1] =
     { 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 64, 64 };
 
+int    tcp_syn_backoff_low[TCP_MAXRXTSHIFT + 1] =
+    { 1, 2, 4, 4, 4, 8, 16, 16, 32, 64, 64, 64, 64 };
+
 int    tcp_backoff[TCP_MAXRXTSHIFT + 1] =
     { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
 
@@ -544,10 +547,17 @@ tcp_timer_rexmt_handler(struct tcpcb *tp)
        /* Throw away SACK blocks on a RTO, as specified by RFC2018. */
        tcp_sack_cleanup(&tp->scb);
        tcpstat.tcps_rexmttimeo++;
-       if (tp->t_state == TCPS_SYN_SENT)
-               rexmt = TCP_REXMTVAL(tp) * tcp_syn_backoff[tp->t_rxtshift];
-       else
+       if (tp->t_state == TCPS_SYN_SENT) {
+               if (tcp_low_rtobase) {
+                       rexmt = TCP_REXMTVAL(tp) *
+                               tcp_syn_backoff_low[tp->t_rxtshift];
+               } else {
+                       rexmt = TCP_REXMTVAL(tp) *
+                               tcp_syn_backoff[tp->t_rxtshift];
+               }
+       } else {
                rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
+       }
        TCPT_RANGESET(tp->t_rxtcur, rexmt,
                      tp->t_rttmin, TCPTV_REXMTMAX);
        /*
index a74410d..6af1c8e 100644 (file)
@@ -80,7 +80,8 @@
 #define        TCPTV_MSL       ( 30*hz)                /* max seg lifetime (hah!) */
 #define        TCPTV_SRTTBASE  0                       /* base roundtrip time;
                                                   if 0, no idea yet */
-#define        TCPTV_RTOBASE   (  3*hz)                /* assumed RTO if no info */
+#define        TCPTV_RTOBASE3  (  3*hz)                /* assumed RTO if no info */
+#define        TCPTV_RTOBASE1  (  1*hz)                /* assumed RTO (RFC 6298) */
 #define        TCPTV_SRTTDFLT  (  3*hz)                /* assumed RTT if no info */
 
 #define        TCPTV_PERSMIN   (  5*hz)                /* retransmit persistence */
@@ -130,6 +131,9 @@ static const char *tcptimers[] =
 
 #ifdef _KERNEL
 
+#define TCPTV_RTOBASE \
+       (tcp_low_rtobase ? TCPTV_RTOBASE1 : TCPTV_RTOBASE3)
+
 struct tcpcb;
 struct netmsg_tcp_timer {
        struct netmsg_base tt_msg;
index ab39bcc..b9ea866 100644 (file)
@@ -83,6 +83,7 @@
  */
 extern int tcp_do_rfc1323;
 extern int tcp_do_rfc3390;
+extern int tcp_low_rtobase;
 extern int tcp_do_sack;
 extern int tcp_do_smartsack;
 extern int tcp_aggregate_acks;