patch-2.1.91 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: 166
- Date:
Mon Mar 23 16:48:25 1998
- Orig file:
v2.1.90/linux/net/ipv4/tcp_timer.c
- Orig date:
Tue Mar 17 22:18:16 1998
diff -u --recursive --new-file v2.1.90/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.39 1998/03/13 08:02:17 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.43 1998/03/22 22:10:28 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -77,11 +77,6 @@
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- if((long)when <= 0) {
- printk(KERN_DEBUG "xmit_timer <= 0 - timer:%d when:%lx\n", what, when);
- when=HZ/50;
- }
-
switch (what) {
case TIME_RETRANS:
/* When seting the transmit timer the probe timer
@@ -91,24 +86,15 @@
*/
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);
+ mod_timer(&tp->retransmit_timer, jiffies+when);
break;
case TIME_DACK:
- if(tp->delack_timer.prev)
- del_timer(&tp->delack_timer);
- tp->delack_timer.expires=jiffies+when;
- add_timer(&tp->delack_timer);
+ mod_timer(&tp->delack_timer, jiffies+when);
break;
case TIME_PROBE0:
- if(tp->probe_timer.prev)
- del_timer(&tp->probe_timer);
- tp->probe_timer.expires=jiffies+when;
- add_timer(&tp->probe_timer);
+ mod_timer(&tp->probe_timer, jiffies+when);
break;
case TIME_WRITE:
@@ -150,17 +136,12 @@
return 1;
}
-/*
- * A write timeout has occurred. Process the after effects. BROKEN (badly)
- */
-
+/* A write timeout has occurred. Process the after effects. */
static int tcp_write_timeout(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- /*
- * Look for a 'soft' timeout.
- */
+ /* Look for a 'soft' timeout. */
if ((sk->state == TCP_ESTABLISHED &&
tp->retransmits && (tp->retransmits % TCP_QUICK_TRIES) == 0) ||
(sk->state != TCP_ESTABLISHED && tp->retransmits > sysctl_tcp_retries1)) {
@@ -206,11 +187,10 @@
return;
}
- /*
- * *WARNING* RFC 1122 forbids this
- * It doesn't AFAIK, because we kill the retransmit timer -AK
- * FIXME: We ought not to do it, Solaris 2.5 actually has fixing
- * this behaviour in Solaris down as a bug fix. [AC]
+ /* *WARNING* RFC 1122 forbids this
+ * It doesn't AFAIK, because we kill the retransmit timer -AK
+ * FIXME: We ought not to do it, Solaris 2.5 actually has fixing
+ * this behaviour in Solaris down as a bug fix. [AC]
*/
if (tp->probes_out > sysctl_tcp_retries2) {
if(sk->err_soft)
@@ -226,9 +206,10 @@
/* Clean up time. */
tcp_set_state(sk, TCP_CLOSE);
}
+ } else {
+ /* Only send another probe if we didn't close things up. */
+ tcp_send_probe0(sk);
}
-
- tcp_send_probe0(sk);
}
static __inline__ int tcp_keepopen_proc(struct sock *sk)
@@ -375,6 +356,21 @@
/* Clear delay ack timer. */
tcp_clear_xmit_timer(sk, TIME_DACK);
+ /* RFC 2018, clear all 'sacked' flags in retransmission queue,
+ * the sender may have dropped out of order frames and we must
+ * send them out should this timer fire on us.
+ */
+ if(tp->sack_ok) {
+ struct sk_buff *skb = skb_peek(&sk->write_queue);
+
+ while((skb != NULL) &&
+ (skb != tp->send_head) &&
+ (skb != (struct sk_buff *)&sk->write_queue)) {
+ TCP_SKB_CB(skb)->sacked = 0;
+ skb = skb->next;
+ }
+ }
+
/* Retransmission. */
tp->retrans_head = NULL;
if (tp->retransmits == 0) {
@@ -390,7 +386,7 @@
tp->dup_acks = 0;
tp->high_seq = tp->snd_nxt;
- tcp_do_retransmit(sk, 0);
+ tcp_retransmit_skb(sk, skb_peek(&sk->write_queue));
/* Increase the timeout each time we retransmit. Note that
* we do not increase the rtt estimate. rto is initialized
@@ -407,7 +403,7 @@
* implemented ftp to mars will work nicely. We will have to fix
* the 120 second clamps though!
*/
- tp->backoff++; /* FIXME: always same as retransmits? -- erics */
+ tp->backoff++;
tp->rto = min(tp->rto << 1, 120*HZ);
tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
@@ -523,18 +519,18 @@
void __tcp_inc_slow_timer(struct tcp_sl_timer *slt)
{
unsigned long now = jiffies;
- unsigned long next = 0;
unsigned long when;
slt->last = now;
-
+
when = now + slt->period;
- if (del_timer(&tcp_slow_timer))
- next = tcp_slow_timer.expires;
- if (next && ((long)(next - when) < 0))
- when = next;
-
- tcp_slow_timer.expires = when;
- add_timer(&tcp_slow_timer);
+ if (tcp_slow_timer.prev) {
+ if ((long)(tcp_slow_timer.expires - when) >= 0) {
+ mod_timer(&tcp_slow_timer, when);
+ }
+ } else {
+ tcp_slow_timer.expires = when;
+ add_timer(&tcp_slow_timer);
+ }
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov