PATCH to 2.1.47: connections in TIME_WAIT *don't* reconnect

Kevin Buhr (buhr@stat.wisc.edu)
05 Aug 1997 19:43:41 -0500


Alan and Linus:

I discovered that, in 2.1.47, the code to allow the reestablishment of
a TCP socket that's in the TIME_WAIT state (a la BSD, I assume)
doesn't work. The effect can be observed by "tcpdump"ing the result of:

rsh linuxhost echo
rsh linuxhost echo

The first SYN from the second "rsh" (to "linuxhost"'s "shell" port) is
reset if the old connection is still in TIME_WAIT. Since "rsh"
retries anyway, the user doesn't notice the problem. I noticed it
because the Kerberos version of "rsh" *doesn't* retry.

The problem seems to be that if an incoming connection scans the
TIME_WAIT hash and finds a matching socket, it sets the socket's state
to CLOSE but doesn't rehash it, so the second scan (to find another
taker) finds the CLOSEd socket, which Should Not Happen. This results
in a RST of the connection.

The enclosed patch to "linux/include/net/tcp.h" (against 2.1.47)
simply makes sure a socket is rehashed whenever it's closed.

Maybe there's a better way to do this?

Kevin <buhr@stat.wisc.edu>

* * *

Index: linux/include/net/tcp.h
diff -c linux/include/net/tcp.h:1.1.1.1 linux/include/net/tcp.h:1.2
*** linux/include/net/tcp.h:1.1.1.1 Thu Jul 17 12:48:51 1997
--- linux/include/net/tcp.h Tue Aug 5 19:26:20 1997
***************
*** 566,572 ****
default:
if (oldstate==TCP_ESTABLISHED)
tcp_statistics.TcpCurrEstab--;
! if (state == TCP_TIME_WAIT)
sk->prot->rehash(sk);
}
}
--- 566,572 ----
default:
if (oldstate==TCP_ESTABLISHED)
tcp_statistics.TcpCurrEstab--;
! if (state == TCP_TIME_WAIT || state == TCP_CLOSE)
sk->prot->rehash(sk);
}
}