Date: Thu, 16 Oct 1997 11:37:41 -0700 (PDT) From: Matt Dillon <dillon@best.net> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/4782: Bug in TCP connection establishment on same port pair as TIME_WAIT Message-ID: <199710161837.LAA03536@flea.best.net> Resent-Message-ID: <199710161840.LAA16720@hub.freebsd.org>
index | next in thread | raw e-mail
>Number: 4782
>Category: kern
>Synopsis: Under certain conditions, several krsh's in a row to the same destination machine can result in refused connections
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Oct 16 11:40:00 PDT 1997
>Last-Modified:
>Originator: Matt Dillon
>Organization:
Best Internet
>Release: FreeBSD 2.2-STABLE i386
>Environment:
Latest 2.2 system, many rack mount FreeBSD boxes running 2.2.
>Description:
When krsh'ing between two FreeBSD boxes, it is possible to get
the destination in a TIME_WAIT state which causes the next krsh
from the source machine to get a connection refused (an RST).
The problem only seems to occur when the previous connection
has been established for longer then TCPTV_MSL and the destination
goes into TIME_WAIT on termination of the previous connection.
The new connection attempts to use the same port pair.
>How-To-Repeat:
Make a krsh from host1 to host2 and run a command which takes
longer then TCPTV_MSL to execute. Then try doing another random
krsh right after the first one finishes.
(assuming 10BaseT, this takes around 65 seconds)
host1> krsh host2 "dd if=/dev/zero bs=64k count=138" || dd of=/dev/null
host1> krsh host2 -n "echo hello world"
>Fix:
I believe the ordering of the TCPS_TIME_WAIT state code in
tcp_input.c is incorrect. If I patch it as below, the problem
goes away. However, I DO NOT KNOW if I am breaking something else
by reordering this code. My understanding is that the condition can
only occur if the same port pair is reused (which rcmd and krcmd
will do) and that THIS can only occur if the source machine's tcb
has already been completely closed, in which case it is safe to
close the destination machine's tcb.
-Matt
*** LINK/tcp_input.c Wed Sep 17 15:08:54 1997
--- tcp_input.c Thu Oct 16 11:10:19 1997
***************
*** 937,949 ****
case TCPS_TIME_WAIT:
if ((tiflags & TH_SYN) &&
(to.to_flag & TOF_CC) && tp->cc_recv != 0) {
- if (tp->t_state == TCPS_TIME_WAIT &&
- tp->t_duration > TCPTV_MSL)
- goto dropwithreset;
if (CC_GT(to.to_cc, tp->cc_recv)) {
tp = tcp_close(tp);
goto findpcb;
}
else
goto drop;
}
--- 937,950 ----
case TCPS_TIME_WAIT:
if ((tiflags & TH_SYN) &&
(to.to_flag & TOF_CC) && tp->cc_recv != 0) {
if (CC_GT(to.to_cc, tp->cc_recv)) {
tp = tcp_close(tp);
goto findpcb;
}
+ else
+ if (tp->t_state == TCPS_TIME_WAIT &&
+ tp->t_duration > TCPTV_MSL)
+ goto dropwithreset;
else
goto drop;
}
>Audit-Trail:
>Unformatted:
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199710161837.LAA03536>
