Moving to v2 because v1 references repositories that have been
deleted from GitHub, breaking GOPROXY=direct.
The lint config (.golangci.yml) was already in v2 format; this updates
the tool dependency used by 'make lint' to golangci-lint/v2 v2.13.2,
drops the now-obsolete blank import in internal/tooldeps in favor of a
Go 'tool' directive, and bumps the CI workflow binary to match.
Updates #cleanup
Signed-off-by: James Tucker <jftucker@gmail.com>
Adds tsweb/compserve: content negotiation for precompressed static
variants, with a transcode-to-identity fallback for clients that do not
accept an encoding (including when the raw file is absent), and
CompressWriter, which live-compresses dynamic responses with zstd in its
fastest mode, streamed incrementally with no buffering. Negotiation is
q-value and wildcard aware (gzip;q=0 previously matched gzip).
client/web serves its prebuilt embedded assets through compserve,
replacing brotli with zstd; the embedded FS is wrapped in
tsweb/vcstime for conditional-request mod times. tsweb/compserve/gzip.go
keeps transitional serving of gzip variants from pre-zstd file systems
(such as the currently published web-client-prebuilt module):
passthrough to gzip-accepting clients, transcoded to identity otherwise;
it becomes inert once a zstd-only module is published.
util/zstdframe gains pooled GetDecoder and GetStreamingEncoder
(concurrency=1). util/precompress is now a build-time tool, generating
zstd variants only. cmd/tsconnect and cmd/build-webclient consume the
new precompress/compserve split. tsweb.AcceptsEncoding and
tsweb/tswebutil are removed; negotiation lives in compserve and the
deprecated shim had no callers. go.mod bumps web-client-prebuilt.
Also fixes a transcoding bug where http.ServeContent's size probe via
the promoted zstd.Decoder.WriteTo could report a zero length, serving
empty bodies.
Updates tailscale/corp#20099
Signed-off-by: James Tucker <james@tailscale.com>
This is the output of the new misc/bumpdeps tool (#21325) run with
--exclude-newer-than-days=7, which asks proxy.golang.org for the newest
version of every direct dependency, ignoring releases younger than a
week in favor of the newest older one, and runs a single go get.
gvisor tracks its "go" branch, wireguard-go its "tailscale" branch,
and golang-x-crypto its "main" branch (the proxy's @latest for it is
a stray v0.91.0 tag from 2024 that predates our acme fork changes).
Indirect deps only moved as far as MVS pulled them.
The week-long cooldown held back gvisor, the gokrazy modules,
chromedp/cdproto, and hashicorp/raft-boltdb/v2, whose only newer
versions are days old; they'll come along next time.
Several upstream changes needed small fixes: nfpm's PrepareForPackager
takes a modification time now (a zero time keeps the old behavior of
using the source file's mtime), esbuild's ServeOptions.Port became an
int while ServeResult.Host became a Hosts slice, client-go's
EventRecorder.Eventf is now recognized by vet as a printf wrapper (so
the k8s-operator calls that passed a preformatted message switch to
Event), google/nftables v0.3.0 reads back the kernel's
NF_NAT_RANGE_PROTO_SPECIFIED flag into a new expr.NAT.Specified field
(so the port map DNAT rule now sets it too or findRule never matches
the rule it just added), and staticcheck v0.8.1 knows encoding/json/v2's
embed tag option, so the two SA5008 suppressions for it are gone.
Two tests assumed old library behavior. client-go's fake clientset now
replays existing objects when a watch starts, as a real apiserver does,
so the k8s-proxy config test must tolerate the loader ignoring that
no-op event before the real reload arrives. fyne.io/systray moved its
dbusmenu object path and answers the first GetLayout with depth 1, so
the systray test now finds the menu via the item's Menu property and
polls until the submenu entries appear.
Then make tidy, make updatedeps, and make kube-generate-all (the
controller-gen bump to v0.22.0 changes doc strings, stops listing
top-level metadata as required, and crd-ref-docs now marks optional
fields).
Updates #8043
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I3f9a2c6e8b1d4705a9e2c7b8d1f4e6a0c2b5d8e3
Update gVisor to include its fix for RACK loss detection with coarse
monotonic clocks. Configure netstack with the 500 microsecond clock
resolution used on Windows so RACK accounts for timestamp quantization.
Remove the TCP recovery override that disabled RACK, enabling gVisor's
default RACK behavior on all platforms.
Switch netstack to cubic congestion control. The int overflow in CUBIC
sender cwnd arithmetic that required pinning reno has since been reworked
upstream into float arithmetic with RFC 9438 target clamping.
Align the natlab vnet stack with netstack: enable cubic, and drop the
now-redundant explicit SACK and receive-buffer moderation sets, both of
which are gVisor defaults.
Fixes#9707
Signed-off-by: James Tucker <jftucker@gmail.com>
This commit bumps the wireguard-go dependency to incorporate changes to
the packet memory model and the tun.Device.Read and conn.ReceiveFunc I/O
interfaces. It updates their implementations accordingly.
These changes improve throughput in all measured benchmarks and reduce
peak RSS in six of eight cases. The two regressions will be addressed in
a follow-up commit that reduces peak RSS below the baseline measured at
1e69418. That work is kept separate to simplify review.
The following throughput and peak RSS benchmarks were performed with
iperf3 between two Intel i5-12400 nodes running Ubuntu 24.04 (Linux 6.8).
The UDP benchmarks did not use UDP GSO on the sender, so they were
roughly equivalent to single packet I/O through wireguard-go.
TCP/1 signifies one TCP stream; TCP/128 signifies 128 parallel TCP
streams.
Throughput (Mb/s)
Test 1e69418 After Change
TCP/1 10,371 11,354 +9.5%
TCP/128 7,886 8,404 +6.6%
UDP/1 2,111 2,853 +35.1%
UDP/128 1,747 2,235 +28.0%
Peak memory (VmHWM, kB)
Test Side 1e69418 After Change
TCP/1 TX 98,240 52,596 -46.5%
RX 287,748 73,384 -74.5%
TCP/128 TX 101,196 52,812 -47.8%
RX 290,420 63,620 -78.1%
UDP/1 TX 58,864 160,840 +173.2%
RX 137,516 49,900 -63.7%
UDP/128 TX 66,148 116,096 +75.5%
RX 154,384 56,556 -63.4%
Updates tailscale/corp#46716
Updates tailscale/corp#22467
Updates tailscale/corp#36989
Updates tailscale/corp#37878
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Replace the allowed-IP-only peer callback result with wgcfg.PeerConfig.
It carries allowed IPs and an optional pre-shared key through lazy peer
creation and active peer synchronization.
Update wireguard-go for the new peer PSK APIs.
Updates tailscale/tailcat#84
Change-Id: Iacd9d2c74b0b64d690f3cbdf93918686ac6076d7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
From Go 1.27.0 to Go 1.27.0 + latest upstream release branches,
plus a cherry-pick of an x/net http2 hpack memory optimization
that didn't make Go 1.27 (https://go.dev/cl/807260)
Updates #29053
Change-Id: I5c694d8c4aebf4854773ea2856177aaebb2c39a4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Promote the toolchain from Go 1.26.6 to Go 1.27.0, matching what
go.toolchain.next.rev has been testing. Besides the toolchain files
themselves (updated by pull-toolchain.sh), this bumps the go.mod go
directive, the Dockerfile golang base image, and the README, and
regenerates the depaware.txt files and the gzip assets in
tempfork/spf13/cobra and util/eventbus, whose bytes change with
Go 1.27's rewritten compress/flate.
Also bump golangci-lint to v2.13.1, the first release line built
with Go 1.27; the prebuilt v2.10.1 binary refuses to target a Go
version newer than the one it was built with.
Also bump golang.org/x/net to v0.58.0 (plus the sibling x/ module
upgrades it requires) to pick up upstream commit 8d10596d2624
(http2: avoid deadlocks in wrapped ClientConn state callback),
which we hit during Go 1.27 rc testing.
Also add docs/go-bump-checklist.md for next time.
Updates #20220
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: Ia3e4c9effafbc91227eed39efb52f1fba1b8d89c
(bumping in oss mostly to get it into corp, and we require them to be in sync
for now. But we do use this in derpserver too.)
Updates tailscale/corp#46884
Change-Id: If01e3e91787e9ec4331eb9c997292239c6b379f1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There's a deadlock in x/net/http2 with Go 1.27 that's
fixed with v0.58. This is prep for switching to Go 1.27.
Updates #20220
Change-Id: I8e81eafc0c2f78e1760b36e9d39ac4f6046565af
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Pulls in https://github.com/tailscale/wireguard-go/pull/85 which
fixes an unbounded memory leak in mkIPInCIDRsTestFunc. It used a
package-level placeholder Peer, and AllowedIPs.Insert threads every
trie node onto that peer's trieEntries list, so each call leaked
its whole trie. SetAllowedIPs calls it on every netmap update, so
peer churn accumulated trie nodes until the client OOMed.
Fixestailscale/corp#47010
Signed-off-by: Adriano Sela Aviles <adriano@tailscale.com>
Bump five dependencies to resolve the following advisories;
GO-2026-6238, GO-2026-5764, GO-2026-5597, GO-2026-5490, GO-2026-5496,
GO-2026-5105.
Updates tailscale/corp#9497
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Move away from mutating global, exported variables in wireguard-go. Use
device.Option's passed to device.NewDevice, instead. No functional
changes, just API cleanup in preparation of future changes.
Updates tailscale/corp#22467
Updates tailscale/corp#46396
Updates tailscale/corp#37878
Signed-off-by: Jordan Whited <jordan@tailscale.com>
We'll need this in corp at least, which means we need this here.
Updates #20220
Change-Id: I5dbf93f2b9ce05658193fc8ba61eb61185637521
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Commit 33042fb97 (go.mod: bump sigs.k8s.io/controller-runtime to
v0.23.3) was based on a stale tree and accidentally reverted the
staticcheck bump from 7eeb62415 back to v0.7.0. That version's IR
builder panics on the Go 1.27 standard library (unexpected expr:
*ast.KeyValueExpr), breaking staticcheck CI on the Go 1.27 test
branch. Everything else in that commit was intentional k8s ecosystem
upgrades; staticcheck was the only collateral revert.
Updates #20220
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I763a3dcc29e592adcf6979c80d6e720b02c0bb09
Go 1.27's go mod tidy merges and reorganizes the require blocks once
the go directive in go.mod is 1.27 or newer. Land that mechanical
reorganization now (generated with a temporary 1.27 directive, with
the directive then restored) so the eventual toolchain switch doesn't
carry a 300+ line go.mod diff. Both Go 1.26's and Go 1.27's go mod
tidy leave the reorganized file unchanged, and go.sum and the selected
module versions are identical, so this is purely cosmetic.
Updates #20220
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: If7af51ca71ec30026034cf736f992e731c0e0531
PR #20388 (commit ca9f6971e) bumped k8s.io/* from v0.34 to v0.35 as a
transitive effect of pulling in helm v3.21 (for containerd CVE fixes).
The old controller-runtime v0.19.4 is aligned with k8s 1.31 APIs and
regresses at runtime against v0.35 client-go (informer reflectors stall
on Watch responses), leaving the operator unable to reconcile.
v0.23.3 is the release aligned with k8s.io/* v0.35 / Kubernetes 1.35.
The operator uses a narrow slice of controller-runtime (manager +
builder + client + reconcile + handler + source), so this bump is a
lift-and-shift: no reconciler wiring changes needed.
Test scaffolding fix: controller-runtime v0.20+ populates TypeMeta
(Kind/APIVersion) on objects returned by the fake client. The shared
expectEqual helper now strips TypeMeta before diffing so existing
tests continue to work without needing every 'want' object updated.
Tested: deployed to live clusters across Kubernetes 1.33, 1.34, 1.35,
and 1.36 (identical build per cluster). Verified the operator starts and
reconciles cleanly on all versions with no RBAC/forbidden errors, CRDs
establish and enforce validation, and the field indexers resolve
correctly under annotation churn (no stale-index misrouting). Exercised
the Service, ProxyClass, Connector, egress (simple + ProxyGroup, incl.
the EndpointSlice reconciler), and HA ingress-for-pg reconcilers.
Confirmed informer/watch recovery after an API server restart forces a
re-list/re-watch (the exact regression this bump fixes).
Updates tailscale/corp#44898
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Go 1.27 requires this new v0.8.0-rc.1.
But staticcheck 0.8's SA4023 gets stricter and points out that
modifiedExternallyError and handleListenersAccept always return
non-nil errors, and that MonitorHealth's callers don't need a separate
nil check before errors.Is. Simplify all three call sites; no behavior
change.
But then a handful of other places that SA4023 is angry about are
wrong (because it's not considering build tags) and can't be addressed
by ignore directives (again not considering build tags), so we just
disable SA4023 for now.
Updates #20220
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I2fefe3b986b5798c2e01624a0e9820839d21a569
Files whose names contain characters with Unicode decompositions (such
as umlauts or voiced kana) could not be opened or written over
Taildrive.
Background: keyboards and IMEs emit NFC (precomposed) characters on
every platform, so filenames on Linux (ext4 etc) and Windows (NTFS)
disks are usually NFC bytes. NFD (decomposed) names mostly come from
Apple software: HFS+ forced a variant of NFD on write, and Apple's
frameworks still decompose paths via fileSystemRepresentation. APFS
preserves whatever bytes it is given but does normalization-insensitive
lookups (it stores a hash of the normalized name), so canonically
equivalent names find the same file. ext4 and NTFS lookups, by
contrast, are byte-exact.
On the wire, the macOS WebDAV client sends paths in NFD form (they
pass through the decomposing file system representation, and unlike
Apple's NFS client there is no "nfc" mount option). Windows and Linux
WebDAV clients pass names through as the application provided them,
typically NFC. WebDAV itself mandates no normalization, and PROPFIND
hrefs reflect the server's on-disk bytes.
The two forms are canonically equivalent but byte-wise different, so a
macOS client requesting the NFD form of an NFC-named file on a Linux
or Windows host got a 404 from the exact-byte lookup. Even against an
APFS host, where the filesystem absorbs the mismatch, the client-side
StatCache could still infer a 404: a cached directory listing in one
form caused depth 0 PROPFINDs in the other form to be treated as not
found without ever reaching the server. The inverse direction (NFD
bytes on a Linux disk, copied there from a Mac, requested in NFC form
by a Windows or Linux client) was broken too.
Alternative regimes considered: normalizing names at storage time (as
Nextcloud and Syncthing's autoNormalize do) would rename user files in
shared directories as a side effect of serving them; normalizing
request paths to a fixed form on the wire is unsound because the
on-disk form is unknowable a priori (ext4 can hold either form, or
both). Instead, adopt the APFS model: preserve bytes, but make lookups
normalization-insensitive.
Concretely, wrap the remote file server's webdav.Dir in a
normalizingFS that, when an exact path lookup fails, rescans the
parent directory for an entry whose name is canonically equivalent,
comparing the NFC form of both sides (which also sidesteps Apple's
nonstandard decomposition tables). Exact matches always win, and newly
created files keep the exact bytes the client sent. Also NFC-normalize
StatCache keys so canonically equivalent names share a cache entry.
The change is covered at three levels: unit tests for the StatCache,
an in-process two-node test in drive/driveimpl, and a new TestTaildrive
VM integration test in tstest/natlab/vmtest that shares a directory
between two Ubuntu VMs and exercises the NFC/NFD cases over the real
stack with curl playing the part of a macOS WebDAV client.
Fixes#15020
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I9c2f157e604efc629828581e08d5b3191dbb7d4e
Revert the direct fork dependency and its regenerated depaware/flake
manifests; not ready to ship yet.
This reverts commit 745bb8507.
Updates #1866
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Depend on the tailscale/breakglass fork directly for its new
access-control flags. The fork renamed its module path so no replace
directive (disallowed here) is needed. Upstream gokrazy/breakglass
stays for the arm64 appliances.
Regenerate depaware manifests and nix flake hashes for the pkg/sftp
bump pulled in by the fork.
Updates #1866
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This bumps go.mod to the current tailscale/golang-x-crypto, picking up
its rebase onto current upstream golang.org/x/crypto and its
cherry-pick of the pending upstream change
https://go-review.googlesource.com/c/crypto/+/788000, which adds ACME
certificate profile support: a new WithOrderProfile order option and
profile discovery via the directory metadata. That change has not yet
been submitted upstream and is subject to final API changes before it
lands there.
It then re-vendors that fork's acme package into tempfork/acme as
usual (per the TestSyncedToUpstream workflow), except for upstream's
pebble_test.go, which is now excluded from the sync: its
TestWithPebble downloads the Pebble module from outside our go.mod,
then builds and runs its binaries during tests.
Profile support is needed to request LetsEncrypt IP address
certificates, which require the "shortlived" profile.
Updates tailscale/corp#45167
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I3f7c2a91e5d8b4a6c0e2f9d1b7a3c8e6f4d0a2b9
The tailscale/gokrazy-kernel module was a fork of rtr7/kernel that
stalled at Linux 6.8.9 (July 2024). All of the kernel config options we
had added in that fork (ENA, Xen for EC2, virtio-mmio for qemu microvm,
virtio RNG, IPv6 policy routing, netlink diag, etc) are now present in
the gokrazy project's own gokrazy/kernel.amd64 module, which tracks
current kernel.org releases (Linux 7.1.3 as of this change) and is the
gokrazy project's supported kernel for x86_64 PCs and VMs.
Switch the tsapp and natlabapp images, the natlab VM tests, and the
CI workflow to gokrazy/kernel.amd64, drop the tailscale/gokrazy-kernel
dependency, and update gokrazy/kernel.arm64 to latest while here.
Verified with TestEasyEasy, TestJustIPv6, and TestTailscaleSSH in
tstest/natlab/vmtest with --run-vm-tests.
Updates #1866
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I90c3765a4e18f5609b4d77b51ac38d17c8e3688a
Generated by make updatedeps and ./tool/go run ./tool/updateflakes
after adding service/ec2 (and the smithy-go bump it pulls in).
Updates #1866
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This reverts commit 468a7f4973 on request to @ChaosInTheCRD
Although passing all our CI checks, @ChaosInTheCRD would like to plan manual testing as part of incorporating these updates.
Updates #cleanup
Change-Id: I3f007b571b884c9538a97ac5d3ded782bcba2347
Signed-off-by: Mike Jensen <mikej@tailscale.com>
This reverts commit ca9f6971e5.
The dependency updates broke the K8s E2E tests. Reverting so the
updates can be re-landed with the tests passing.
flake.nix, shell.nix, and flakehashes.json were regenerated with
tool/updateflakes rather than reverted, since a later commit
(6fdffd9e5) also updated them for the gowebdav bump.
Change-Id: Id4afd7788d305a674841168e2a66a0009212ffd3
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>