diff options
author | Hugh Graham <hugh@cvs.openbsd.org> | 1999-11-15 05:51:00 +0000 |
---|---|---|
committer | Hugh Graham <hugh@cvs.openbsd.org> | 1999-11-15 05:51:00 +0000 |
commit | 3b40ef82602813dc08a94f1d2a9a19d29b0027e4 (patch) | |
tree | 13e975ae68a32d6aa3736276bbc46bf1c1c9471c /sys | |
parent | ec557b9d0a018d3b4970559b96f35f5852595322 (diff) |
Fix tcp retransmit/persist timers, provos@ OK.
Adapted from NetBSD:
Fix a retransmission bug introduced by the Brakmo and Peterson
RTO estimation changes. Under some circumstances it would
return a value of 0, while the old Van Jacobson RTO code would
return a minimum of 3. This would result in 12 retransmissions,
each 1 second apart. This takes care of those instances, and
ensures that t_rttmin is used everywhere as a lower bound.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/tcp_input.c | 14 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_timer.c | 16 |
3 files changed, 24 insertions, 10 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 142452d0849..e2a6b6136d3 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.50 1999/11/04 11:24:23 ho Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.51 1999/11/15 05:50:59 hugh Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -2551,6 +2551,7 @@ tcp_xmit_timer(tp, rtt) short rtt; { register short delta; + short rttmin; tcpstat.tcps_rttupdated++; --rtt; @@ -2603,8 +2604,11 @@ tcp_xmit_timer(tp, rtt) * statistical, we have to test that we don't drop below * the minimum feasible timer (which is 2 ticks). */ - TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), - rtt + 2, TCPTV_REXMTMAX); + if (tp->t_rttmin > rtt + 2) + rttmin = tp->t_rttmin; + else + rttmin = rtt + 2; + TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), rttmin, TCPTV_REXMTMAX); /* * We received an ack for a packet that wasn't retransmitted; @@ -2704,7 +2708,9 @@ tcp_mss(tp, offer) * is also a minimum value; this is subject to time. */ if (rt->rt_rmx.rmx_locks & RTV_RTT) - tp->t_rttmin = rtt / (RTM_RTTUNIT / PR_SLOWHZ); + TCPT_RANGESET(tp->t_rttmin, + rtt / (RTM_RTTUNIT / PR_SLOWHZ), + TCPTV_MIN, TCPTV_REXMTMAX); tp->t_srtt = rtt / (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE)); if (rt->rt_rmx.rmx_rttvar) tp->t_rttvar = rt->rt_rmx.rmx_rttvar / diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 5324d78f931..b204dfe9b50 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_output.c,v 1.22 1999/11/04 11:24:24 ho Exp $ */ +/* $OpenBSD: tcp_output.c,v 1.23 1999/11/15 05:50:59 hugh Exp $ */ /* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */ /* @@ -1077,6 +1077,8 @@ tcp_setpersist(tp) /* * Start/restart persistance timer. */ + if (t < tp->t_rttmin) + t = tp->t_rttmin; TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], t * tcp_backoff[tp->t_rxtshift], TCPTV_PERSMIN, TCPTV_PERSMAX); diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 79d318637b9..591dc18d7d1 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_timer.c,v 1.14 1999/09/01 21:38:21 provos Exp $ */ +/* $OpenBSD: tcp_timer.c,v 1.15 1999/11/15 05:50:59 hugh Exp $ */ /* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */ /* @@ -177,7 +177,7 @@ tcp_timers(tp, timer) register struct tcpcb *tp; int timer; { - register int rexmt; + short rto; #ifdef TCP_SACK struct sackhole *p, *q; /* @@ -229,8 +229,11 @@ tcp_timers(tp, timer) break; } tcpstat.tcps_rexmttimeo++; - rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; - TCPT_RANGESET((long) tp->t_rxtcur, rexmt, + rto = TCP_REXMTVAL(tp); + if (rto < tp->t_rttmin) + rto = tp->t_rttmin; + TCPT_RANGESET((long) tp->t_rxtcur, + rto * tcp_backoff[tp->t_rxtshift], tp->t_rttmin, TCPTV_REXMTMAX); tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; /* @@ -306,9 +309,12 @@ tcp_timers(tp, timer) * (no responses to probes) reaches the maximum * backoff that we would use if retransmitting. */ + rto = TCP_REXMTVAL(tp); + if (rto < tp->t_rttmin) + rto = tp->t_rttmin; if (tp->t_rxtshift == TCP_MAXRXTSHIFT && (tp->t_idle >= tcp_maxpersistidle || - tp->t_idle >= TCP_REXMTVAL(tp) * tcp_totbackoff)) { + tp->t_idle >= rto * tcp_totbackoff)) { tcpstat.tcps_persistdrop++; tp = tcp_drop(tp, ETIMEDOUT); break; |