diff --git a/wgengine/magicsock/endpoint.go b/wgengine/magicsock/endpoint.go index 1f36aabd3..a8b57b653 100644 --- a/wgengine/magicsock/endpoint.go +++ b/wgengine/magicsock/endpoint.go @@ -24,6 +24,7 @@ import ( "golang.org/x/net/ipv4" "golang.org/x/net/ipv6" "tailscale.com/disco" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn/ipnstate" "tailscale.com/net/packet" "tailscale.com/net/stun" @@ -896,7 +897,7 @@ func (de *endpoint) discoverUDPRelayPathsLocked(now mono.Time) { // wantUDPRelayPathDiscoveryLocked reports whether we should kick off UDP relay // path discovery. func (de *endpoint) wantUDPRelayPathDiscoveryLocked(now mono.Time) bool { - if runtime.GOOS == "js" { + if runtime.GOOS == "js" || !buildfeatures.HasRelayServer { return false } if !de.relayCapable { @@ -2000,8 +2001,10 @@ func (de *endpoint) handleCallMeMaybe(m *disco.CallMeMaybe) { // path discovery can also trigger disco ping transmission, which *could* // lead to an infinite loop of peer relay path discovery between two peers, // absent intended triggers. - if de.wantUDPRelayPathDiscoveryLocked(monoNow) { - de.discoverUDPRelayPathsLocked(monoNow) + if buildfeatures.HasRelayServer { + if de.wantUDPRelayPathDiscoveryLocked(monoNow) { + de.discoverUDPRelayPathsLocked(monoNow) + } } } diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index e3cf249c5..00e85f268 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -644,7 +644,11 @@ func (c *Conn) consumeEventbusTopics(cli *eventbus.Client) func(*eventbus.Client nodeViewsSub := eventbus.Subscribe[NodeViewsUpdate](cli) nodeMutsSub := eventbus.Subscribe[NodeMutationsUpdate](cli) syncSub := eventbus.Subscribe[syncPoint](cli) - allocRelayEndpointSub := eventbus.Subscribe[UDPRelayAllocResp](cli) + + var relayCh <-chan UDPRelayAllocResp + if buildfeatures.HasRelayServer { + relayCh = eventbus.Subscribe[UDPRelayAllocResp](cli).Events() + } return func(cli *eventbus.Client) { for { select { @@ -661,8 +665,10 @@ func (c *Conn) consumeEventbusTopics(cli *eventbus.Client) func(*eventbus.Client case syncPoint := <-syncSub.Events(): c.dlogf("magicsock: received sync point after reconfig") syncPoint.Signal() - case allocResp := <-allocRelayEndpointSub.Events(): - c.onUDPRelayAllocResp(allocResp) + case allocResp := <-relayCh: + if buildfeatures.HasRelayServer { + c.onUDPRelayAllocResp(allocResp) + } } } } @@ -1945,11 +1951,13 @@ func (c *Conn) sendDiscoMessage(dst epAddr, dstKey key.NodePublic, dstDisco key. var di *discoInfo switch { case isRelayHandshakeMsg: - var ok bool - di, ok = c.relayManager.discoInfo(dstDisco) - if !ok { - c.mu.Unlock() - return false, errors.New("unknown relay server") + if buildfeatures.HasRelayServer { + var ok bool + di, ok = c.relayManager.discoInfo(dstDisco) + if !ok { + c.mu.Unlock() + return false, errors.New("unknown relay server") + } } case c.peerMap.knownPeerDiscoKey(dstDisco): di = c.discoInfoForKnownPeerLocked(dstDisco) @@ -2169,13 +2177,15 @@ func (c *Conn) handleDiscoMessage(msg []byte, src epAddr, shouldBeRelayHandshake var di *discoInfo switch { case shouldBeRelayHandshakeMsg: - var ok bool - di, ok = c.relayManager.discoInfo(sender) - if !ok { - if debugDisco() { - c.logf("magicsock: disco: ignoring disco-looking relay handshake frame, no active handshakes with key %v over %v", sender.ShortString(), src) + if buildfeatures.HasRelayServer { + var ok bool + di, ok = c.relayManager.discoInfo(sender) + if !ok { + if debugDisco() { + c.logf("magicsock: disco: ignoring disco-looking relay handshake frame, no active handshakes with key %v over %v", sender.ShortString(), src) + } + return } - return } case c.peerMap.knownPeerDiscoKey(sender): di = c.discoInfoForKnownPeerLocked(sender) @@ -2894,6 +2904,9 @@ func (c *Conn) onFilterUpdate(f FilterUpdate) { // 2. Moving this work upstream into [nodeBackend] or similar, and publishing // the computed result over the eventbus instead. func (c *Conn) updateRelayServersSet(filt *filter.Filter, self tailcfg.NodeView, peers views.Slice[tailcfg.NodeView]) { + if !buildfeatures.HasRelayServer { + return + } relayServers := make(set.Set[candidatePeerRelay]) nodes := append(peers.AsSlice(), self) for _, maybeCandidate := range nodes { diff --git a/wgengine/magicsock/relaymanager.go b/wgengine/magicsock/relaymanager.go index 4680832d9..0f2324d46 100644 --- a/wgengine/magicsock/relaymanager.go +++ b/wgengine/magicsock/relaymanager.go @@ -12,6 +12,7 @@ import ( "time" "tailscale.com/disco" + "tailscale.com/feature/buildfeatures" "tailscale.com/net/packet" "tailscale.com/net/stun" udprelay "tailscale.com/net/udprelay/endpoint" @@ -419,6 +420,9 @@ func (r *relayManager) handleCallMeMaybeVia(ep *endpoint, lastBest addrQuality, // [*disco.AllocateUDPRelayEndpointResponse] then relayServerNodeKey must be // nonzero. func (r *relayManager) handleRxDiscoMsg(conn *Conn, dm disco.Message, relayServerNodeKey key.NodePublic, discoKey key.DiscoPublic, src epAddr) { + if !buildfeatures.HasRelayServer { + return + } relayManagerInputEvent(r, nil, &r.rxDiscoMsgCh, relayDiscoMsgEvent{ conn: conn, msg: dm, @@ -445,6 +449,9 @@ func (r *relayManager) handleRelayServersSet(servers set.Set[candidatePeerRelay] // goroutine to return, i.e. the calling goroutine was birthed by runLoop and is // cancelable via 'ctx'. 'ctx' may be nil. func relayManagerInputEvent[T any](r *relayManager, ctx context.Context, eventCh *chan T, event T) { + if !buildfeatures.HasRelayServer { + return + } r.init() var ctxDoneCh <-chan struct{} if ctx != nil {