fix: correct TCP window and duplicate-ACK reporting - #589
Open
domcyrus wants to merge 3 commits into
Open
Conversation
One shared slot was overwritten by whichever side sent last, so the Details window jumped between the local and remote advertised windows. Track both, and show bytes only when the handshake proved the scale. Claude-Session: https://claude.ai/code/session_017EwRvzAya3cHc66f2YeKR8
domcyrus
force-pushed
the
fix/tcp-window-size-per-direction
branch
from
August 29, 2026 10:35
799dc01 to
7ba725e
Compare
The packet that created a connection skipped the analytics, so a connection's own SYN never taught it the local window scale. Duplicate ACKs now require outstanding data and an unchanged window (RFC 5681), and a RST no longer overwrites the last advertised window. Claude-Session: https://claude.ai/code/session_017EwRvzAya3cHc66f2YeKR8
A window whose scale was never observed stands for anything up to 16384 times the header field, so print unknown instead of that number. Details help gains a Transport Health section and USAGE documents the row. Claude-Session: https://claude.ai/code/session_017EwRvzAya3cHc66f2YeKR8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three related defects in the Details Transport Health card.
Window size mixed both directions. One slot, overwritten by every segment
either way, so the value flipped between the local and remote advertised
windows (e.g. 8 one refresh, 1100 the next). Now tracked per direction and
shown as
↓local (bounds inbound) /↑remote (bounds outbound).Window scaling is negotiated only in the SYN handshake (RFC 7323), so on a
connection rustnet joined mid-stream the scale is unknowable from the wire and
the raw 16-bit field stands for anything up to 16384 times its value. That row
now reads
unknown (no handshake)instead of a number nobody can act on. Awindow never observed at all still reads
-.A connection's first packet never reached the analytics. New connections
went through
create_connection_from_packet, which never calledanalyze_tcp_segment. For a connection this host initiates that skipped packetis its own SYN, the only carrier of the local window-scale option, so the local
shift stayed unknown for the connection's whole life and windows could not be
reported in bytes even with the full handshake captured. It also left the
sequence high-water marks unseeded.
Duplicate ACKs counted keepalives and window updates. RFC 5681 §2 also
requires outstanding data and an unchanged window; only the no-data test was
implemented. An idle connection that the capture joined mid-stream reported 12
duplicate ACKs and 1 fast retransmit against 0 retransmits. A RST's window
field is meaningless, so it no longer overwrites the last advertisement either.
The Details help overlay gains a Transport Health section covering the window
pair, the unknown case, and why Initial RTT can be blank; USAGE.md and
USAGE.zh-CN.md document the row.
QUIC and transactional-UDP counters were checked for the same problems: they
are cumulative event counts, not last-value samples, so none of them mix
directions.
Benchmarked with
cargo bench --bench connection_merge: within run-to-runnoise (~33 ns per merged packet before and after).
https://claude.ai/code/session_017EwRvzAya3cHc66f2YeKR8