Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -244,6 +244,9 @@ CTLFLAG_VNET, &VNET_NAME(tcps_states)[0], TCP_NSTATES, "TCP connection counts by TCP state"); +VNET_DECLARE(int, drop_synfin); +#define V_drop_synfin VNET(drop_synfin) + static void tcp_vnet_init(const void *unused) { @@ -1551,6 +1554,16 @@ 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. Index: sys/netinet/tcp_stacks/fastpath.c =================================================================== --- sys/netinet/tcp_stacks/fastpath.c +++ sys/netinet/tcp_stacks/fastpath.c @@ -132,6 +132,8 @@ #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, @@ -1787,7 +1789,6 @@ struct tcpopt to; thflags = th->th_flags; - tp->sackhint.last_sack_ack = 0; inc = &tp->t_inpcb->inp_inc; nsegs = max(1, m->m_pkthdr.lro_nsegs); /* @@ -1818,6 +1819,23 @@ 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. @@ -2233,7 +2251,6 @@ 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 @@ -2263,6 +2280,23 @@ 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.