consomme: send window updates when the TCP receive window reopens#3780
Draft
benhillis wants to merge 1 commit into
Draft
consomme: send window updates when the TCP receive window reopens#3780benhillis wants to merge 1 commit into
benhillis wants to merge 1 commit into
Conversation
Under sustained guest egress the host socket backs up, consomme's rx buffer fills, and it advertises a zero window. When the host later drained and the window reopened, nothing set needs_ack, so no window update was sent. The guest stalled at window 0 until its persist-timer probe, whose data landed out of window and was dropped as an unacceptable segment, collapsing egress throughput. Track the last window advertised to the guest (as it reconstructs it after window-scale truncation) and proactively re-advertise on reopen once a full segment is available (RFC 1122 SWS avoidance). Also fix send_syn to advertise the SYN-ACK window unscaled per RFC 7323 2.2. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a TCP flow-control stall in consomme by ensuring the guest receives a window-update ACK when the host drains the receive buffer after a previously advertised zero-window condition. It also corrects SYN/SYN-ACK window advertisement behavior under window scaling per RFC 7323.
Changes:
- Track the last receive window value actually observable by the guest (
rx_window_last_adv) and use it to detect a closed→reopened window transition. - Proactively set
needs_ackwhen host-side draining reopens the receive window enough to safely advertise (receiver SWS avoidance gate). - Fix SYN-ACK window advertisement to be unscaled (and add/adjust integration tests covering the regression scenarios).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| vm/devices/net/net_consomme/consomme/src/tcp.rs | Adds tracked advertised-window state and reopen detection; sends window-update ACKs on reopen; fixes SYN/SYN-ACK window advertisement semantics. |
| vm/devices/net/net_consomme/consomme/src/tcp/tests.rs | Extends the TCP test harness and adds regression tests for zero-window reopen, advertised-window truncation under scaling, and SYN-ACK unscaled window behavior. |
jstarks
reviewed
Jun 19, 2026
|
|
||
| sender.send_packet(&tcp, None); | ||
| self.stats.standalone_acks_tx.increment(); | ||
| self.record_advertised_window(); |
Member
There was a problem hiding this comment.
I think it would be clearer to capture rx_window_len() above and explicitly save it (shifted by scale) here, and in the send_data path.
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.
Problem
Under sustained guest egress, the host socket backs up, consomme's rx buffer fills, and it advertises a zero window. When the host later drained and the window reopened, nothing set
needs_ack, so no window-update ACK was sent. The guest stalled at window 0 until its slow persist-timer zero-window probe, whose data landed out-of-window and was dropped as "bad tcp state: unacceptable segment number". This collapsed egress throughput.Reported via WSL networking (consomme powers
wsldevicehost): a workload's egress dropped to ~20 Mbps under load.Fix
rx_window_last_adv), as the guest reconstructs it after window-scale truncation.poll_socket_backend, proactively re-advertise once a full segment of window is available (should_reopen_window, RFC 1122 4.2.3.3 receiver SWS avoidance), instead of waiting on the guest's persist timer.send_synto advertise the SYN-ACK window unscaled per RFC 7323 2.2 (it was scaling 16 KiB down to 128, throttling connection start).Tests
test_tcp_zero_window_reopen_sends_update(integration, scale 0)test_tcp_record_advertised_window_truncates_with_scale(scale 7 truncation)test_tcp_should_reopen_window_waits_for_full_segment(scale 7 gate: fires once, no re-arm)test_tcp_window_scale_activationupdated to require an unscaled SYN-ACK windowAll verified fail-without-fix / pass-with-fix. 81 consomme tests pass; clippy and
cargo xtask fmtclean.