runtime.GOOS=="android" (not "linux"), so StdNetBind enabled UDP_GRO and read
rxOffload=true, but the GRO receive dispatcher in bind_std.go is gated on
GOOS=="linux" → dead on android. A coalesced GRO super-packet was read as one
datagram, corrupting the WG transport stream → download died on no-detour
WG-endpoint (detour path uses ClientBind, no offload, so it worked).
Gate both the UDP_GRO setsockopt (controlfns_linux.go) and the rxOffload
readback (features_linux.go) behind !android. TX/GSO untouched, so non-android
linux performance is unchanged. Confirmed on device (CPH2411/Android-15:
probe gave rxOffload=true + dispatch=single).
See SPECS/010-B-O-WG_ENDPOINT_GRO_SPLIT_BRAIN.
Explain why this fork exists (sing-box needs sagernet APIs, AmneziaWG obfuscation
lives in amneziawg-go, neither alone works), how the merge is done
(3-way merge + MessageEncapsulatingTransportSize=0, obfuscation isolated to
device/), how sing-box-lx consumes it (submodule + replace), and the recipe to
rebase onto a new sagernet tag.
3-way merge of amnezia-vpn/amneziawg-go (AWG2, I1-I5 CPS + S4 keepalive) into
sagernet/wireguard-go@506b763185 (the base sing-box uses). Keeps sagernet's
sing-box-compat additions (Send offset contract, InputPacket, conn reserved/
control) and neutralizes the encapsulating headroom (MessageEncapsulatingTransportSize=0)
so obfuscation composes cleanly. Obfuscation lives in device/ (obf*.go, magic-header.go
new files + send/receive/device/uapi grafts); conn/tun/ipc kept pure sagernet.
LIVE-VALIDATED: handshake + keepalive + traffic against a real AmneziaWG 2.0 server.
Keepalive packets were excluded from S4 padding because the padding
logic was nested inside the dataSent guard. The receiving side
(DeterminePacketTypeAndPadding) expects S4 padding on all transport
packets, so unpadded keepalives fail H4 header validation and are
silently dropped.
This prevents the responder from completing key confirmation —
lastHandshakeNano stays 0 until real data flows through the tunnel.
* feat: added outline integration layer
* chore: make the function used in RegisterFallbackParser a standalone one
* fix: check if domain has a dot prior trimming it
* fix: use net.JoinHostPort instead of plain concat
(cherry picked from commit 7c2acadba17cadf8a1df957c49e1333130d460ad)
(cherry picked from commit a7bac1754e7717e1d4009d1ffd2d13330067d631)
(cherry picked from commit 7a2f11c693b49e784318bbf987173095c67b563d)
Peer.SetEndpointFromPacket is not called per-packet. It is
guaranteed to be called at least once per packet batch.
Updates tailscale/corp#30042
Updates tailscale/corp#20732
Signed-off-by: Jordan Whited <jordan@tailscale.com>
To be implemented by [magicsock.lazyEndpoint], which is responsible for
triggering JIT peer configuration.
Updates tailscale/corp#20732
Updates tailscale/corp#30042
Signed-off-by: Jordan Whited <jordan@tailscale.com>
It was previously suppressed if roaming was disabled for the peer.
Tailscale always disables roaming as we explicitly configure
conn.Endpoint's for all peers.
This commit also modifies PeerAwareEndpoint usage such that wireguard-go
never uses/sets it as a Peer Endpoint value. In theory we (Tailscale)
always disable roaming, so we should always return early from
SetEndpointFromPacket(), but this acts as an extra footgun guard and
improves clarity around intended usage.
Updates tailscale/corp#27502
Updates tailscale/corp#29422
Updates tailscale/corp#30042
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Kernels below 5.12 are missing this:
commit 98184612aca0a9ee42b8eb0262a49900ee9eef0d
Author: Norman Maurer <norman_maurer@apple.com>
Date: Thu Apr 1 08:59:17 2021
net: udp: Add support for getsockopt(..., ..., UDP_GRO, ..., ...);
Support for UDP_GRO was added in the past but the implementation for
getsockopt was missed which did lead to an error when we tried to
retrieve the setting for UDP_GRO. This patch adds the missing switch
case for UDP_GRO
Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.")
Signed-off-by: Norman Maurer <norman_maurer@apple.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
That means we can't set the option and then read it back later. Given
how buggy UDP_GRO is in general on odd kernels, just disable it on older
kernels all together.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
It should be POLLIN because closeFd is read-only file.
Signed-off-by: Kurnia D Win <kurnia.d.win@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Colin's commit went a step further and protected tun.incomingPacket with
a lock on shutdown, but let's see if the tun.stack.Close() call actually
solves that on its own.
Suggested-by: kshangx <hikeshang@hotmail.com>
Suggested-by: Colin Adler <colin1adler@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Since 3c75945fd ("netstack: remove PacketBuffer.IsNil()") this has been
invalid. Follow the replacement pattern of that commit.
The old definition inlined to the same code anyway:
func (pk *PacketBuffer) IsNil() bool {
return pk == nil
}
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>