Subject: Re: Panix Attack: synflooding and source routing?
To: Jonathan M. Bresler <jmb@freefall.freebsd.org>
From: Charles M. Hannum <mycroft@mit.edu>
List: tech-net
Date: 09/10/1996 19:19:20
"Jonathan M. Bresler" <jmb@freefall.freebsd.org> writes:

> 
> --- tcp_input.c.old	Sat Sep  7 22:49:11 1996
> +++ tcp_input.c	Sat Sep  7 22:49:44 1996
> @@ -451,5 +451,6 @@
>  	 */
>  	tp->t_idle = 0;
> -	tp->t_timer[TCPT_KEEP] = tcp_keepidle;
> +	if (TCPS_HAVEESTABLISHED(tp->t_state))
> +		tp->t_timer[TCPT_KEEP] = tcp_keepidle;
>  
>  	/*

I'm not sure this is complete.

In the case where we get an ACK that causes us to transition from
SYN-RECEIVED to ESTABLISHED (or a SYN+ACK that causes us to transition
from SYN-SENT to ESTABLISHED), this seems to leave the keepalive timer
still set to the initial connection timeout.  While this isn't
necessarily a bug, per se, it could cause the first keepalive probe to
be done earlier than it should be.  Stevens even points this out: `But
applying this fix then requires that the keepalive timer be set to its
initial value of 2 hours when the connection moves to the established
state.'

Also, it's worth noting explicitly that this change also affects (and
*should* affect) SYN-SENT state in the same fashion as SYN-RECEIVED
state; namely that we don't reset the timer until we've actually
established the connection.  This is relevant if we get just an ACK or
just a SYN while in SYN-SENT and either remain in SYN-SENT or
transition to SYN-RECEIVED.


With all of the above in mind, the following change seems correct:

Index: tcp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v
retrieving revision 1.24
diff -c -2 -r1.24 tcp_input.c
*** tcp_input.c	1996/09/09 14:51:20	1.24
--- tcp_input.c	1996/09/10 23:06:14
***************
*** 424,428 ****
  	 */
  	tp->t_idle = 0;
! 	tp->t_timer[TCPT_KEEP] = tcp_keepidle;
  
  	/*
--- 424,429 ----
  	 */
  	tp->t_idle = 0;
! 	if (TCPS_HAVEESTABLISHED(tp->t_state))
! 		tp->t_timer[TCPT_KEEP] = tcp_keepidle;
  
  	/*
***************
*** 668,671 ****
--- 669,673 ----
  			soisconnected(so);
  			tp->t_state = TCPS_ESTABLISHED;
+ 			tp->t_timer[TCPT_KEEP] = tcp_keepidle;
  			/* Do window scaling on this connection? */
  			if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
***************
*** 911,914 ****
--- 913,917 ----
  		soisconnected(so);
  		tp->t_state = TCPS_ESTABLISHED;
+ 		tp->t_timer[TCPT_KEEP] = tcp_keepidle;
  		/* Do window scaling? */
  		if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==