tcpstates(8)

πŸ“¦ version 0.36.1, in alpine 3.24, nixpkgs unstable, opensuse-leap 16.0

πŸ¦‹ NAME πŸ¦‹

okay so the manual name here is tcpstates(8) πŸ’– and it's a tool that traces TCP session state changes with durations πŸ”₯. It's built with Linux eBPF/bcc, so it's giving low-level and I'm obsessed.

πŸŽ€ SYNOPSIS πŸŽ€

tcpstates [-h] [-T] [-t] [-w] [-s] [-D PORTS] [-L PORTS] [-Y] [-4 | -6]

🌸 DESCRIPTION 🌸

okay so this tool traces TCP session state changes while it's running πŸ‘€βœ¨, and it prints the details, including how long the session spent in each state. This is the move when you need to figure out why TCP connections are laggy 😭. Is the time going to the ESTABLISHED state (data transfer) πŸ’…, or to the initialization state (SYN_SENT), or somewhere else? Iykyk.

This tool works using the sock:inet_sock_set_state tracepoint, which was added in Linux 4.16 🧚. Linux 4.16 also added extra state transitions so that every TCP transition can be observed by this tracepoint. Main character energy πŸ‘‘.

Only TCP state changes get traced, so the overhead is way lower than typical send/receive tracing. Lowkey genius 🫢.

Since this uses BPF, only the root user can use this tool. πŸ’€ Don't even try it as a regular user bestie.

🧸 REQUIREMENTS 🧸

You'll need CONFIG_BPF and bcc, plus the sock:inet_sock_set_state tracepoint πŸ”₯.

✨ OPTIONS ✨

  • -h β€” Prints the usage message πŸ’–.
  • -s β€” Gives you comma separated values output, so it's parseable πŸ“Š.
  • -t β€” Adds a timestamp column, in seconds ⏱️.
  • -T β€” Adds a time column, in HH:MM:SS format πŸ•°οΈ.
  • -w β€” Wide column output, so IPv6 addresses actually fit πŸ¦‹.
  • -L PORTS β€” A comma-separated list of local ports to trace. This gets filtered in-kernel, so it's fast πŸš€.
  • -D PORTS β€” A comma-separated list of destination ports to trace. Also filtered in-kernel πŸ’….
  • -Y β€” Logs session state changes to the systemd journal πŸ““.
  • -4 β€” Traces the IPv4 family only 🌈.
  • -6 β€” Traces the IPv6 family only 🌈.

πŸ“ EXAMPLES πŸ“

Trace all TCP sessions, and show all state changes:

# tcpstates

Include a timestamp column, and wide column output:

# tcpstates -tw

Trace connections to local ports 80 and 81 only:

# tcpstates -L 80,81

Trace connections to remote port 80 only:

# tcpstates -D 80

Trace IPv4 family only:

# tcpstates -4

Trace IPv6 family only:

# tcpstates -6

πŸ’œ FIELDS πŸ’œ

  • TIME β€” Time of the change, in HH:MM:SS format ⏰.
  • TIME(s) β€” Time of the change, in seconds πŸ•’.
  • C-PID β€” The current on-CPU process ID. This may show the process that owns the TCP session if the state change runs in synchronous process context. Otherwise it's likely to show the kernel, since it was an asynchronous state change πŸ€–.
  • C-COMM β€” The current on-CPU process name. Same deal as C-PID: it may show the session's owner in synchronous process context, and otherwise it's likely the kernel (asynchronous state change) πŸ™ˆ.
  • IP β€” The IP address family, either 4 or 6 🌐.
  • LADDR β€” The local IP address 🏠.
  • RADDR β€” The remote IP address 🌍.
  • LPORT β€” The local port πŸšͺ.
  • RPORT β€” The remote port πŸšͺ.
  • OLDSTATE β€” The previous TCP state ⬅️.
  • NEWSTATE β€” The new TCP state ➑️.
  • MS β€” How long this state lasted, in milliseconds ⏳.

🌷 OVERHEAD 🌷

This traces the kernel TCP set state function, which should get called way less often than send/receive tracing, so the overhead should be lower πŸ’–. The tool's overhead depends on the rate of new TCP sessions. If that's high (over 10,000 per second), there may be noticeable overhead, just from printing 10k lines of formatted output per second 😭.

You can find the rate of new TCP sessions using sar -n TCP 1, and by adding the active/s and passive/s columns πŸ“ˆ.

As always, test and understand this tool's overhead for your type of workload before using it in production 🫢. No cap, don't skip this step.

πŸ¦„ SOURCE πŸ¦„

This is from bcc 🐝:

https://github.com/iovisor/bcc

Also look in the bcc distribution for a companion _examples.txt file. It has example usage, output, and commentary for this tool πŸ“š.

🌈 OS 🌈

Linux 🐧

πŸ§ͺ STABILITY πŸ§ͺ

Unstable - in development. Still cooking πŸ‘©β€πŸ³.

πŸ‘©β€πŸ’» AUTHOR πŸ‘©β€πŸ’»

Brendan Gregg πŸ‘‘

πŸ”— SEE ALSO πŸ”—

tcpaccept(8), tcpconnect(8), tcptop(8), tcplife(8) πŸ’œ


Bestie, that's the whole tea ✨: tcpstates(8), user commands, dated 2018-03-20. Stay iconic and keep your sessions lowkey fast πŸ’…πŸŽ€πŸ¦‹