diff options
author | tuexen <tuexen@FreeBSD.org> | 2017-06-01 08:29:08 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2017-06-01 08:29:08 +0000 |
commit | 8b0c82adf5d60712da23781672d64d5f29c88aca (patch) | |
tree | 6249d1f2655a267f625e6854c68ef739ec34173e /sys | |
parent | 5e0e121be6212d776d98e80ff2df076a1f543b5c (diff) | |
download | FreeBSD-src-8b0c82adf5d60712da23781672d64d5f29c88aca.zip FreeBSD-src-8b0c82adf5d60712da23781672d64d5f29c88aca.tar.gz |
MFC r316743:
The sysctl variable net.inet.tcp.drop_synfin is not honored in all states,
for example not in SYN-SENT.
This patch adds code to check the sysctl variable in other states than
LISTEN.
Thanks to ae and gnn for providing comments.
Reviewed by: gnn
Differential Revision: https://reviews.freebsd.org/D9894
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/tcp_input.c | 10 | ||||
-rw-r--r-- | sys/netinet/tcp_stacks/fastpath.c | 38 |
2 files changed, 46 insertions, 2 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 1423796..be461dc 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1596,6 +1596,16 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tcp_pcap_add(th, m, &(tp->t_inpkts)); #endif + if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { + log(LOG_DEBUG, "%s; %s: " + "SYN|FIN segment ignored (based on " + "sysctl setting)\n", s, __func__); + free(s, M_TCPLOG); + } + goto drop; + } + /* * Segment received on connection. * Reset idle time and keep-alive timer. diff --git a/sys/netinet/tcp_stacks/fastpath.c b/sys/netinet/tcp_stacks/fastpath.c index 375a098..f2c493e 100644 --- a/sys/netinet/tcp_stacks/fastpath.c +++ b/sys/netinet/tcp_stacks/fastpath.c @@ -128,6 +128,8 @@ VNET_DECLARE(int, tcp_insecure_rst); #define V_tcp_insecure_rst VNET(tcp_insecure_rst) VNET_DECLARE(int, tcp_insecure_syn); #define V_tcp_insecure_syn VNET(tcp_insecure_syn) +VNET_DECLARE(int, drop_synfin); +#define V_drop_synfin VNET(drop_synfin) static void tcp_do_segment_fastslow(struct mbuf *, struct tcphdr *, struct socket *, struct tcpcb *, int, int, uint8_t, @@ -1699,7 +1701,6 @@ tcp_do_segment_fastslow(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpopt to; thflags = th->th_flags; - tp->sackhint.last_sack_ack = 0; inc = &tp->t_inpcb->inp_inc; /* * If this is either a state-changing packet or current state isn't @@ -1729,6 +1730,23 @@ tcp_do_segment_fastslow(struct mbuf *m, struct tcphdr *th, struct socket *so, KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", __func__)); + if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { + log(LOG_DEBUG, "%s; %s: " + "SYN|FIN segment ignored (based on " + "sysctl setting)\n", s, __func__); + free(s, M_TCPLOG); + } + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); + } + INP_WUNLOCK(tp->t_inpcb); + m_freem(m); + return; + } + + tp->sackhint.last_sack_ack = 0; + /* * Segment received on connection. * Reset idle time and keep-alive timer. @@ -2141,7 +2159,6 @@ tcp_do_segment_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpopt to; thflags = th->th_flags; - tp->sackhint.last_sack_ack = 0; inc = &tp->t_inpcb->inp_inc; /* * If this is either a state-changing packet or current state isn't @@ -2171,6 +2188,23 @@ tcp_do_segment_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", __func__)); + if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { + log(LOG_DEBUG, "%s; %s: " + "SYN|FIN segment ignored (based on " + "sysctl setting)\n", s, __func__); + free(s, M_TCPLOG); + } + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); + } + INP_WUNLOCK(tp->t_inpcb); + m_freem(m); + return; + } + + tp->sackhint.last_sack_ack = 0; + /* * Segment received on connection. * Reset idle time and keep-alive timer. |