mirror of
https://github.com/amnezia-vpn/amneziawg-go.git
synced 2026-10-14 05:41:54 +00:00
[GH-ISSUE #110] arm64: outbound H4 header corrupted in transport packets (AmneziaWG 1.5) #57
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#57
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?
Originally created by @FrankBacon24 on GitHub (Jan 26, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-go/issues/110
Originally assigned to: @ygurov on GitHub.
Summary
Outbound AmneziaWG transport packets have corrupted H4 (uint32) message type header on embedded Linux (arm64, CGO disabled).
Handshake works correctly, but transport packets are sent with incorrect H4 bytes, causing the server to drop all data traffic.
This blocks AmneziaWG 1.5 usage on embedded routers (Keenetic / Entware).
Environment
v0.2.14-beta-awg-1.5-1linux/arm64CGO_ENABLED=0go1.25.6Build snippet (client side):
Expected behavior
Transport UDP payload starts with correct little-endian uint32 H4 value from config.
Example:
Actual behavior
Transport packets are sent with corrupted H4 bytes:
Bytes 0 and 3 are correct, bytes 1–2 are wrong (looks like partial write / stale bytes).
Symptoms
Reproduction steps
GOARCH=arm64CGO_ENABLED=0Notes
Inbound H4 parsing issue (previous “unknown type: 54”) was fixed in another project, but this report is about outbound transport packet encoding, where the uint32 header appears to be written incorrectly on arm64.
Related reference
This issue was first investigated in sing-box-extended, then confirmed to persist with amneziawg-go
v0.2.14-beta-awg-1.5-1, so it likely belongs here.Also providing WireShark screenshot
Hypothesis / where to look
The corruption pattern is stable: byte0 and byte3 match expected, while byte1–byte2 are wrong:
Expected:
36 0C 4A 0BActual:
36 38 49 0BThis looks like one of the following in the outbound transport path:
Unsafe/unaligned uint32 write on arm64
*(*uint32)(unsafe.Pointer(&buf[i])) = h4[]byteto[]uint32/ struct overlay without alignment guaranteesPartial overwrite / stale bytes due to buffer reuse
Endian/offset bug limited to transport packets
Suggested mitigation: avoid unsafe/unaligned writes and always write H4 with:
binary.LittleEndian.PutUint32(buf[offset:], h4)and ensure
buf[offset:]has length ≥ 4 andoffsetmatches the real payload start.@FrankBacon24 commented on GitHub (Jan 27, 2026):
I've may mistaken with the version whicn contains this issue. Probably this issue happens not in the beta version. I've cathed it in the base contained in singbox-extended. I'm sorry for the mistarget
@websharik commented on GitHub (Mar 12, 2026):
Same issue in amd64 container. Handshake ok, but transfering data error.
@remotetohome commented on GitHub (May 7, 2026):
Possibly related: amnezia-client#2582.
AmneziaVPN-Android (4.8.15.5 / awg-go v0.2.16, arm64) silently fails transport when the server uses non-zero S3/S4 - handshake completes, data plane stays broken. The on-the-wire mechanism: with non-zero S4, the H4 field's byte offset in transport packets shifts by S4 bytes, which would expose any alignment/offset bug in the H4 writer; setting S3=S4=0 hides the bug because no offset shift occurs.
Hypothesis only as I don't have a direct repro of the byte-1/byte-2 corruption you describe in this issue from my Android client's outbound packets. But the symptom shape matches (handshake OK, transport broken, server-side asymmetric counters), and your hypothesis-section comments about unsafe/unaligned uint32 writes on arm64 line up with what would happen if the H4 writer's destination offset is wrong by exactly S4 bytes. Cross-posting in case it helps narrow the root cause.