patch-2.1.127 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

diff -u --recursive --new-file v2.1.126/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.130 1998/10/04 07:06:47 davem Exp $
+ * Version:	$Id: tcp_input.c,v 1.136 1998/11/07 14:36:18 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -53,6 +53,8 @@
  *		Andi Kleen:		Add tcp_measure_rcv_mss to make 
  *					connections with MSS<min(MTU,ann. MSS)
  *					work without delayed acks. 
+ *		Andi Kleen:		Process packets with PSH set in the
+ *					fast path.
  */
 
 #include <linux/config.h>
@@ -75,7 +77,6 @@
 int sysctl_tcp_timestamps = 1;
 int sysctl_tcp_window_scaling = 1;
 int sysctl_tcp_sack = 1;
-int sysctl_tcp_hoe_retransmits = 1;
 
 int sysctl_tcp_syncookies = SYNC_INIT; 
 int sysctl_tcp_stdurg;
@@ -566,14 +567,6 @@
 
 /* This is Jacobson's slow start and congestion avoidance. 
  * SIGCOMM '88, p. 328.
- *
- * FIXME: What happens when the congestion window gets larger
- * than the maximum receiver window by some large factor
- * Suppose the pipeline never looses packets for a long
- * period of time, then traffic increases causing packet loss.
- * The congestion window should be reduced, but what it should
- * 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)
 {
@@ -1139,7 +1132,7 @@
 	/* Zap SWALK, by moving every further SACK up by one slot.
 	 * Decrease num_sacks.
 	 */
-	for(this_sack += 1; this_sack < num_sacks; this_sack++, swalk++) {
+	for(this_sack += 1; this_sack < num_sacks-1; this_sack++, swalk++) {
 		struct tcp_sack_block *next = (swalk + 1);
 		swalk->start_seq = next->start_seq;
 		swalk->end_seq = next->end_seq;
@@ -1524,7 +1517,7 @@
 	 *      - delay time <= 0.5 HZ
 	 *      - we don't have a window update to send
 	 *      - must send at least every 2 full sized packets
-	 *	- must send an ACK if we have any SACKs
+	 *	- must send an ACK if we have any out of order data
 	 *
 	 * With an extra heuristic to handle loss of packet
 	 * situations and also helping the sender leave slow
@@ -1537,8 +1530,8 @@
 	    tcp_raise_window(sk) ||
 	    /* We entered "quick ACK" mode or... */
 	    tcp_in_quickack_mode(tp) ||
-	    /* We have pending SACKs */
-	    (tp->sack_ok && tp->num_sacks)) {
+	    /* We have out of order data */
+	    (skb_peek(&tp->out_of_order_queue) != NULL)) {
 		/* Then ack it now */
 		tcp_send_ack(sk);
 	} else {
@@ -1654,8 +1647,11 @@
 			return 0;
 	}
 	
-	/* Now continue with the receive queue if it wasn't enough */
-	while ((skb = skb_peek_tail(&sk->receive_queue))) {
+	/* Now continue with the receive queue if it wasn't enough.
+	 * But only do this if we are really being abused.
+	 */
+	while ((atomic_read(&sk->rmem_alloc) >= (sk->rcvbuf * 2)) &&
+	       (skb = skb_peek_tail(&sk->receive_queue))) {
 		/* Never toss anything when we've seen the FIN.
 		 * It's just too complex to recover from it.
 		 */
@@ -1678,8 +1674,6 @@
 			   TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
 			   tp->copied_seq); 
 		kfree_skb(skb);
-		if (atomic_read(&sk->rmem_alloc) <= sk->rcvbuf) 
-			break;
 	}
 	return 0;
 }
@@ -1745,14 +1739,15 @@
 		}
 	}
 
-	flg = *(((u32 *)th) + 3);
-		
+	flg = *(((u32 *)th) + 3) & ~htonl(0x8 << 16);
+
 	/*	pred_flags is 0xS?10 << 16 + snd_wnd
 	 *	if header_predition is to be made
 	 *	'S' will always be tp->tcp_header_len >> 2
 	 *	'?' will be 0 else it will be !0
 	 *	(when there are holes in the receive 
 	 *	 space for instance)
+	 *	PSH flag is ignored.
          */
 
 	if (flg == tp->pred_flags && TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
@@ -1769,7 +1764,7 @@
 				goto discard;
 			}
 		} else if (TCP_SKB_CB(skb)->ack_seq == tp->snd_una &&
-			atomic_read(&sk->rmem_alloc) <= sk->rcvbuf) {
+			   atomic_read(&sk->rmem_alloc) <= sk->rcvbuf) {
 			/* Bulk data transfer: receiver */
 			__skb_pull(skb,th->doff*4);
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov