Subject: Re: More TCP changes for review
To: None <tech-net@netbsd.org>
From: Charles M. Hannum <abuse@spamalicious.com>
List: tech-net
Date: 01/27/2005 20:33:15
--Boundary-00=_LAV+B+x0HyfXiFI
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Whoops, forgot to attach the diff.

--Boundary-00=_LAV+B+x0HyfXiFI
Content-Type: text/x-diff;
  charset="us-ascii";
  name="tcp.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="tcp.diff"

Index: tcp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v
retrieving revision 1.217
diff -u -r1.217 tcp_input.c
--- tcp_input.c	27 Jan 2005 17:14:04 -0000	1.217
+++ tcp_input.c	27 Jan 2005 20:24:51 -0000
@@ -879,7 +879,7 @@
 	struct tcpcb *tp = 0;
 	int tiflags;
 	struct socket *so = NULL;
-	int todrop, acked, ourfinisacked, needoutput = 0;
+	int todrop, dupseg, acked, ourfinisacked, needoutput = 0;
 #ifdef TCP_DEBUG
 	short ostate = 0;
 #endif
@@ -1815,6 +1815,7 @@
 	}
 
 	todrop = tp->rcv_nxt - th->th_seq;
+	dupseg = FALSE;
 	if (todrop > 0) {
 		if (tiflags & TH_SYN) {
 			tiflags &= ~TH_SYN;
@@ -1843,6 +1844,7 @@
 			 */
 			tp->t_flags |= TF_ACKNOW;
 			todrop = tlen;
+			dupseg = TRUE;
 			tcpstat.tcps_rcvdupbyte += todrop;
 			tcpstat.tcps_rcvduppack++;
 		} else if ((tiflags & TH_RST) &&
@@ -2059,7 +2061,7 @@
 	case TCPS_TIME_WAIT:
 
 		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
-			if (tlen == 0 && tiwin == tp->snd_wnd) {
+			if (tlen == 0 && !dupseg && tiwin == tp->snd_wnd) {
 				tcpstat.tcps_rcvdupack++;
 				/*
 				 * If we have outstanding data (other than
@@ -2127,17 +2129,20 @@
 					(void) tcp_output(tp);
 					goto drop;
 				}
-			} else if (tlen) {
-				tp->t_dupacks = 0;	/*XXX*/
-				/* drop very old ACKs unless th_seq matches */
-				if (th->th_seq != tp->rcv_nxt &&
+			} else {
+				/*
+				 * If the ack appears to be very old, only
+				 * allow data that is in-sequence.  This
+				 * makes it somewhat more difficult to insert
+				 * forged data by guessing sequence numbers.
+				 * Sent an ack to try to update the send
+				 * sequence number on the other side.
+				 */
+				if (tlen && th->th_seq != tp->rcv_nxt &&
 				    SEQ_LT(th->th_ack,
-				    tp->snd_una - tp->max_sndwnd)) {
-					goto drop;
-				}
-				break;
-			} else
-				tp->t_dupacks = 0;
+				    tp->snd_una - tp->max_sndwnd))
+					goto dropafterack;
+			}
 			break;
 		}
 		/*
@@ -2198,7 +2203,7 @@
 			u_int cw = tp->snd_cwnd;
 			u_int incr = tp->t_segsz;
 
-			if (cw > tp->snd_ssthresh)
+			if (cw >= tp->snd_ssthresh)
 				incr = incr * incr / cw;
 			tp->snd_cwnd = min(cw + incr,
 			    TCP_MAXWIN << tp->snd_scale);

--Boundary-00=_LAV+B+x0HyfXiFI--