Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Sep 1996 00:47:49 +0400 (MSD)
From:      apg@demos.net (Paul Antonov)
To:        Paul Antonov <apg@demos.net>, Guido van Rooij <guido@gvr.win.tue.nl>
Cc:        hackers@FreeBSD.org
Subject:   Re: patch against SYN floods (RED impl.)
Message-ID:  <hFrr3JouB0@dream.demos.su>
In-Reply-To: <199609271937.VAA02005@gvr.win.tue.nl>; from Guido van Rooij at Fri, 27 Sep 1996 21:37:52 %2B0200 (MET DST)
References:  <199609271937.VAA02005@gvr.win.tue.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
In message <199609271937.VAA02005@gvr.win.tue.nl> Guido van Rooij
    writes:

>> I've tested in on SYN attacks with over 1000pps rate, and it works
>> reasonably well.

>Seeing your patch: isn't it much quicker to walk down the so_q0 list and
>get the pcb's from there?

Surely, I just found why I was unable to do it - in the body of loop
I've written tp = sototcpcb(so) instead of tp = sototcpcb(sp) and was
much confused to see all sockets on LISTEN state :) I hate do things on
the run, but sometimes you need to ...

*** tcp_input.c.orig	Fri Sep 27 14:53:03 1996
--- tcp_input.c	Sat Sep 28 00:37:26 1996
***************
*** 396,405 ****
  		}
  #endif
  		if (so->so_options & SO_ACCEPTCONN) {
! 			register struct tcpcb *tp0 = tp;
! 			so = sonewconn(so, 0);
! 			if (so == 0)
! 				goto drop;
  			/*
  			 * This is ugly, but ....
  			 *
--- 396,412 ----
  		}
  #endif
  		if (so->so_options & SO_ACCEPTCONN) {
! 			register struct tcpcb  *tp0 = tp;
! 			register struct socket *so0 = so;
! 			void     tcp_sodrop();
! 
! 			so = sonewconn(so0, 0);
! 			if (so == 0) {
! 				tcp_sodrop(so0, ti);
! 				so = sonewconn(so0, 0);
! 				if (so == 0)
! 					goto drop;
! 			}
  			/*
  			 * This is ugly, but ....
  			 *
***************
*** 1654,1659 ****
--- 1661,1698 ----
  		(void) soabort(so);
  	return;
  #ifndef TUBA_INCLUDE
+ }
+ 
+ /*
+  * Simple RED (Random Early Drop) implementation against SYN floods.
+  */
+ void
+ tcp_sodrop(so, ti)
+ struct socket   *so;
+ struct tcpiphdr *ti;
+ {
+ 	extern struct timeval time;
+ 	struct tcpcb    *tp;
+ 	struct inpcb    *inp;
+ 	struct socket   *sp;
+ 	int             rnd;
+ 
+ 	/* pseudo-random function */
+ 	rnd = (unsigned int) (ti->ti_seq + time.tv_usec / 33) %
+ 		so->so_q0len;
+ 	for (sp = so->so_q0; sp; sp = sp->so_q0) {
+ 		tp = sototcpcb(sp);
+ 		rnd--;
+ 		if (!tp || tp->t_state != TCPS_SYN_RECEIVED)
+ 			continue;
+ 		if (rnd <= 0) {
+ 			tp->t_timer[TCPT_KEEP] = 0;
+ 			(void) tcp_usrreq(tp->t_inpcb->inp_socket,
+ 			    PRU_SLOWTIMO, (struct mbuf *)0,
+ 			    (struct mbuf *) TCPT_KEEP, (struct mbuf *)0);
+ 			return;
+ 		}
+ 	}
  }
  
  void


-- Paul




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?hFrr3JouB0>