TCP complete end status work.

The ending of a connection can tell us a lot about what happened i.e. did
it fail to setup, did it timeout, was it a normal close. Often times this is
useful information to help analyze and debug issues. Rack has had
end status for some time but the base stack as not. Lets go a ahead
and add in the missing bits to populate the end status.

Reviewed by: tuexen, rscheff
Sponsored by: Netflix Inc
Differential Revision: https://reviews.freebsd.org/D36712
This commit is contained in:
Randall Stewart 2022-09-26 15:20:18 -04:00
parent e5049a1733
commit d1b07f36a2
2 changed files with 18 additions and 0 deletions

View File

@ -1604,6 +1604,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) {
rstreason = BANDLIM_UNLIMITED;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
@ -1615,6 +1616,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
tp->t_rcvtime = ticks;
if (thflags & TH_FIN)
tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_FIN);
/*
* Scale up the window into a 32-bit value.
* For the SYN_SENT state the scale is zero.
@ -1988,6 +1991,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
(SEQ_LEQ(th->th_ack, tp->snd_una) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
rstreason = BANDLIM_RST_OPENPORT;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
if (IS_FASTOPEN(tp->t_flags)) {
@ -2000,6 +2004,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
if ((thflags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) {
rstreason = BANDLIM_RST_OPENPORT;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
} else if (thflags & TH_SYN) {
/* non-initial SYN is ignored */
@ -2031,6 +2036,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if ((thflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) {
TCP_PROBE5(connect__refused, NULL, tp,
m, tp, th);
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
tp = tcp_drop(tp, ECONNREFUSED);
}
if (thflags & TH_RST)
@ -2193,6 +2199,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
close:
/* FALLTHROUGH */
default:
tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_RST);
tp = tcp_close(tp);
}
} else {
@ -2217,6 +2224,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (V_tcp_insecure_syn &&
SEQ_GEQ(th->th_seq, tp->last_ack_sent) &&
SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
tp = tcp_drop(tp, ECONNRESET);
rstreason = BANDLIM_UNLIMITED;
} else {
@ -2268,6 +2276,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) {
rstreason = BANDLIM_RST_OPENPORT;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
@ -2341,6 +2350,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
s, __func__, tcpstates[tp->t_state], tlen);
free(s, M_TCPLOG);
}
tcp_log_end_status(tp, TCP_EI_STATUS_DATA_A_CLOSE);
/* tcp_close will kill the inp pre-log the Reset */
tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST);
tp = tcp_close(tp);
TCPSTAT_INC(tcps_rcvafterclose);
rstreason = BANDLIM_UNLIMITED;
@ -3332,6 +3344,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
(SEQ_GT(tp->snd_una, th->th_ack) ||
SEQ_GT(th->th_ack, tp->snd_max)) ) {
rstreason = BANDLIM_RST_OPENPORT;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
#ifdef TCPDEBUG

View File

@ -327,6 +327,7 @@ tcp_timer_2msl(void *xtp)
inp = tp->t_inpcb;
KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp));
INP_WLOCK(inp);
tcp_log_end_status(tp, TCP_EI_STATUS_2MSL);
tcp_free_sackholes(tp);
if (callout_pending(&tp->t_timers->tt_2msl) ||
!callout_active(&tp->t_timers->tt_2msl)) {
@ -490,6 +491,7 @@ tcp_timer_keep(void *xtp)
dropit:
TCPSTAT_INC(tcps_keepdrops);
NET_EPOCH_ENTER(et);
tcp_log_end_status(tp, TCP_EI_STATUS_KEEP_MAX);
tp = tcp_drop(tp, ETIMEDOUT);
#ifdef TCPDEBUG
@ -550,6 +552,7 @@ tcp_timer_persist(void *xtp)
ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff)) {
TCPSTAT_INC(tcps_persistdrop);
NET_EPOCH_ENTER(et);
tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX);
tp = tcp_drop(tp, ETIMEDOUT);
NET_EPOCH_EXIT(et);
tcp_inpinfo_lock_del(inp, tp);
@ -563,6 +566,7 @@ tcp_timer_persist(void *xtp)
(ticks - tp->t_rcvtime) >= TCPTV_PERSMAX) {
TCPSTAT_INC(tcps_persistdrop);
NET_EPOCH_ENTER(et);
tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX);
tp = tcp_drop(tp, ETIMEDOUT);
NET_EPOCH_EXIT(et);
tcp_inpinfo_lock_del(inp, tp);
@ -631,6 +635,7 @@ tcp_timer_rexmt(void * xtp)
tp->t_rxtshift = TCP_MAXRXTSHIFT;
TCPSTAT_INC(tcps_timeoutdrop);
NET_EPOCH_ENTER(et);
tcp_log_end_status(tp, TCP_EI_STATUS_RETRAN);
tp = tcp_drop(tp, ETIMEDOUT);
NET_EPOCH_EXIT(et);
tcp_inpinfo_lock_del(inp, tp);