[TCP]: Process linger2 timeout consistently.
authorDavid S. Miller <davem@sunset.davemloft.net>
Tue, 1 Aug 2006 05:32:09 +0000 (22:32 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 2 Aug 2006 20:38:24 +0000 (13:38 -0700)
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>
net/ipv4/tcp.c

index f6a2d9223d07ca1503aecfdaa9124e09b8e22247..7b621e44b124d43b60a3b2aac3bdccacf7801b81 100644 (file)
@@ -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;