From owner-svn-src-all@FreeBSD.ORG Wed Sep 16 05:33:16 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 23AEC106566B; Wed, 16 Sep 2009 05:33:16 +0000 (UTC) (envelope-from silby@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 115A38FC1C; Wed, 16 Sep 2009 05:33:16 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n8G5XFq6013229; Wed, 16 Sep 2009 05:33:15 GMT (envelope-from silby@svn.freebsd.org) Received: (from silby@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n8G5XFg4013222; Wed, 16 Sep 2009 05:33:15 GMT (envelope-from silby@svn.freebsd.org) Message-Id: <200909160533.n8G5XFg4013222@svn.freebsd.org> From: Mike Silbersack Date: Wed, 16 Sep 2009 05:33:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r197244 - in head: sys/netinet usr.bin/netstat X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Sep 2009 05:33:16 -0000 Author: silby Date: Wed Sep 16 05:33:15 2009 New Revision: 197244 URL: http://svn.freebsd.org/changeset/base/197244 Log: 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 Modified: head/sys/netinet/tcp_subr.c head/sys/netinet/tcp_timer.c head/sys/netinet/tcp_timer.h head/sys/netinet/tcp_var.h head/usr.bin/netstat/inet.c head/usr.bin/netstat/netstat.1 Modified: head/sys/netinet/tcp_subr.c ============================================================================== --- head/sys/netinet/tcp_subr.c Wed Sep 16 03:49:54 2009 (r197243) +++ head/sys/netinet/tcp_subr.c Wed Sep 16 05:33:15 2009 (r197244) @@ -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 { Modified: head/sys/netinet/tcp_timer.c ============================================================================== --- head/sys/netinet/tcp_timer.c Wed Sep 16 03:49:54 2009 (r197243) +++ head/sys/netinet/tcp_timer.c Wed Sep 16 05:33:15 2009 (r197244) @@ -659,3 +659,24 @@ tcp_timer_active(struct tcpcb *tp, int t } 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); +} Modified: head/sys/netinet/tcp_timer.h ============================================================================== --- head/sys/netinet/tcp_timer.h Wed Sep 16 03:49:54 2009 (r197243) +++ head/sys/netinet/tcp_timer.h Wed Sep 16 05:33:15 2009 (r197244) @@ -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 */ Modified: head/sys/netinet/tcp_var.h ============================================================================== --- head/sys/netinet/tcp_var.h Wed Sep 16 03:49:54 2009 (r197243) +++ head/sys/netinet/tcp_var.h Wed Sep 16 05:33:15 2009 (r197244) @@ -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 Modified: head/usr.bin/netstat/inet.c ============================================================================== --- head/usr.bin/netstat/inet.c Wed Sep 16 03:49:54 2009 (r197243) +++ head/usr.bin/netstat/inet.c Wed Sep 16 05:33:15 2009 (r197244) @@ -313,6 +313,7 @@ protopr(u_long off, const char *name, in 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, in 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, in "%-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, in 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, in 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) Modified: head/usr.bin/netstat/netstat.1 ============================================================================== --- head/usr.bin/netstat/netstat.1 Wed Sep 16 03:49:54 2009 (r197243) +++ head/usr.bin/netstat/netstat.1 Wed Sep 16 05:33:15 2009 (r197244) @@ -87,7 +87,7 @@ show network addresses as numbers (as wi 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