Try this patch, already sent to Linus:

diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore 
vanilla/linux/include/net/tcp.h linux/include/net/tcp.h
--- vanilla/linux/include/net/tcp.h     Mon Jan 24 18:15:40 2000
+++ linux/include/net/tcp.h     Mon Jan 24 19:09:24 2000
@@ -975,7 +975,7 @@
 {
        __u32 cwnd;
 
-       if (!tp->srtt || tp->srtt > (HZ/50) || tp->mss_cache > 1460)
+       if (!tp->srtt || tp->srtt > ((HZ/50)<<3) || tp->mss_cache > 1460)
                cwnd = 2;
        else if (tp->mss_cache > 1095)
                cwnd = 3;
diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore 
vanilla/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- vanilla/linux/net/ipv4/tcp.c        Mon Jan 24 18:15:41 2000
+++ linux/net/ipv4/tcp.c        Mon Jan 24 10:40:32 2000
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp.c,v 1.158 2000/01/21 23:45:57 davem Exp $
+ * Version:    $Id: tcp.c,v 1.160 2000/01/24 18:40:32 davem Exp $
  *
  * Authors:    Ross Biro, <[EMAIL PROTECTED]>
  *             Fred N. van Kempen, <[EMAIL PROTECTED]>
@@ -1027,7 +1027,6 @@
        TCP_CHECK_TIMER(sk);
 out_unlock:
        release_sock(sk);
-       tcp_push_pending_frames(sk, tp);
        return err;
 }
 
@@ -1347,6 +1346,35 @@
 
                        BUG_TRAP(tp->copied_seq == tp->rcv_nxt);
 
+                       /* Ugly... If prequeue is not empty, we have to
+                        * process it before releasing socket, otherwise
+                        * order will be broken at second iteration.
+                        * More elegant solution is required!!!
+                        *
+                        * Look: we have the following (pseudo)queues:
+                        *
+                        * 1. packets in flight
+                        * 2. backlog
+                        * 3. prequeue
+                        * 4. receive_queue
+                        *
+                        * Each queue can be processed only if the next ones
+                        * are empty. At this point we have empty receive_queue.
+                        * But prequeue _can_ be not empty after second iteration,
+                        * when we jumped to start of loop because backlog
+                        * processing added something to receive_queue.
+                        * We cannot release_sock(), because backlog contains
+                        * packets arrived _after_ prequeued ones.
+                        *
+                        * Shortly, algorithm is clear --- to process all
+                        * the queues in order. We could make it more directly,
+                        * requeueing packets from backlog to prequeue, if
+                        * is not empty. It is more elegant, but eats cycles,
+                        * unfortunately.
+                        */
+                       if (skb_queue_len(&tp->ucopy.prequeue))
+                               goto do_prequeue;
+
                        /* __ Set realtime policy in scheduler __ */
                }
 
@@ -1371,6 +1399,7 @@
 
                        if (tp->rcv_nxt == tp->copied_seq &&
                            skb_queue_len(&tp->ucopy.prequeue)) {
+do_prequeue:
                                tcp_prequeue_process(sk);
 
                                if ((chunk = len - tp->ucopy.len) != 0) {
diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore 
vanilla/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- vanilla/linux/net/ipv4/tcp_input.c  Mon Jan 24 18:15:41 2000
+++ linux/net/ipv4/tcp_input.c  Mon Jan 24 10:40:33 2000
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_input.c,v 1.182 2000/01/21 23:45:59 davem Exp $
+ * Version:    $Id: tcp_input.c,v 1.183 2000/01/24 18:40:33 davem Exp $
  *
  * Authors:    Ross Biro, <[EMAIL PROTECTED]>
  *             Fred N. van Kempen, <[EMAIL PROTECTED]>
@@ -1323,7 +1323,11 @@
        if (th->doff > (sizeof(struct tcphdr)>>2) && tw->ts_recent_stamp) {
                tcp_parse_options(NULL, th, &tp, 0);
 
-               paws_reject = tp.saw_tstamp && tcp_paws_check(&tp, th->rst);
+               if (tp.saw_tstamp) {
+                       tp.ts_recent = tw->ts_recent;
+                       tp.ts_recent_stamp = tw->ts_recent_stamp;
+                       paws_reject = tcp_paws_check(&tp, th->rst);
+               }
        }
 
        if (tw->substate == TCP_FIN_WAIT2) {
@@ -2832,7 +2836,15 @@
        if (th->doff > (sizeof(struct tcphdr)>>2)) {
                tcp_parse_options(NULL, th, &ttp, 0);
 
-               paws_reject = ttp.saw_tstamp && tcp_paws_check(&ttp, th->rst);
+               if (ttp.saw_tstamp) {
+                       ttp.ts_recent = req->ts_recent;
+                       /* We do not store true stamp, but it is not required,
+                        * it can be estimated (approximately)
+                        * from another data.
+                        */
+                       ttp.ts_recent_stamp = xtime.tv_sec - 
+((TCP_TIMEOUT_INIT/HZ)<<req->retrans);
+                       paws_reject = tcp_paws_check(&ttp, th->rst);
+               }
        }
 
        /* Check for pure retransmited SYN. */
@@ -3019,12 +3031,26 @@
                 * checked in SYN-SENT unlike another states, hence
                 * echoed tstamp must be checked too.
                 */
-               if (tp->saw_tstamp &&
-                   ((__s32)(tp->rcv_tsecr - tcp_time_stamp) > 0 ||
-                    (__s32)(tp->rcv_tsecr - tp->syn_stamp) < 0)) {
-                       NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: synsent 
reject.\n"));
-                       NET_INC_STATS_BH(PAWSActiveRejected);
-                       return 1;
+               if (tp->saw_tstamp) {
+                       if (tp->rcv_tsecr == 0) {
+                               /* Workaround for bug in linux-2.1 and early
+                                * 2.2 kernels. Let's pretend that we did not
+                                * see such timestamp to avoid bogus rtt value,
+                                * calculated by tcp_ack().
+                                */
+                               tp->saw_tstamp = 0;
+
+                               /* But do not forget to store peer's timestamp! */
+                               if (th->syn) {
+                                       tp->ts_recent = tp->rcv_tsval;
+                                       tp->ts_recent_stamp = xtime.tv_sec;
+                               }
+                       } else if ((__s32)(tp->rcv_tsecr - tcp_time_stamp) > 0 ||
+                                  (__s32)(tp->rcv_tsecr - tp->syn_stamp) < 0) {
+                               NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: 
+synsent reject.\n"));
+                               NET_INC_STATS_BH(PAWSActiveRejected);
+                               return 1;
+                       }
                }
 
                /* Now ACK is acceptable.
@@ -3449,6 +3475,14 @@
                                        tmo = tcp_fin_time(tp);
                                        if (tmo > TCP_TIMEWAIT_LEN) {
                                                tcp_reset_keepalive_timer(sk, tmo - 
TCP_TIMEWAIT_LEN);
+                                       } else if (th->fin || sk->lock.users) {
+                                               /* Bad case. We could lose such FIN 
+otherwise.
+                                                * It is not a big problem, but it 
+looks confusing
+                                                * and not so rare event. We still can 
+lose it now,
+                                                * if it spins in bh_lock_sock(), but 
+it is really
+                                                * marginal case.
+                                                */
+                                               tcp_reset_keepalive_timer(sk, tmo);
                                        } else {
                                                tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
                                                goto discard;
diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore 
vanilla/linux/net/packet/af_packet.c linux/net/packet/af_packet.c
--- vanilla/linux/net/packet/af_packet.c        Mon Jan 24 18:15:41 2000
+++ linux/net/packet/af_packet.c        Mon Jan 24 15:35:59 2000
@@ -5,7 +5,7 @@
  *
  *             PACKET - implements raw packet sockets.
  *
- * Version:    $Id: af_packet.c,v 1.27 2000/01/18 08:24:27 davem Exp $
+ * Version:    $Id: af_packet.c,v 1.28 2000/01/24 23:35:59 davem Exp $
  *
  * Authors:    Ross Biro, <[EMAIL PROTECTED]>
  *             Fred N. van Kempen, <[EMAIL PROTECTED]>
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]

Reply via email to