diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-09-20 22:53:14 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-09-20 22:53:14 +0000 |
commit | c922f1a659a0bb42a2e826c000568c540770e4af (patch) | |
tree | a4e78fa7dccb50511704fecbc4877af2064ffbcd /sys/netinet/tcp_input.c | |
parent | 33a9681c867009363487e3d4d4201e9d7c4d25fb (diff) |
`solve' the syn bomb problem as well as currently known; add sysctl's for
SOMAXCONN (kern.somaxconn), SOMINCONN (kern.sominconn), and TCPTV_KEEP_INIT
(net.inet.tcp.keepinittime). when this is not enough (ie. overfull), start
doing tail drop, but slightly prefer the same port.
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 8b7da3d6e30..0be9bed6e99 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.6 1996/08/07 06:36:26 tholo Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.7 1996/09/20 22:53:11 deraadt Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -66,6 +66,7 @@ int tcprexmtthresh = 3; struct tcpiphdr tcp_saveti; +int tcptv_keep_init = TCPTV_KEEP_INIT; extern u_long sb_max; @@ -232,6 +233,51 @@ present: } /* + * First check for a port-specific bomb. We do not want to drop half-opens + * for other ports if this is the only port being bombed. We only check + * the bottom 40 half open connections, to avoid wasting too much time. + * + * Or, otherwise it is more likely a generic syn bomb, so delete the oldest + * half-open connection. + */ +void +tcpdropoldhalfopen(avoidtp, port) + struct tcpcb *avoidtp; + u_int16_t port; +{ + register struct inpcb *inp; + register struct tcpcb *tp, *droptp = NULL; + int ncheck = 40; + int s; + + s = splnet(); + inp = tcbtable.inpt_queue.cqh_first; + if (inp) /* XXX */ + for (; inp != (struct inpcb *)&tcbtable.inpt_queue && --ncheck; + inp = inp->inp_queue.cqe_prev) { + if ((tp = (struct tcpcb *)inp->inp_ppcb) && + tp != avoidtp && + tp->t_state == TCPS_SYN_RECEIVED && + port == inp->inp_lport) { + tcp_close(tp); + goto done; + } + } + + inp = tcbtable.inpt_queue.cqh_first; + if (inp) /* XXX */ + for (; inp != (struct inpcb *)&tcbtable.inpt_queue; + inp = inp->inp_queue.cqe_prev) { + if ((tp = (struct tcpcb *)inp->inp_ppcb) && + tp != avoidtp && + tp->t_state == TCPS_SYN_RECEIVED) + break; + } +done: + splx(s); +} + +/* * TCP input routine, follows pages 65-76 of the * protocol specification dated September, 1981 very closely. */ @@ -386,9 +432,16 @@ findpcb: tcp_saveti = *ti; } if (so->so_options & SO_ACCEPTCONN) { - so = sonewconn(so, 0); - if (so == 0) - goto drop; + struct socket *so1; + + so1 = sonewconn(so, 0); + if (so1 == NULL) { + tcpdropoldhalfopen(tp, ti->ti_dport); + so1 = sonewconn(so, 0); + if (so1 == NULL) + goto drop; + } + so = so1; /* * This is ugly, but .... * @@ -630,7 +683,7 @@ findpcb: tcp_rcvseqinit(tp); tp->t_flags |= TF_ACKNOW; tp->t_state = TCPS_SYN_RECEIVED; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tp->t_timer[TCPT_KEEP] = tcptv_keep_init; dropsocket = 0; /* committed to socket */ tcpstat.tcps_accepts++; goto trimthenstep6; |