Skip to content

Server: a frame's payload buffer grows with the bytes received - #167

Merged
undecuple merged 2 commits into
mainfrom
fork-frame-alloc
Nov 13, 2026
Merged

undecuple merged 2 commits into
mainfrom
fork-frame-alloc

Conversation

@undecuple

Copy link
Copy Markdown
Owner

Why

readPacket allocated a buffer of the length the frame header declares, up to 65535 bytes, before reading any of the payload. A connection that sent a header declaring a long payload and then stopped held that whole buffer until the read deadline ended. An ordinary idle connection holds a few KB, so each half-sent frame cost many times that, and the total scaled with the number of open connections (-max-conns, default 4096).

Change

  • server/proto.go: readPacket starts the payload buffer at readChunk (2048 bytes, or the declared length if smaller) and grows it by doubling as bytes arrive, so the memory held tracks what was received. Frames that arrive whole read exactly as before.
  • server/proto_alloc_test.go: payload sizes around the chunk and doubling boundaries and the maximum round-trip intact; truncated frames return an EOF error; a header declaring the maximum with no payload allocates at most 8 KB per call (65 KB before).
  • CHANGELOG Server: entry; the generated site files are regenerated.

Tests

  • go vet and go test -race ./server pass.
  • Mutation: setting readChunk to 65535 makes TestReadPacketDeclaredSizeNotAllocated fail (66074 bytes per call).
  • python3 tools/features.py, python3 tools/site.py, python3 tools/repo_check.py and scripts/check-deploy.sh pass.

Evidence

Before the change, a throwaway test (not in this PR) opened connections to a test server from one address, each sending only the three header bytes declaring 65535: the per-address limit admitted 32 of them and the heap grew by about 2170 KB, roughly 68 KB each.

Not in this change

The read deadline, the packet size limit and the connection limits are unchanged.

Overlap

None open on server/proto.go. Touches CHANGELOG.md, site/index.html and site/data.json, which other open PRs also change.

Developed with AI agent assistance.

@undecuple
undecuple merged commit ce4cf23 into main Nov 13, 2026
10 checks passed
@undecuple
undecuple deleted the fork-frame-alloc branch November 13, 2026 04:17
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