Conversation
TestTheRecordLayerDoesNotAllocatePerRecord failed on every target (3 allocs per record on amd64, 5 on 386, limit 2): the read side allocated a fresh frame buffer, a header array that escaped through io.ReadFull, and a separate plaintext buffer for every record. Read now reads each record into a buffer the connection keeps and decrypts it in place. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W2VziS7icb6hVwbTgrJF3W
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.
Requested by Amin · project thread
Before:
TestTheRecordLayerDoesNotAllocatePerRecordfailed onmainfor every target, with 3 allocations per record on amd64 and 5 on 386 against a limit of 2.After: it passes, with 2 on amd64 and 1 on 386.
The write side was already fixed to reuse its frame buffer. The read side still allocated a new frame buffer for every record, a header array that escaped through
io.ReadFull, and a separate plaintext buffer fromDecrypt(nil, …).How:
noiseConnnow keeps aninBuf.readNoiseFrameIntoreads the header and body into it and only grows it when a record doesn't fit, andReaddecrypts in place (Decrypt(frame[:0], nil, frame)). This is safe becausereadBufalways points intoinBuf, and the next record is only read oncereadBufis empty. The handshake still goes throughreadNoiseFrame, which is now a thin wrapper.Found during a v1.8.4 release check. All 7 release targets (linux 386, amd64, arm64, armv5/6/7, s390x) build and pass
go vetbefore and after this change.🤖 Generated with Claude Code
https://claude.ai/code/session_01W2VziS7icb6hVwbTgrJF3W
Generated by Claude Code