summaryrefslogtreecommitdiffhomepage
path: root/derp/derphttp
AgeCommit message (Collapse)AuthorFilesLines
2025-08-11derp/derphttp: test improvements (#16723)Mike O'Driscoll1-14/+20
Update some logging to help future failures. Improve test shutdown concurrency issues. Fixes #16722 Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2025-07-02derp/derphttp: fix DERP TLS client server name inclusion in URL formJames Tucker2-1/+39
When dialed with just an URL and no node, the recent proxy fixes caused a regression where there was no TLS server name being included. Updates #16222 Updates #16223 Signed-off-by: James Tucker <james@tailscale.com> Co-Authored-by: Jordan Whited <jwhited@tailscale.com>
2025-06-18net/tlsdial: fix TLS cert validation of HTTPS proxiesBrad Fitzpatrick2-1/+36
If you had HTTPS_PROXY=https://some-valid-cert.example.com running a CONNECT proxy, we should've been able to do a TLS CONNECT request to e.g. controlplane.tailscale.com:443 through that, and I'm pretty sure it used to work, but refactorings and lack of integration tests made it regress. It probably regressed when we added the baked-in LetsEncrypt root cert validation fallback code, which was testing against the wrong hostname (the ultimate one, not the one which we were being asked to validate) Fixes #16222 Change-Id: If014e395f830e2f87f056f588edacad5c15e91bc Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-06-17derp/derphttp: add error notify for RunWatchConnectionLoop (#16261)Mike O'Driscoll2-6/+82
The caller of client.RunWatchConnectionLoop may need to be aware of errors that occur within loop. Add a channel that notifies of errors to the caller to allow for decisions to be make as to the state of the client. Updates tailscale/corp#25756 Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
2025-05-22cmd/derper: fix mesh auth for DERP servers (#16061)Simon Law2-3/+9
To authenticate mesh keys, the DERP servers used a simple == comparison, which is susceptible to a side channel timing attack. By extracting the mesh key for a DERP server, an attacker could DoS it by forcing disconnects using derp.Client.ClosePeer. They could also enumerate the public Wireguard keys, IP addresses and ports for nodes connected to that DERP server. DERP servers configured without mesh keys deny all such requests. This patch also extracts the mesh key logic into key.DERPMesh, to prevent this from happening again. Security bulletin: https://tailscale.com/security-bulletins#ts-2025-003 Fixes tailscale/corp#28720 Signed-off-by: Simon Law <sfllaw@tailscale.com>
2025-05-19cmd/derper, net/tlsdial: fix client's self-signed cert validationBrad Fitzpatrick1-1/+2
This fixes the implementation and test from #15208 which apparently never worked. Ignore the metacert when counting the number of expected certs presented. And fix the test, pulling out the TLSConfig setup code into something shared between the real cmd/derper and the test. Fixes #15579 Change-Id: I90526e38e59f89b480629b415f00587b107de10a Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-16derp/derphttp: remove ban on websockets dependencyDavid Anderson1-22/+0
The event bus's debug page uses websockets. Updates #15160 Signed-off-by: David Anderson <dave@tailscale.com>
2025-04-08net/{netx,memnet},all: add netx.DialFunc, move memnet Network implBrad Fitzpatrick1-1/+2
This adds netx.DialFunc, unifying a type we have a bazillion other places, giving it now a nice short name that's clickable in editors, etc. That highlighted that my earlier move (03b47a55c7956) of stuff from nettest into netx moved too much: it also dragged along the memnet impl, meaning all users of netx.DialFunc who just wanted netx for the type definition were instead also pulling in all of memnet. So move the memnet implementation netx.Network into memnet, a package we already had. Then use netx.DialFunc in a bunch of places. I'm sure I missed some. And plenty remain in other repos, to be updated later. Updates tailscale/corp#27636 Change-Id: I7296cd4591218e8624e214f8c70dab05fb884e95 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-03-07cmd/derper, derp/derphttp: support, generate self-signed IP address certsBrad Fitzpatrick1-3/+17
For people who can't use LetsEncrypt because it's banned. Per https://github.com/tailscale/tailscale/issues/11776#issuecomment-2520955317 This does two things: 1) if you run derper with --certmode=manual and --hostname=$IP_ADDRESS we previously permitted, but now we also: * auto-generate the self-signed cert for you if it doesn't yet exist on disk * print out the derpmap configuration you need to use that self-signed cert 2) teaches derp/derphttp's derp dialer to verify the signature of self-signed TLS certs, if so declared in the existing DERPNode.CertName field, which previously existed for domain fronting, separating out the dial hostname from how certs are validates, so it's not overloaded much; that's what it was meant for. Fixes #11776 Change-Id: Ie72d12f209416bb7e8325fe0838cd2c66342c5cf Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-02-03derp/derphttp,ipn/localapi,net/captivedetection: add cache resistance to ↵James Tucker1-1/+2
captive portal detection Observed on some airlines (British Airways, WestJet), Squid is configured to cache and transform these results, which is disruptive. The server and client should both actively request that this is not done by setting Cache-Control headers. Send a timestamp parameter to further work against caches that do not respect the cache-control headers. Updates #14856 Signed-off-by: James Tucker <james@tailscale.com>
2024-12-10prober,derp/derphttp: make dev-mode DERP probes work without TLS (#14347)Mario Minardi1-0/+3
Make dev-mode DERP probes work without TLS. Properly dial port `3340` when not using HTTPS when dialing nodes in `derphttp_client`. Skip verifying TLS state in `newConn` if we are not running a prober. Updates tailscale/corp#24635 Signed-off-by: Percy Wegmann <percy@tailscale.com> Co-authored-by: Percy Wegmann <percy@tailscale.com>
2024-11-07derp/derphttp: don't link websockets other than on GOOS=jsBrad Fitzpatrick4-2/+37
Or unless the new "ts_debug_websockets" build tag is set. Updates #1278 Change-Id: Ic4c4f81c1924250efd025b055585faec37a5491d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-10-20derp: track client-advertised non-ideal DERP connections in more placesBrad Fitzpatrick2-2/+8
In f77821fd63 (released in v1.72.0), we made the client tell a DERP server when the connection was not its ideal choice (the first node in its region). But we didn't do anything with that information until now. This adds a metric about how many such connections are on a given derper, and also adds a bit to the PeerPresentFlags bitmask so watchers can identify (and rebalance) them. Updates tailscale/corp#372 Change-Id: Ief8af448750aa6d598e5939a57c062f4e55962be Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-09-24derp: document the RunWatchConnectionLoop callback gotchasBrad Fitzpatrick1-0/+4
Updates #13566 Change-Id: I497b5adc57f8b1b97dbc3f74c0dc67140caad436 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-08-14go.{mod,sum}: migrate from nhooyr.io/websocket to github.com/coder/websocketKyle Carberry1-1/+1
Coder has just adopted nhooyr/websocket which unfortunately changes the import path. `github.com/coder/coder` imports `tailscale.com/net/wsconn` which was still pointing to `nhooyr.io/websocket`, but this change updates it. See https://coder.com/blog/websocket Updates #13154 Change-Id: I3dec6512472b14eae337ae22c5bcc1e3758888d5 Signed-off-by: Kyle Carberry <kyle@carberry.com>
2024-08-06cmd/derper: move 204 handler from package main to derphttpBrad Fitzpatrick1-0/+27
Updates #13038 Change-Id: I28a8284dbe49371cae0e9098205c7c5f17225b40 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-07-17derp/derphttp: determine whether a region connect was to non-ideal nodeBrad Fitzpatrick1-0/+14
... and then do approximately nothing with that information, other than a big TODO. This is mostly me relearning this code and leaving breadcrumbs for others in the future. Updates #12724 Signed-off-by: Brad Fitzpatrick <brad@danga.com>
2024-06-25derp: make RunConnectionLoop funcs take Messages, support PeerPresentFlagsBrad Fitzpatrick2-22/+21
PeerPresentFlags was added in 5ffb2668ef but wasn't plumbed through to the RunConnectionLoop. Rather than add yet another parameter (as IP:port was added earlier), pass in the raw PeerPresentMessage and PeerGoneMessage struct values, which are the same things, plus two fields: PeerGoneReasonType for gone and the PeerPresentFlags from 5ffb2668ef. Updates tailscale/corp#17816 Change-Id: Ib19d9f95353651ada90656071fc3656cf58b7987 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-03derp/derphttp: fix netcheck HTTPS probesBrad Fitzpatrick2-0/+43
The netcheck client, when no UDP is available, probes distance using HTTPS. Several problems: * It probes using /derp/latency-check. * But cmd/derper serves the handler at /derp/probe * Despite the difference, it work by accident until c8f4dfc8c0600 which made netcheck's probe require a 2xx status code. * in tests, we only use derphttp.Handler, so the cmd/derper-installed mux routes aren't preesnt, so there's no probe. That breaks tests in airplane mode. netcheck.Client then reports "unexpected HTTP status 426" (Upgrade Required) This makes derp handle both /derp/probe and /derp/latency-check equivalently, and in both cmd/derper and derphttp.Handler standalone modes. I notice this when wgengine/magicsock TestActiveDiscovery was failing in airplane mode (no wifi). It still doesn't pass, but it gets further. Fixes #11989 Change-Id: I45213d4bd137e0f29aac8bd4a9ac92091065113f
2024-05-03derp/derphttp, net/netcheck: plumb netmon.Monitor to derp netcheck clientBrad Fitzpatrick1-2/+9
Fixes #11981 Change-Id: I0e15a09f93aefb3cfddbc12d463c1c08b83e09fd Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-27net/netns, net/dns/resolver, etc: make netmon required in most placesBrad Fitzpatrick2-6/+15
The goal is to move more network state accessors to netmon.Monitor where they can be cheaper/cached. But first (this change and others) we need to make sure the one netmon.Monitor is plumbed everywhere. Some notable bits: * tsdial.NewDialer is added, taking a now-required netmon * because a tsdial.Dialer always has a netmon, anything taking both a Dialer and a NetMon is now redundant; take only the Dialer and get the NetMon from that if/when needed. * netmon.NewStatic is added, primarily for tests Updates tailscale/corp#10910 Updates tailscale/corp#18960 Updates #7967 Updates #3299 Change-Id: I877f9cb87618c4eb037cee098241d18da9c01691 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-25tsd, ipnlocal, etc: add tsd.System.HealthTracker, start some plumbingBrad Fitzpatrick1-5/+8
This adds a health.Tracker to tsd.System, accessible via a new tsd.System.HealthTracker method. In the future, that new method will return a tsd.System-specific HealthTracker, so multiple tsnet.Servers in the same process are isolated. For now, though, it just always returns the temporary health.Global value. That permits incremental plumbing over a number of changes. When the second to last health.Global reference is gone, then the tsd.System.HealthTracker implementation can return a private Tracker. The primary plumbing this does is adding it to LocalBackend and its dozen and change health calls. A few misc other callers are also plumbed. Subsequent changes will flesh out other parts of the tree (magicsock, controlclient, etc). Updates #11874 Updates #4136 Change-Id: Id51e73cfc8a39110425b6dc19d18b3975eac75ce Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-16all: use Go 1.22 range-over-intBrad Fitzpatrick1-4/+4
Updates #11058 Change-Id: I35e7ef9b90e83cac04ca93fd964ad00ed5b48430 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-08derp/derphttp: don't block in LocalAddr methodBrad Fitzpatrick2-7/+42
The derphttp.Client mutex is held during connects (for up to 10 seconds) so this LocalAddr method (blocking on said mutex) could also block for up to 10 seconds, causing a pileup upstream in magicsock/wgengine and ultimately a watchdog timeout resulting in a crash. Updates #11519 Change-Id: Idd1d94ee00966be1b901f6899d8b9492f18add0f Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-03-27derp/derphttp: make CONNECT Host match request-target's authority-formBrad Fitzpatrick1-1/+1
This CONNECT client doesn't match what Go's net/http.Transport does (making the two values match). This makes it match. This is all pretty unspecified but most clients & doc examples show these matching. And some proxy implementations (such as Zscaler) care. Updates tailscale/corp#18716 Change-Id: I135c5facbbcec9276faa772facbde1bb0feb2d26 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-02-07util/cmpx: delete now that we're using Go 1.22Brad Fitzpatrick1-2/+2
Updates #11058 Change-Id: I09dea8e86f03ec148b715efca339eab8b1f0f644 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-11-06derp/derphttp: use a getter method to read server keyAnton Tolchanov1-1/+1
To hold the mutex while accessing it. Fixes #10122 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2023-11-04derp/derphttp: fix derptrack fixBrad Fitzpatrick2-1/+65
3d7fb6c21d dropped the explicit called to (*Client).connect when its (*Client).WatchConnectionChanges got removed+refactored. This puts it back, but in RunWatchConnectionLoop, before the call to the (*Client).ServerPublicKey accessor, which is documented to return the zero value (which is what broke us) on an unconnected connection. Plus some tests. Fixes tailscale/corp#15604 Change-Id: I0f242816f5ee4ad3bb0bf0400abc961dbe9f5fc8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-11-01derp/derphttp: close DERP client to avoid data race in testAnton Tolchanov1-10/+14
Fixes #10041 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2023-10-31derp/derphttp: add watch reconnection tests from #9719Anton Tolchanov2-1/+193
Co-authored-by: Val <valerie@tailscale.com> Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2023-10-31derp/derphttp: fix race in mesh watcherBrad Fitzpatrick2-32/+42
The derphttp client automatically reconnects upon failure. RunWatchConnectionLoop called derphttp.Client.WatchConnectionChanges once, but that wrapper method called the underlying derp.Client.WatchConnectionChanges exactly once on derphttp.Client's currently active connection. If there's a failure, we need to re-subscribe upon all reconnections. This removes the derphttp.Client.WatchConnectionChanges method, which was basically impossible to use correctly, and changes it to be a boolean field on derphttp.Client alongside MeshKey and IsProber. Then it moves the call to the underlying derp.Client.WatchConnectionChanges to derphttp's client connection code, so it's resubscribed on any reconnect. Some paranoia is then added to make sure people hold the API right, not calling derphttp.Client.RunWatchConnectionLoop on an already-started Client without having set the bool to true. (But still auto-setting it to true if that's the first method that's been called on that derphttp.Client, as is commonly the case, and prevents existing code from breaking) Fixes tailscale/corp#9916 Supercedes tailscale/tailscale#9719 Co-authored-by: Val <valerie@tailscale.com> Co-authored-by: Irbe Krumina <irbe@tailscale.com> Co-authored-by: Anton Tolchanov <anton@tailscale.com> Signed-off-by: Brad Fitzpatrick <brad@danga.com>
2023-10-24derp/derphttp: strip port numbers from URL hostnameThomas Kosiewski1-1/+1
When trying to set up multiple derper instances meshing with each other, it turned out that while one can specify an alternative listening port using the -a flag, the TLS hostname gets incorrectly determined and includes the set alternative listening port as part of the hostname. Thus, the TLS hostname validation always fails when the -mesh-with values have ports. Updates #9949 Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
2023-08-29net/wsconn: accept a remote addr string and plumb it throughDavid Anderson1-1/+1
This makes wsconn.Conns somewhat present reasonably when they are the client of an http.Request, rather than just put a placeholder in that field. Updates tailscale/corp#13777 Signed-off-by: David Anderson <danderson@tailscale.com>
2023-08-29derp/derphttp: fix data race and crash in proxy dial error pathBrad Fitzpatrick1-1/+2
Named result meant error paths assigned that variable to nil. But a goroutine was concurrently using that variable. Don't use a named result for that first parameter. Then then return paths don't overwrite it. Fixes #9129 Change-Id: Ie57f99d40ca8110085097780686d9bd620aaf160 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-16derp: include src IPs in mesh watch messagesBrad Fitzpatrick1-5/+6
Updates tailscale/corp#13945 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-07-30derp/derphttp: add optional Client.BaseContext hookBrad Fitzpatrick1-5/+23
Like net/http.Server.BaseContext, this lets callers specify a base context for dials. Updates tailscale/corp#12702 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-07-27derp: use tstime (#8634)Claire Wang2-8/+12
Updates #8587 Signed-off-by: Claire Wang <claire@tailscale.com>
2023-06-07all: use cmpx.Or where it made senseBrad Fitzpatrick1-4/+2
I left a few out where writing it explicitly was better for various reasons. Updates #8296 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-04-20all: avoid repeated default interface lookupsMihai Parparita1-3/+7
On some platforms (notably macOS and iOS) we look up the default interface to bind outgoing connections to. This is both duplicated work and results in logspam when the default interface is not available (i.e. when a phone has no connectivity, we log an error and thus cause more things that we will try to upload and fail). Fixed by passing around a netmon.Monitor to more places, so that we can use its cached interface state. Fixes #7850 Updates #7621 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-04-12net/sockstats: pass in logger to sockstats.WithSockStatsMihai Parparita1-1/+1
Using log.Printf may end up being printed out to the console, which is not desirable. I noticed this when I was investigating some client logs with `sockstats: trace "NetcheckClient" was overwritten by another`. That turns to be harmless/expected (the netcheck client will fall back to the DERP client in some cases, which does its own sockstats trace). However, the log output could be visible to users if running the `tailscale netcheck` CLI command, which would be needlessly confusing. Updates tailscale/corp#9230 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-04-04derp,magicsock: add debug envknobs for HTTP and derp server name (#7744)valscale1-1/+13
Make developing derp easier by: 1. Creating an envknob telling clients to use HTTP to connect to derp servers, so devs don't have to acquire a valid TLS cert. 2. Creating an envknob telling clients which derp server to connect to, so devs don't have to edit the ACLs in the admin console to add a custom DERP map. 3. Explaining how the -dev and -a command lines args to derper interact. To use this: 1. Run derper with -dev. 2. Run tailscaled with TS_DEBUG_USE_DERP_HTTP=1 and TS_DEBUG_USE_DERP_ADDR=localhost This will result in the client connecting to derp via HTTP on port 3340. Fixes #7700 Signed-off-by: Val <valerie@tailscale.com>
2023-03-24derp, derphttp, magicsock: send new unknown peer frame when destination is ↵valscale1-1/+11
unknown (#7552) * wgengine/magicsock: add envknob to send CallMeMaybe to non-existent peer For testing older client version responses to the PeerGone packet format change. Updates #4326 Signed-off-by: Val <valerie@tailscale.com> * derp: remove dead sclient struct member replaceLimiter Leftover from an previous solution to the duplicate client problem. Updates #2751 Signed-off-by: Val <valerie@tailscale.com> * derp, derp/derphttp, wgengine/magicsock: add new PeerGone message type Not Here Extend the PeerGone message type by adding a reason byte. Send a PeerGone "Not Here" message when an endpoint sends a disco message to a peer that this server has no record of. Fixes #4326 Signed-off-by: Val <valerie@tailscale.com> --------- Signed-off-by: Val <valerie@tailscale.com>
2023-03-20derp: add optional debug logging for prober clientsAnton Tolchanov1-0/+4
This allows tracking packet flow via logs for prober clients. Note that the new sclient.debug() function is called on every received packet, but will do nothing for most clients. I have adjusted sclient logging to print public keys in short format rather than full. This takes effect even for existing non-debug logging (mostly client disconnect messages). Example logs for a packet being sent from client [SbsJn] (connected to derper [dM2E3]) to client [10WOo] (connected to derper [AVxvv]): ``` derper [dM2E3]: derp client 10.0.0.1:35470[SbsJn]: register single client mesh("10.0.1.1"): 4 peers derp client 10.0.0.1:35470[SbsJn]: read frame type 4 len 40 err <nil> derp client 10.0.0.1:35470[SbsJn]: SendPacket for [10WOo], forwarding via <derphttp_client.Client [AVxvv] url=https://10.0.1.1/derp>: <nil> derp client 10.0.0.1:35470[SbsJn]: read frame type 0 len 0 err EOF derp client 10.0.0.1:35470[SbsJn]: read EOF derp client 10.0.0.1:35470[SbsJn]: sender failed: context canceled derp client 10.0.0.1:35470[SbsJn]: removing connection derper [AVxvv]: derp client 10.0.1.1:50650[10WOo]: register single client derp client 10.0.1.1:50650[10WOo]: received forwarded packet from [SbsJn] via [dM2E3] derp client 10.0.1.1:50650[10WOo]: sendPkt attempt 0 enqueued derp client 10.0.1.1:50650[10WOo]: sendPacket from [SbsJn]: <nil> derp client 10.0.1.1:50650[10WOo]: read frame type 0 len 0 err EOF derp client 10.0.1.1:50650[10WOo]: read EOF derp client 10.0.1.1:50650[10WOo]: sender failed: context canceled derp client 10.0.1.1:50650[10WOo]: removing connection ``` Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2023-03-07derp/derphttp: cleanup WebSocket connection on closeKyle Carberry1-1/+1
This was causing a leak in our CI! Signed-off-by: Kyle Carberry <kyle@carberry.com>
2023-03-06sockstats: switch label to enumMihai Parparita1-1/+1
Makes it cheaper/simpler to persist values, and encourages reuse of labels as opposed to generating an arbitrary number. Updates tailscale/corp#9230 Updates #3363 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-03-01sockstats: instrument networking code pathsMihai Parparita1-0/+3
Uses the hooks added by tailscale/go#45 to instrument the reads and writes on the major code paths that do network I/O in the client. The convention is to use "<package>.<type>:<label>" as the annotation for the responsible code path. Enabled on iOS, macOS and Android only, since mobile platforms are the ones we're most interested in, and we are less sensitive to any throughput degradation due to the per-I/O callback overhead (macOS is also enabled for ease of testing during development). For now just exposed as counters on a /v0/sockstats PeerAPI endpoint. We also keep track of the current interface so that we can break out the stats by interface. Updates tailscale/corp#9230 Updates #3363 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-02-01all: use Go 1.20's bytes.CloneBrad Fitzpatrick1-1/+2
Updates #7123 Updates #6257 (more to do in other repos) Change-Id: I073e2a6d81a5d7fbecc29caddb7e057ff65239d0 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-02-01all: update to Go 1.20, use strings.CutPrefix/Suffix instead of our forkBrad Fitzpatrick1-2/+2
Updates #7123 Updates #5309 Change-Id: I90bcd87a2fb85a91834a0dd4be6e03db08438672 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-01-27all: update copyright and license headersWill Norris5-15/+10
This updates all source files to use a new standard header for copyright and license declaration. Notably, copyright no longer includes a date, and we now use the standard SPDX-License-Identifier header. This commit was done almost entirely mechanically with perl, and then some minimal manual fixes. Updates #6865 Signed-off-by: Will Norris <will@tailscale.com>
2022-11-21all: use strs.CutPrefix and strs.CutSuffix moreMihai Parparita1-3/+4
Updates places where we use HasPrefix + TrimPrefix to use the combined function. Updates #5309 Signed-off-by: Mihai Parparita <mihai@tailscale.com>