Skip to content

Configure TCP receive-window grow threshold per interface (#89) - #113

Merged
tinic merged 3 commits into
mainfrom
feat/tcp-grow-rtt
Sep 28, 2026
Merged

tinic merged 3 commits into
mainfrom
feat/tcp-grow-rtt

Conversation

@tinic

@tinic tinic commented Sep 28, 2026

Copy link
Copy Markdown
Owner

Adds TCPGROWRTT=<ms> (1..65535) to interface files (#89). It sets the handshake round trip at or above which a socket on that interface grows its receive window from BSD_TCP_WINDOW_LAN (100352) to its maximum. Shaped after #109 (TCPACKMAX).

  • Default stays 10 ms on every interface, WiFiPi included. There is no sana2_policy default; TCPGROWRTT=2 is an explicit opt-in.
  • A NULL interface (or TCPGROWRTT unset) uses BSD_TCP_WINDOW_GROW_RTT_MS (10), never a configured value.
  • Parsed in config_parse.c; 0, >65535 and non-numbers are warned and ignored, like TCPACKMAX. Carried on AmiSana2If.tcp_grow_rtt (set at open beside RXBUFFER). New getter: ami_sana2_get_tcp_grow_rtt().
  • bsd_tcp_window_settle (socket.c) reads it from the socket's own nx_tcp_socket_connect_interface. On the passive path, that is the accepted socket that select.c:133 passes in, whose interface the syncache set (nx_tcp_syncache.c:1300) before the handshake RTT. It is never the listener, whose connect_interface is NULL.
  • ami_bsd_tcp_window_settle and ami_bsd_tcp_window_burst_bound both take the threshold (0 = built-in 10).
  • The setting is read from the interface file alone and needs no rebuild. It takes effect when the interface is next attached.
  • No NetX change, no submodule change.

Hardware leg (2.4 GHz WiFiPi, default vs TCPGROWRTT=2, same head): a connect with a handshake RTT of 2 ms or more must show rwnd > 100352 with TCPGROWRTT=2. If it does not, the key silently fell back to the default.

Tests:

  • test_config: the key is optional and parsed; 0, 65536 and fast are each reported once.
  • pool_window: per-interface threshold cases for settle and burst_bound.
  • sana2_device: the key reaches the interface. The getter is composed with settle the way socket.c does it: a NULL interface keeps rtt >= 10, and TCPGROWRTT=2 grows a 2 ms connect but not a 1 ms one.
  • Full host ctest: 453/453 pass.
  • Cross build default on playhouse2: bsdsocket.library is 365408 bytes, against 365308 on 08c23b2 (+100 B). The budget of 366000 is unchanged.
  • check-stack-frames.sh is clean.

🤖 Generated with Claude Code

tinic and others added 3 commits September 27, 2026 22:05
TCPGROWRTT=<ms> in an interface file sets the handshake round trip at or
above which a socket on that interface grows its receive window from
BSD_TCP_WINDOW_LAN to its maximum.  1..65535, bad values are warned and
ignored like TCPACKMAX.  Unset is 0, which keeps the built-in 10 ms on
every device, WiFiPi included; there is no per-device default.

The value rides on AmiSana2If (set at open beside RXBUFFER) and
bsd_tcp_window_settle reads it from the socket's own connect interface,
so accepted sockets see it too.  ami_bsd_tcp_window_settle and
ami_bsd_tcp_window_burst_bound both take the threshold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_sana2_device composes ami_sana2_get_tcp_grow_rtt() with the window
functions the way bsd_tcp_window_settle does: a NULL interface or an
unset key keeps the rtt >= 10 line, TCPGROWRTT=2 grows a 2 ms connect.
The field is a UWORD (1..65535) and the advice text is shorter, for the
resident budget.

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

The window setting applies to accepted sockets as well as connects, so
the guide and the installer comment name the handshake round trip.  The
guide no longer promises growth from exactly 100352 bytes: both sizes
depend on the pool and on window scaling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tinic
tinic merged commit 7fd931d into main Sep 28, 2026
42 of 43 checks passed
tinic added a commit that referenced this pull request Sep 28, 2026
The v1.0.0-beta7 tag (7fd931d) contains #109 (TCPACKMAX, WiFiPi default
11,680) and #113 (TCPGROWRTT), but both entries sat under Unreleased.
Notes cut from the beta7 section would have left them out and shown them
as new in beta8.  Moved into 1.0.0-beta7 unchanged, with the corrected
sizes from #117.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
tinic added a commit that referenced this pull request Sep 28, 2026
…#119)

beta7's published notes carried the #113 squash commit's body instead of
the annotated tag's paragraph.  actions/checkout leaves the pushed tag as
a ref to the commit; on such a ref, %(contents:body) is the commit
message, which the script took for the tag body.

release-notes.sh reads the body only when refs/tags/$tag is a tag object
(a lightweight tag gets no paragraph, as documented), and release.yml
fetches the annotated tag object before rendering.  Checked on the
v1.0.0-beta7 tree: the annotated tag gives its four bullets; the tag
rewritten as a commit ref gives no paragraph instead of the commit body.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants