mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-29 08:08:37 +00:00
Add the ability to see TCP timers via netstat -x. This can be a useful
feature when you have a seemingly stuck socket and want to figure out why it has not been closed yet. No plans to MFC this, as it changes the netstat sysctl ABI. Reviewed by: andre, rwatson, Eric Van Gyzen
This commit is contained in:
parent
fdc1a1131e
commit
b8614722ff
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=197244
@ -1151,8 +1151,11 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
else if (inp->inp_flags & INP_TIMEWAIT) {
|
||||
bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
|
||||
xt.xt_tp.t_state = TCPS_TIME_WAIT;
|
||||
} else
|
||||
} else {
|
||||
bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
|
||||
if (xt.xt_tp.t_timers)
|
||||
tcp_timer_to_xtimer(&xt.xt_tp, xt.xt_tp.t_timers, &xt.xt_timer);
|
||||
}
|
||||
if (inp->inp_socket != NULL)
|
||||
sotoxsocket(inp->inp_socket, &xt.xt_socket);
|
||||
else {
|
||||
|
@ -659,3 +659,24 @@ tcp_timer_active(struct tcpcb *tp, int timer_type)
|
||||
}
|
||||
return callout_active(t_callout);
|
||||
}
|
||||
|
||||
#define ticks_to_msecs(t) (1000*(t) / hz)
|
||||
|
||||
void
|
||||
tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer, struct xtcp_timer *xtimer)
|
||||
{
|
||||
bzero(xtimer, sizeof(struct xtcp_timer));
|
||||
if (timer == NULL)
|
||||
return;
|
||||
if (callout_active(&timer->tt_delack))
|
||||
xtimer->tt_delack = ticks_to_msecs(timer->tt_delack.c_time - ticks);
|
||||
if (callout_active(&timer->tt_rexmt))
|
||||
xtimer->tt_rexmt = ticks_to_msecs(timer->tt_rexmt.c_time - ticks);
|
||||
if (callout_active(&timer->tt_persist))
|
||||
xtimer->tt_persist = ticks_to_msecs(timer->tt_persist.c_time - ticks);
|
||||
if (callout_active(&timer->tt_keep))
|
||||
xtimer->tt_keep = ticks_to_msecs(timer->tt_keep.c_time - ticks);
|
||||
if (callout_active(&timer->tt_2msl))
|
||||
xtimer->tt_2msl = ticks_to_msecs(timer->tt_2msl.c_time - ticks);
|
||||
xtimer->t_rcvtime = ticks_to_msecs(ticks - tp->t_rcvtime);
|
||||
}
|
||||
|
@ -141,6 +141,8 @@ static const char *tcptimers[] =
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct xtcp_timer;
|
||||
|
||||
struct tcp_timer {
|
||||
struct callout tt_rexmt; /* retransmit timer */
|
||||
struct callout tt_persist; /* retransmit persistence */
|
||||
@ -177,6 +179,8 @@ void tcp_timer_keep(void *xtp);
|
||||
void tcp_timer_persist(void *xtp);
|
||||
void tcp_timer_rexmt(void *xtp);
|
||||
void tcp_timer_delack(void *xtp);
|
||||
void tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
|
||||
struct xtcp_timer *xtimer);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -495,11 +495,20 @@ void kmod_tcpstat_inc(int statnum);
|
||||
* included. Not all of our clients do.
|
||||
*/
|
||||
#if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_)
|
||||
struct xtcp_timer {
|
||||
int tt_rexmt; /* retransmit timer */
|
||||
int tt_persist; /* retransmit persistence */
|
||||
int tt_keep; /* keepalive */
|
||||
int tt_2msl; /* 2*msl TIME_WAIT timer */
|
||||
int tt_delack; /* delayed ACK timer */
|
||||
int t_rcvtime; /* Time since last packet received */
|
||||
};
|
||||
struct xtcpcb {
|
||||
size_t xt_len;
|
||||
struct inpcb xt_inp;
|
||||
struct tcpcb xt_tp;
|
||||
struct xsocket xt_socket;
|
||||
struct xtcp_timer xt_timer;
|
||||
u_quad_t xt_alignment_hack;
|
||||
};
|
||||
#endif
|
||||
|
@ -313,6 +313,7 @@ protopr(u_long off, const char *name, int af1, int proto)
|
||||
struct inpcb *inp;
|
||||
struct xinpgen *xig, *oxig;
|
||||
struct xsocket *so;
|
||||
struct xtcp_timer *timer;
|
||||
|
||||
istcp = 0;
|
||||
switch (proto) {
|
||||
@ -347,6 +348,7 @@ protopr(u_long off, const char *name, int af1, int proto)
|
||||
xig->xig_len > sizeof(struct xinpgen);
|
||||
xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
|
||||
if (istcp) {
|
||||
timer = &((struct xtcpcb *)xig)->xt_timer;
|
||||
tp = &((struct xtcpcb *)xig)->xt_tp;
|
||||
inp = &((struct xtcpcb *)xig)->xt_inp;
|
||||
so = &((struct xtcpcb *)xig)->xt_socket;
|
||||
@ -414,14 +416,17 @@ protopr(u_long off, const char *name, int af1, int proto)
|
||||
"%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s",
|
||||
"Proto", "Recv-Q", "Send-Q",
|
||||
"Local Address", "Foreign Address");
|
||||
if (xflag)
|
||||
printf("%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %s\n",
|
||||
if (xflag) {
|
||||
printf("%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s ",
|
||||
"R-MBUF", "S-MBUF", "R-CLUS",
|
||||
"S-CLUS", "R-HIWA", "S-HIWA",
|
||||
"R-LOWA", "S-LOWA", "R-BCNT",
|
||||
"S-BCNT", "R-BMAX", "S-BMAX",
|
||||
"(state)");
|
||||
else
|
||||
"S-BCNT", "R-BMAX", "S-BMAX");
|
||||
printf("%7.7s %7.7s %7.7s %7.7s %7.7s %7.7s %s\n",
|
||||
"rexmt", "persist", "keep",
|
||||
"2msl", "delack", "rcvtime",
|
||||
"(state)");
|
||||
} else
|
||||
printf("(state)\n");
|
||||
}
|
||||
first = 0;
|
||||
@ -516,7 +521,7 @@ protopr(u_long off, const char *name, int af1, int proto)
|
||||
so->so_rcv.sb_lowat, so->so_snd.sb_lowat,
|
||||
so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt,
|
||||
so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax);
|
||||
else
|
||||
else {
|
||||
printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u ",
|
||||
so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt,
|
||||
so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt,
|
||||
@ -524,6 +529,14 @@ protopr(u_long off, const char *name, int af1, int proto)
|
||||
so->so_rcv.sb_lowat, so->so_snd.sb_lowat,
|
||||
so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt,
|
||||
so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax);
|
||||
printf("%4d.%02d %4d.%02d %4d.%02d %4d.%02d %4d.%02d %4d.%02d ",
|
||||
timer->tt_rexmt / 1000, (timer->tt_rexmt % 1000) / 10,
|
||||
timer->tt_persist / 1000, (timer->tt_persist % 1000) / 10,
|
||||
timer->tt_keep / 1000, (timer->tt_keep % 1000) / 10,
|
||||
timer->tt_2msl / 1000, (timer->tt_2msl % 1000) / 10,
|
||||
timer->tt_delack / 1000, (timer->tt_delack % 1000) / 10,
|
||||
timer->t_rcvtime / 1000, (timer->t_rcvtime % 1000) / 10);
|
||||
}
|
||||
}
|
||||
if (istcp && !Lflag) {
|
||||
if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
|
||||
|
@ -87,7 +87,7 @@ show network addresses as numbers (as with
|
||||
but show ports symbolically.
|
||||
If
|
||||
.Fl x
|
||||
is present display full socket buffer statistics for each internet socket.
|
||||
is present, display socket buffer and tcp timer statistics for each internet socket.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
|
Loading…
Reference in New Issue
Block a user