From 588c92252f4485641de3f9f1fc84e97e43e825fa Mon Sep 17 00:00:00 2001 From: John Polstra Date: Mon, 3 Jun 1996 15:37:52 +0000 Subject: [PATCH] Fix a bug in the handling of the "persist" state which, under certain circumstances, caused perfectly good connections to be dropped. This happened for connections over a LAN, where the retransmit timer calculation TCP_REXMTVAL(tp) returned 0. If sending was blocked by flow control for long enough, the old code dropped the connection, even though timely replies were being received for all window probes. Reviewed by: W. Richard Stevens --- sys/netinet/tcp_timer.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 776d076130d..8fbac15bb6d 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)tcp_timer.c 8.2 (Berkeley) 5/24/95 - * $Id: tcp_timer.c,v 1.15 1996/04/04 11:17:04 phk Exp $ + * $Id: tcp_timer.c,v 1.16 1996/04/15 03:46:33 davidg Exp $ */ #ifndef TUBA_INCLUDE @@ -297,12 +297,17 @@ tcp_timers(tp, timer) * (no responses to probes) reaches the maximum * backoff that we would use if retransmitting. */ - if (tp->t_rxtshift == TCP_MAXRXTSHIFT && - (tp->t_idle >= tcp_maxpersistidle || - tp->t_idle >= TCP_REXMTVAL(tp) * tcp_totbackoff)) { - tcpstat.tcps_persistdrop++; - tp = tcp_drop(tp, ETIMEDOUT); - break; + if (tp->t_rxtshift == TCP_MAXRXTSHIFT) { + u_long maxidle = TCP_REXMTVAL(tp); + if (maxidle < tp->t_rttmin) + maxidle = tp->t_rttmin; + maxidle *= tcp_totbackoff; + if (tp->t_idle >= tcp_maxpersistidle || + tp->t_idle >= maxidle) { + tcpstat.tcps_persistdrop++; + tp = tcp_drop(tp, ETIMEDOUT); + break; + } } tcp_setpersist(tp); tp->t_force = 1;