summaryrefslogtreecommitdiffhomepage
path: root/net
AgeCommit message (Collapse)AuthorFilesLines
2026-04-17cmd/cloner: deep-clone pointer elements in map-of-slice valuesAndrew Dunham1-2/+12
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>
2026-04-14net/dns: fix TestDNSTrampleRecovery failure under flakestressBrad Fitzpatrick4-31/+36
The test had two problems: 1. runFileWatcher passed hardcoded "/etc/" to the inotify watcher, but the test filesystem uses a temp directory prefix. The watcher was watching the real /etc/, never seeing the test's file writes. 2. The test's watchFile used gonotify.NewDirWatcher which creates goroutines that block on real inotify syscalls. These don't work inside synctest's fake-time bubble. The test only passed standalone by accident: gonotify walks /etc/ on startup producing fake events that happened to trigger trample detection at the right time. Fix the path issue by adding ActualPath to the wholeFileFS interface, which translates logical paths (like "/etc/resolv.conf") to real filesystem paths (respecting any test prefix). Use it in runFileWatcher so the inotify watch targets the correct directory. Replace gonotify in the test with a one-shot timer that synctest can advance through fake time, reliably triggering the trample check. Fixes #19400 Change-Id: Idb252881ec24d0ab3b3c1d154dbdaf532db837d4 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-04-13all: fix six tests that failed with -count=2Brad Fitzpatrick1-1/+1
Avery found a bunch of tests that fail with -count=2. Updates tailscale/corp#40176 (tracks making our CI detect them) Change-Id: Ie3e4398070dd92e4fe0146badddf1254749cca20 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Co-authored-by: Avery Pennarun <apenwarr@tailscale.com>
2026-04-07tsd, all: add Sys.ExtraRootCAs, plumb through TLS dial pathsBrad Fitzpatrick1-4/+56
Add ExtraRootCAs *x509.CertPool to tsd.System and plumb it through the control client, noise transport, DERP, and wgengine layers so that platforms like Android can inject user-installed CA certificates into Go's TLS verification. tlsdial.Config now honors base.RootCAs as additional trusted roots, tried after system roots and before the baked-in LetsEncrypt fallback. SetConfigExpectedCert gets the same treatment for domain-fronted DERP. The Android client will set sys.ExtraRootCAs with a pool built from x509.SystemCertPool + user-installed certs obtained via the Android KeyStore API, replacing the current SSL_CERT_DIR environment variable approach. Updates #8085 Change-Id: Iecce0fd140cd5aa0331b124e55a7045e24d8e0c2 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-04-06ipn/ipnlocal,net/netmon: make frequent darkwake more efficientJames Tucker4-34/+409
Investigating battery costs on a busy tailnet I noticed a large number of nodes regularly reconnecting to control and DERP. In one case I was able to analyze closely `pmset` reported the every-minute wake-ups being triggered by bluetooth. The node was by side effect reconnecting to control constantly, and this was at times visible to peers as well. Three changes here improve the situation: - Short time jumps (less than 10 minutes) no longer produce "major network change" events, and so do not trigger full rebind/reconnect. - Many "incidental" fields on interfaces are ignored, like MTU, flags and so on - if the route is still good, the rest should be manageable. - Additional log output will provide more detail about the cause of major network change events. Updates #3363 Signed-off-by: James Tucker <james@tailscale.com>
2026-04-05cmd/cloner, cmd/viewer: handle named map/slice types with Clone/View methodsBrad Fitzpatrick1-2/+1
The cloner and viewer code generators didn't handle named types with basic underlying types (map/slice) that have their own Clone or View methods. For example, a type like: type Map map[string]any func (m Map) Clone() Map { ... } func (m Map) View() MapView { ... } When used as a struct field, the cloner would descend into the underlying map[string]any and fail because it can't clone the any (interface{}) value type. Similarly, the viewer would try to create a MapFnOf view and fail. Fix the cloner to check for a Clone method on the named type before falling through to the underlying type handling. Fix the viewer to check for a View method on named map/slice types, so the type author can provide a purpose-built safe view that doesn't leak raw any values. Named map/slice types without a View method fall through to normal handling, which correctly rejects types like map[string]any as unsupported. Updates tailscale/corp#39502 (needed by tailscale/corp#39594) Change-Id: Iaef0192a221e02b4b8e409c99ef8398090327744 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-04-05cmd/vet: add subtestnames analyzer; fix all existing violationsBrad Fitzpatrick11-60/+60
Add a new vet analyzer that checks t.Run subtest names don't contain characters requiring quoting when re-running via "go test -run". This enforces the style guide rule: don't use spaces or punctuation in subtest names. The analyzer flags: - Direct t.Run calls with string literal names containing spaces, regex metacharacters, quotes, or other problematic characters - Table-driven t.Run(tt.name, ...) calls where tt ranges over a slice/map literal with bad name field values Also fix all 978 existing violations across 81 test files, replacing spaces with hyphens and shortening long sentence-like names to concise hyphenated forms. Updates #19242 Change-Id: Ib0ad96a111bd8e764582d1d4902fe2599454ab65 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-04-01tailcfg,ipn/ipnlocal: regulate netmap caching via a node attribute (#19117)M. J. Fromberger1-1/+1
Add a new tailcfg.NodeCapability (NodeAttrCacheNetworkMaps) to control whether a node with support for caching network maps will attempt to do so. Update the capability version to reflect this change (mainly as a safety measure, as the control plane does not currently need to know about it). Use the presence (or absence) of the node attribute to decide whether to create and update a netmap cache for each profile. If caching is disabled, discard the cached data; this allows us to use the presence of a cached netmap as an indicator it should be used (unless explicitly overridden). Add a test that verifies the attribute is respected. Reverse the sense of the environment knob to be true by default, with an override to disable caching at the client regardless what the node attribute says. Move the creation/update of the netmap cache (when enabled) until after successfully applying the network map, to reduce the possibility that we will cache (and thus reuse after a restart) a network map that fails to correctly configure the client. Updates #12639 Change-Id: I1df4dd791fdb485c6472a9f741037db6ed20c47e Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2026-03-26net,tsnet: fix the capitalisation of "Wireshark"Alex Chan2-2/+2
See https://www.wireshark.org/; there's no intercapped S. Updates #cleanup Change-Id: I7c89a3fc6fb0436d0ce0e25a620bde7e310e89d2 Signed-off-by: Alex Chan <alexc@tailscale.com>
2026-03-25net/batching: use vectored writes on Linux (#19054)Alex Valiushko2-30/+59
On Linux batching.Conn will now write a vector of coalesced buffers via sendmmsg(2) instead of copying fragments into a single buffer. Scatter-gather I/O has been available on Linux since the earliest days (reworked in 2.6.24). Kernel passes fragments to the driver if it supports it, otherwise linearizes upon receiving the data. Removing the copy overhead from userspace yields up to 4-5% packet and bitrate improvement on Linux with GSO enabled: 46Gb/s 4.4m pps vs 44Gb/s 4.2m pps w/32 Peer Relay client flows. Updates tailscale/corp#36989 Change-Id: Idb2248d0964fb011f1c8f957ca555eab6a6a6964 Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
2026-03-25net/dns: fix duplicate search line entries (OpenBSD, primarily)Greg Steuck1-1/+8
Fixes #12360 Signed-off-by: Greg Steuck <greg@nest.cx>
2026-03-24net/udprelay: remove experimental label from package docsJordan Whited1-3/+3
Update #cleanup Signed-off-by: Jordan Whited <jordan@tailscale.com>
2026-03-24feature/*,net/tstun: add tundev_txq_drops clientmetric on LinuxJordan Whited1-0/+21
By polling RTM_GETSTATS via netlink. RTM_GETSTATS is a relatively efficient and targeted (single device) polling method available since Linux v4.7. The tundevstats "feature" can be extended to other platforms in the future, and it's trivial to add new rtnl_link_stats64 counters on Linux. Updates tailscale/corp#38181 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2026-03-24all: use `bart.Lite` instead of `bart.Table` where appropriateAlex Chan1-10/+3
When we don't care about the payload value and are just checking whether a set contains an IP/prefix, we can use `bart.Lite` for the same lookup times but a lower memory footprint. Fixes #19075 Change-Id: Ia709e8b718666cc61ea56eac1066467ae0b6e86c Signed-off-by: Alex Chan <alexc@tailscale.com>
2026-03-23net/dns/resolver: treat DNS REFUSED responses as soft errors in forwarder ↵Brendan Creane4-52/+198
race (#19053) When racing multiple upstream DNS resolvers, a REFUSED (RCode 5) response from a broken or misconfigured resolver could win the race and be returned to the client before healthier resolvers had a chance to respond with a valid answer. This caused complete DNS failure in cases where, e.g., a broken upstream resolver returned REFUSED quickly while a working resolver (such as 1.1.1.1) was still responding. Previously, only SERVFAIL (RCode 2) was treated as a soft error. REFUSED responses were returned as successful bytes and could win the race immediately. This change also treats REFUSED as a soft error in the UDP and TCP forwarding paths, so the race continues until a better answer arrives. If all resolvers refuse, the first REFUSED response is returned to the client. Additionally, SERVFAIL responses from upstream resolvers are now returned verbatim to the client rather than replaced with a locally synthesized packet. Synthesized SERVFAIL responses were authoritative and guaranteed to include a question section echoing the original query; upstream responses carry no such guarantees but may include extended error information (e.g. RFC 8914 extended DNS errors) that would otherwise be lost. Fixes #19024 Signed-off-by: Brendan Creane <bcreane@gmail.com>
2026-03-20wgengine/magicsock,control/controlclient: do not overwrite discokey with old ↵Claus Lensbøl1-10/+4
key (#18606) When a client starts up without being able to connect to control, it sends its discoKey to other nodes it wants to communicate with over TSMP. This disco key will be a newer key than the one control knows about. If the client that can connect to control gets a full netmap, ensure that the disco key for the node not connected to control is not overwritten with the stale key control knows about. This is implemented through keeping track of mapSession and use that for the discokey injection if it is available. This ensures that we are not constantly resetting the wireguard connection when getting the wrong keys from control. This is implemented as: - If the key is received via TSMP: - Set lastSeen for the peer to now() - Set online for the peer to false - When processing new keys, only accept keys where either: - Peer is online - lastSeen is newer than existing last seen If mapSession is not available, as in we are not yet connected to control, punt down the disco key injection to magicsock. Ideally, we will want to have mapSession be long lived at some point in the near future so we only need to inject keys in one location and then also use that for testing and loading the cache, but that is a yak for another PR. Updates #12639 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-19net/dns: use the correct separator for multiple servers in the same NRPT ↵Nick Khyl1-1/+1
rule on Windows If an NRPT rule lists more than one server, those servers should be separated by a semicolon (";"), rather than a semicolon followed by a space ("; "). Otherwise, Windows fails to parse the created registry value, and DNS resolution may fail. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gpnrpt/06088ca3-4cf1-48fa-8837-ca8d853ee1e8 Fixes #19040 Updates #15404 (enabled MagicDNS IPv6 by default, adding a second server and triggering the issue) Signed-off-by: Nick Khyl <nickk@tailscale.com>
2026-03-18net/tstun: do not write when Wrapper is closed (#19038)Claus Lensbøl1-3/+7
Two methods could deadlock during shutdown when closing the wrapper. Ensure that the writers are aware of the wrapper being closed. Fixes #19037 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-18net/batching: eliminate gso helper func indirectionJordan Whited2-45/+34
These were previously swappable for historical reasons that are no longer relevant. Removing the indirection enables future inlining optimizations if we simplify further. Updates tailscale/corp#38703 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2026-03-13net/{batching,udprelay},wgengine/magicsock: add SO_RXQ_OVFL clientmetricsJordan Whited4-52/+329
For the purpose of improved observability of UDP socket receive buffer overflows on Linux. Updates tailscale/corp#37679 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2026-03-11netns: add Android callback to bind socket to network (#18915)kari-ts2-3/+48
After switching from cellular to wifi without ipv6, ForeachInterface still sees rmnet prefixes, so HaveV6 stays true, and magicsock keeps attempting ipv6 connections that either route through cellular or time out for users on wifi without ipv6 This: -Adds SetAndroidBindToNetworkFunc, a callback to bind the socket to the selected Android Network object Updates tailscale/tailscale#6152 Signed-off-by: kari-ts <kari@tailscale.com>
2026-03-11net/batching: clarify & simplify single packet read limitationsJordan Whited2-11/+12
ReadFromUDPAddrPort worked if UDP GRO was unsupported, but we don't actually want attempted usage, nor does any exist today. Future work on tailscale/corp#37679 would have required more complexity in this method, vs clarifying the API intents. Updates tailscale/corp#37679 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2026-03-06all: use Go 1.26 things, run most gofix modernizersBrad Fitzpatrick20-67/+46
I omitted a lot of the min/max modernizers because they didn't result in more clear code. Some of it's older "for x := range 123". Also: errors.AsType, any, fmt.Appendf, etc. Updates #18682 Change-Id: I83a451577f33877f962766a5b65ce86f7696471c Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05types/ptr: deprecate ptr.To, use Go 1.26 newBrad Fitzpatrick2-8/+6
Updates #18682 Change-Id: I62f6aa0de2a15ef8c1435032c6aa74a181c25f8f Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05all: fix typos in commentsBrad Fitzpatrick1-1/+1
Fix its/it's, who's/whose, wether/whether, missing apostrophes in contractions, and other misspellings across the codebase. Updates #cleanup Change-Id: I20453b81a7aceaa14ea2a551abba08a2e7f0a1d8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05clientupdate,net/tstun: add support for OpenWrt 25.12.0 using apk (#18545)Claus Lensbøl1-8/+26
OpenWrt is changing to using alpine like `apk` for package installation over its previous opkg. Additionally, they are not using the same repo files as alpine making installation fail. Add support for the new repository files and ensure that the required package detection system uses apk. Updates #18535 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-04net/porttrack: change magic listen address format for Go 1.26Brad Fitzpatrick1-17/+25
Go 1.26's url.Parser is stricter and made our tests elsewhere fail with this scheme because when these listen addresses get shoved into a URL, it can't parse back out. I verified this makes tests elsewhere pass with Go 1.26. Updates #18682 Change-Id: I04dd3cee591aa85a9417a0bbae2b6f699d8302fa Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-04net/udprelay: use GOMAXPROCS instead of NumCPU for socket countDaniel Pañeda1-2/+3
runtime.NumCPU() returns the number of CPUs on the host, which in containerized environments is the node's CPU count rather than the container's CPU limit. This causes excessive memory allocation in pods with low CPU requests running on large nodes, as each socket's packetReadLoop allocates significant buffer memory. Use runtime.GOMAXPROCS(0) instead, which is container-aware since Go 1.25 and respects CPU limits set via cgroups. Fixes #18774 Signed-off-by: Daniel Pañeda <daniel.paneda@clickhouse.com>
2026-03-04cmd/tailscale,ipn,net/netutil: remove rp_filter strict mode warnings (#18863)Mike O'Driscoll2-125/+0
PR #18860 adds firewall rules in the mangle table to save outbound packet marks to conntrack and restore them on reply packets before the routing decision. When reply packets have their marks restored, the kernel uses the correct routing table (based on the mark) and the packets pass the rp_filter check. This makes the risk check and reverse path filtering warnings unnecessary. Updates #3310 Fixes tailscale/corp#37846 Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2026-03-03net/porttrack: add net.Listen wrapper to help tests allocate ports race-freeBrad Fitzpatrick2-0/+271
Updates tailscale/corp#27805 Updates tailscale/corp#27806 Updates tailscale/corp#37964 Change-Id: I7bb5ed7f258e840a8208e5d725c7b2f126d7ef96 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-03wgengine/magicsoc,net/tstun: put disco key advertisement behind a nob (#18857)Claus Lensbøl1-4/+7
To be less spammy in stable, add a nob that disables the creation and processing of TSMPDiscoKeyAdvertisements until we have a proper rollout mechanism. Updates #12639 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-02-27net/netmon: ignore NetBird interface on LinuxJames Tucker1-1/+6
Windows and macOS are not covered by this change, as neither have safely distinct names to make it easy to do so. This covers the requested case on Linux. Updates #18824 Signed-off-by: James Tucker <james@tailscale.com>
2026-02-25netns,wgengine: add OpenBSD support to netns via an rtablejoshua stein9-11/+189
When an exit node has been set and a new default route is added, create a new rtable in the default rdomain and add the current default route via its physical interface. When control() is requesting a connection not go through the exit-node default route, we can use the SO_RTABLE socket option to force it through the new rtable we created. Updates #17321 Signed-off-by: joshua stein <jcs@jcs.org>
2026-02-25cmd/containerboot, net/dns/resolver: remove unused funcs in testsBrad Fitzpatrick1-6/+0
staticcheck was complaining about it on a PR I sent: https://github.com/tailscale/tailscale/actions/runs/22408882872/job/64876543467?pr=18804 And: https://github.com/tailscale/tailscale/actions/runs/22408882872/job/64876543475?pr=18804 Updates #cleanup Updates #18157 Change-Id: I6225481f3aab9e43ef1920aa1a12e86c5073a638 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-02-20appc,feature/conn25,net: Add DNS response interception for conn25Fran Bull1-3/+24
The new version of app connector (conn25) needs to read DNS responses for domains it is interested in and store and swap out IP addresses. Add a hook to dns manager to enable this. Give the conn25 updated netmaps so that it knows when to assign connecting addresses and from what pool. Assign an address when we see a DNS response for a domain we are interested in, but don't do anything with the address yet. Updates tailscale/corp#34252 Signed-off-by: Fran Bull <fran@tailscale.com>
2026-02-18netmon: use State AnyInterfaceUp in ChangeDelta (#18752)Jonathan Nobels1-6/+1
fixes tailscale/corp#37048 We're duplicating logic in AnyInterfaceUp in the ChangeDelta and we're duplicating it wrong. The new State has the logic for this based on the HaveV6 and HaveV4 flags. Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
2026-02-17net/dns: make MagicDNS IPv6 registration opt-out now, not opt-inBrad Fitzpatrick3-33/+67
This adds a new ControlKnob to make MagicDNS IPv6 registration (telling systemd/etc) opt-out rather than opt-in. Updates #15404 Change-Id: If008e1cb046b792c6aff7bb1d7c58638f7d650b1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-02-13control/controlknobs,net/dns,tailcfg: add a control knob that disables hosts ↵Nick Khyl1-7/+14
file updates on Windows In the absence of a better mechanism, writing unqualified hostnames to the hosts file may be required for MagicDNS to work on some Windows environments, such as domain-joined machines. It can also improve MagicDNS performance on non-domain joined devices when we are not the device's primary DNS resolver. At the same time, updating the hosts file can be slow and expensive, especially when it already contains many entries, as was previously reported in #14327. It may also have negative side effects, such as interfering with the system's DNS resolution policies. Additionally, to fix #18712, we had to extend hosts file usage to domain-joined machines when we are not the primary DNS resolver. For the reasons above, this change may introduce risk. To allow customers to disable hosts file updates remotely without disabling MagicDNS entirely, whether on domain-joined machines or not, this PR introduces the `disable-hosts-file-updates` node attribute. Updates #18712 Updates #14327 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2026-02-13net/dns: write MagicDNS host names to the hosts file on domain-joined ↵Nick Khyl1-1/+9
Windows machines On domain-joined Windows devices the primary search domain (the one the device is joined to) always takes precedence over other search domains. This breaks MagicDNS when we are the primary resolver on the device (see #18712). To work around this Windows behavior, we should write MagicDNS host names the hosts file just as we do when we're not the primary resolver. This commit does exactly that. Fixes #18712 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2026-02-11tstun: add test for intercept orderingMichael Ben-Ami1-0/+65
Fixes tailscale/corp#36999 Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
2026-02-10net/dns, ipn/local: skip health warnings in dns forwarder when accept-dns is ↵Jonathan Nobels6-5/+33
false (#18572) fixes tailscale/tailscale#18436 Queries can still make their way to the forwarder when accept-dns is disabled. Since we have not configured the forwarder if --accept-dns is false, this errors out (correctly) but it also generates a persistent health warning. This forwards the Pref setting all the way through the stack to the forwarder so that we can be more judicious about when we decide that the forward path is unintentionally missing, vs simply not configured. Testing: tailscale set --accept-dns=false. (or from the GUI) dig @100.100.100.100 example.com tailscale status No dns related health warnings should be surfaced. Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
2026-02-09tstun,wgengine: add new datapath hooks for intercepting Connectors 2025Michael Ben-Ami1-0/+20
app connector packets We introduce the Conn25PacketHooks interface to be used as a nil-able field in userspaceEngine. The engine then plumbs through the functions to the corresponding tstun.Wrapper intercepts. The new intercepts run pre-filter when egressing toward WireGuard, and post-filter when ingressing from WireGuard. This is preserve the design invariant that the filter recognizes the traffic as interesting app connector traffic. This commit does not plumb through implementation of the interface, so should be a functional no-op. Fixes tailscale/corp#35985 Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
2026-01-30net/dns/resolver: set TC flag when UDP responses exceed size limits (#18157)Brendan Creane4-64/+654
The forwarder was not setting the Truncated (TC) flag when UDP DNS responses exceeded either the EDNS buffer size (if present) or the RFC 1035 default 512-byte limit. This affected DoH, TCP fallback, and UDP response paths. The fix ensures checkResponseSizeAndSetTC is called in all code paths that return UDP responses, enforcing both EDNS and default UDP size limits. Added comprehensive unit tests and consolidated duplicate test helpers. Updates #18107 Signed-off-by: Brendan Creane <bcreane@gmail.com>
2026-01-30net/dns,ipn/ipnlocal: add nodecap to resolve subdomains (#18258)Fernando Serboncini6-4/+94
This adds a new node capability 'dns-subdomain-resolve' that signals that all of hosts' subdomains should resolve to the same IP address. It allows wildcard matching on any node marked with this capability. This change also includes an util/dnsname utility function that lets us access the parent of a full qualified domain name. MagicDNS takes this function and recursively searchs for a matching real node name. One important thing to observe is that, in this context, a subdomain can have multiple sub labels. This means that for a given node named machine, both my.machine and be.my.machine will be a positive match. Updates #1196 Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
2026-01-30net/dns: skip DNS base config when using userspace networking (#18355)Fernando Serboncini2-3/+8
When tailscaled gets started with userspace networking, it won't modify your system's network configuration. For this, it creates a noopManager for DNS management. noopManager correctly observes that there's no real OS DNS to send queries to. This leads to we completely dropping any DNS internal resolution from `dns query` This change alters this so that even without a base config we'll still allow the internal resolver to handle internal DNS queries Fixes #18354 Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
2026-01-26ipn/localapi: stop logging "broken pipe" errors (#18487)Amal Bansode3-0/+76
The Tailscale CLI has some methods to watch the IPN bus for messages, say, the current netmap (`tailscale debug netmap`). The Tailscale daemon supports this using a streaming HTTP response. Sometimes, the client can close its connection abruptly -- due to an interruption, or in the case of `debug netmap`, intentionally after consuming one message. If the server daemon is writing a response as the client closes its end of the socket, the daemon typically encounters a "broken pipe" error. The "Watch IPN Bus" handler currently logs such errors after they're propagated by a JSON encoding/writer helper. Since the Tailscale CLI nominally closes its socket with the daemon in this slightly ungraceful way (viz. `debug netmap`), stop logging these broken pipe errors as far as possible. This will help avoid confounding users when they scan backend logs. Updates #18477 Signed-off-by: Amal Bansode <amal@tailscale.com>
2026-01-26net/dns: add test for DoH upgrade of system DNSAndrew Dunham2-0/+242
Someone asked me if we use DNS-over-HTTPS if the system's resolver is an IP address that supports DoH and there's no global nameserver set (i.e. no "Override DNS servers" set). I didn't know the answer offhand, and it took a while for me to figure it out. The answer is yes, in cases where we take over the system's DNS configuration and read the base config, we do upgrade any DoH-capable resolver to use DoH. Here's a test that verifies this behaviour (and hopefully helps as documentation the next time someone has this question). Updates #cleanup Signed-off-by: Andrew Dunham <andrew@tailscale.com>
2026-01-26net/dns/publicdns: support CIRA Canadian ShieldAndrew Dunham1-0/+20
RELNOTE=Add DNS-over-HTTPS support for CIRA Canadian Shield Fixes #18524 Signed-off-by: Andrew Dunham <andrew@tailscale.com>
2026-01-23all: remove AUTHORS file and references to itWill Norris280-280/+280
This file was never truly necessary and has never actually been used in the history of Tailscale's open source releases. A Brief History of AUTHORS files --- The AUTHORS file was a pattern developed at Google, originally for Chromium, then adopted by Go and a bunch of other projects. The problem was that Chromium originally had a copyright line only recognizing Google as the copyright holder. Because Google (and most open source projects) do not require copyright assignemnt for contributions, each contributor maintains their copyright. Some large corporate contributors then tried to add their own name to the copyright line in the LICENSE file or in file headers. This quickly becomes unwieldy, and puts a tremendous burden on anyone building on top of Chromium, since the license requires that they keep all copyright lines intact. The compromise was to create an AUTHORS file that would list all of the copyright holders. The LICENSE file and source file headers would then include that list by reference, listing the copyright holder as "The Chromium Authors". This also become cumbersome to simply keep the file up to date with a high rate of new contributors. Plus it's not always obvious who the copyright holder is. Sometimes it is the individual making the contribution, but many times it may be their employer. There is no way for the proejct maintainer to know. Eventually, Google changed their policy to no longer recommend trying to keep the AUTHORS file up to date proactively, and instead to only add to it when requested: https://opensource.google/docs/releasing/authors. They are also clear that: > Adding contributors to the AUTHORS file is entirely within the > project's discretion and has no implications for copyright ownership. It was primarily added to appease a small number of large contributors that insisted that they be recognized as copyright holders (which was entirely their right to do). But it's not truly necessary, and not even the most accurate way of identifying contributors and/or copyright holders. In practice, we've never added anyone to our AUTHORS file. It only lists Tailscale, so it's not really serving any purpose. It also causes confusion because Tailscalars put the "Tailscale Inc & AUTHORS" header in other open source repos which don't actually have an AUTHORS file, so it's ambiguous what that means. Instead, we just acknowledge that the contributors to Tailscale (whoever they are) are copyright holders for their individual contributions. We also have the benefit of using the DCO (developercertificate.org) which provides some additional certification of their right to make the contribution. The source file changes were purely mechanical with: git ls-files | xargs sed -i -e 's/\(Tailscale Inc &\) AUTHORS/\1 contributors/g' Updates #cleanup Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d Signed-off-by: Will Norris <will@tailscale.com>
2026-01-21net/udprelay: add tailscaled_peer_relay_endpoints gauge (#18265)Alex Valiushko4-24/+258
New gauge reflects endpoints state via labels: - open, when both peers are connected and ready to talk, and - connecting. when at least one peer hasn't connected yet. Corresponding client metrics are logged as - udprelay_endpoints_connecting - udprelay_endpoints_open Updates tailscale/corp#30820 Change-Id: Idb1baa90a38c97847e14f9b2390093262ad0ea23 Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>