diff options
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 81 |
1 files changed, 48 insertions, 33 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 07070ba..2c838c6 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.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, |