Skip to content

consomme: send window updates when the TCP receive window reopens#3780

Draft
benhillis wants to merge 1 commit into
microsoft:mainfrom
benhillis:consomme-window-reopen
Draft

consomme: send window updates when the TCP receive window reopens#3780
benhillis wants to merge 1 commit into
microsoft:mainfrom
benhillis:consomme-window-reopen

Conversation

@benhillis

Copy link
Copy Markdown
Member

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

  • Track the window last advertised to the guest (rx_window_last_adv), as the guest reconstructs it after window-scale truncation.
  • On host drain in 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.
  • Fix send_syn to 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_activation updated to require an unscaled SYN-ACK window

All verified fail-without-fix / pass-with-fix. 81 consomme tests pass; clippy and cargo xtask fmt clean.

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>
Copilot AI review requested due to automatic review settings June 19, 2026 05:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_ack when 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.


sender.send_packet(&tcp, None);
self.stats.standalone_acks_tx.increment();
self.record_advertised_window();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants