Skip to content

fix(network-stack): ACK zero-length segments outside the receive window - #156

Open
TadahiroYamamura wants to merge 1 commit into
earendil-works:mainfrom
TadahiroYamamura:fix/tcp-ack-zero-length-unacceptable
Open

TadahiroYamamura wants to merge 1 commit into
earendil-works:mainfrom
TadahiroYamamura:fix/tcp-ack-zero-length-unacceptable

Conversation

@TadahiroYamamura

Copy link
Copy Markdown

A1 of #155.

Problem
Gondolin does not answer guest keepalive probes (zero-length, seq = RCV.NXT - 1), so the guest kernel drops idle connections with ETIMEDOUT. Connecting through tcp.hosts with curl --keepalive-time 5 to a server that never responds, the connection is cut after 50.6s (with --no-keepalive it stays open).

Fix
Answer zero-length segments outside the receive window with an ACK (<SEQ=SND.NXT><ACK=RCV.NXT>). The receive window value (65535) now comes from the same constant that sendTCP uses.

Tests

  • A keepalive probe gets exactly one ACK with the right seq and ack
  • An acceptable bare ACK gets no reply (so two stacks do not keep ACKing each other)

Please check
RFC 9293 §3.10.7.4 says an unacceptable segment is ACKed and dropped, without processing its ack number or window. This PR keeps processing the ack number and window as before and then sends the ACK. Doing it the RFC way makes the existing test "TCP flow control pauses when tx buffer grows and resumes when drained" fail: that test sends the guest's ACKs with seq: session.vmSeq (still the guest's ISN, one before myAck), so they are treated as unacceptable and their ack numbers are no longer processed. If you prefer the RFC behavior, changing that test's seq to myAck makes it pass. Please let us know which you prefer.

Suggested CHANGELOG entry
Fix guest TCP connections being dropped after ~60s of idle time: zero-length segments outside the receive window, such as keepalive probes, are now ACKed.

🤖 AI (Claude Code) was used for the investigation and for writing the code.

Contribution Agreement

Please ensure this PR follows the guidelines in CONTRIBUTING.md.

By submitting this pull request, I confirm the following:

I understand that the entity Earendil Inc. (incorporated in the state of Delaware in 2025) needs some rights from me in order to utilize my contributions in this PR. As a contributor I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Earendil Inc. can use, modify, copy, and redistribute my contributions, under Earendil Inc.'s choice of terms.

Guest keepalive probes (zero-length, seq = RCV.NXT - 1) got no reply,
so the guest kernel dropped idle connections with ETIMEDOUT. Answer
zero-length segments outside the receive window with an ACK. Their ack
and window are still processed as before; this only adds the ACK.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant