diff options
author | pst <pst@FreeBSD.org> | 1996-10-07 04:32:42 +0000 |
---|---|---|
committer | pst <pst@FreeBSD.org> | 1996-10-07 04:32:42 +0000 |
commit | b51353f335c040b93b8b1ff67548f54b0583bf05 (patch) | |
tree | 814c80d2758967fd9cd0fbbf088e6190d2a39dbb /sys/netinet/tcp_reass.c | |
parent | e80eb7c64875936656241e55c93e705df082c3f7 (diff) | |
download | FreeBSD-src-b51353f335c040b93b8b1ff67548f54b0583bf05.zip FreeBSD-src-b51353f335c040b93b8b1ff67548f54b0583bf05.tar.gz |
Increase robustness of FreeBSD against high-rate connection attempt
denial of service attacks.
Reviewed by: bde,wollman,olah
Inspired by: vjs@sgi.com
Diffstat (limited to 'sys/netinet/tcp_reass.c')
-rw-r--r-- | sys/netinet/tcp_reass.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 35a3ba5..a31fe9f 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95 - * $Id: tcp_input.c,v 1.50 1996/09/21 06:30:06 ache Exp $ + * $Id: tcp_input.c,v 1.51 1996/09/21 06:39:20 pst Exp $ */ #ifndef TUBA_INCLUDE @@ -411,20 +411,25 @@ findpcb: if (so->so_options & SO_ACCEPTCONN) { register struct tcpcb *tp0 = tp; struct socket *so2; - /* - * If the attempt to get onto the socket queue failed, - * drop the oldest queue entry and try again. - */ + if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) { + /* + * Note: dropwithreset makes sure we don't + * send a RST in response to a RST. + */ + if (tiflags & TH_ACK) { + tcpstat.tcps_badsyn++; + goto dropwithreset; + } + goto drop; + } so2 = sonewconn(so, 0); - if (!so2) { + if (so2 == 0) { tcpstat.tcps_listendrop++; - so2 = TAILQ_FIRST(&so->so_incomp); - if (so2) { - tcp_drop(sototcpcb(so2), ETIMEDOUT); - so2 = sonewconn(so, 0); - } - if (!so2) - goto drop; + so2 = sodropablereq(so); + if (so2) + tcp_drop(sototcpcb(so2), ETIMEDOUT); + else + goto drop; } so = so2; /* @@ -753,6 +758,8 @@ findpcb: } /* + * If the state is SYN_RECEIVED: + * do just the ack and RST checks from SYN_SENT state. * If the state is SYN_SENT: * if seg contains an ACK, but not for our SYN, drop the input. * if seg contains a RST, then drop the connection. @@ -764,6 +771,7 @@ findpcb: * arrange for segment to be acked (eventually) * continue processing rest of data/controls, beginning with URG */ + case TCPS_SYN_RECEIVED: case TCPS_SYN_SENT: if ((taop = tcp_gettaocache(inp)) == NULL) { taop = &tao_noncached; @@ -791,6 +799,8 @@ findpcb: tp = tcp_drop(tp, ECONNREFUSED); goto drop; } + if (tp->t_state == TCPS_SYN_RECEIVED) + break; if ((tiflags & TH_SYN) == 0) goto drop; tp->snd_wnd = ti->ti_win; /* initial send window */ |