patch-2.1.90 linux/net/ipv4/tcp_timer.c
Next file: linux/net/ipv4/timer.c
Previous file: linux/net/ipv4/tcp_output.c
Back to the patch index
Back to the overall index
- Lines: 156
- Date:
Sat Mar 14 11:37:27 1998
- Orig file:
v2.1.89/linux/net/ipv4/tcp_timer.c
- Orig date:
Mon Jan 12 15:28:28 1998
diff -u --recursive --new-file v2.1.89/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_timer.c,v 1.33 1997/12/13 21:53:01 kuznet Exp $
+ * Version: $Id: tcp_timer.c,v 1.39 1998/03/13 08:02:17 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -31,6 +31,7 @@
static void tcp_sltimer_handler(unsigned long);
static void tcp_syn_recv_timer(unsigned long);
static void tcp_keepalive(unsigned long data);
+static void tcp_bucketgc(unsigned long);
struct timer_list tcp_slow_timer = {
NULL, NULL,
@@ -41,7 +42,8 @@
struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX] = {
{ATOMIC_INIT(0), TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK */
- {ATOMIC_INIT(0), TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive} /* KEEPALIVE */
+ {ATOMIC_INIT(0), TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive}, /* KEEPALIVE */
+ {ATOMIC_INIT(0), TCP_BUCKETGC_PERIOD, 0, tcp_bucketgc} /* BUCKETGC */
};
const char timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n";
@@ -87,20 +89,24 @@
* The delayed ack timer can be set if we are changing the
* retransmit timer when removing acked frames.
*/
- del_timer(&tp->probe_timer);
- del_timer(&tp->retransmit_timer);
+ if(tp->probe_timer.prev)
+ del_timer(&tp->probe_timer);
+ if(tp->retransmit_timer.prev)
+ del_timer(&tp->retransmit_timer);
tp->retransmit_timer.expires=jiffies+when;
add_timer(&tp->retransmit_timer);
break;
case TIME_DACK:
- del_timer(&tp->delack_timer);
+ if(tp->delack_timer.prev)
+ del_timer(&tp->delack_timer);
tp->delack_timer.expires=jiffies+when;
add_timer(&tp->delack_timer);
break;
case TIME_PROBE0:
- del_timer(&tp->probe_timer);
+ if(tp->probe_timer.prev)
+ del_timer(&tp->probe_timer);
tp->probe_timer.expires=jiffies+when;
add_timer(&tp->probe_timer);
break;
@@ -118,9 +124,12 @@
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- del_timer(&tp->retransmit_timer);
- del_timer(&tp->delack_timer);
- del_timer(&tp->probe_timer);
+ if(tp->retransmit_timer.prev)
+ del_timer(&tp->retransmit_timer);
+ if(tp->delack_timer.prev)
+ del_timer(&tp->delack_timer);
+ if(tp->probe_timer.prev)
+ del_timer(&tp->probe_timer);
}
static int tcp_write_err(struct sock *sk, int force)
@@ -131,9 +140,8 @@
tcp_clear_xmit_timers(sk);
/* Time wait the socket. */
- if (!force && (1<<sk->state) & (TCPF_FIN_WAIT1|TCPF_FIN_WAIT2|TCPF_CLOSING)) {
- tcp_set_state(sk,TCP_TIME_WAIT);
- tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
+ if (!force && ((1<<sk->state) & (TCPF_FIN_WAIT1|TCPF_FIN_WAIT2|TCPF_CLOSING))) {
+ tcp_time_wait(sk);
} else {
/* Clean up time. */
tcp_set_state(sk, TCP_CLOSE);
@@ -173,9 +181,8 @@
return 1;
}
-
-void tcp_delack_timer(unsigned long data) {
-
+void tcp_delack_timer(unsigned long data)
+{
struct sock *sk = (struct sock*)data;
if(sk->zapped)
@@ -185,8 +192,8 @@
tcp_read_wakeup(sk);
}
-void tcp_probe_timer(unsigned long data) {
-
+void tcp_probe_timer(unsigned long data)
+{
struct sock *sk = (struct sock*)data;
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
@@ -212,10 +219,9 @@
sk->err = ETIMEDOUT;
sk->error_report(sk);
- /* Time wait the socket. */
if ((1<<sk->state) & (TCPF_FIN_WAIT1|TCPF_FIN_WAIT2|TCPF_CLOSING)) {
- tcp_set_state(sk, TCP_TIME_WAIT);
- tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
+ /* Time wait the socket. */
+ tcp_time_wait(sk);
} else {
/* Clean up time. */
tcp_set_state(sk, TCP_CLOSE);
@@ -250,6 +256,35 @@
}
}
return res;
+}
+
+/* Garbage collect TCP bind buckets. */
+static void tcp_bucketgc(unsigned long __unused)
+{
+ int i;
+
+ for(i = 0; i < TCP_BHTABLE_SIZE; i++) {
+ struct tcp_bind_bucket *tb = tcp_bound_hash[i];
+
+ while(tb) {
+ struct tcp_bind_bucket *next = tb->next;
+
+ if((tb->owners == NULL) &&
+ !(tb->flags & TCPB_FLAG_LOCKED)) {
+ /* Eat timer reference. */
+ tcp_dec_slow_timer(TCP_SLT_BUCKETGC);
+
+ /* Unlink bucket. */
+ if(tb->next)
+ tb->next->pprev = tb->pprev;
+ *tb->pprev = tb->next;
+
+ /* Finally, free it up. */
+ kmem_cache_free(tcp_bucket_cachep, tb);
+ }
+ tb = next;
+ }
+ }
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov