summary refs log tree commit diff
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-07-31 22:32:09 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2006-08-02 13:38:24 -0700
commit52499afe40387524e9f46ef9ce4695efccdd2ed9 (patch)
treeeb097a1c4150ff00a66a692f378ea4fb6f1035f0 /net/ipv4/tcp.c
parenta280b89982f48e9a32c6410a37419b12ca88af6b (diff)
downloadlinux-52499afe40387524e9f46ef9ce4695efccdd2ed9.tar.gz
[TCP]: Process linger2 timeout consistently.
Based upon guidance from Alexey Kuznetsov.

When linger2 is active, we check to see if the fin_wait2
timeout is longer than the timewait.  If it is, we schedule
the keepalive timer for the difference between the timewait
timeout and the fin_wait2 timeout.

When this orphan socket is seen by tcp_keepalive_timer()
it will try to transform this fin_wait2 socket into a
fin_wait2 mini-socket, again if linger2 is active.

Not all paths were setting this initial keepalive timer correctly.
The tcp input path was doing it correctly, but tcp_close() wasn't,
potentially making the socket linger longer than it really needs to.

Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f6a2d9223d07..7b621e44b124 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1659,7 +1659,8 @@ adjudge_to_death:
 			const int tmo = tcp_fin_time(sk);
 
 			if (tmo > TCP_TIMEWAIT_LEN) {
-				inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk));
+				inet_csk_reset_keepalive_timer(sk,
+						tmo - TCP_TIMEWAIT_LEN);
 			} else {
 				tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
 				goto out;