Skip to content

Implemented socket state capturing#49

Merged
GyulyVGC merged 9 commits into
GyulyVGC:mainfrom
antoncxx:feat/state
Jun 10, 2026
Merged

Implemented socket state capturing#49
GyulyVGC merged 9 commits into
GyulyVGC:mainfrom
antoncxx:feat/state

Conversation

@antoncxx

@antoncxx antoncxx commented May 8, 2026

Copy link
Copy Markdown
Contributor

Add socket state to Listener

Exposes the TCP connection state (e.g. LISTEN, ESTABLISHED, TIME_WAIT) as a new state: SocketState field on the Listener struct, available on all supported platforms.

What changed

  • New SocketState enum with 12 variants covering the full TCP state machine, plus Unknown for UDP and unrecognized values
  • Display impl renders standard names (ESTABLISHED, SYN_SENT, CLOSE_WAIT, etc.)
  • Listener::new and its Display impl updated to include the state field
  • Platform-specific state parsing on all four targets:
    • Linux — hex value from /proc/net/tcp parsed via from_linux(u8)
    • macOS — tcpsi_state from proc_pidfdinfo socket info via from_bsd(i32)
    • FreeBSD / NetBSD / OpenBSD — t_state / ki_tstate from native C layer, UDP gets -1 → Unknown
    • Windows — MIB_TCP_STATE row field via from_windows(u32), UDP gets Unknown

Breaking change

Listener gains a new state field — callers constructing Listener directly (e.g. in tests) must now supply a SocketState. Integration test updated
accordingly.

@GyulyVGC GyulyVGC added the enhancement New feature or request label May 8, 2026
@GyulyVGC GyulyVGC added this to the v0.6.0 milestone May 8, 2026
@GyulyVGC

GyulyVGC commented May 8, 2026

Copy link
Copy Markdown
Owner

Thanks so much Anton, this is a nice addition.

I'd love to have comprehensive tests about some, if not all, the possible states.
But I'm not sure TCP states are something that can be easily replicated in a programmatic way in a test suite.

Introduces a `SocketState` enum covering all standard TCP connection
states (Established, Listen, SynSent, SynReceived, FinWait1, FinWait2,
TimeWait, Closed, CloseWait, LastAck, Closing), plus Unknown for UDP or
unrecognized raw values.

Each platform decodes the kernel's raw state integer into SocketState:
- Linux: parses the hex state column from /proc/net/tcp and /proc/net/tcp6
- Windows: maps MIB_TCP_STATE integer constants
- macOS/BSD: maps BSD kernel socket state integers

The `state` field is added to the public `Listener` struct and included
in its `Display` output. Integration tests cover Listen and Established
states for both IPv4 and IPv6, CloseWait (verified by reading until EOF
on the accepted socket before sampling), and UDP state.
@antoncxx

antoncxx commented May 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks so much Anton, this is a nice addition.

I'd love to have comprehensive tests about some, if not all, the possible states. But I'm not sure TCP states are something that can be easily replicated in a programmatic way in a test suite.

I added the following integration tests for the SocketState field:

  • test_tcp_listen_state — binds a TCP listener on IPv4 and asserts the state is Listen
  • test_tcp_established_state — connects a TCP stream to a local server, accepts it, and asserts the accepted socket has state Established
  • test_udp_state_is_unknown — binds a UDP socket and asserts the state is Unknown; even though the Linux kernel reports 0x07 (CLOSED) for UDP sockets in /proc/net/udp, we override it to Unknown since UDP is connectionless and the value is meaningless
  • test_tcp_listen_state_ipv6 — same as the listen test but on IPv6
  • test_tcp_established_state_ipv6 — same as the established test but on IPv6
  • test_tcp_close_wait_state — drops the client side of a connection to send a FIN, reads until EOF on the accepted socket to confirm the kernel received it, then asserts the state is CloseWait

I couldn't come up with a reliable way to test the remaining states (SynSent, SynReceived, FinWait1, FinWait2, TimeWait, LastAck, Closing) as they are transient and require precise timing to observe before the kernel advances past them.

@Jamba777

Jamba777 commented May 20, 2026

Copy link
Copy Markdown

@GyulyVGC Hey! Just wondering if you have an ETA for merging this PR 🙂

@GyulyVGC

Copy link
Copy Markdown
Owner

Hey @Jamba777 thanks for your interest in this feature

I'm pretty busy this period but I'll try my best to merge this and publish a new version in June

@GyulyVGC GyulyVGC merged commit 50119a7 into GyulyVGC:main Jun 10, 2026
6 checks passed
@GyulyVGC GyulyVGC mentioned this pull request Jun 10, 2026
@antoncxx antoncxx deleted the feat/state branch June 11, 2026 03:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants