--- 2.2.14-tcp/net/ipv4/tcp_output.c.~1~ Fri Jan 7 18:19:25 2000 +++ 2.2.14-tcp/net/ipv4/tcp_output.c Wed Jan 19 06:48:23 2000 @@ -1004,9 +1004,20 @@ unsigned long timeout; /* Stay within the limit we were given */ - timeout = tp->ato; + timeout = tp->ato & ~(1<<31); if (timeout > max_timeout) timeout = max_timeout; + if (!timeout) + { + timeout = tp->rto; + if ((signed) timeout <= 0) + { + printk(KERN_ERR + "tcp_send_delayed_ack: rto %ld!\n", timeout); + timeout = 1; + } + timeout = min(timeout, max_timeout); + } timeout += jiffies; /* Use new timeout only if there wasn't a older one earlier. */ --- 2.2.14-tcp/net/ipv4/tcp_input.c.~1~ Fri Jan 7 18:19:25 2000 +++ 2.2.14-tcp/net/ipv4/tcp_input.c Wed Jan 19 06:49:41 2000 @@ -96,6 +96,7 @@ */ static void tcp_delack_estimator(struct tcp_opt *tp) { + tcp_exit_quickack_mode(tp); if(tp->ato == 0) { tp->lrcvtime = tcp_time_stamp; @@ -114,10 +115,7 @@ if(m > tp->rto) tp->ato = tp->rto; else { - /* This funny shift makes sure we - * clear the "quick ack mode" bit. - */ - tp->ato = ((tp->ato << 1) >> 2) + m; + tp->ato = (tp->ato >> 1) + m; } } } --- 2.2.14-tcp/net/ipv4/tcp_ipv4.c.~1~ Fri Jan 7 18:19:25 2000 +++ 2.2.14-tcp/net/ipv4/tcp_ipv4.c Wed Jan 19 06:55:16 2000 @@ -1394,6 +1394,7 @@ newtp->snd_una = req->snt_isn + 1; newtp->srtt = 0; newtp->ato = 0; + tcp_enter_quickack_mode(newtp); newtp->snd_wl1 = req->rcv_isn; newtp->snd_wl2 = req->snt_isn; @@ -1937,6 +1938,7 @@ skb_queue_head_init(&tp->out_of_order_queue); tcp_init_xmit_timers(sk); + tcp_enter_quickack_mode(tp); tp->rto = TCP_TIMEOUT_INIT; /*TCP_WRITE_TIME*/ tp->mdev = TCP_TIMEOUT_INIT; tp->mss_clamp = ~0; --- 2.2.14-tcp/net/ipv4/tcp_timer.c.~1~ Fri Jan 7 18:19:25 2000 +++ 2.2.14-tcp/net/ipv4/tcp_timer.c Wed Jan 19 06:47:20 2000 @@ -173,7 +173,21 @@ if (!atomic_read(&sk->sock_readers)) tcp_send_ack(sk); else - tcp_send_delayed_ack(&(sk->tp_pinfo.af_tcp), HZ/10); + { + struct tcp_opt * tp = &(sk->tp_pinfo.af_tcp); + int rto; + + rto = tp->rto; + if (rto <= 0) + { + printk(KERN_ERR + "tcp_delack_timer: rto %d!\n", rto); + rto = 1; + } + rto = min(rto, HZ/10); + tp->delack_timer.expires = rto + jiffies; + add_timer(&tp->delack_timer); + } } }