From owner-freebsd-hackers Fri Sep 27 13:51:54 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id NAA16144 for hackers-outgoing; Fri, 27 Sep 1996 13:51:54 -0700 (PDT) Received: from dream.demos.su (dream.demos.su [194.87.1.2]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id NAA16096 for ; Fri, 27 Sep 1996 13:51:49 -0700 (PDT) Received: by dream.demos.su id AAA00261; (8.6.12/D) Sat, 28 Sep 1996 00:47:49 +0400 To: Paul Antonov , Guido van Rooij Cc: hackers@FreeBSD.org References: <199609271937.VAA02005@gvr.win.tue.nl> In-Reply-To: <199609271937.VAA02005@gvr.win.tue.nl>; from Guido van Rooij at Fri, 27 Sep 1996 21:37:52 +0200 (MET DST) Message-ID: Organization: Demos, Moscow, Russia Date: Sat, 28 Sep 1996 00:47:49 +0400 (MSD) X-Mailer: Mail/@ [v2.40 FreeBSD] From: apg@demos.net (Paul Antonov) X-NCC-RegID: su.demos Subject: Re: patch against SYN floods (RED impl.) Lines: 91 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-hackers@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk 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