wireguard #
A copy of the tun, conn and rwcancel packages of
wireguard-go, with the changes from
tailscale's fork that ranet3's tun
uses, as the module ranet3.com/pkgs/wireguard.
The code keeps upstream's style and license (MIT, in LICENSE), so a change
made here can be offered upstream as it is.
Provenance #
The copy is built in a clone of upstream in four steps:
- Upstream's tip
2631ce99a06f27120d581611cf125d68bc6aa565(2026-10-06, Jason A. Donenfeld, "device: noise: reject response consumption after intermediate initiation"). - The 15 commits of tailscale's
tailscalebranch below, cherry-picked in their order withgit cherry-pick -x, authorship kept. Their imports ofgithub.com/tailscale/wireguard-go/...are rewritten togolang.zx2c4.com/wireguard/...in the pick. tailscale never merges or rebases upstream: its branch leaves upstream at469159ecf7d1(2023-07-04) and takes upstream's later commits one by one, so the picks land on code that both sides changed since. - One commit renaming the module to
ranet3.com/pkgs/wireguard: themoduleline ofgo.modand every import of the module's own packages, nothing else. - The trim: the files of
tun,connandrwcancelthat some build of linux, darwin, freebsd or openbsd on amd64 or arm64 compiles, their tests,tun/generate_amd64.go(the source oftun/checksum_generated_amd64.s),LICENSE, andgo.modandgo.sumtidied to what is left. The trim dropsx/cryptoandwintunfromgo.mod.gvisorstays, for tests oftun.
The first commit of this directory is the result of these steps. The changes
made here since are the later commits that git log shows for this directory.
The tailscale commits #
| tailscale commit | Subject | Author | Where the pick conflicted |
|---|---|---|---|
ec6f23b33e03 |
tun: checksum tests and benchmarks | Adrian Dewhurst | tun/checksum_test.go, against upstream's reference tests from b82c016. Both sets are kept, and tailscale's table test TestChecksum is renamed TestChecksumVectors, since upstream has a TestChecksum of its own. |
88b11b4a0dde |
tun: AMD64 optimized checksum | Adrian Dewhurst | tun/checksum.go takes tailscale's rewrite whole, which replaces upstream's add-with-carry checksumNoFold from b82c016. Upstream renamed tun/tcp_offload_linux.go to tun/offload_linux.go in d0bc03c, so the pick's edits to the old file are made in the new one: pseudoHeaderChecksum with a folded uint16 in checksumValid, both coalesce accountings, gsoSplit and gsoNoneChecksum. Upstream's TestPseudoHeaderChecksum calls pseudoHeaderChecksum. |
03c5a0ccf754 |
tun: implement API for disabling UDP GRO on Linux | Jordan Whited | Clean. ranet3 does not call it, but 799c197, 07ca723 and cbffc0a build on its groDisablementFlags. |
60eeedfd624b |
tun: export GSOSplit() for external Device implementers | Jordan Whited | Clean, imports rewritten in tun/offload_test.go. |
6c039a188c2d |
tun: export optimized IP checksum funcs | Jordan Whited | Clean. Upstream's reference tests call the exported Checksum and PseudoHeaderChecksum, since the unexported names no longer exist off amd64. |
71393c576b98 |
tun: fix checksum test failures on non-4KiB page sizes | Adrian Dewhurst | Clean. |
799c1978fafc |
tun: add method for disabling TCP GRO on Linux | Jordan Whited | Clean. Upstream's test from ecfc5a8 passed false for canUDPGRO to handleGRO and now passes udpGRODisabled, which means the same. |
4e883d38c8d3 |
tun: use x/sys/unix IoctlIfreq/NewIfreq to set MTU on Linux | Brad Fitzpatrick | Clean. |
65cd6eed7d7f |
conn,device: provide 8 free bytes at packet head to conn.Bind.Send() | Jordan Whited | Clean. |
cd4feb8708a9 |
conn: coalesce via scatter-gather writes | Alex Valiushko | putMessages in conn/bind_std.go: upstream's OOB[:0] reset is kept beside tailscale's Buffers[:1]. The retry without GSO in Send first trims each message back to Buffers[:1], as tailscale does only in its later f4ef62e. Without it the retry sends the datagrams coalesced into a message again behind its first one. The pick's message carries a note saying so, and the pick adds TestStdNetBindSendRetryWithoutGSO to conn/sticky_linux_test.go, a root test that draws the kernel's EIO with an xfrm policy on loopback and fails without the trim. |
07ca723923d8 |
tun: coalesce via scatter-gather writes (#52) | Alex Valiushko | Test_handleGRO_invalidItemCsumClearsVirtioNetHdr, upstream's test from ecfc5a8 against tailscale's rewrite of it: tailscale's body, calling handleGRO with udpGRODisabled. |
24b5b6917431 |
conn,device,tun: use single ~128KiB packet buf for batched i/o | Jordan Whited | tun/tun_plan9.go is dropped, since upstream has no plan9 port. conn/bind_std.go takes tailscale's putMessages(msgs, used) with upstream's OOB[:0] reset, and tailscale's slab path in receiveIP with upstream's linux || android checks from 24ea133. The device, tun/netstack and windows changes are resolved in the full stack and are not part of this copy. |
7658b3f64aff |
tun: remove extra read buf/mutex on Linux | Jordan Whited | Clean. |
cbffc0a83ffa |
device,tun: shard the tun side of the dataplane across queues (#96) | Alex Valiushko | The tun files merge without a conflict. The device half is ported by hand onto upstream's device and is not part of this copy. |
e61b6b78110b |
device: serialize nonce stamping with the outbound enqueue (#103) | Alex Valiushko | device only, not part of this copy: the hunk in tailscale's SendPriorityMessage and its registry change are dropped, and the lock goes into upstream's SendStagedPackets. |
What was left out #
The commits of tailscale's branch since the merge base that touch tun, conn
or rwcancel and are not picked:
- In upstream already, patch for patch:
915962d(tun: unwind summing loop in checksumNoFold()),ceb9a09(tun: reduce redundant checksumming in tcpGRO()),2f6748d(tun: fix crash when ForceMTU is called after close). - In upstream already, as upstream's own version of the same change:
e06231b(conn, device: use UDP GSO and GRO on Linux) as upstream's6a84778,24f8d7canddb7604d(tun: implement UDP GSO/GRO for Linux, tun: don't assume UDP GRO is supported) as upstream'sd0bc03c,e26adb8(go.mod,tun/netstack: bump gvisor) as upstream's42ec952, and92a4d28(tun: clear virtioNetHdr when deleting item from tcpGROTable) as upstream'secfc5a8. - tailscale's module path:
bd7e9d3(all: rename module), replaced here by the rename toranet3.com/pkgs/wireguard. - Platforms ranet3 does not build for:
6cd5922(all: adjust build tags for plan9),202a340(adjust build tags for tamago),91a0587(tun: add plan9 support). - tailscale's peer-aware endpoints, which ranet3 does not use:
2f5d148(conn,device: enable cryptorouting via PeerAwareEndpoint),24483d7(conn,device: always perform PeerAwareEndpoint check),1f398ae(conn,device: implement InitiationAwareEndpoint),1d0488a(conn,device: eval conn.PeerAwareEndpoint per-packet). f4ef62e(device,conn: shard the UDP side of the dataplane across queues), adevicechange ranet3 does not use. Its reset of a message's buffers before the retry without GSO is carried in the pick ofcd4feb8.
Syncing with upstream #
A later upstream applies as upstream's own diff, limited to the packages kept
here, onto this directory. Fetch upstream into this repository first so that
-3 finds the blobs the diff names, which lets the import rewrite merge with
upstream's changes:
git fetch https://git.zx2c4.com/wireguard-go master
git diff 2631ce99a06f27120d581611cf125d68bc6aa565 FETCH_HEAD -- tun conn rwcancel go.mod go.sum \
| git apply --directory=pkgs/wireguard -3
Then rewrite new imports of golang.zx2c4.com/wireguard/ to
ranet3.com/pkgs/wireguard/, remove any new file that the trim above would not
keep, tidy go.mod, regenerate gomod2nix.toml with nix fmt, and update the
hash in this file and the date in the version of default.nix.
go.mod requires each module that pkgs/ranet3/go.mod also requires, such as
golang.org/x/net and golang.org/x/sys, at the version ranet3 links into
these packages, so that the tests here build what ranet3 ships. checks/tree
fails when the two files require a module at different versions, and names both
versions. A sync keeps the higher of upstream's version and this one, and a bump
of such a module goes into both files in the same commit.
Offering a fix #
A fix made here is exported relative to this directory, with the imports rewritten back to the upstream module path:
git format-patch --relative=pkgs/wireguard <base>..<tip> -- pkgs/wireguard
sed -i 's|"ranet3.com/pkgs/wireguard/|"golang.zx2c4.com/wireguard/|g' 0*.patch
Code that the tailscale commits above brought in and upstream does not have
follows tailscale's tailscale branch rather than upstream: the scatter-gather
write path (07ca723), the exported GSOSplit with the checks it makes before
it splits a packet (60eeedf), and the reads into one slab (24b5b69). A fix
to that code goes to tailscale/wireguard-go, with the imports rewritten to
github.com/tailscale/wireguard-go/ instead.
The rename sorted the module's imports anew: they sort after gvisor.dev here
and before it upstream, and after golang.org here and before it in tailscale's
tree. A hunk whose context holds such an import block does not apply after the
rewrite, so it is made again by hand in a checkout of the target, and gofmt
runs on every file the fix touches there.