patch-2.1.122 linux/net/ipv4/tcp_input.c
Next file: linux/net/ipv4/tcp_ipv4.c
Previous file: linux/net/ipv4/tcp.c
Back to the patch index
Back to the overall index
- Lines: 172
- Date:
Mon Sep 14 22:52:10 1998
- Orig file:
v2.1.121/linux/net/ipv4/tcp_input.c
- Orig date:
Wed Sep 9 14:51:13 1998
diff -u --recursive --new-file v2.1.121/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_input.c,v 1.127 1998/08/26 12:04:20 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.128 1998/09/15 02:11:18 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -166,7 +166,7 @@
static __inline__ void tcp_set_rto(struct tcp_opt *tp)
{
tp->rto = (tp->srtt >> 3) + tp->mdev;
- tp->rto += (tp->rto >> 2) + (tp->rto >> ((tp->snd_cwnd>>TCP_CWND_SHIFT)-1));
+ tp->rto += (tp->rto >> 2) + (tp->rto >> (tp->snd_cwnd-1));
}
@@ -231,16 +231,13 @@
{
u32 end_window = tp->rcv_wup + tp->rcv_wnd;
- if (tp->rcv_wnd) {
- if (!before(seq, tp->rcv_nxt) && before(seq, end_window))
- return 1;
-
- if ((end_seq - seq) && after(end_seq, tp->rcv_nxt) &&
- !after(end_seq, end_window))
- return 1;
- }
-
- return 0;
+ if (tp->rcv_wnd &&
+ after(end_seq, tp->rcv_nxt) &&
+ before(seq, end_window))
+ return 1;
+ if (seq != end_window)
+ return 0;
+ return (seq == end_seq);
}
/* This functions checks to see if the tcp header is actually acceptable. */
@@ -292,7 +289,7 @@
/* The retransmission queue is always in order, so
* we can short-circuit the walk early.
*/
- if(after(TCP_SKB_CB(skb)->end_seq, end_seq))
+ if(!before(start_seq, TCP_SKB_CB(skb)->end_seq))
break;
/* We play conservative, we don't allow SACKS to partially
@@ -442,7 +439,7 @@
static __inline__ void clear_fast_retransmit(struct tcp_opt *tp)
{
if (tp->dup_acks > 3)
- tp->snd_cwnd = (tp->snd_ssthresh << TCP_CWND_SHIFT);
+ tp->snd_cwnd = (tp->snd_ssthresh);
tp->dup_acks = 0;
}
@@ -471,11 +468,11 @@
* to one half the current congestion window, but no less
* than two segments. Retransmit the missing segment.
*/
- tp->dup_acks++;
if (tp->high_seq == 0 || after(ack, tp->high_seq)) {
+ tp->dup_acks++;
if ((tp->fackets_out > 3) || (tp->dup_acks == 3)) {
- tp->snd_ssthresh = max(tp->snd_cwnd >> (TCP_CWND_SHIFT + 1), 2);
- tp->snd_cwnd = (tp->snd_ssthresh + 3) << TCP_CWND_SHIFT;
+ tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2);
+ tp->snd_cwnd = (tp->snd_ssthresh + 3);
tp->high_seq = tp->snd_nxt;
if(!tp->fackets_out)
tcp_retransmit_skb(sk, skb_peek(&sk->write_queue));
@@ -495,7 +492,7 @@
*/
if (tp->dup_acks > 3) {
if(!tp->fackets_out) {
- tp->snd_cwnd += (1 << TCP_CWND_SHIFT);
+ tp->snd_cwnd++;
} else {
/* Fill any further holes which may have appeared.
* We may want to change this to run every further
@@ -567,14 +564,20 @@
* be reduced to is not clear, since 1/2 the old window may
* still be larger than the maximum sending rate we ever achieved.
*/
-static void tcp_cong_avoid(struct tcp_opt *tp, u32 seq, u32 ack, u32 seq_rtt)
+static void tcp_cong_avoid(struct tcp_opt *tp)
{
- if ((tp->snd_cwnd>>TCP_CWND_SHIFT) <= tp->snd_ssthresh) {
+ if (tp->snd_cwnd <= tp->snd_ssthresh) {
/* In "safe" area, increase. */
- tp->snd_cwnd += (1 << TCP_CWND_SHIFT);
+ tp->snd_cwnd++;
} else {
- /* In dangerous area, increase slowly. */
- tp->snd_cwnd += 1;
+ /* In dangerous area, increase slowly.
+ * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
+ */
+ if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+ tp->snd_cwnd++;
+ tp->snd_cwnd_cnt=0;
+ } else
+ tp->snd_cwnd_cnt++;
}
}
@@ -684,7 +687,7 @@
}
} else {
tcp_set_rto(tp);
- tcp_cong_avoid(tp, seq, ack, seq_rtt);
+ tcp_cong_avoid(tp);
}
/* NOTE: safe here so long as cong_ctl doesn't use rto */
tcp_bound_rto(tp);
@@ -803,7 +806,7 @@
tcp_set_rto(tp);
tcp_bound_rto(tp);
}
- tcp_cong_avoid(tp, seq, ack, seq_rtt);
+ tcp_cong_avoid(tp);
}
}
}
@@ -1457,7 +1460,7 @@
if ((skb = tp->send_head)) {
if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) &&
- tcp_packets_in_flight(tp) < (tp->snd_cwnd >> TCP_CWND_SHIFT)) {
+ tcp_packets_in_flight(tp) < tp->snd_cwnd) {
/* Put more data onto the wire. */
tcp_write_xmit(sk);
} else if (tp->packets_out == 0 && !tp->pending) {
@@ -1711,10 +1714,6 @@
*/
if (flg == tp->pred_flags && TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
- if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) {
- tcp_send_ack(sk);
- goto discard;
- }
if (len <= th->doff*4) {
/* Bulk data transfer: sender */
if (len == th->doff*4) {
@@ -1728,7 +1727,14 @@
goto discard;
}
} else if (TCP_SKB_CB(skb)->ack_seq == tp->snd_una) {
- /* Bulk data transfer: receiver */
+ /* Bulk data transfer: receiver
+ *
+ * Check if the segment is out-of-window.
+ * It may be a zero window probe.
+ */
+ if (!before(TCP_SKB_CB(skb)->seq,
+ tp->rcv_wup + tp->rcv_wnd))
+ goto unacceptable_packet;
if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf)
goto discard;
@@ -1772,6 +1778,7 @@
TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
tp->rcv_wup, tp->rcv_wnd);
}
+unacceptable_packet:
tcp_send_ack(sk);
goto discard;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov