From a268076347aa6ae5e3d427b9aada96830ad874bc Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Wed, 19 Mar 2025 20:28:19 -0700 Subject: [PATCH] {wgengine,util/portmapper}: add and plumb an event bus (#15359) Updates #15160 Change-Id: I2510fb4a8905fb0abe8a8e0c5b81adb15d50a6f8 Signed-off-by: M. J. Fromberger --- cmd/tailscale/depaware.txt | 18 +++++++++++++++--- net/portmapper/portmapper.go | 10 ++++++++++ wgengine/magicsock/magicsock.go | 15 +++++++++++++-- wgengine/userspace.go | 1 + 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt index 431bf7b71..be8f53a29 100644 --- a/cmd/tailscale/depaware.txt +++ b/cmd/tailscale/depaware.txt @@ -5,6 +5,10 @@ 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 + github.com/coder/websocket from tailscale.com/util/eventbus + github.com/coder/websocket/internal/errd from github.com/coder/websocket + github.com/coder/websocket/internal/util from github.com/coder/websocket + 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 @@ -89,6 +93,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/drive from tailscale.com/client/local+ tailscale.com/envknob from tailscale.com/client/local+ tailscale.com/envknob/featureknob from tailscale.com/client/web + tailscale.com/feature from tailscale.com/tsweb tailscale.com/feature/capture/dissector from tailscale.com/cmd/tailscale/cli tailscale.com/health from tailscale.com/net/tlsdial+ tailscale.com/health/healthmsg from tailscale.com/cmd/tailscale/cli @@ -131,7 +136,8 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/tstime from tailscale.com/control/controlhttp+ tailscale.com/tstime/mono from tailscale.com/tstime/rate tailscale.com/tstime/rate from tailscale.com/cmd/tailscale/cli+ - tailscale.com/tsweb/varz from tailscale.com/util/usermetric + tailscale.com/tsweb from tailscale.com/util/eventbus + tailscale.com/tsweb/varz from tailscale.com/util/usermetric+ tailscale.com/types/dnstype from tailscale.com/tailcfg+ tailscale.com/types/empty from tailscale.com/ipn tailscale.com/types/ipproto from tailscale.com/ipn+ @@ -156,6 +162,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep 💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting L 💣 tailscale.com/util/dirwalk from tailscale.com/metrics tailscale.com/util/dnsname from tailscale.com/cmd/tailscale/cli+ + tailscale.com/util/eventbus from tailscale.com/net/portmapper tailscale.com/util/groupmember from tailscale.com/client/web 💣 tailscale.com/util/hashx from tailscale.com/util/deephash tailscale.com/util/httpm from tailscale.com/client/tailscale+ @@ -166,6 +173,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/util/must from tailscale.com/clientupdate/distsign+ tailscale.com/util/nocasemaps from tailscale.com/types/ipproto tailscale.com/util/quarantine from tailscale.com/cmd/tailscale/cli + tailscale.com/util/rands from tailscale.com/tsweb tailscale.com/util/set from tailscale.com/derp+ tailscale.com/util/singleflight from tailscale.com/net/dnscache+ tailscale.com/util/slicesx from tailscale.com/net/dns/recursive+ @@ -328,7 +336,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep hash/crc32 from compress/gzip+ hash/maphash from go4.org/mem html from html/template+ - html/template from github.com/gorilla/csrf + html/template from github.com/gorilla/csrf+ image from github.com/skip2/go-qrcode+ image/color from github.com/skip2/go-qrcode+ image/png from github.com/skip2/go-qrcode @@ -352,7 +360,8 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep internal/nettrace from net+ internal/oserror from io/fs+ internal/poll from net+ - internal/profilerecord from runtime + internal/profile from net/http/pprof + internal/profilerecord from runtime+ internal/race from internal/poll+ internal/reflectlite from context+ internal/runtime/atomic from internal/runtime/exithook+ @@ -394,6 +403,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep net/http/httputil from tailscale.com/client/web+ net/http/internal from net/http+ net/http/internal/ascii from net/http+ + net/http/pprof from tailscale.com/tsweb net/netip from go4.org/netipx+ net/textproto from golang.org/x/net/http/httpguts+ net/url from crypto/x509+ @@ -408,6 +418,8 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep regexp/syntax from regexp runtime from archive/tar+ runtime/debug from tailscale.com+ + runtime/pprof from net/http/pprof + runtime/trace from net/http/pprof slices from tailscale.com/client/web+ sort from compress/flate+ strconv from archive/tar+ diff --git a/net/portmapper/portmapper.go b/net/portmapper/portmapper.go index b49a8f7bb..8fe9ba493 100644 --- a/net/portmapper/portmapper.go +++ b/net/portmapper/portmapper.go @@ -31,6 +31,7 @@ import ( "tailscale.com/types/logger" "tailscale.com/types/nettype" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" ) var disablePortMapperEnv = envknob.RegisterBool("TS_DISABLE_PORTMAPPER") @@ -84,6 +85,7 @@ const trustServiceStillAvailableDuration = 10 * time.Minute // Client is a port mapping client. type Client struct { + eventBus *eventbus.Bus logf logger.Logf netMon *netmon.Monitor // optional; nil means interfaces will be looked up on-demand controlKnobs *controlknobs.Knobs @@ -203,6 +205,13 @@ func (m *pmpMapping) Release(ctx context.Context) { // Config carries the settings for a [Client]. type Config struct { + // EventBus, if non-nil, is used for event publication and subscription by + // portmapper clients created from this config. + // + // TODO(creachadair): As of 2025-03-19 this is optional, but is intended to + // become required non-nil. + EventBus *eventbus.Bus + // Logf is called to generate text logs for the client. If nil, logger.Discard is used. Logf logger.Logf @@ -229,6 +238,7 @@ func NewClient(c Config) *Client { panic("nil netMon") } ret := &Client{ + eventBus: c.EventBus, logf: c.Logf, netMon: c.NetMon, ipAndGateway: netmon.LikelyHomeRouterIP, // TODO(bradfitz): move this to method on netMon diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index 62658cac4..8190fa145 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -56,6 +56,7 @@ import ( "tailscale.com/types/nettype" "tailscale.com/types/views" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" "tailscale.com/util/mak" "tailscale.com/util/ringbuffer" "tailscale.com/util/set" @@ -136,6 +137,7 @@ type Conn struct { // This block mirrors the contents and field order of the Options // struct. Initialized once at construction, then constant. + eventBus *eventbus.Bus logf logger.Logf epFunc func([]tailcfg.Endpoint) derpActiveFunc func() @@ -401,8 +403,15 @@ func (c *Conn) dlogf(format string, a ...any) { // Options contains options for Listen. type Options struct { - // Logf optionally provides a log function to use. - // Must not be nil. + // EventBus, if non-nil, is used for event publication and subscription by + // each Conn created from these Options. + // + // TODO(creachadair): As of 2025-03-19 this is optional, but is intended to + // become required non-nil. + EventBus *eventbus.Bus + + // Logf provides a log function to use. It must not be nil. + // Use [logger.Discard] to disrcard logs. Logf logger.Logf // Port is the port to listen on. @@ -529,6 +538,7 @@ func NewConn(opts Options) (*Conn, error) { } c := newConn(opts.logf()) + c.eventBus = opts.EventBus c.port.Store(uint32(opts.Port)) c.controlKnobs = opts.ControlKnobs c.epFunc = opts.endpointsFunc() @@ -545,6 +555,7 @@ func NewConn(opts Options) (*Conn, error) { DisableAll: func() bool { return opts.DisablePortMapper || c.onlyTCP443.Load() }, } c.portMapper = portmapper.NewClient(portmapper.Config{ + EventBus: c.eventBus, Logf: portmapperLogf, NetMon: opts.NetMon, DebugKnobs: portMapOpts, diff --git a/wgengine/userspace.go b/wgengine/userspace.go index 974959df7..201d7df51 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -404,6 +404,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) } } magicsockOpts := magicsock.Options{ + EventBus: e.eventBus, Logf: logf, Port: conf.ListenPort, EndpointsFunc: endpointsFn,