patch-2.3.99-pre4 linux/net/ipv4/tcp_output.c
Next file: linux/net/ipv6/icmp.c
Previous file: linux/net/ipv4/tcp_ipv4.c
Back to the patch index
Back to the overall index
- Lines: 105
- Date:
Mon Mar 27 10:35:57 2000
- Orig file:
v2.3.99-pre3/linux/net/ipv4/tcp_output.c
- Orig date:
Sat Feb 26 22:32:08 2000
diff -u --recursive --new-file v2.3.99-pre3/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_output.c,v 1.122 2000/02/21 15:51:41 davem Exp $
+ * Version: $Id: tcp_output.c,v 1.123 2000/03/25 01:52:05 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -126,7 +126,7 @@
#define SYSCTL_FLAG_SACK 0x4
sysctl_flags = 0;
- if(tcb->flags & TCPCB_FLAG_SYN) {
+ if (tcb->flags & TCPCB_FLAG_SYN) {
tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
if(sysctl_tcp_timestamps) {
tcp_header_size += TCPOLEN_TSTAMP_ALIGNED;
@@ -141,7 +141,7 @@
if(!(sysctl_flags & SYSCTL_FLAG_TSTAMPS))
tcp_header_size += TCPOLEN_SACKPERM_ALIGNED;
}
- } else if(tp->sack_ok && tp->num_sacks) {
+ } else if (tp->num_sacks) {
/* A SACK is 2 pad bytes, a 2 byte header, plus
* 2 32-bit sequence numbers for each SACK block.
*/
@@ -157,16 +157,19 @@
th->dest = sk->dport;
th->seq = htonl(TCP_SKB_CB(skb)->seq);
th->ack_seq = htonl(tp->rcv_nxt);
- th->doff = (tcp_header_size >> 2);
- th->res1 = 0;
- *(((__u8 *)th) + 13) = tcb->flags;
- th->check = 0;
- th->urg_ptr = ntohs(tcb->urg_ptr);
- if(tcb->flags & TCPCB_FLAG_SYN) {
+ *(((__u16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) | tcb->flags);
+ if (tcb->flags & TCPCB_FLAG_SYN) {
/* RFC1323: The window in SYN & SYN/ACK segments
* is never scaled.
*/
th->window = htons(tp->rcv_wnd);
+ } else {
+ th->window = htons(tcp_select_window(sk));
+ }
+ th->check = 0;
+ th->urg_ptr = ntohs(tcb->urg_ptr);
+
+ if (tcb->flags & TCPCB_FLAG_SYN) {
tcp_syn_build_options((__u32 *)(th + 1),
tcp_advertise_mss(sk),
(sysctl_flags & SYSCTL_FLAG_TSTAMPS),
@@ -176,13 +179,12 @@
TCP_SKB_CB(skb)->when,
tp->ts_recent);
} else {
- th->window = htons(tcp_select_window(sk));
tcp_build_and_update_options((__u32 *)(th + 1),
tp, TCP_SKB_CB(skb)->when);
}
tp->af_specific->send_check(sk, th, skb->len, skb);
- if (th->ack)
+ if (tcb->flags & TCPCB_FLAG_ACK)
tcp_event_ack_sent(sk);
if (skb->len != tcp_header_size)
@@ -1097,10 +1099,26 @@
void tcp_send_delayed_ack(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+ long ato = tp->ack.ato;
unsigned long timeout;
+ if (ato > TCP_DELACK_MIN) {
+ int max_ato;
+
+ /* If some rtt estimate is known, use it to bound delayed ack.
+ * Do not use tp->rto here, use results of rtt measurements
+ * directly.
+ */
+ if (tp->srtt)
+ max_ato = (tp->srtt >> 3) + tp->mdev;
+ else
+ max_ato = TCP_DELACK_MAX;
+
+ ato = min(ato, max_ato);
+ }
+
/* Stay within the limit we were given */
- timeout = jiffies + tp->ack.ato;
+ timeout = jiffies + ato;
/* Use new timeout only if there wasn't a older one earlier. */
spin_lock_bh(&sk->timer_lock);
@@ -1111,7 +1129,7 @@
/* If delack timer was blocked or is about to expire,
* send ACK now.
*/
- if (tp->ack.blocked || time_before_eq(tp->delack_timer.expires, jiffies+(tp->ack.ato>>2))) {
+ if (tp->ack.blocked || time_before_eq(tp->delack_timer.expires, jiffies+(ato>>2))) {
spin_unlock_bh(&sk->timer_lock);
tcp_send_ack(sk);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)