diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1517,6 +1517,21 @@ } } +/* + * Drop space held by incoming segment. + */ +static __inline void +tcp_do_segment_drop(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th) +{ + INP_WLOCK_ASSERT(tptoinpcb(tp)); + TCP_PROBE3(debug__input, tp, th, m); + + if (tp != NULL) { + INP_WUNLOCK(tptoinpcb(tp)); + } + m_freem(m); +} + void tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, int drop_hdrlen, int tlen, uint8_t iptos) @@ -1562,7 +1577,8 @@ "sysctl setting)\n", s, __func__); free(s, M_TCPLOG); } - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } /* @@ -1728,7 +1744,8 @@ "segment silently dropped\n", s, __func__); free(s, M_TCPLOG); } - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } } /* @@ -2008,11 +2025,15 @@ goto dropwithreset; } else if (thflags & TH_SYN) { /* non-initial SYN is ignored */ - if ((tcp_timer_active(tp, TT_DELACK) || - tcp_timer_active(tp, TT_REXMT))) - goto drop; - } else if (!(thflags & (TH_ACK|TH_FIN|TH_RST))) { - goto drop; + if (tcp_timer_active(tp, TT_DELACK) || + tcp_timer_active(tp, TT_REXMT)) { + tcp_do_segment_drop(tp, m, th); + return; + } + + } else if ((thflags & (TH_ACK|TH_FIN|TH_RST)) == 0) { + tcp_do_segment_drop(tp, m, th); + return; } } break; @@ -2039,10 +2060,14 @@ tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); tp = tcp_drop(tp, ECONNREFUSED); } - if (thflags & TH_RST) - goto drop; - if (!(thflags & TH_SYN)) - goto drop; + if (thflags & TH_RST) { + tcp_do_segment_drop(tp, m, th); + return; + } + if ((thflags & TH_SYN) == 0) { + tcp_do_segment_drop(tp, m, th); + return; + } tp->irs = th->th_seq; tcp_rcvseqinit(tp); @@ -2209,7 +2234,8 @@ m = NULL; } } - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } /* @@ -2230,7 +2256,8 @@ tcp_send_challenge_ack(tp, th, m); m = NULL; } - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } /* @@ -2257,9 +2284,11 @@ TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, tlen); TCPSTAT_INC(tcps_pawsdrop); - if (tlen) + if (tlen) { goto dropafterack; - goto drop; + } + tcp_do_segment_drop(tp, m, th); + return; } } @@ -2425,10 +2454,12 @@ cc_conn_init(tp); } goto step6; - } else if (tp->t_flags & TF_ACKNOW) + } else if (tp->t_flags & TF_ACKNOW) { goto dropafterack; - else - goto drop; + } else { + tcp_do_segment_drop(tp, m, th); + return; + } } /* @@ -2467,7 +2498,8 @@ TCPSTAT_INC(tcps_rcvacktooold); tcp_send_challenge_ack(tp, th, m); m = NULL; - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } } switch (tp->t_state) { @@ -2677,7 +2709,8 @@ tp->snd_cwnd += maxseg; } (void) tcp_output(tp); - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } else if (tp->t_dupacks == tcprexmtthresh || (tp->t_flags & TF_SACK_PERMIT && V_tcp_do_newsack && @@ -2749,7 +2782,8 @@ if (SEQ_GT(th->th_ack, tp->snd_una)) { goto resume_partialack; } - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } tp->snd_nxt = th->th_ack; tp->snd_cwnd = maxseg; @@ -2762,7 +2796,8 @@ (tp->t_dupacks - tp->snd_limited); if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } else if (V_tcp_do_rfc3042) { /* * Process first and second duplicate @@ -2820,7 +2855,8 @@ ++tp->snd_limited; } tp->snd_cwnd = oldcwnd; - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } } break; @@ -3106,7 +3142,8 @@ case TCPS_LAST_ACK: if (ourfinisacked) { tp = tcp_close(tp); - goto drop; + tcp_do_segment_drop(tp, m, th); + return; } break; } @@ -3452,17 +3489,6 @@ INP_WUNLOCK(inp); } else tcp_dropwithreset(m, th, NULL, tlen, rstreason); - return; - -drop: - /* - * Drop space held by incoming segment and return. - */ - TCP_PROBE3(debug__input, tp, th, m); - if (tp != NULL) { - INP_WUNLOCK(inp); - } - m_freem(m); } /*