diff options
author | bmilekic <bmilekic@FreeBSD.org> | 2001-02-11 07:39:51 +0000 |
---|---|---|
committer | bmilekic <bmilekic@FreeBSD.org> | 2001-02-11 07:39:51 +0000 |
commit | 0f9088da5625e8088bdbd7b3587fdadb265b1482 (patch) | |
tree | 05dfca28095c82a06dee66b4ae5d1541036a93af /sys/netinet/tcp_reass.c | |
parent | cc52eb42bff57e11d166025d0d19cae8152a462d (diff) | |
download | FreeBSD-src-0f9088da5625e8088bdbd7b3587fdadb265b1482.zip FreeBSD-src-0f9088da5625e8088bdbd7b3587fdadb265b1482.tar.gz |
Clean up RST ratelimiting. Previously, ratelimiting occured before tests
were performed to determine if the received packet should be reset. This
created erroneous ratelimiting and false alarms in some cases. The code
has now been reorganized so that the checks for validity come before
the call to badport_bandlim. Additionally, a few changes in the symbolic
names of the bandlim types have been made, as well as a clarification of
exactly which type each RST case falls under.
Submitted by: Mike Silbersack <silby@silby.com>
Diffstat (limited to 'sys/netinet/tcp_reass.c')
-rw-r--r-- | sys/netinet/tcp_reass.c | 81 |
1 files changed, 48 insertions, 33 deletions
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 07070ba..2c838c6 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -392,7 +392,7 @@ tcp_input(m, off0, proto) struct ip6_hdr *ip6 = NULL; int isipv6; #endif /* INET6 */ - int rstreason = 0; /* For badport_bandlim accounting purposes */ + int rstreason; /* For badport_bandlim accounting purposes */ #ifdef INET6 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; @@ -642,13 +642,13 @@ findpcb: goto drop; } } - rstreason = BANDLIM_RST_NOTOPEN; - goto maybedropwithreset; + rstreason = BANDLIM_RST_CLOSEDPORT; + goto dropwithreset; } tp = intotcpcb(inp); if (tp == 0) { - rstreason = BANDLIM_RST_NOTOPEN; - goto maybedropwithreset; + rstreason = BANDLIM_RST_CLOSEDPORT; + goto dropwithreset; } if (tp->t_state == TCPS_CLOSED) goto drop; @@ -709,7 +709,8 @@ findpcb: */ if (thflags & TH_ACK) { tcpstat.tcps_badsyn++; - goto maybedropwithreset; + rstreason = BANDLIM_RST_OPENPORT; + goto dropwithreset; } goto drop; } @@ -789,7 +790,8 @@ findpcb: */ if (thflags & TH_ACK) { tcpstat.tcps_badsyn++; - goto maybedropwithreset; + rstreason = BANDLIM_RST_OPENPORT; + goto dropwithreset; } goto drop; } @@ -1015,8 +1017,10 @@ findpcb: if (thflags & TH_RST) goto drop; - if (thflags & TH_ACK) - goto maybedropwithreset; + if (thflags & TH_ACK) { + rstreason = BANDLIM_RST_OPENPORT; + goto dropwithreset; + } if ((thflags & TH_SYN) == 0) goto drop; if (th->th_dport == th->th_sport) { @@ -1208,8 +1212,10 @@ findpcb: case TCPS_SYN_RECEIVED: if ((thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->snd_una) || - SEQ_GT(th->th_ack, tp->snd_max))) - goto maybedropwithreset; + SEQ_GT(th->th_ack, tp->snd_max))) { + rstreason = BANDLIM_RST_OPENPORT; + goto dropwithreset; + } break; /* @@ -1243,8 +1249,10 @@ findpcb: */ if (taop->tao_ccsent != 0) goto drop; - else + else { + rstreason = BANDLIM_UNLIMITED; goto dropwithreset; + } } if (thflags & TH_RST) { if (thflags & TH_ACK) @@ -1271,8 +1279,10 @@ findpcb: if (tp->cc_send != to.to_ccecho) { if (taop->tao_ccsent != 0) goto drop; - else + else { + rstreason = BANDLIM_UNLIMITED; goto dropwithreset; + } } } else tp->t_flags &= ~TF_RCVD_CC; @@ -1404,8 +1414,10 @@ trimthenstep6: if ((thflags & TH_SYN) && (to.to_flag & TOF_CC) && tp->cc_recv != 0) { if (tp->t_state == TCPS_TIME_WAIT && - (ticks - tp->t_starttime) > tcp_msl) + (ticks - tp->t_starttime) > tcp_msl) { + rstreason = BANDLIM_UNLIMITED; goto dropwithreset; + } if (CC_GT(to.to_cc, tp->cc_recv)) { tp = tcp_close(tp); goto findpcb; @@ -1550,8 +1562,10 @@ trimthenstep6: * the sequence numbers haven't wrapped. This is a partial fix * for the "LAND" DoS attack. */ - if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) - goto maybedropwithreset; + if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) { + rstreason = BANDLIM_RST_OPENPORT; + goto dropwithreset; + } todrop = tp->rcv_nxt - th->th_seq; if (todrop > 0) { @@ -1607,6 +1621,7 @@ trimthenstep6: tp->t_state > TCPS_CLOSE_WAIT && tlen) { tp = tcp_close(tp); tcpstat.tcps_rcvafterclose++; + rstreason = BANDLIM_UNLIMITED; goto dropwithreset; } @@ -1669,6 +1684,7 @@ trimthenstep6: */ if (thflags & TH_SYN) { tp = tcp_drop(tp, ECONNRESET); + rstreason = BANDLIM_UNLIMITED; goto dropwithreset; } @@ -2245,8 +2261,10 @@ dropafterack: */ if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) && (SEQ_GT(tp->snd_una, th->th_ack) || - SEQ_GT(th->th_ack, tp->snd_max)) ) - goto maybedropwithreset; + SEQ_GT(th->th_ack, tp->snd_max)) ) { + rstreason = BANDLIM_RST_OPENPORT; + goto dropwithreset; + } #ifdef TCPDEBUG if (so->so_options & SO_DEBUG) tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen, @@ -2257,22 +2275,7 @@ dropafterack: (void) tcp_output(tp); return; - - /* - * Conditionally drop with reset or just drop depending on whether - * we think we are under attack or not. - */ -maybedropwithreset: - if (rstreason != BANDLIM_RST_NOTOPEN) - rstreason = BANDLIM_RST_OPEN; - if (badport_bandlim(rstreason) < 0) - goto drop; - /* fall through */ dropwithreset: -#ifdef TCP_RESTRICT_RST - if (restrict_rst) - goto drop; -#endif /* * Generate a RST, dropping incoming segment. * Make ACK acceptable to originator of segment. @@ -2292,6 +2295,18 @@ dropwithreset: ip->ip_src.s_addr == htonl(INADDR_BROADCAST)) goto drop; /* IPv6 anycast check is done at tcp6_input() */ + + /* + * Perform bandwidth limiting (and RST blocking + * if kernel is so configured.) + */ +#ifdef TCP_RESTRICT_RST + if (restrict_rst) + goto drop; +#endif + if (badport_bandlim(rstreason) < 0) + goto drop; + #ifdef TCPDEBUG if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen, |