Add two tests building on TestExitNode's framework:
TestSubnetRouterPublicIP brings up a client, a subnet router, and a
webserver, each on its own NAT'd network with distinct WAN IPs. The
subnet router advertises the webserver's network as a route. The test
toggles the client's --accept-routes preference and asserts that the
webserver's echoed source IP switches between the client's own WAN
(direct dial) and the subnet router's WAN (forwarded through the
router and SNAT'd).
TestSubnetRouterAndExitNode adds a fourth node, an exit node that
advertises 0.0.0.0/0 + ::/0, and uses a table-driven layout with
subtests to cover the four combinations of (exit on/off, subnet
on/off). The case where both are on confirms longest-prefix match
wins: the subnet router's /24 takes precedence over the exit node's
/0. The exit node itself is configured with --accept-routes=off so
that, in the exit-only case, it forwards directly to the simulated
internet rather than re-routing the forwarded traffic via the subnet
router (which would otherwise mask the exit node's WAN as the
observed source).
Adds an Env.SetAcceptRoutes helper for toggling the RouteAll pref via
EditPrefs, used by both tests.
Updates #13038
Change-Id: Ifc2726db1df2f039c477c222484f535bebc40445
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add NIC attachment hot-swap support to Host.app: VZNetworkDevice.attachment
is writable at runtime, so --disconnected-nic creates a NIC with no
attachment, and --attach-network hot-swaps it to a vnet dgram socket
after boot/restore. macOS detects link-up and does DHCP.
Refactor TailMacConfigHelper: extract createDgramAttachment() and
createDisconnectedNetworkDeviceConfiguration() from the monolithic
createSocketNetworkDeviceConfiguration().
Add --screenshot-port flag for headless mode. Host.app serves GET
/screenshot as JPEG via a localhost HTTP server, capturing the
VZVirtualMachineView via CGWindowListCreateImage. The Go test harness
polls these to push live thumbnails to the web dashboard.
Also: SIGINT handler in headless mode for clean VM state save.
Updates #13038
Change-Id: I42fba0ecd760371b4ec5b26a0557e3dd0ba9ecae
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add a vmtest TestExitNode that brings up a client, two exit nodes, and a
non-Tailscale webserver, each on its own NAT'd vnet network with a
distinct WAN IP. The test cycles the client's exit node setting between
off, exit1, and exit2 and asserts that the webserver echoes the expected
post-NAT source IP for each.
Three pieces were needed to make this work:
vnet now forwards TCP between simulated networks at the packet level,
mirroring the existing UDP path. When a guest VM sends TCP to another
simulated network's WAN IP, the source network's gateway rewrites src
via doNATOut and routeTCPPacket hands the packet off to the destination
network, which rewrites dst via doNATIn and writes the rewritten frame
onto the destination LAN. The TCP stacks of the two guest VM kernels
talk end-to-end; vnet just NATs the IP/port headers in flight, so all
TCP semantics (handshakes, options, sequence numbers, payload) are
preserved without a gvisor TCP termination in the middle. Adds a
focused TestInterNetworkTCP that exercises this path without any
Tailscale machinery.
cmd/tta binds its outbound dial to the default route's interface using
SO_BINDTODEVICE. Without that, the moment tailscaled installs
0.0.0.0/0 → tailscale0 in response to setting an exit node, TTA's
existing TCP connection to test-driver gets rerouted through the exit
node. From the test driver's perspective the connection's packets then
arrive with the exit node's WAN IP as the source rather than the
client's, so they don't match the existing flow and the connection is
dead — manifesting in the test as a hang on EditPrefs (which had
actually completed in milliseconds on the daemon side, but whose
response never made it back). Pinning the socket to the underlying NIC
keeps TTA's agent connection on a real interface regardless of any
policy routing tailscaled installs later. We bind rather than carry the
Tailscale bypass fwmark because the fwmark approach is conditional on
tailscaled having configured SO_MARK-based policy routing, while
binding is unconditional.
vmtest grows an Env.SetExitNode helper that sets ExitNodeIP via
EditPrefs through the agent, used by the new test.
Updates #13038
Change-Id: I9fc8f91848b7aa2297ef3eaf71fed9d96056a024
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
While working on #19444, I assumed that omitting `Start` would return a
clock that started at January 1, year 1, because that's the zero value
for a `time.Time`, but actually it uses the current UTC time instead.
This behaviour is non-obvious, so document it.
Updates #cleanup
Change-Id: Id91400778578655953ff3e1671ce470db97cfe91
Signed-off-by: Alex Chan <alexc@tailscale.com>
Add a Go benchmark that exercises a single tailnet client (a [tsnet.Server]
running in the test process) against a synthetic large initial netmap and
a stream of caller-driven peer add/remove deltas, all in-process.
The harness is split in two parts:
- tstest/largetailnet, a reusable package containing a [Streamer]
that hijacks the map long-poll on a [testcontrol.Server] via the new
AltMapStream hook, sends one initial MapResponse with N synthetic
peers, and forwards caller-supplied delta MapResponses on the same
stream. Helpers like MakePeer / AllocPeer build synthetic peers with
unique IDs and addresses derived from the Tailscale ULA range.
- tstest/largetailnet/largetailnet_test.go, BenchmarkGiantTailnet
(headless tailscaled workload, no IPN bus subscriber) and
BenchmarkGiantTailnetBusWatcher (GUI-client workload with one
Notify subscriber attached). Both are gated on
--actually-test-giant-tailnet (skipped by default), stand up an
in-process testcontrol + tsnet.Server, let Up block until the
initial N-peer netmap has been processed, then ResetTimer and run
add+remove pairs via b.Loop. Per-delta sync is via a test-only
[ipnlocal.LocalBackend.AwaitNodeKeyForTest] channel that closes
once the just-added peer key appears in the netmap (no-watcher
variant) or via bus-Notify drain (bus-watcher variant).
To support the hijack, [testcontrol.Server] grows an AltMapStream hook
and a small MapStreamWriter interface for benchmarks/stress tests that
need to drive a controlled MapResponse sequence; the normal serveMap
path is untouched when AltMapStream is nil. The streamer answers
non-streaming "lite" map polls (which controlclient issues before the
streaming long-poll to push HostInfo) with an empty MapResponse and
returns immediately, so the streaming poll that follows is the one
that gets the initial netmap.
The benchmark is intended for before/after comparisons of netmap- and
delta-handling changes targeted at large tailnets. CPU profiles on
unmodified main show the expected O(N) hotspots:
setControlClientStatusLocked / authReconfigLocked /
userspaceEngine.Reconfig / setNetMapLocked, plus JSON encoding of the
full Notify.NetMap to bus watchers (which dominates the BusWatcher
variant).
Median ms/op over 10 runs on unmodified main, by tailnet size N:
N no-watcher bus-watcher
10000 32 166
50000 222 865
100000 504 1765
250000 1551 4696
Recommended invocation:
go test ./tstest/largetailnet/ -run=^$ \
-bench='BenchmarkGiantTailnet(BusWatcher)?$' \
-benchtime=2000x -timeout=10m \
--actually-test-giant-tailnet \
--giant-tailnet-n=250000 \
-cpuprofile=/tmp/giant.cpu.pprof
Updates #12542
Change-Id: I4f5b2bb271a36ba853d5a0ffe82054ef2b15c585
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On systems where this sysctl defaults to 0 (including GCP VMs), rp_filter performs its lookup with fwmark=0, hits rule 5270 then table 52 and routes to 0.0.0.0/0 dev tailscale0, and drops every reply packet arriving on the physical interface as a martian. This breaks all connectivity when using an exit node: DERP, DNS, control plane, and even the cloud metadata service.
Set src_valid_mark=1 when enabling the connmark rules so the rp_filter workaround actually works in these cases.
Updates #3310
Updates tailscale/corp#37846
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Add a tsdial.Dialer.UserDialPlan method that resolves an address and
reports whether the dialer would route it via Tailscale. The LocalAPI
/dial handler now uses this to skip proxying for addresses that aren't
Tailscale routes (e.g. localhost), returning a Dial-Self response with
the resolved address so the client can dial it directly. This avoids
an unnecessary round-trip through the daemon for local connections.
The client's UserDial handles the new response by dialing the resolved
address itself, and the server passes the pre-resolved IP:port for
Tailscale dials to avoid redundant DNS lookups.
Thanks to giacomo and Moyao for pointing this out!
Updates tailscale/corp#39702
Change-Id: I78d640f11ccd92f43ddd505cbb0db8fee19f43a6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Replace hardcoded resource names with dynamically generated names in
k8s-operator-e2e ingress tests to avoid collisions with stale resources.
Updates #tailscale/corp#40612
Signed-off-by: Becky Pauley <becky@tailscale.com>
Device posture checking can fail while enabled if tailscaled does not
have access to smbios. Previously, this was only observable by looking
in the tailscaled logs.
Fixestailscale/corp#39314
Signed-off-by: Evan Lowry <evan@tailscale.com>
TestPackageDocs walked into directories starting with "." (such as
.claude worktrees) and only logged warnings on duplicate package docs
across files in a directory. Skip dot-directories (which covers the
old .git but also .claude), ignore files with "//go:build ignore" so
command files don't falsely trip the duplicate check, and promote the
duplicate-doc warning to a t.Errorf.
While here, deduplicate the package docs that were previously only
logged: drop the redundant comment from client/systray/startup-creator.go,
move the comprehensive taildrop doc into feature/taildrop/doc.go, and
remove a leftover doc fragment from feature/condlite/expvar/omit.go.
The tstest/integration/vms allowlist is no longer needed since the
//go:build ignore filter now handles its dns_tester.go and udp_tester.go
files generically.
Fixes#19526
Change-Id: Id794d96bd728826a1883a054e4a244f90fa05d3d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously, handleLocalPackets intercepted traffic to the Tailscale
service IP (100.100.100.100 / fd7a:115c:a1e0::53) only for an allow-list
of ports: TCP 53/80/8080 and UDP 53. Any other port returned
filter.Accept, letting the packet fall through to the ACL filter and
wireguard-go, which would attempt a peer lookup. No peer owns the
quad-100 AllowedIP, so after ~5s pendopen.go would log:
open-conn-track: timeout opening ...; no associated peer node
This is the common "conntrack error no peer found for 100.100.100.100:853"
log spam seen in the wild (e.g. from systemd-resolved or another
resolver speculatively trying DoT on quad-100). It also leaks quad-100
packets onto the tailnet.
Remove the port allow-list so handleLocalPackets absorbs every quad-100
packet into netstack regardless of IP protocol or port. Traffic never
reaches the conntrack / peer-routing layers.
With the allow-list gone, acceptTCP needs a corresponding guard: on a
quad-100 TCP port we don't serve, execution used to fall through to the
isTailscaleIP case (quad-100 is in the tailscale IP range), which
rewrote the dial target to 127.0.0.1:<port> and forwardTCP'd the
connection to whatever happened to be listening on the host's loopback
at that port. Add a hittingServiceIP case that RSTs cleanly instead,
placed before the isTailscaleIP fallthrough.
TestQuad100UnservedTCPPortDoesNotForward is a new integration test that
injects a TCP SYN to 100.100.100.100:853 via handleLocalPackets, stubs
forwardDialFunc, and asserts the dialer is not invoked; it catches
regressions of the acceptTCP recursion/loopback-redirection case.
Fixes#15796Fixes#19421
Updates #3261
Updates #11305
Signed-off-by: James Tucker <james@tailscale.com>
CmdName was re-opening the running executable and scanning it in
64KiB chunks for the Go modinfo markers on every call. The same
modinfo is already parsed at startup and exposed via
runtime/debug.ReadBuildInfo, so prefer that on non-Windows. Windows
still takes the scanning path because its GUI-binary override keys
off the on-disk executable name.
benchstat of BenchmarkCmdName (Linux, before vs after):
goos: linux
goarch: amd64
pkg: tailscale.com/version
cpu: Intel(R) Xeon(R) 6975P-C
│ /tmp/old.txt │ /tmp/new.txt │
│ sec/op │ sec/op vs base │
CmdName-16 556045.5n ± 1% 825.6n ± 1% -99.85% (p=0.000 n=10)
│ /tmp/old.txt │ /tmp/new.txt │
│ B/op │ B/op vs base │
CmdName-16 64.587Ki ± 0% 1.156Ki ± 0% -98.21% (p=0.000 n=10)
│ /tmp/old.txt │ /tmp/new.txt │
│ allocs/op │ allocs/op vs base │
CmdName-16 8.000 ± 0% 7.000 ± 0% -12.50% (p=0.000 n=10)
Fixes#19486
Change-Id: I925c5e28b64815a602459beb6c8dab8779339a6c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This drops the per peer "appending remote" log while constructing the remote list, which can get noisy on big tailnets, and keeps logs around remote availability checks, including whether a peer is missing, offline, lacks PeerAPI reachability, lacks sharing permission, or is available.
Updates tailscale/corp#40580
Signed-off-by: kari-ts <kari@tailscale.com>
This drops an indirect dependency on the old github.com/docker/docker
(which was replaced with github.com/moby/moby) and fixes a couple recent
CVEs.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
When there is an active connection between devices, do not send new
disco keys via TSMP.
Updates #12639
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Adds a CI check to keep opted-in directories' README.md files in sync
with their package godoc. For now tsnet (and its sub-packages under
tsnet/example) is the only opted-in tree. The list of directories
lives in misc/genreadme/genreadme.go as defaultRoots, so CI and humans
both just run `./tool/go run ./misc/genreadme` with no arguments.
The check piggybacks on the existing go_generate job in test.yml and
fails if any README.md is out of date, pointing the user at the same
command.
Along the way:
- tempfork/pkgdoc now emits Markdown instead of plain text: headings
become level-2 with no {#hdr-...} anchors, and [Symbol] doc links
resolve to pkg.go.dev URLs, including for symbols in the current
package (which the default Printer would otherwise emit as bare
#Name fragments with no backing anchor in a README). Parsing no
longer uses parser.ImportsOnly, so doc.Package knows the package's
symbols and can resolve [Symbol] links at all.
- genreadme also emits a pkg.go.dev Go Reference badge at the top of
a library package's README; suppressed for package main.
- tsnet/tsnet.go's package godoc is expanded in idiomatic godoc
syntax — [Type], [Type.Method], reference-style [link]: URL
definitions — rather than Markdown-flavored [text](url) or
backtick-quoted identifiers, so that both pkg.go.dev and the
generated README.md render cleanly from a single source.
Fixes#19431Fixes#19483Fixes#19470
Change-Id: I8ca37e9e7b3bd446b8bfa7a91ac548f142688cb1
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Walter Poupore <walterp@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Replace Conn.peers (sorted views.Slice) with peersByID, a
map[tailcfg.NodeID]tailcfg.NodeView. The only caller that needed
the sorted slice (the disco message receive path's binary search)
becomes a single map lookup. Drop nodesEqual.
Add Conn.UpsertPeer / Conn.RemovePeer for O(1) single-peer endpoint
work. RemovePeer also performs a targeted single-disco-key cleanup
(previously that scan was O(discoInfo)).
Extract the shared per-peer upsert body as upsertPeerLocked; still
used by SetNetworkMap's bulk path. SetNetworkMap is documented as
the bulk / initial / self-change path; UpsertPeer and RemovePeer
are preferred for single-peer changes.
Make the relay server set update O(1) per peer: add serverUpsertCh
/ serverRemoveCh to relayManager with matching run-loop handlers.
UpsertPeer / RemovePeer evaluate the per-peer relay predicate
locally and dispatch upsert or remove. The full-rebuild
updateRelayServersSet stays for the initial netmap, filter
changes, and fallback.
Move the hasPeerRelayServers atomic from Conn onto relayManager,
next to the serversByNodeKey map it summarizes. The run loop is
now the single writer and needs no back-pointer to Conn;
endpoint's two hot-path readers take one extra hop to
de.c.relayManager.hasPeerRelayServers but the cost is the same
atomic load.
No callers use UpsertPeer/RemovePeer yet; a subsequent change will
plumb per-peer add/remove through the incremental map update path.
Updates #12542
Change-Id: If6a3442fe29ccbd77890ea61b754a4d1ad6ef225
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Verifies that site-to-site Tailscale subnet routing with
--snat-subnet-routes=false preserves the original source IP
end-to-end.
Topology: two sites, each with a Linux subnet router on a NATted WAN
plus an internal LAN, and a non-Tailscale backend on each LAN. Backends
are given static routes pointing to their local subnet router for the
remote site's prefix; an HTTP GET from backend-a to backend-b over
Tailscale returns a body containing backend-a's LAN IP.
Adds the supporting vmtest.SNATSubnetRoutes NodeOption and plumbs
snat-subnet-routes through TTA's /up handler. The webserver started by
vmtest.WebServer now also echoes the remote IP, for the preservation
assertion.
Adds a /add-route TTA endpoint (Linux-only for now) and a vmtest
Env.AddRoute helper so the test can install the backend static routes
through TTA rather than needing a host SSH key and debug NIC.
ensureGokrazy now always rebuilds the natlab qcow2 (once per test
process, via sync.Once) so the test picks up the new TTA and webserver
behavior.
This is pulled out of a larger pending change that adds FreeBSD
site-to-site subnet routing support; figured we should have at least
the Linux test covering what works today.
Updates #5573
Change-Id: I881c55b0f118ac9094546b5fbe68dddf179bb042
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Exposes a local port on the tailnet under a chosen hostname. Raw TCP by
default; --http or --https reverse-proxy with Tailscale-User-* identity
headers from WhoIs, matching tailscaled's serve header conventions.
Useful as a one-shot to put a dev server on the tailnet.
Fixes#19467
Change-Id: I79f63cfbbedf7e40cf0f1f51cbae8df86ae90cdf
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
Remove the remaining known sources of flakiness in TestStateMachine and
TestStateMachineSeamless.
Updates tailscale/corp#36230
Updates #19377
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
For use in parallelizing go:generate up-to-date checks.
Updates tailscale/corp#28679
Change-Id: Ifc31c56de4225ba2e0fc048b0f18974dc2f2fc82
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And use it to allow overwrites of old address assignments in the conn25 client.
The magic and transit address pools from which the addresses come are limited
resources and we want to reuse them. This commit is a small part of that bigger
need.
We expect to follow soon:
* Extending expiry if assignments are still in use.
* Returning expired addresses back to the pools so they can be reallocated.
Updates tailscale/corp#39975
Signed-off-by: Fran Bull <fran@tailscale.com>
addrAssignments is a table of addrs with lookup indices, representing
the assignments of magic+destination+transit IP addresses the client has
made dut to the domain being routed because of an app
.
byConnKey is a map of node public key to prefixes of transit IPs, so it
is associated with, but not that data itself, and can be its own thing.
Updates tailscale/corp#39975
Signed-off-by: Fran Bull <fran@tailscale.com>
also port pkgdoc, into the tempfork folder
git rev from corp at the time this copy was made:
- e909fc93595414c90ff1339cece7c84500ab3c36
Updates #19470
Change-Id: I3d98d82020a2b336647b795210dcb7065dfa44d7
Change-Id: Ie63141860b76dd2d5ae3ff52f8a4bcdf6106421e
Signed-off-by: Walter Poupore <walterp@tailscale.com>
When the repo is checked out as a nested worktree, a go.work in the
outer tree hijacks module resolution, which makes the rebuild fails
with "main module does not contain package." Set GOWORK=off for the
build since the hook is self-contained.
Bumps HOOK_VERSION so existing installs pick up the fix.
Updates #cleanup
Change-Id: Ibd14849efc26e4e1893c5b8e300caa71573f54bd
Signed-off-by: Fernando Serboncini <fserb@fserb.com.br>
TestEncodeAndUploadMessages waited on the default 2s FlushDelay,
making the logtail package the slowest non-integration test in
the tree (~2s real time). Switch the shared harness from an
httptest.Server-on-loopback to a memnet.Listener-backed *http.Server
and run the tests inside synctest.Test, so fake time advances the
flush timer instantly.
Drops the net/http/httptest dependency from these tests. Combined
with the TestMain non-localhost dial guard added in the previous
commit, no test in this package can accidentally reach the real
log.tailscale.com server. Whole package now runs in ~7ms.
Updates tailscale/corp#28679
Change-Id: Ie0e7a6a79641384ed0eecb99d767e17cda8bb944
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
NewLogger unconditionally writes a "logtail started" banner before
it returns, which callers that later call Logger.SetEnabled(false)
have no way to suppress: the banner is already buffered for upload
by the time the caller gets the logger back.
Add Config.Disabled so callers that know up front they want the
logger to start disabled (e.g. Android's remote-logging opt-out)
can seed the state before NewLogger's internal Write. The process-
wide Disable kill switch still takes precedence; SetEnabled can
still flip the state at runtime.
Updates #13174
Updates tailscale/tailscale-android#695
Change-Id: Icc4fa88c198447cf0faa707264dac84e359fe52c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Reverting back to the previous format (including
the "svc:" prefix in the map's keys).
Note that the /services endpoint in localapi, along
with any software that relies on this is unreleased
so this does not break any clients.
Updates tailscale/corp#40052
Signed-off-by: Adriano Sela Aviles <adriano@tailscale.com>
TestStateMachine & TestStateMachineSeamless both flake a lot asserting the
"Shutdown" call on cc after a Logout. This is because Shutdown is called on
a goroutine to avoid a deadlock if it's called while holding the
LocalBackend lock (#18052).
This fixes that cause of flakes by waiting for LocalBackend's goroutine
tracker to have no goroutines running (so the goroutine that calls Shutdown
must have finished).
This does not make TestStateMachine non-flaky because it can flake later in
the test, too: the assertion on "unpause" after clearing the netmap between
"Start4" and "Start4 -> netmap" sometimes fails.
Updates tailscale/corp#36230
Updates #19377
Updates #18052
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
Update this log message to show both the local and remote TKA HEAD; this
is useful for debugging issues on nodes that have fallen behind the
remote TKA HEAD.
Updates tailscale/corp#39455
Change-Id: Ia62ce15756180d2fbac4a898fb94d6143df08b54
Signed-off-by: Alex Chan <alexc@tailscale.com>
LocalBackend stores loginFlags at construction so that per-instance
properties (e.g. LoginEphemeral set by tsnet.Server.Ephemeral) persist
for the session. StartLoginInteractiveAs already merges b.loginFlags
into its cc.Login call, but the two auto-login call sites pass bare
controlclient.LoginDefault, silently dropping any stored flags.
Merge b.loginFlags at both auto-login call sites to match the existing
StartLoginInteractiveAs pattern. LoginDefault is zero so this is a
no-op when loginFlags is empty, and restores the documented behavior
when it isn't.
Fixes#15852
Signed-off-by: Scott Graham <scott.github@h4ck3r.net>
Updates the format of the service map that is served over
the local api to be keyed without the "svc:" prefix. This
change is backwards incompatible, this is OK because there
is only one tailnet with the services-in-nodecapmap feature
flag enabled, and the client side changes that start showing
services over local api have not been released. (These were
added in 4fcce6000d).
Updates tailscale/corp#40052
Signed-off-by: Adriano Sela Aviles <adriano@tailscale.com>
Pull the hook logic into a reusable githook library package so
tailscale/corp can share it via a thin wrapper main instead of
keeping a forked copy in sync.
The install flow also changes: a wrapper scripts now build the
binary and reinstall the git hooks. Pulling new shared code no
longer requires re-running the installer.
Updates tailscale/corp#39860
Change-Id: I4d606d11c8c883015c190c54e3387a7f9fe4dd32
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
Callers that need to turn logtail uploads on and off in response to
user preference or policy changes previously had no choice: the
package-level Disable is a one-way kill switch intended for the
controlplane DisableLogTail debug message, and requires a process
restart to undo.
Add a per-Logger disabled flag, toggled via SetEnabled, that drops
incoming entries without buffering while disabled. The process-wide
Disable still takes precedence, so a controlplane-issued kill switch
cannot be overridden by a client setting it back on.
To simplify https://github.com/tailscale/tailscale-android/pull/695
Updates #13174
Change-Id: I06e75bd719c851f5f837ca5b2d1e17f7c68355f0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Currently, clientupdate.NewUpdater().Update() is called directly inside tailscaled, which fatals. There is also a failure that doesn't return, causing a panic.
This fix allows us to use the same approach as startAutoUpdate, which is to find tailscale.exe and run tailscale.exe --update, though since it's calling the updater library directly, we get progress messages.
Fixes tailscale/corp#40430s
Signed-off-by: kari-ts <kari@tailscale.com>
This change adds setup for a second tailnet to enable multi-tailnet e2e
tests. When running against devcontrol, a second tailnet is created via the
API. Otherwise, credentials are read from SECOND_TS_API_CLIENT_SECRET.
Also adds an l7 HA Ingress test for multi-tailnet.
Fixestailscale/corp#37498
Signed-off-by: Becky Pauley <becky@tailscale.com>
The cloner's codegen for map[K][]*V fields was doing a shallow
append (copying pointer values) instead of cloning each element.
This meant that cloned structs aliased the original's pointed-to
values through the map's slice entries.
Mirror the existing standalone-slice logic that checks
ContainsPointers(sliceType.Elem()) and generates per-element
cloning for pointer, interface, and struct types.
Regenerate net/dns and tailcfg which both had affected
map[...][]*dnstype.Resolver fields.
Fixes#19284
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
Expose priorityClassName in the operator Helm chart values so that
users can configure the operator deployment with a Kubernetes
PriorityClass. This prevents the operator pods from being preempted
by lower-priority workloads.
Fixes#19235
Signed-off-by: Bjorn Stange <bjorn.stange@expel.io>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>