Skip to content

Fix Snell v6 shaped buffer headroom fallback - #5

Open
kitdine wants to merge 1 commit into
SagerNet:mainfrom
kitdine:build/snellv6-buffer-headroom
Open

Fix Snell v6 shaped buffer headroom fallback#5
kitdine wants to merge 1 commit into
SagerNet:mainfrom
kitdine:build/snellv6-buffer-headroom

Conversation

@kitdine

@kitdine kitdine commented Jul 23, 2026

Copy link
Copy Markdown

Summary

Restore the allocating fallback for Snell v6 shaped records when an input
buffer does not provide enough front headroom or AEAD-tag tailroom.

The in-place fast path is unchanged when the supplied buffer has sufficient
space.

Root cause

f4a50434aa5e removed the fallback from
shapedWriter.makeBufferRecord. A routed UDP packet can legitimately arrive
with less headroom than the current shaping sequence requires. Calling
ExtendHeader in that case panics instead of writing an allocated record.

Observed with sing-box v1.14.0-alpha.50 and Snell v6:

panic: buffer overflow: capacity 2093,start 1024, need 1147

snellv6.(*shapedWriter).makeBufferRecord
snellv6.(*shapedWriter).WritePacketBuffer
snellv6.(*clientPacketConn).WritePacket

Changes

  • fall back to makeSliceRecord when front or rear space is insufficient;
  • preserve the zero-copy path when the original buffer is large enough;
  • update buffer ownership in stream, packet, and vectorised callers for both
    possible return values;
  • add regression coverage for the insufficient-headroom path and the
    sufficient-space fast path.

Verification

go test ./... -count=1
go vet ./...
gofmt -l snellv6/shaped.go snellv6/shaped_test.go
git diff --check origin/main...HEAD

All completed successfully on Go 1.26.5.

The patched dependency was also built into sing-box for Linux/amd64 and tested
with a greater-than-1-KiB UDP packet across:

SOCKS client -> sing-box Snell v6 -> sing-box Snell v6
             -> official Snell Server v6.0.0rc -> UDP echo

The packet completed and the intermediate sing-box process remained running.

Refs #4.

This PR intentionally limits its scope to the reproduced Snell v6 shaped
packet failure. The original issue also reports a Snell v4 nested-vectorised
writer failure, which follows a different call path and is not closed by this
change.

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