From 020cacbe702463f14a5d2d5427819c491c7e6578 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 7 Nov 2024 16:49:47 -0800 Subject: [PATCH] derp/derphttp: don't link websockets other than on GOOS=js Or unless the new "ts_debug_websockets" build tag is set. Updates #1278 Change-Id: Ic4c4f81c1924250efd025b055585faec37a5491d Signed-off-by: Brad Fitzpatrick --- cmd/derper/depaware.txt | 2 +- cmd/k8s-operator/depaware.txt | 5 ----- cmd/tailscale/depaware.txt | 7 +----- cmd/tailscaled/depaware.txt | 5 ----- control/controlhttp/client_js.go | 5 +++-- .../controlhttpserver/controlhttpserver.go | 2 +- derp/derphttp/derphttp_client.go | 5 ++++- derp/derphttp/derphttp_test.go | 22 +++++++++++++++++++ derp/derphttp/websocket.go | 4 +++- derp/derphttp/websocket_stub.go | 8 +++++++ tstest/deptest/deptest.go | 17 ++++++++++---- 11 files changed, 56 insertions(+), 26 deletions(-) create mode 100644 derp/derphttp/websocket_stub.go diff --git a/cmd/derper/depaware.txt b/cmd/derper/depaware.txt index 8fa5334aa..81a7f14f4 100644 --- a/cmd/derper/depaware.txt +++ b/cmd/derper/depaware.txt @@ -116,7 +116,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa tailscale.com/net/tlsdial/blockblame from tailscale.com/net/tlsdial tailscale.com/net/tsaddr from tailscale.com/ipn+ 💣 tailscale.com/net/tshttpproxy from tailscale.com/derp/derphttp+ - tailscale.com/net/wsconn from tailscale.com/cmd/derper+ + tailscale.com/net/wsconn from tailscale.com/cmd/derper tailscale.com/paths from tailscale.com/client/tailscale 💣 tailscale.com/safesocket from tailscale.com/client/tailscale tailscale.com/syncs from tailscale.com/cmd/derper+ diff --git a/cmd/k8s-operator/depaware.txt b/cmd/k8s-operator/depaware.txt index cdd2ee722..900d10efe 100644 --- a/cmd/k8s-operator/depaware.txt +++ b/cmd/k8s-operator/depaware.txt @@ -80,10 +80,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/ github.com/beorn7/perks/quantile from github.com/prometheus/client_golang/prometheus github.com/bits-and-blooms/bitset from github.com/gaissmai/bart 💣 github.com/cespare/xxhash/v2 from github.com/prometheus/client_golang/prometheus - L github.com/coder/websocket from tailscale.com/derp/derphttp+ - L github.com/coder/websocket/internal/errd from github.com/coder/websocket - L github.com/coder/websocket/internal/util from github.com/coder/websocket - L github.com/coder/websocket/internal/xsync from github.com/coder/websocket L github.com/coreos/go-iptables/iptables from tailscale.com/util/linuxfw 💣 github.com/davecgh/go-spew/spew from k8s.io/apimachinery/pkg/util/dump W 💣 github.com/dblohm7/wingoes from github.com/dblohm7/wingoes/com+ @@ -741,7 +737,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/ tailscale.com/net/tsdial from tailscale.com/control/controlclient+ 💣 tailscale.com/net/tshttpproxy from tailscale.com/clientupdate/distsign+ tailscale.com/net/tstun from tailscale.com/tsd+ - L tailscale.com/net/wsconn from tailscale.com/derp/derphttp tailscale.com/omit from tailscale.com/ipn/conffile tailscale.com/paths from tailscale.com/client/tailscale+ 💣 tailscale.com/portlist from tailscale.com/ipn/ipnlocal diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt index 60af1de01..d18d88873 100644 --- a/cmd/tailscale/depaware.txt +++ b/cmd/tailscale/depaware.txt @@ -5,10 +5,6 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/internal/common+ W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy - L github.com/coder/websocket from tailscale.com/derp/derphttp+ - L github.com/coder/websocket/internal/errd from github.com/coder/websocket - L github.com/coder/websocket/internal/util from github.com/coder/websocket - L github.com/coder/websocket/internal/xsync from github.com/coder/websocket L github.com/coreos/go-iptables/iptables from tailscale.com/util/linuxfw W 💣 github.com/dblohm7/wingoes from github.com/dblohm7/wingoes/pe+ W 💣 github.com/dblohm7/wingoes/pe from tailscale.com/util/winutil/authenticode @@ -125,7 +121,6 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/net/tlsdial/blockblame from tailscale.com/net/tlsdial tailscale.com/net/tsaddr from tailscale.com/client/web+ 💣 tailscale.com/net/tshttpproxy from tailscale.com/clientupdate/distsign+ - L tailscale.com/net/wsconn from tailscale.com/derp/derphttp tailscale.com/paths from tailscale.com/client/tailscale+ 💣 tailscale.com/safesocket from tailscale.com/client/tailscale+ tailscale.com/syncs from tailscale.com/cmd/tailscale/cli+ @@ -326,7 +321,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep reflect from archive/tar+ regexp from github.com/coreos/go-iptables/iptables+ regexp/syntax from regexp - runtime/debug from github.com/coder/websocket/internal/xsync+ + runtime/debug from tailscale.com+ slices from tailscale.com/client/web+ sort from compress/flate+ strconv from archive/tar+ diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index 707c0c065..81cd53271 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -79,10 +79,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de L github.com/aws/smithy-go/transport/http/internal/io from github.com/aws/smithy-go/transport/http L github.com/aws/smithy-go/waiter from github.com/aws/aws-sdk-go-v2/service/ssm github.com/bits-and-blooms/bitset from github.com/gaissmai/bart - L github.com/coder/websocket from tailscale.com/derp/derphttp+ - L github.com/coder/websocket/internal/errd from github.com/coder/websocket - L github.com/coder/websocket/internal/util from github.com/coder/websocket - L github.com/coder/websocket/internal/xsync from github.com/coder/websocket L github.com/coreos/go-iptables/iptables from tailscale.com/util/linuxfw LD 💣 github.com/creack/pty from tailscale.com/ssh/tailssh W 💣 github.com/dblohm7/wingoes from github.com/dblohm7/wingoes/com+ @@ -328,7 +324,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/net/tsdial from tailscale.com/cmd/tailscaled+ 💣 tailscale.com/net/tshttpproxy from tailscale.com/clientupdate/distsign+ tailscale.com/net/tstun from tailscale.com/cmd/tailscaled+ - L tailscale.com/net/wsconn from tailscale.com/derp/derphttp tailscale.com/omit from tailscale.com/ipn/conffile tailscale.com/paths from tailscale.com/client/tailscale+ 💣 tailscale.com/portlist from tailscale.com/ipn/ipnlocal diff --git a/control/controlhttp/client_js.go b/control/controlhttp/client_js.go index 4b7126b52..cc05b5b19 100644 --- a/control/controlhttp/client_js.go +++ b/control/controlhttp/client_js.go @@ -12,6 +12,7 @@ import ( "github.com/coder/websocket" "tailscale.com/control/controlbase" + "tailscale.com/control/controlhttp/controlhttpcommon" "tailscale.com/net/wsconn" ) @@ -42,11 +43,11 @@ func (d *Dialer) Dial(ctx context.Context) (*ClientConn, error) { // Can't set HTTP headers on the websocket request, so we have to to send // the handshake via an HTTP header. RawQuery: url.Values{ - handshakeHeaderName: []string{base64.StdEncoding.EncodeToString(init)}, + controlhttpcommon.HandshakeHeaderName: []string{base64.StdEncoding.EncodeToString(init)}, }.Encode(), } wsConn, _, err := websocket.Dial(ctx, wsURL.String(), &websocket.DialOptions{ - Subprotocols: []string{upgradeHeaderValue}, + Subprotocols: []string{controlhttpcommon.UpgradeHeaderValue}, }) if err != nil { return nil, err diff --git a/control/controlhttp/controlhttpserver/controlhttpserver.go b/control/controlhttp/controlhttpserver/controlhttpserver.go index 47f049c18..af3207810 100644 --- a/control/controlhttp/controlhttpserver/controlhttpserver.go +++ b/control/controlhttp/controlhttpserver/controlhttpserver.go @@ -3,7 +3,7 @@ //go:build !ios -// Packet controlhttpserver contains the HTTP server side of the ts2021 control protocol. +// Package controlhttpserver contains the HTTP server side of the ts2021 control protocol. package controlhttpserver import ( diff --git a/derp/derphttp/derphttp_client.go b/derp/derphttp/derphttp_client.go index b695a52a8..c95d072b1 100644 --- a/derp/derphttp/derphttp_client.go +++ b/derp/derphttp/derphttp_client.go @@ -313,6 +313,9 @@ func (c *Client) preferIPv6() bool { var dialWebsocketFunc func(ctx context.Context, urlStr string) (net.Conn, error) func useWebsockets() bool { + if !canWebsockets { + return false + } if runtime.GOOS == "js" { return true } @@ -383,7 +386,7 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien var node *tailcfg.DERPNode // nil when using c.url to dial var idealNodeInRegion bool switch { - case useWebsockets(): + case canWebsockets && useWebsockets(): var urlStr string if c.url != nil { urlStr = c.url.String() diff --git a/derp/derphttp/derphttp_test.go b/derp/derphttp/derphttp_test.go index cfb3676cd..cf6032a5e 100644 --- a/derp/derphttp/derphttp_test.go +++ b/derp/derphttp/derphttp_test.go @@ -17,7 +17,9 @@ import ( "tailscale.com/derp" "tailscale.com/net/netmon" + "tailscale.com/tstest/deptest" "tailscale.com/types/key" + "tailscale.com/util/set" ) func TestSendRecv(t *testing.T) { @@ -485,3 +487,23 @@ func TestProbe(t *testing.T) { } } } + +func TestDeps(t *testing.T) { + deptest.DepChecker{ + GOOS: "darwin", + GOARCH: "arm64", + BadDeps: map[string]string{ + "github.com/coder/websocket": "shouldn't link websockets except on js/wasm", + }, + }.Check(t) + + deptest.DepChecker{ + GOOS: "darwin", + GOARCH: "arm64", + Tags: "ts_debug_websockets", + WantDeps: set.Of( + "github.com/coder/websocket", + ), + }.Check(t) + +} diff --git a/derp/derphttp/websocket.go b/derp/derphttp/websocket.go index 6ef47473a..9dd640ee3 100644 --- a/derp/derphttp/websocket.go +++ b/derp/derphttp/websocket.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build linux || js +//go:build js || ((linux || darwin) && ts_debug_websockets) package derphttp @@ -14,6 +14,8 @@ import ( "tailscale.com/net/wsconn" ) +const canWebsockets = true + func init() { dialWebsocketFunc = dialWebsocket } diff --git a/derp/derphttp/websocket_stub.go b/derp/derphttp/websocket_stub.go new file mode 100644 index 000000000..d84bfba57 --- /dev/null +++ b/derp/derphttp/websocket_stub.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !(js || ((linux || darwin) && ts_debug_websockets)) + +package derphttp + +const canWebsockets = false diff --git a/tstest/deptest/deptest.go b/tstest/deptest/deptest.go index ba214de32..00faa8a38 100644 --- a/tstest/deptest/deptest.go +++ b/tstest/deptest/deptest.go @@ -13,15 +13,19 @@ import ( "path/filepath" "regexp" "runtime" + "slices" "strings" "testing" + + "tailscale.com/util/set" ) type DepChecker struct { - GOOS string // optional - GOARCH string // optional - BadDeps map[string]string // package => why - Tags string // comma-separated + GOOS string // optional + GOARCH string // optional + BadDeps map[string]string // package => why + WantDeps set.Set[string] // packages expected + Tags string // comma-separated } func (c DepChecker) Check(t *testing.T) { @@ -55,6 +59,11 @@ func (c DepChecker) Check(t *testing.T) { t.Errorf("package %q is not allowed as a dependency (env: %q); reason: %s", dep, extraEnv, why) } } + for dep := range c.WantDeps { + if !slices.Contains(res.Deps, dep) { + t.Errorf("expected package %q to be a dependency (env: %q)", dep, extraEnv) + } + } t.Logf("got %d dependencies", len(res.Deps)) }