mirror of
https://github.com/amnezia-vpn/amneziawg-go.git
synced 2026-10-13 21:34:25 +00:00
[PR #202] fix: split handshake junk packets into bind-sized batches #201
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
amnezia-vpn/amneziawg-go#201
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/amnezia-vpn/amneziawg-go/pull/202
Author: @earmark-halt
Created: 10/8/2026
Status: 🔄 Open
Base:
master← Head:fix/handshake-junk-batch-size📝 Commits (1)
d5bcc5cfix: split handshake junk packets into bind-sized batches📊 Changes
2 files changed (+38 additions, -4 deletions)
View changed files
📝
device/device_test.go(+18 -0)📝
device/peer.go(+20 -4)📄 Description
Fixes #111.
Problem
SendHandshakeInitiationhands the I1–I5 packets, allJcjunk packets and the initiation itself to the bind in a singleSendcall. Theconn.Bindcontract caps oneSendatBatchSize()buffers, andStdNetBindonly has room forconn.IdealBatchSize(128) messages per call. OnceJc + <number of I-packets> + 1 > 128, the first handshake panics and takes the whole process down:Junk and I-packets are allocated with
cap == len, so GSO never coalesces them and the threshold is the same everywhere:Jc = 128without I-packets,Jc = 123with all of I1–I5 set.Jcis auint16in the docs, inamneziawg-toolsand in the kernel module (which sends junk packets one skb at a time). Such configs are accepted everywhere and work with the kernel module, but crash amneziawg-go.Fix
Peer.SendBuffersnow splits the buffers into chunks of at mostbind.BatchSize(), as theBindinterface requires. The transport path never passes more than one batch, so it still makes exactly oneSendcall with the same error handling as before.If the bind falls back from UDP GSO while sending a chunk (
ErrUDPGSODisabledwith a nilRetryErr), that chunk did go out, so the remaining chunks, including the initiation, are still sent.Testing
TestAWGDevicePingManyJunkPackets: ping/pong over real UDP sockets withjc=128. Without the fix it panics with the trace above on both send paths (macOS without UDP GSO, Linux with it). With the fix it passes (-count=5, also under-race).go test ./...on macOS and Linux: everything passes exceptTestAWGDevicePing, which also fails onmaster(#168)../deviceand./conncross-compile for windows/{amd64,arm64}, linux/{amd64,mips}, freebsd, openbsd, android/arm64 and ios/arm64.🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.