From 4722f7e32283c383f397076799959e246103f02a Mon Sep 17 00:00:00 2001 From: Mihai Parparita Date: Tue, 18 Apr 2023 14:26:58 -0700 Subject: [PATCH] all: move network monitoring from wgengine/monitor to net/netmon We're using it in more and more places, and it's not really specific to our use of Wireguard (and does more just link/interface monitoring). Also removes the separate interface we had for it in sockstats -- it's a small enough package (we already pull in all of its dependencies via other paths) that it's not worth the extra complexity. Updates #7621 Updates #7850 Signed-off-by: Mihai Parparita --- cmd/derper/depaware.txt | 5 +- cmd/tailscale/depaware.txt | 3 +- cmd/tailscaled/debug.go | 10 +-- cmd/tailscaled/depaware.txt | 2 +- cmd/tailscaled/tailscaled.go | 24 +++--- control/controlclient/direct.go | 12 +-- ipn/ipnlocal/local.go | 16 ++-- ipn/ipnlocal/serve.go | 2 +- ipn/localapi/localapi.go | 8 +- logtail/logtail.go | 16 ++-- net/dns/manager.go | 6 +- net/dns/resolver/forwarder.go | 12 +-- net/dns/resolver/macios_ext.go | 4 +- net/dns/resolver/tsdns.go | 12 +-- net/dns/resolver/tsdns_test.go | 6 +- net/interfaces/interfaces.go | 6 -- net/interfaces/interfaces_linux.go | 4 +- .../monitor.go => net/netmon/netmon.go | 49 ++++++----- .../netmon/netmon_darwin.go | 4 +- .../netmon/netmon_darwin_test.go | 2 +- .../netmon/netmon_freebsd.go | 4 +- .../netmon/netmon_linux.go | 4 +- .../netmon/netmon_linux_test.go | 2 +- .../netmon/netmon_polling.go | 4 +- .../netmon/netmon_test.go | 2 +- .../netmon/netmon_windows.go | 4 +- {wgengine/monitor => net/netmon}/polling.go | 6 +- net/sockstats/sockstats.go | 15 +--- net/sockstats/sockstats_noop.go | 3 +- net/sockstats/sockstats_tsgo.go | 5 +- net/tsdial/tsdial.go | 44 +++++----- tsnet/tsnet.go | 18 ++-- .../tailscaled_deps_test_darwin.go | 2 +- .../tailscaled_deps_test_freebsd.go | 2 +- .../integration/tailscaled_deps_test_linux.go | 2 +- .../tailscaled_deps_test_openbsd.go | 2 +- .../tailscaled_deps_test_windows.go | 2 +- wgengine/bench/wg.go | 16 ++-- wgengine/magicsock/magicsock.go | 18 ++-- wgengine/router/router.go | 8 +- wgengine/router/router_darwin.go | 6 +- wgengine/router/router_default.go | 4 +- wgengine/router/router_freebsd.go | 6 +- wgengine/router/router_linux.go | 26 +++--- wgengine/router/router_linux_test.go | 8 +- wgengine/router/router_openbsd.go | 8 +- wgengine/router/router_userspace_bsd.go | 8 +- wgengine/router/router_windows.go | 8 +- wgengine/userspace.go | 82 +++++++++---------- wgengine/watchdog.go | 6 +- wgengine/wgengine.go | 8 +- 51 files changed, 266 insertions(+), 270 deletions(-) rename wgengine/monitor/monitor.go => net/netmon/netmon.go (87%) rename wgengine/monitor/monitor_darwin.go => net/netmon/netmon_darwin.go (98%) rename wgengine/monitor/monitor_darwin_test.go => net/netmon/netmon_darwin_test.go (97%) rename wgengine/monitor/monitor_freebsd.go => net/netmon/netmon_freebsd.go (94%) rename wgengine/monitor/monitor_linux.go => net/netmon/netmon_linux.go (99%) rename wgengine/monitor/monitor_linux_test.go => net/netmon/netmon_linux_test.go (99%) rename wgengine/monitor/monitor_polling.go => net/netmon/netmon_polling.go (86%) rename wgengine/monitor/monitor_test.go => net/netmon/netmon_test.go (99%) rename wgengine/monitor/monitor_windows.go => net/netmon/netmon_windows.go (98%) rename {wgengine/monitor => net/netmon}/polling.go (95%) diff --git a/cmd/derper/depaware.txt b/cmd/derper/depaware.txt index 7f60654b0..7e82305d1 100644 --- a/cmd/derper/depaware.txt +++ b/cmd/derper/depaware.txt @@ -16,7 +16,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa github.com/golang/protobuf/ptypes/timestamp from github.com/prometheus/client_model/go github.com/hdevalence/ed25519consensus from tailscale.com/tka L github.com/josharian/native from github.com/mdlayher/netlink+ - L 💣 github.com/jsimonetti/rtnetlink from tailscale.com/net/interfaces + L 💣 github.com/jsimonetti/rtnetlink from tailscale.com/net/interfaces+ L github.com/jsimonetti/rtnetlink/internal/unix from github.com/jsimonetti/rtnetlink github.com/klauspost/compress/flate from nhooyr.io/websocket github.com/matttproud/golang_protobuf_extensions/pbutil from github.com/prometheus/common/expfmt @@ -86,6 +86,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa 💣 tailscale.com/net/interfaces from tailscale.com/net/netns+ tailscale.com/net/netaddr from tailscale.com/ipn+ tailscale.com/net/netknob from tailscale.com/net/netns + tailscale.com/net/netmon from tailscale.com/net/sockstats tailscale.com/net/netns from tailscale.com/derp/derphttp tailscale.com/net/netutil from tailscale.com/client/tailscale tailscale.com/net/packet from tailscale.com/wgengine/filter @@ -129,7 +130,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa tailscale.com/util/lineread from tailscale.com/hostinfo+ tailscale.com/util/mak from tailscale.com/syncs+ tailscale.com/util/multierr from tailscale.com/health - tailscale.com/util/set from tailscale.com/health + tailscale.com/util/set from tailscale.com/health+ tailscale.com/util/singleflight from tailscale.com/net/dnscache tailscale.com/util/slicesx from tailscale.com/cmd/derper+ tailscale.com/util/vizerror from tailscale.com/tsweb diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt index 93d29fe20..b146ec567 100644 --- a/cmd/tailscale/depaware.txt +++ b/cmd/tailscale/depaware.txt @@ -13,7 +13,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep github.com/google/uuid from tailscale.com/util/quarantine+ github.com/hdevalence/ed25519consensus from tailscale.com/tka L github.com/josharian/native from github.com/mdlayher/netlink+ - L 💣 github.com/jsimonetti/rtnetlink from tailscale.com/net/interfaces + L 💣 github.com/jsimonetti/rtnetlink from tailscale.com/net/interfaces+ L github.com/jsimonetti/rtnetlink/internal/unix from github.com/jsimonetti/rtnetlink github.com/kballard/go-shellquote from tailscale.com/cmd/tailscale/cli github.com/klauspost/compress/flate from nhooyr.io/websocket @@ -74,6 +74,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/net/netcheck from tailscale.com/cmd/tailscale/cli tailscale.com/net/neterror from tailscale.com/net/netcheck+ tailscale.com/net/netknob from tailscale.com/net/netns + tailscale.com/net/netmon from tailscale.com/net/sockstats tailscale.com/net/netns from tailscale.com/derp/derphttp+ tailscale.com/net/netutil from tailscale.com/client/tailscale+ tailscale.com/net/packet from tailscale.com/wgengine/filter+ diff --git a/cmd/tailscaled/debug.go b/cmd/tailscaled/debug.go index 4cc3af129..8c1ad88b1 100644 --- a/cmd/tailscaled/debug.go +++ b/cmd/tailscaled/debug.go @@ -23,10 +23,10 @@ import ( "tailscale.com/derp/derphttp" "tailscale.com/ipn" "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" "tailscale.com/net/tshttpproxy" "tailscale.com/tailcfg" "tailscale.com/types/key" - "tailscale.com/wgengine/monitor" ) var debugArgs struct { @@ -42,7 +42,7 @@ var debugModeFunc = debugMode // so it can be addressable func debugMode(args []string) error { fs := flag.NewFlagSet("debug", flag.ExitOnError) fs.BoolVar(&debugArgs.ifconfig, "ifconfig", false, "If true, print network interface state") - fs.BoolVar(&debugArgs.monitor, "monitor", false, "If true, run link monitor forever. Precludes all other options.") + fs.BoolVar(&debugArgs.monitor, "monitor", false, "If true, run network monitor forever. Precludes all other options.") fs.BoolVar(&debugArgs.portmap, "portmap", false, "If true, run portmap debugging. Precludes all other options.") fs.StringVar(&debugArgs.getURL, "get-url", "", "If non-empty, fetch provided URL.") fs.StringVar(&debugArgs.derpCheck, "derp", "", "if non-empty, test a DERP ping via named region code") @@ -76,7 +76,7 @@ func runMonitor(ctx context.Context, loop bool) error { j, _ := json.MarshalIndent(st, "", " ") os.Stderr.Write(j) } - mon, err := monitor.New(log.Printf) + mon, err := netmon.New(log.Printf) if err != nil { return err } @@ -84,10 +84,10 @@ func runMonitor(ctx context.Context, loop bool) error { mon.RegisterChangeCallback(func(changed bool, st *interfaces.State) { if !changed { - log.Printf("Link monitor fired; no change") + log.Printf("Network monitor fired; no change") return } - log.Printf("Link monitor fired. New state:") + log.Printf("Network monitor fired. New state:") dump(st) }) if loop { diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index 1d53813d0..b51b3a3de 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -240,6 +240,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/net/netcheck from tailscale.com/wgengine/magicsock tailscale.com/net/neterror from tailscale.com/net/dns/resolver+ tailscale.com/net/netknob from tailscale.com/net/netns+ + tailscale.com/net/netmon from tailscale.com/cmd/tailscaled+ tailscale.com/net/netns from tailscale.com/derp/derphttp+ 💣 tailscale.com/net/netstat from tailscale.com/ipn/ipnauth+ tailscale.com/net/netutil from tailscale.com/ipn/ipnlocal+ @@ -324,7 +325,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/wgengine/capture from tailscale.com/ipn/ipnlocal+ tailscale.com/wgengine/filter from tailscale.com/control/controlclient+ 💣 tailscale.com/wgengine/magicsock from tailscale.com/ipn/ipnlocal+ - tailscale.com/wgengine/monitor from tailscale.com/control/controlclient+ tailscale.com/wgengine/netlog from tailscale.com/wgengine tailscale.com/wgengine/netstack from tailscale.com/cmd/tailscaled tailscale.com/wgengine/router from tailscale.com/ipn/ipnlocal+ diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go index 5db801fb7..3bae560a2 100644 --- a/cmd/tailscaled/tailscaled.go +++ b/cmd/tailscaled/tailscaled.go @@ -39,6 +39,7 @@ import ( "tailscale.com/logtail" "tailscale.com/net/dns" "tailscale.com/net/dnsfallback" + "tailscale.com/net/netmon" "tailscale.com/net/netns" "tailscale.com/net/proxymux" "tailscale.com/net/socks5" @@ -59,7 +60,6 @@ import ( "tailscale.com/version" "tailscale.com/version/distro" "tailscale.com/wgengine" - "tailscale.com/wgengine/monitor" "tailscale.com/wgengine/netstack" "tailscale.com/wgengine/router" ) @@ -451,18 +451,18 @@ func startIPNServer(ctx context.Context, logf logger.Logf, logID logid.PublicID) } func getLocalBackend(ctx context.Context, logf logger.Logf, logID logid.PublicID) (_ *ipnlocal.LocalBackend, retErr error) { - linkMon, err := monitor.New(logf) + netMon, err := netmon.New(logf) if err != nil { - return nil, fmt.Errorf("monitor.New: %w", err) + return nil, fmt.Errorf("netmon.New: %w", err) } if logPol != nil { - logPol.Logtail.SetLinkMonitor(linkMon) + logPol.Logtail.SetNetMon(netMon) } socksListener, httpProxyListener := mustStartProxyListeners(args.socksAddr, args.httpProxyAddr) dialer := &tsdial.Dialer{Logf: logf} // mutated below (before used) - e, onlyNetstack, err := createEngine(logf, linkMon, dialer) + e, onlyNetstack, err := createEngine(logf, netMon, dialer) if err != nil { return nil, fmt.Errorf("createEngine: %w", err) } @@ -551,14 +551,14 @@ func getLocalBackend(ctx context.Context, logf logger.Logf, logID logid.PublicID // // onlyNetstack is true if the user has explicitly requested that we use netstack // for all networking. -func createEngine(logf logger.Logf, linkMon *monitor.Mon, dialer *tsdial.Dialer) (e wgengine.Engine, onlyNetstack bool, err error) { +func createEngine(logf logger.Logf, netMon *netmon.Monitor, dialer *tsdial.Dialer) (e wgengine.Engine, onlyNetstack bool, err error) { if args.tunname == "" { return nil, false, errors.New("no --tun value specified") } var errs []error for _, name := range strings.Split(args.tunname, ",") { logf("wgengine.NewUserspaceEngine(tun %q) ...", name) - e, onlyNetstack, err = tryEngine(logf, linkMon, dialer, name) + e, onlyNetstack, err = tryEngine(logf, netMon, dialer, name) if err == nil { return e, onlyNetstack, nil } @@ -590,11 +590,11 @@ func handleSubnetsInNetstack() bool { var tstunNew = tstun.New -func tryEngine(logf logger.Logf, linkMon *monitor.Mon, dialer *tsdial.Dialer, name string) (e wgengine.Engine, onlyNetstack bool, err error) { +func tryEngine(logf logger.Logf, netMon *netmon.Monitor, dialer *tsdial.Dialer, name string) (e wgengine.Engine, onlyNetstack bool, err error) { conf := wgengine.Config{ - ListenPort: args.port, - LinkMonitor: linkMon, - Dialer: dialer, + ListenPort: args.port, + NetMon: netMon, + Dialer: dialer, } onlyNetstack = name == "userspace-networking" @@ -633,7 +633,7 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, dialer *tsdial.Dialer, na return e, false, err } - r, err := router.New(logf, dev, linkMon) + r, err := router.New(logf, dev, netMon) if err != nil { dev.Close() return nil, false, fmt.Errorf("creating router: %w", err) diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index 15c26cc78..85bd7f07b 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -37,6 +37,7 @@ import ( "tailscale.com/net/dnscache" "tailscale.com/net/dnsfallback" "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" "tailscale.com/net/netutil" "tailscale.com/net/tlsdial" "tailscale.com/net/tsdial" @@ -54,7 +55,6 @@ import ( "tailscale.com/util/multierr" "tailscale.com/util/singleflight" "tailscale.com/util/systemd" - "tailscale.com/wgengine/monitor" ) // Direct is the client that connects to a tailcontrol server for a node. @@ -67,7 +67,7 @@ type Direct struct { newDecompressor func() (Decompressor, error) keepAlive bool logf logger.Logf - linkMon *monitor.Mon // or nil + netMon *netmon.Monitor // or nil discoPubKey key.DiscoPublic getMachinePrivKey func() (key.MachinePrivate, error) debugFlags []string @@ -113,7 +113,7 @@ type Options struct { HTTPTestClient *http.Client // optional HTTP client to use (for tests only) NoiseTestClient *http.Client // optional HTTP client to use for noise RPCs (tests only) DebugFlags []string // debug settings to send to control - LinkMonitor *monitor.Mon // optional link monitor + NetMon *netmon.Monitor // optional network monitor PopBrowserURL func(url string) // optional func to open browser OnClientVersion func(*tailcfg.ClientVersion) // optional func to inform GUI of client version status OnControlTime func(time.Time) // optional func to notify callers of new time from control @@ -241,7 +241,7 @@ func NewDirect(opts Options) (*Direct, error) { discoPubKey: opts.DiscoPublicKey, debugFlags: opts.DebugFlags, keepSharerAndUserSplit: opts.KeepSharerAndUserSplit, - linkMon: opts.LinkMonitor, + netMon: opts.NetMon, skipIPForwardingCheck: opts.SkipIPForwardingCheck, pinger: opts.Pinger, popBrowser: opts.PopBrowserURL, @@ -871,8 +871,8 @@ func (c *Direct) sendMapRequest(ctx context.Context, maxPolls int, readOnly bool ReadOnly: readOnly && !allowStream, } var extraDebugFlags []string - if hi != nil && c.linkMon != nil && !c.skipIPForwardingCheck && - ipForwardingBroken(hi.RoutableIPs, c.linkMon.InterfaceState()) { + if hi != nil && c.netMon != nil && !c.skipIPForwardingCheck && + ipForwardingBroken(hi.RoutableIPs, c.netMon.InterfaceState()) { extraDebugFlags = append(extraDebugFlags, "warn-ip-forwarding-off") } if health.RouterHealth() != nil { diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 07decb04d..532e68d19 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -142,7 +142,7 @@ type LocalBackend struct { store ipn.StateStore dialer *tsdial.Dialer // non-nil backendLogID logid.PublicID - unregisterLinkMon func() + unregisterNetMon func() unregisterHealthWatch func() portpoll *portlist.Poller // may be nil portpollOnce sync.Once // guards starting readPoller @@ -330,12 +330,12 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, store ipn.StateStor b.statusChanged = sync.NewCond(&b.statusLock) b.e.SetStatusCallback(b.setWgengineStatus) - linkMon := e.GetLinkMonitor() - b.prevIfState = linkMon.InterfaceState() + netMon := e.GetNetMon() + b.prevIfState = netMon.InterfaceState() // Call our linkChange code once with the current state, and // then also whenever it changes: - b.linkChange(false, linkMon.InterfaceState()) - b.unregisterLinkMon = linkMon.RegisterChangeCallback(b.linkChange) + b.linkChange(false, netMon.InterfaceState()) + b.unregisterNetMon = netMon.RegisterChangeCallback(b.linkChange) b.unregisterHealthWatch = health.RegisterWatcher(b.onHealthChange) @@ -499,7 +499,7 @@ func (b *LocalBackend) maybePauseControlClientLocked() { b.cc.SetPaused((b.state == ipn.Stopped && b.netMap != nil) || !networkUp) } -// linkChange is our link monitor callback, called whenever the network changes. +// linkChange is our network monitor callback, called whenever the network changes. // major is whether ifst is different than earlier. func (b *LocalBackend) linkChange(major bool, ifst *interfaces.State) { b.mu.Lock() @@ -576,7 +576,7 @@ func (b *LocalBackend) Shutdown() { b.sockstatLogger.Shutdown() } - b.unregisterLinkMon() + b.unregisterNetMon() b.unregisterHealthWatch() if cc != nil { cc.Shutdown() @@ -1423,7 +1423,7 @@ func (b *LocalBackend) Start(opts ipn.Options) error { HTTPTestClient: httpTestClient, DiscoPublicKey: discoPublic, DebugFlags: debugFlags, - LinkMonitor: b.e.GetLinkMonitor(), + NetMon: b.e.GetNetMon(), Pinger: b, PopBrowserURL: b.tellClientToBrowseToURL, OnClientVersion: b.onClientVersion, diff --git a/ipn/ipnlocal/serve.go b/ipn/ipnlocal/serve.go index a9058dec2..e6d1d0104 100644 --- a/ipn/ipnlocal/serve.go +++ b/ipn/ipnlocal/serve.go @@ -143,7 +143,7 @@ func (s *serveListener) Run() { } func (s *serveListener) shouldWarnAboutListenError(err error) bool { - if !s.b.e.GetLinkMonitor().InterfaceState().HasIP(s.ap.Addr()) { + if !s.b.e.GetNetMon().InterfaceState().HasIP(s.ap.Addr()) { // Machine likely doesn't have IPv6 enabled (or the IP is still being // assigned). No need to warn. Notably, WSL2 (Issue 6303). return false diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go index 5d7b36e9a..be15cbe08 100644 --- a/ipn/localapi/localapi.go +++ b/ipn/localapi/localapi.go @@ -34,6 +34,7 @@ import ( "tailscale.com/ipn/ipnlocal" "tailscale.com/ipn/ipnstate" "tailscale.com/logtail" + "tailscale.com/net/netmon" "tailscale.com/net/netutil" "tailscale.com/net/portmapper" "tailscale.com/tailcfg" @@ -46,7 +47,6 @@ import ( "tailscale.com/util/httpm" "tailscale.com/util/mak" "tailscale.com/version" - "tailscale.com/wgengine/monitor" ) type localAPIHandler func(*Handler, http.ResponseWriter, *http.Request) @@ -695,7 +695,7 @@ func (h *Handler) serveDebugPortmap(w http.ResponseWriter, r *http.Request) { }) defer c.Close() - linkMon, err := monitor.New(logger.WithPrefix(logf, "monitor: ")) + netMon, err := netmon.New(logger.WithPrefix(logf, "monitor: ")) if err != nil { logf("error creating monitor: %v", err) return @@ -707,14 +707,14 @@ func (h *Handler) serveDebugPortmap(w http.ResponseWriter, r *http.Request) { self = netip.MustParseAddr(b) return gw, self, true } - return linkMon.GatewayAndSelfIP() + return netMon.GatewayAndSelfIP() } c.SetGatewayLookupFunc(gatewayAndSelfIP) gw, selfIP, ok := gatewayAndSelfIP() if !ok { - logf("no gateway or self IP; %v", linkMon.InterfaceState()) + logf("no gateway or self IP; %v", netMon.InterfaceState()) return } logf("gw=%v; self=%v", gw, selfIP) diff --git a/logtail/logtail.go b/logtail/logtail.go index 92e544fed..3c32df3a0 100644 --- a/logtail/logtail.go +++ b/logtail/logtail.go @@ -24,11 +24,11 @@ import ( "tailscale.com/envknob" "tailscale.com/logtail/backoff" "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" "tailscale.com/net/sockstats" tslogger "tailscale.com/types/logger" "tailscale.com/types/logid" "tailscale.com/util/set" - "tailscale.com/wgengine/monitor" ) // DefaultHost is the default host name to upload logs to when @@ -179,7 +179,7 @@ type Logger struct { url string lowMem bool skipClientTime bool - linkMonitor *monitor.Mon + netMonitor *netmon.Monitor buffer Buffer drainWake chan struct{} // signal to speed up drain flushDelayFn func() time.Duration // negative or zero return value to upload aggressively, or >0 to batch at this delay @@ -214,12 +214,12 @@ func (l *Logger) SetVerbosityLevel(level int) { atomic.StoreInt64(&l.stderrLevel, int64(level)) } -// SetLinkMonitor sets the optional the link monitor. +// SetNetMon sets the optional the network monitor. // // It should not be changed concurrently with log writes and should // only be set once. -func (l *Logger) SetLinkMonitor(lm *monitor.Mon) { - l.linkMonitor = lm +func (l *Logger) SetNetMon(lm *netmon.Monitor) { + l.netMonitor = lm } // SetSockstatsLabel sets the label used in sockstat logs to identify network traffic from this logger. @@ -403,16 +403,16 @@ func (l *Logger) uploading(ctx context.Context) { } func (l *Logger) internetUp() bool { - if l.linkMonitor == nil { + if l.netMonitor == nil { // No way to tell, so assume it is. return true } - return l.linkMonitor.InterfaceState().AnyInterfaceUp() + return l.netMonitor.InterfaceState().AnyInterfaceUp() } func (l *Logger) awaitInternetUp(ctx context.Context) { upc := make(chan bool, 1) - defer l.linkMonitor.RegisterChangeCallback(func(changed bool, st *interfaces.State) { + defer l.netMonitor.RegisterChangeCallback(func(changed bool, st *interfaces.State) { if st.AnyInterfaceUp() { select { case upc <- true: diff --git a/net/dns/manager.go b/net/dns/manager.go index a4366d52d..e909cbe5d 100644 --- a/net/dns/manager.go +++ b/net/dns/manager.go @@ -18,12 +18,12 @@ import ( "golang.org/x/exp/slices" "tailscale.com/health" "tailscale.com/net/dns/resolver" + "tailscale.com/net/netmon" "tailscale.com/net/tsdial" "tailscale.com/types/dnstype" "tailscale.com/types/logger" "tailscale.com/util/clientmetric" "tailscale.com/util/dnsname" - "tailscale.com/wgengine/monitor" ) var ( @@ -64,14 +64,14 @@ type Manager struct { } // NewManagers created a new manager from the given config. -func NewManager(logf logger.Logf, oscfg OSConfigurator, linkMon *monitor.Mon, dialer *tsdial.Dialer, linkSel resolver.ForwardLinkSelector) *Manager { +func NewManager(logf logger.Logf, oscfg OSConfigurator, netMon *netmon.Monitor, dialer *tsdial.Dialer, linkSel resolver.ForwardLinkSelector) *Manager { if dialer == nil { panic("nil Dialer") } logf = logger.WithPrefix(logf, "dns: ") m := &Manager{ logf: logf, - resolver: resolver.New(logf, linkMon, linkSel, dialer), + resolver: resolver.New(logf, netMon, linkSel, dialer), os: oscfg, } m.ctx, m.ctxCancel = context.WithCancel(context.Background()) diff --git a/net/dns/resolver/forwarder.go b/net/dns/resolver/forwarder.go index 0a02e6edb..3373ffcf1 100644 --- a/net/dns/resolver/forwarder.go +++ b/net/dns/resolver/forwarder.go @@ -25,6 +25,7 @@ import ( "tailscale.com/net/dns/publicdns" "tailscale.com/net/dnscache" "tailscale.com/net/neterror" + "tailscale.com/net/netmon" "tailscale.com/net/netns" "tailscale.com/net/sockstats" "tailscale.com/net/tsdial" @@ -34,7 +35,6 @@ import ( "tailscale.com/util/cloudenv" "tailscale.com/util/dnsname" "tailscale.com/version" - "tailscale.com/wgengine/monitor" ) // headerBytes is the number of bytes in a DNS message header. @@ -176,7 +176,7 @@ type resolverAndDelay struct { // forwarder forwards DNS packets to a number of upstream nameservers. type forwarder struct { logf logger.Logf - linkMon *monitor.Mon + netMon *netmon.Monitor linkSel ForwardLinkSelector // TODO(bradfitz): remove this when tsdial.Dialer absorbs it dialer *tsdial.Dialer @@ -206,10 +206,10 @@ func init() { rand.Seed(time.Now().UnixNano()) } -func newForwarder(logf logger.Logf, linkMon *monitor.Mon, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *forwarder { +func newForwarder(logf logger.Logf, netMon *netmon.Monitor, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *forwarder { f := &forwarder{ logf: logger.WithPrefix(logf, "forward: "), - linkMon: linkMon, + netMon: netMon, linkSel: linkSel, dialer: dialer, } @@ -355,7 +355,7 @@ func (f *forwarder) packetListener(ip netip.Addr) (nettype.PacketListenerWithNet return stdNetPacketListener, nil } lc := new(net.ListenConfig) - if err := initListenConfig(lc, f.linkMon, linkName); err != nil { + if err := initListenConfig(lc, f.netMon, linkName); err != nil { return nil, err } return nettype.MakePacketListenerWithNetIP(lc), nil @@ -763,7 +763,7 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo } } -var initListenConfig func(_ *net.ListenConfig, _ *monitor.Mon, tunName string) error +var initListenConfig func(_ *net.ListenConfig, _ *netmon.Monitor, tunName string) error // nameFromQuery extracts the normalized query name from bs. func nameFromQuery(bs []byte) (dnsname.FQDN, error) { diff --git a/net/dns/resolver/macios_ext.go b/net/dns/resolver/macios_ext.go index ee3efa666..895b8714f 100644 --- a/net/dns/resolver/macios_ext.go +++ b/net/dns/resolver/macios_ext.go @@ -9,15 +9,15 @@ import ( "errors" "net" + "tailscale.com/net/netmon" "tailscale.com/net/netns" - "tailscale.com/wgengine/monitor" ) func init() { initListenConfig = initListenConfigNetworkExtension } -func initListenConfigNetworkExtension(nc *net.ListenConfig, mon *monitor.Mon, tunName string) error { +func initListenConfigNetworkExtension(nc *net.ListenConfig, mon *netmon.Monitor, tunName string) error { nif, ok := mon.InterfaceState().Interface[tunName] if !ok { return errors.New("utun not found") diff --git a/net/dns/resolver/tsdns.go b/net/dns/resolver/tsdns.go index 6344328b7..4ed0e57ba 100644 --- a/net/dns/resolver/tsdns.go +++ b/net/dns/resolver/tsdns.go @@ -26,6 +26,7 @@ import ( "tailscale.com/envknob" "tailscale.com/net/dns/resolvconffile" "tailscale.com/net/netaddr" + "tailscale.com/net/netmon" "tailscale.com/net/tsaddr" "tailscale.com/net/tsdial" "tailscale.com/syncs" @@ -34,7 +35,6 @@ import ( "tailscale.com/util/clientmetric" "tailscale.com/util/cloudenv" "tailscale.com/util/dnsname" - "tailscale.com/wgengine/monitor" ) const dnsSymbolicFQDN = "magicdns.localhost-tailscale-daemon." @@ -179,7 +179,7 @@ func WriteRoutes(w *bufio.Writer, routes map[dnsname.FQDN][]*dnstype.Resolver) { // it delegates to upstream nameservers if any are set. type Resolver struct { logf logger.Logf - linkMon *monitor.Mon // or nil + netMon *netmon.Monitor // or nil dialer *tsdial.Dialer // non-nil saveConfigForTests func(cfg Config) // used in tests to capture resolver config // forwarder forwards requests to upstream nameservers. @@ -205,20 +205,20 @@ type ForwardLinkSelector interface { } // New returns a new resolver. -// linkMon optionally specifies a link monitor to use for socket rebinding. -func New(logf logger.Logf, linkMon *monitor.Mon, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *Resolver { +// netMon optionally specifies a network monitor to use for socket rebinding. +func New(logf logger.Logf, netMon *netmon.Monitor, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *Resolver { if dialer == nil { panic("nil Dialer") } r := &Resolver{ logf: logger.WithPrefix(logf, "resolver: "), - linkMon: linkMon, + netMon: netMon, closed: make(chan struct{}), hostToIP: map[dnsname.FQDN][]netip.Addr{}, ipToHost: map[netip.Addr]dnsname.FQDN{}, dialer: dialer, } - r.forwarder = newForwarder(r.logf, linkMon, linkSel, dialer) + r.forwarder = newForwarder(r.logf, netMon, linkSel, dialer) return r } diff --git a/net/dns/resolver/tsdns_test.go b/net/dns/resolver/tsdns_test.go index 9862da8fb..ad3d36c99 100644 --- a/net/dns/resolver/tsdns_test.go +++ b/net/dns/resolver/tsdns_test.go @@ -24,11 +24,11 @@ import ( miekdns "github.com/miekg/dns" dns "golang.org/x/net/dns/dnsmessage" "tailscale.com/net/netaddr" + "tailscale.com/net/netmon" "tailscale.com/net/tsdial" "tailscale.com/tstest" "tailscale.com/types/dnstype" "tailscale.com/util/dnsname" - "tailscale.com/wgengine/monitor" ) var ( @@ -315,7 +315,7 @@ func TestRDNSNameToIPv6(t *testing.T) { } func newResolver(t testing.TB) *Resolver { - return New(t.Logf, nil /* no link monitor */, nil /* no link selector */, new(tsdial.Dialer)) + return New(t.Logf, nil /* no network monitor */, nil /* no link selector */, new(tsdial.Dialer)) } func TestResolveLocal(t *testing.T) { @@ -997,7 +997,7 @@ func TestMarshalResponseFormatError(t *testing.T) { func TestForwardLinkSelection(t *testing.T) { configCall := make(chan string, 1) - tstest.Replace(t, &initListenConfig, func(nc *net.ListenConfig, mon *monitor.Mon, tunName string) error { + tstest.Replace(t, &initListenConfig, func(nc *net.ListenConfig, mon *netmon.Monitor, tunName string) error { select { case configCall <- tunName: return nil diff --git a/net/interfaces/interfaces.go b/net/interfaces/interfaces.go index fbde96190..e9e21eabc 100644 --- a/net/interfaces/interfaces.go +++ b/net/interfaces/interfaces.go @@ -351,12 +351,6 @@ func (s *State) String() string { return sb.String() } -// ChangeFunc is a callback function (usually registered with -// wgengine/monitor's Mon) that's called when the network -// changed. The changed parameter is whether the network changed -// enough for State to have changed since the last callback. -type ChangeFunc func(changed bool, state *State) - // An InterfaceFilter indicates whether EqualFiltered should use i when deciding whether two States are equal. // ips are all the IPPrefixes associated with i. type InterfaceFilter func(i Interface, ips []netip.Prefix) bool diff --git a/net/interfaces/interfaces_linux.go b/net/interfaces/interfaces_linux.go index b7d405828..cad5d4a4a 100644 --- a/net/interfaces/interfaces_linux.go +++ b/net/interfaces/interfaces_linux.go @@ -167,8 +167,8 @@ func defaultRoute() (d DefaultRouteDetails, err error) { // /proc/net/route. Use netlink to find the default route. // // TODO(bradfitz): this allocates a fair bit. We should track - // this in wgengine/monitor instead and have - // interfaces.GetState take a link monitor or similar so the + // this in net/interfaces/monitor instead and have + // interfaces.GetState take a netmon.Monitor or similar so the // routing table can be cached and the monitor's existing // subscription to route changes can update the cached state, // rather than querying the whole thing every time like diff --git a/wgengine/monitor/monitor.go b/net/netmon/netmon.go similarity index 87% rename from wgengine/monitor/monitor.go rename to net/netmon/netmon.go index fc318d358..4de8a47f4 100644 --- a/wgengine/monitor/monitor.go +++ b/net/netmon/netmon.go @@ -4,7 +4,7 @@ // Package monitor provides facilities for monitoring network // interface and route changes. It primarily exists to know when // portable devices move between different networks. -package monitor +package netmon import ( "encoding/json" @@ -48,15 +48,15 @@ type osMon interface { IsInterestingInterface(iface string) bool } -// Mon represents a monitoring instance. -type Mon struct { +// Monitor represents a monitoring instance. +type Monitor struct { logf logger.Logf om osMon // nil means not supported on this platform change chan struct{} stop chan struct{} // closed on Stop mu sync.Mutex // guards all following fields - cbs set.HandleSet[interfaces.ChangeFunc] + cbs set.HandleSet[ChangeFunc] ruleDelCB set.HandleSet[RuleDeleteCallback] ifState *interfaces.State gwValid bool // whether gw and gwSelfIP are valid @@ -70,12 +70,17 @@ type Mon struct { timeJumped bool // whether we need to send a changed=true after a big time jump } +// ChangeFunc is a callback function registered with Monitor that's called when the +// network changed. The changed parameter is whether the network changed +// enough for State to have changed since the last callback. +type ChangeFunc func(changed bool, state *interfaces.State) + // New instantiates and starts a monitoring instance. // The returned monitor is inactive until it's started by the Start method. // Use RegisterChangeCallback to get notified of network changes. -func New(logf logger.Logf) (*Mon, error) { +func New(logf logger.Logf) (*Monitor, error) { logf = logger.WithPrefix(logf, "monitor: ") - m := &Mon{ + m := &Monitor{ logf: logf, change: make(chan struct{}, 1), stop: make(chan struct{}), @@ -102,13 +107,13 @@ func New(logf logger.Logf) (*Mon, error) { // interfaces. // // The returned value is owned by Mon; it must not be modified. -func (m *Mon) InterfaceState() *interfaces.State { +func (m *Monitor) InterfaceState() *interfaces.State { m.mu.Lock() defer m.mu.Unlock() return m.ifState } -func (m *Mon) interfaceStateUncached() (*interfaces.State, error) { +func (m *Monitor) interfaceStateUncached() (*interfaces.State, error) { return interfaces.GetState() } @@ -117,7 +122,7 @@ func (m *Mon) interfaceStateUncached() (*interfaces.State, error) { // // It's the same as interfaces.LikelyHomeRouterIP, but it caches the // result until the monitor detects a network change. -func (m *Mon) GatewayAndSelfIP() (gw, myIP netip.Addr, ok bool) { +func (m *Monitor) GatewayAndSelfIP() (gw, myIP netip.Addr, ok bool) { m.mu.Lock() defer m.mu.Unlock() if m.gwValid { @@ -133,7 +138,7 @@ func (m *Mon) GatewayAndSelfIP() (gw, myIP netip.Addr, ok bool) { // RegisterChangeCallback adds callback to the set of parties to be // notified (in their own goroutine) when the network state changes. // To remove this callback, call unregister (or close the monitor). -func (m *Mon) RegisterChangeCallback(callback interfaces.ChangeFunc) (unregister func()) { +func (m *Monitor) RegisterChangeCallback(callback ChangeFunc) (unregister func()) { m.mu.Lock() defer m.mu.Unlock() handle := m.cbs.Add(callback) @@ -153,7 +158,7 @@ type RuleDeleteCallback func(table uint8, priority uint32) // RegisterRuleDeleteCallback adds callback to the set of parties to be // notified (in their own goroutine) when a Linux ip rule is deleted. // To remove this callback, call unregister (or close the monitor). -func (m *Mon) RegisterRuleDeleteCallback(callback RuleDeleteCallback) (unregister func()) { +func (m *Monitor) RegisterRuleDeleteCallback(callback RuleDeleteCallback) (unregister func()) { m.mu.Lock() defer m.mu.Unlock() handle := m.ruleDelCB.Add(callback) @@ -166,7 +171,7 @@ func (m *Mon) RegisterRuleDeleteCallback(callback RuleDeleteCallback) (unregiste // Start starts the monitor. // A monitor can only be started & closed once. -func (m *Mon) Start() { +func (m *Monitor) Start() { m.mu.Lock() defer m.mu.Unlock() if m.started || m.closed { @@ -187,7 +192,7 @@ func (m *Mon) Start() { } // Close closes the monitor. -func (m *Mon) Close() error { +func (m *Monitor) Close() error { m.mu.Lock() if m.closed { m.mu.Unlock() @@ -218,7 +223,7 @@ func (m *Mon) Close() error { // change and re-check the state of the network. Any registered // ChangeFunc callbacks will be called within the event coalescing // period (under a fraction of a second). -func (m *Mon) InjectEvent() { +func (m *Monitor) InjectEvent() { select { case m.change <- struct{}{}: default: @@ -228,7 +233,7 @@ func (m *Mon) InjectEvent() { } } -func (m *Mon) stopped() bool { +func (m *Monitor) stopped() bool { select { case <-m.stop: return true @@ -239,7 +244,7 @@ func (m *Mon) stopped() bool { // pump continuously retrieves messages from the connection, notifying // the change channel of changes, and stopping when a stop is issued. -func (m *Mon) pump() { +func (m *Monitor) pump() { defer m.goroutines.Done() for !m.stopped() { msg, err := m.om.Receive() @@ -263,7 +268,7 @@ func (m *Mon) pump() { } } -func (m *Mon) notifyRuleDeleted(rdm ipRuleDeletedMessage) { +func (m *Monitor) notifyRuleDeleted(rdm ipRuleDeletedMessage) { m.mu.Lock() defer m.mu.Unlock() for _, cb := range m.ruleDelCB { @@ -274,13 +279,13 @@ func (m *Mon) notifyRuleDeleted(rdm ipRuleDeletedMessage) { // isInterestingInterface reports whether the provided interface should be // considered when checking for network state changes. // The ips parameter should be the IPs of the provided interface. -func (m *Mon) isInterestingInterface(i interfaces.Interface, ips []netip.Prefix) bool { +func (m *Monitor) isInterestingInterface(i interfaces.Interface, ips []netip.Prefix) bool { return m.om.IsInterestingInterface(i.Name) && interfaces.UseInterestingInterfaces(i, ips) } // debounce calls the callback function with a delay between events // and exits when a stop is issued. -func (m *Mon) debounce() { +func (m *Monitor) debounce() { defer m.goroutines.Done() for { select { @@ -343,7 +348,7 @@ func wallTime() time.Time { return time.Now().Round(0) } -func (m *Mon) pollWallTime() { +func (m *Monitor) pollWallTime() { m.mu.Lock() defer m.mu.Unlock() if m.closed { @@ -365,7 +370,7 @@ const shouldMonitorTimeJump = runtime.GOOS != "android" && runtime.GOOS != "ios" // checkWallTimeAdvanceLocked reports whether wall time jumped more than 150% of // pollWallTimeInterval, indicating we probably just came out of sleep. Once a // time jump is detected it must be reset by calling resetTimeJumpedLocked. -func (m *Mon) checkWallTimeAdvanceLocked() bool { +func (m *Monitor) checkWallTimeAdvanceLocked() bool { if !shouldMonitorTimeJump { panic("unreachable") // if callers are correct } @@ -378,7 +383,7 @@ func (m *Mon) checkWallTimeAdvanceLocked() bool { } // resetTimeJumpedLocked consumes the signal set by checkWallTimeAdvanceLocked. -func (m *Mon) resetTimeJumpedLocked() { +func (m *Monitor) resetTimeJumpedLocked() { m.timeJumped = false } diff --git a/wgengine/monitor/monitor_darwin.go b/net/netmon/netmon_darwin.go similarity index 98% rename from wgengine/monitor/monitor_darwin.go rename to net/netmon/netmon_darwin.go index da720f5d6..cc6301125 100644 --- a/wgengine/monitor/monitor_darwin.go +++ b/net/netmon/netmon_darwin.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package monitor +package netmon import ( "fmt" @@ -24,7 +24,7 @@ type unspecifiedMessage struct{} func (unspecifiedMessage) ignore() bool { return false } -func newOSMon(logf logger.Logf, _ *Mon) (osMon, error) { +func newOSMon(logf logger.Logf, _ *Monitor) (osMon, error) { fd, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, 0) if err != nil { return nil, err diff --git a/wgengine/monitor/monitor_darwin_test.go b/net/netmon/netmon_darwin_test.go similarity index 97% rename from wgengine/monitor/monitor_darwin_test.go rename to net/netmon/netmon_darwin_test.go index 375cd87a7..84c67cf6f 100644 --- a/wgengine/monitor/monitor_darwin_test.go +++ b/net/netmon/netmon_darwin_test.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package monitor +package netmon import ( "encoding/hex" diff --git a/wgengine/monitor/monitor_freebsd.go b/net/netmon/netmon_freebsd.go similarity index 94% rename from wgengine/monitor/monitor_freebsd.go rename to net/netmon/netmon_freebsd.go index 5acd8e098..30480a1d3 100644 --- a/wgengine/monitor/monitor_freebsd.go +++ b/net/netmon/netmon_freebsd.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package monitor +package netmon import ( "bufio" @@ -24,7 +24,7 @@ type devdConn struct { conn net.Conn } -func newOSMon(logf logger.Logf, m *Mon) (osMon, error) { +func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { conn, err := net.Dial("unixpacket", "/var/run/devd.seqpacket.pipe") if err != nil { logf("devd dial error: %v, falling back to polling method", err) diff --git a/wgengine/monitor/monitor_linux.go b/net/netmon/netmon_linux.go similarity index 99% rename from wgengine/monitor/monitor_linux.go rename to net/netmon/netmon_linux.go index 4acb79887..9065b9953 100644 --- a/wgengine/monitor/monitor_linux.go +++ b/net/netmon/netmon_linux.go @@ -3,7 +3,7 @@ //go:build !android -package monitor +package netmon import ( "net" @@ -44,7 +44,7 @@ type nlConn struct { addrCache map[uint32]map[netip.Addr]bool } -func newOSMon(logf logger.Logf, m *Mon) (osMon, error) { +func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { conn, err := netlink.Dial(unix.NETLINK_ROUTE, &netlink.Config{ // Routes get us most of the events of interest, but we need // address as well to cover things like DHCP deciding to give diff --git a/wgengine/monitor/monitor_linux_test.go b/net/netmon/netmon_linux_test.go similarity index 99% rename from wgengine/monitor/monitor_linux_test.go rename to net/netmon/netmon_linux_test.go index 56beb0019..d09fac26a 100644 --- a/wgengine/monitor/monitor_linux_test.go +++ b/net/netmon/netmon_linux_test.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package monitor +package netmon import ( "net" diff --git a/wgengine/monitor/monitor_polling.go b/net/netmon/netmon_polling.go similarity index 86% rename from wgengine/monitor/monitor_polling.go rename to net/netmon/netmon_polling.go index 0f807d053..3d6f94731 100644 --- a/wgengine/monitor/monitor_polling.go +++ b/net/netmon/netmon_polling.go @@ -3,13 +3,13 @@ //go:build (!linux && !freebsd && !windows && !darwin) || android -package monitor +package netmon import ( "tailscale.com/types/logger" ) -func newOSMon(logf logger.Logf, m *Mon) (osMon, error) { +func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { return newPollingMon(logf, m) } diff --git a/wgengine/monitor/monitor_test.go b/net/netmon/netmon_test.go similarity index 99% rename from wgengine/monitor/monitor_test.go rename to net/netmon/netmon_test.go index 30c0ac52a..7d2516404 100644 --- a/wgengine/monitor/monitor_test.go +++ b/net/netmon/netmon_test.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package monitor +package netmon import ( "flag" diff --git a/wgengine/monitor/monitor_windows.go b/net/netmon/netmon_windows.go similarity index 98% rename from wgengine/monitor/monitor_windows.go rename to net/netmon/netmon_windows.go index 6242d7418..836922206 100644 --- a/wgengine/monitor/monitor_windows.go +++ b/net/netmon/netmon_windows.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package monitor +package netmon import ( "context" @@ -44,7 +44,7 @@ type winMon struct { noDeadlockTicker *time.Ticker } -func newOSMon(logf logger.Logf, _ *Mon) (osMon, error) { +func newOSMon(logf logger.Logf, _ *Monitor) (osMon, error) { m := &winMon{ logf: logf, messagec: make(chan eventMessage, 1), diff --git a/wgengine/monitor/polling.go b/net/netmon/polling.go similarity index 95% rename from wgengine/monitor/polling.go rename to net/netmon/polling.go index b1028de73..9332bdde9 100644 --- a/wgengine/monitor/polling.go +++ b/net/netmon/polling.go @@ -3,7 +3,7 @@ //go:build !windows && !darwin -package monitor +package netmon import ( "bytes" @@ -17,7 +17,7 @@ import ( "tailscale.com/types/logger" ) -func newPollingMon(logf logger.Logf, m *Mon) (osMon, error) { +func newPollingMon(logf logger.Logf, m *Monitor) (osMon, error) { return &pollingMon{ logf: logf, m: m, @@ -30,7 +30,7 @@ func newPollingMon(logf logger.Logf, m *Mon) (osMon, error) { // of anything to subscribe to. type pollingMon struct { logf logger.Logf - m *Mon + m *Monitor closeOnce sync.Once stop chan struct{} diff --git a/net/sockstats/sockstats.go b/net/sockstats/sockstats.go index 468fa7005..e968ac7bf 100644 --- a/net/sockstats/sockstats.go +++ b/net/sockstats/sockstats.go @@ -11,7 +11,7 @@ package sockstats import ( "context" - "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" "tailscale.com/types/logger" ) @@ -107,17 +107,10 @@ func GetValidation() *ValidationSockStats { return getValidation() } -// LinkMonitor is the interface for the parts of wgengine/mointor's Mon that we -// need, to avoid the dependency. -type LinkMonitor interface { - InterfaceState() *interfaces.State - RegisterChangeCallback(interfaces.ChangeFunc) (unregister func()) -} - -// SetLinkMonitor configures the sockstats package to monitor the active +// SetNetMon configures the sockstats package to monitor the active // interface, so that per-interface stats can be collected. -func SetLinkMonitor(lm LinkMonitor) { - setLinkMonitor(lm) +func SetNetMon(lm *netmon.Monitor) { + setNetMon(lm) } // DebugInfo returns a string containing debug information about the tracked diff --git a/net/sockstats/sockstats_noop.go b/net/sockstats/sockstats_noop.go index 96fd0da9b..46b5ceaef 100644 --- a/net/sockstats/sockstats_noop.go +++ b/net/sockstats/sockstats_noop.go @@ -8,6 +8,7 @@ package sockstats import ( "context" + "tailscale.com/net/netmon" "tailscale.com/types/logger" ) @@ -29,7 +30,7 @@ func getValidation() *ValidationSockStats { return nil } -func setLinkMonitor(lm LinkMonitor) { +func setNetMon(lm *netmon.Monitor) { } func debugInfo() string { diff --git a/net/sockstats/sockstats_tsgo.go b/net/sockstats/sockstats_tsgo.go index de162e7e7..e2dd05f22 100644 --- a/net/sockstats/sockstats_tsgo.go +++ b/net/sockstats/sockstats_tsgo.go @@ -16,6 +16,7 @@ import ( "time" "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" "tailscale.com/types/logger" "tailscale.com/util/clientmetric" ) @@ -84,7 +85,7 @@ func withSockStats(ctx context.Context, label Label, logf logger.Logf) context.C rxBytesCellularMetric: clientmetric.NewCounter(fmt.Sprintf("sockstats_rx_bytes_cellular_%s", label)), } - // We might be called before setLinkMonitor has been called (and we've + // We might be called before setNetMon has been called (and we've // had a chance to populate knownInterfaces). In that case, we'll have // to get the list of interfaces ourselves. if len(sockStats.knownInterfaces) == 0 { @@ -248,7 +249,7 @@ func getValidation() *ValidationSockStats { return r } -func setLinkMonitor(lm LinkMonitor) { +func setNetMon(lm *netmon.Monitor) { sockStats.mu.Lock() defer sockStats.mu.Unlock() diff --git a/net/tsdial/tsdial.go b/net/tsdial/tsdial.go index 3c3db009c..bb1dde397 100644 --- a/net/tsdial/tsdial.go +++ b/net/tsdial/tsdial.go @@ -20,11 +20,11 @@ import ( "tailscale.com/net/dnscache" "tailscale.com/net/interfaces" "tailscale.com/net/netknob" + "tailscale.com/net/netmon" "tailscale.com/net/netns" "tailscale.com/types/logger" "tailscale.com/types/netmap" "tailscale.com/util/mak" - "tailscale.com/wgengine/monitor" ) // Dialer dials out of tailscaled, while taking care of details while @@ -50,16 +50,16 @@ type Dialer struct { netnsDialerOnce sync.Once netnsDialer netns.Dialer - mu sync.Mutex - closed bool - dns dnsMap - tunName string // tun device name - linkMon *monitor.Mon - linkMonUnregister func() - exitDNSDoHBase string // non-empty if DoH-proxying exit node in use; base URL+path (without '?') - dnsCache *dnscache.MessageCache // nil until first non-empty SetExitDNSDoH - nextSysConnID int - activeSysConns map[int]net.Conn // active connections not yet closed + mu sync.Mutex + closed bool + dns dnsMap + tunName string // tun device name + netMon *netmon.Monitor + netMonUnregister func() + exitDNSDoHBase string // non-empty if DoH-proxying exit node in use; base URL+path (without '?') + dnsCache *dnscache.MessageCache // nil until first non-empty SetExitDNSDoH + nextSysConnID int + activeSysConns map[int]net.Conn // active connections not yet closed } // sysConn wraps a net.Conn that was created using d.SystemDial. @@ -117,9 +117,9 @@ func (d *Dialer) Close() error { d.mu.Lock() defer d.mu.Unlock() d.closed = true - if d.linkMonUnregister != nil { - d.linkMonUnregister() - d.linkMonUnregister = nil + if d.netMonUnregister != nil { + d.netMonUnregister() + d.netMonUnregister = nil } for _, c := range d.activeSysConns { c.Close() @@ -128,15 +128,15 @@ func (d *Dialer) Close() error { return nil } -func (d *Dialer) SetLinkMonitor(mon *monitor.Mon) { +func (d *Dialer) SetNetMon(mon *netmon.Monitor) { d.mu.Lock() defer d.mu.Unlock() - if d.linkMonUnregister != nil { - go d.linkMonUnregister() - d.linkMonUnregister = nil + if d.netMonUnregister != nil { + go d.netMonUnregister() + d.netMonUnregister = nil } - d.linkMon = mon - d.linkMonUnregister = d.linkMon.RegisterChangeCallback(d.linkChanged) + d.netMon = mon + d.netMonUnregister = d.netMon.RegisterChangeCallback(d.linkChanged) } func (d *Dialer) linkChanged(major bool, state *interfaces.State) { @@ -163,10 +163,10 @@ func (d *Dialer) closeSysConn(id int) { } func (d *Dialer) interfaceIndexLocked(ifName string) (index int, ok bool) { - if d.linkMon == nil { + if d.netMon == nil { return 0, false } - st := d.linkMon.InterfaceState() + st := d.netMon.InterfaceState() iface, ok := st.Interface[ifName] if !ok { return 0, false diff --git a/tsnet/tsnet.go b/tsnet/tsnet.go index 7e5236d8f..6e7db9440 100644 --- a/tsnet/tsnet.go +++ b/tsnet/tsnet.go @@ -42,6 +42,7 @@ import ( "tailscale.com/logtail" "tailscale.com/logtail/filch" "tailscale.com/net/memnet" + "tailscale.com/net/netmon" "tailscale.com/net/proxymux" "tailscale.com/net/socks5" "tailscale.com/net/tsdial" @@ -51,7 +52,6 @@ import ( "tailscale.com/types/nettype" "tailscale.com/util/mak" "tailscale.com/wgengine" - "tailscale.com/wgengine/monitor" "tailscale.com/wgengine/netstack" ) @@ -106,7 +106,7 @@ type Server struct { initErr error lb *ipnlocal.LocalBackend netstack *netstack.Impl - linkMon *monitor.Mon + netMon *netmon.Monitor rootPath string // the state directory hostname string shutdownCtx context.Context @@ -356,8 +356,8 @@ func (s *Server) Close() error { if s.lb != nil { s.lb.Shutdown() } - if s.linkMon != nil { - s.linkMon.Close() + if s.netMon != nil { + s.netMon.Close() } if s.dialer != nil { s.dialer.Close() @@ -476,17 +476,17 @@ func (s *Server) start() (reterr error) { return err } - s.linkMon, err = monitor.New(logf) + s.netMon, err = netmon.New(logf) if err != nil { return err } - closePool.add(s.linkMon) + closePool.add(s.netMon) s.dialer = &tsdial.Dialer{Logf: logf} // mutated below (before used) eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{ - ListenPort: 0, - LinkMonitor: s.linkMon, - Dialer: s.dialer, + ListenPort: 0, + NetMon: s.netMon, + Dialer: s.dialer, }) if err != nil { return err diff --git a/tstest/integration/tailscaled_deps_test_darwin.go b/tstest/integration/tailscaled_deps_test_darwin.go index edb891ee9..ed2e6e5ff 100644 --- a/tstest/integration/tailscaled_deps_test_darwin.go +++ b/tstest/integration/tailscaled_deps_test_darwin.go @@ -24,6 +24,7 @@ import ( _ "tailscale.com/net/dns" _ "tailscale.com/net/dnsfallback" _ "tailscale.com/net/interfaces" + _ "tailscale.com/net/netmon" _ "tailscale.com/net/netns" _ "tailscale.com/net/proxymux" _ "tailscale.com/net/socks5" @@ -47,7 +48,6 @@ import ( _ "tailscale.com/version" _ "tailscale.com/version/distro" _ "tailscale.com/wgengine" - _ "tailscale.com/wgengine/monitor" _ "tailscale.com/wgengine/netstack" _ "tailscale.com/wgengine/router" ) diff --git a/tstest/integration/tailscaled_deps_test_freebsd.go b/tstest/integration/tailscaled_deps_test_freebsd.go index edb891ee9..ed2e6e5ff 100644 --- a/tstest/integration/tailscaled_deps_test_freebsd.go +++ b/tstest/integration/tailscaled_deps_test_freebsd.go @@ -24,6 +24,7 @@ import ( _ "tailscale.com/net/dns" _ "tailscale.com/net/dnsfallback" _ "tailscale.com/net/interfaces" + _ "tailscale.com/net/netmon" _ "tailscale.com/net/netns" _ "tailscale.com/net/proxymux" _ "tailscale.com/net/socks5" @@ -47,7 +48,6 @@ import ( _ "tailscale.com/version" _ "tailscale.com/version/distro" _ "tailscale.com/wgengine" - _ "tailscale.com/wgengine/monitor" _ "tailscale.com/wgengine/netstack" _ "tailscale.com/wgengine/router" ) diff --git a/tstest/integration/tailscaled_deps_test_linux.go b/tstest/integration/tailscaled_deps_test_linux.go index edb891ee9..ed2e6e5ff 100644 --- a/tstest/integration/tailscaled_deps_test_linux.go +++ b/tstest/integration/tailscaled_deps_test_linux.go @@ -24,6 +24,7 @@ import ( _ "tailscale.com/net/dns" _ "tailscale.com/net/dnsfallback" _ "tailscale.com/net/interfaces" + _ "tailscale.com/net/netmon" _ "tailscale.com/net/netns" _ "tailscale.com/net/proxymux" _ "tailscale.com/net/socks5" @@ -47,7 +48,6 @@ import ( _ "tailscale.com/version" _ "tailscale.com/version/distro" _ "tailscale.com/wgengine" - _ "tailscale.com/wgengine/monitor" _ "tailscale.com/wgengine/netstack" _ "tailscale.com/wgengine/router" ) diff --git a/tstest/integration/tailscaled_deps_test_openbsd.go b/tstest/integration/tailscaled_deps_test_openbsd.go index edb891ee9..ed2e6e5ff 100644 --- a/tstest/integration/tailscaled_deps_test_openbsd.go +++ b/tstest/integration/tailscaled_deps_test_openbsd.go @@ -24,6 +24,7 @@ import ( _ "tailscale.com/net/dns" _ "tailscale.com/net/dnsfallback" _ "tailscale.com/net/interfaces" + _ "tailscale.com/net/netmon" _ "tailscale.com/net/netns" _ "tailscale.com/net/proxymux" _ "tailscale.com/net/socks5" @@ -47,7 +48,6 @@ import ( _ "tailscale.com/version" _ "tailscale.com/version/distro" _ "tailscale.com/wgengine" - _ "tailscale.com/wgengine/monitor" _ "tailscale.com/wgengine/netstack" _ "tailscale.com/wgengine/router" ) diff --git a/tstest/integration/tailscaled_deps_test_windows.go b/tstest/integration/tailscaled_deps_test_windows.go index ef995d88e..33620c9d9 100644 --- a/tstest/integration/tailscaled_deps_test_windows.go +++ b/tstest/integration/tailscaled_deps_test_windows.go @@ -32,6 +32,7 @@ import ( _ "tailscale.com/net/dns" _ "tailscale.com/net/dnsfallback" _ "tailscale.com/net/interfaces" + _ "tailscale.com/net/netmon" _ "tailscale.com/net/netns" _ "tailscale.com/net/proxymux" _ "tailscale.com/net/socks5" @@ -56,7 +57,6 @@ import ( _ "tailscale.com/version/distro" _ "tailscale.com/wf" _ "tailscale.com/wgengine" - _ "tailscale.com/wgengine/monitor" _ "tailscale.com/wgengine/netstack" _ "tailscale.com/wgengine/router" ) diff --git a/wgengine/bench/wg.go b/wgengine/bench/wg.go index c7b01af28..dd73d560f 100644 --- a/wgengine/bench/wg.go +++ b/wgengine/bench/wg.go @@ -39,10 +39,10 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip. traf: traf, } e1, err := wgengine.NewUserspaceEngine(l1, wgengine.Config{ - Router: router.NewFake(l1), - LinkMonitor: nil, - ListenPort: 0, - Tun: t1, + Router: router.NewFake(l1), + NetMon: nil, + ListenPort: 0, + Tun: t1, }) if err != nil { log.Fatalf("e1 init: %v", err) @@ -63,10 +63,10 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip. traf: traf, } e2, err := wgengine.NewUserspaceEngine(l2, wgengine.Config{ - Router: router.NewFake(l2), - LinkMonitor: nil, - ListenPort: 0, - Tun: t2, + Router: router.NewFake(l2), + NetMon: nil, + ListenPort: 0, + Tun: t2, }) if err != nil { log.Fatalf("e2 init: %v", err) diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index d8595e2ba..5a0a2bf0d 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -47,6 +47,7 @@ import ( "tailscale.com/net/netaddr" "tailscale.com/net/netcheck" "tailscale.com/net/neterror" + "tailscale.com/net/netmon" "tailscale.com/net/netns" "tailscale.com/net/packet" "tailscale.com/net/portmapper" @@ -69,7 +70,6 @@ import ( "tailscale.com/util/uniq" "tailscale.com/version" "tailscale.com/wgengine/capture" - "tailscale.com/wgengine/monitor" ) const ( @@ -279,7 +279,7 @@ type Conn struct { idleFunc func() time.Duration // nil means unknown testOnlyPacketListener nettype.PacketListener noteRecvActivity func(key.NodePublic) // or nil, see Options.NoteRecvActivity - linkMon *monitor.Mon // or nil + netMon *netmon.Monitor // or nil // ================================================================ // No locking required to access these fields, either because @@ -573,9 +573,9 @@ type Options struct { // not hold Conn.mu while calling it. NoteRecvActivity func(key.NodePublic) - // LinkMonitor is the link monitor to use. + // NetMon is the network monitor to use. // With one, the portmapper won't be used. - LinkMonitor *monitor.Mon + NetMon *netmon.Monitor } func (o *Options) logf() logger.Logf { @@ -643,10 +643,10 @@ func NewConn(opts Options) (*Conn, error) { c.testOnlyPacketListener = opts.TestOnlyPacketListener c.noteRecvActivity = opts.NoteRecvActivity c.portMapper = portmapper.NewClient(logger.WithPrefix(c.logf, "portmapper: "), nil, c.onPortMapChanged) - if opts.LinkMonitor != nil { - c.portMapper.SetGatewayLookupFunc(opts.LinkMonitor.GatewayAndSelfIP) + if opts.NetMon != nil { + c.portMapper.SetGatewayLookupFunc(opts.NetMon.GatewayAndSelfIP) } - c.linkMon = opts.LinkMonitor + c.netMon = opts.NetMon if err := c.rebind(keepCurrentPort); err != nil { return nil, err @@ -3369,8 +3369,8 @@ func (c *Conn) Rebind() { } var ifIPs []netip.Prefix - if c.linkMon != nil { - st := c.linkMon.InterfaceState() + if c.netMon != nil { + st := c.netMon.InterfaceState() defIf := st.DefaultRouteInterface ifIPs = st.InterfaceIPs[defIf] c.logf("Rebind; defIf=%q, ips=%v", defIf, ifIPs) diff --git a/wgengine/router/router.go b/wgengine/router/router.go index f6e55b7d9..11668a70e 100644 --- a/wgengine/router/router.go +++ b/wgengine/router/router.go @@ -10,9 +10,9 @@ import ( "reflect" "github.com/tailscale/wireguard-go/tun" + "tailscale.com/net/netmon" "tailscale.com/types/logger" "tailscale.com/types/preftype" - "tailscale.com/wgengine/monitor" ) // Router is responsible for managing the system network stack. @@ -34,11 +34,11 @@ type Router interface { // New returns a new Router for the current platform, using the // provided tun device. // -// If linkMon is nil, it's not used. It's currently (2021-07-20) only +// If netMon is nil, it's not used. It's currently (2021-07-20) only // used on Linux in some situations. -func New(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) { +func New(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor) (Router, error) { logf = logger.WithPrefix(logf, "router: ") - return newUserspaceRouter(logf, tundev, linkMon) + return newUserspaceRouter(logf, tundev, netMon) } // Cleanup restores the system network configuration to its original state diff --git a/wgengine/router/router_darwin.go b/wgengine/router/router_darwin.go index 96076e6e6..38fc78f82 100644 --- a/wgengine/router/router_darwin.go +++ b/wgengine/router/router_darwin.go @@ -5,12 +5,12 @@ package router import ( "github.com/tailscale/wireguard-go/tun" + "tailscale.com/net/netmon" "tailscale.com/types/logger" - "tailscale.com/wgengine/monitor" ) -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) { - return newUserspaceBSDRouter(logf, tundev, linkMon) +func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor) (Router, error) { + return newUserspaceBSDRouter(logf, tundev, netMon) } func cleanup(logger.Logf, string) { diff --git a/wgengine/router/router_default.go b/wgengine/router/router_default.go index 4fcf65ad8..9fee5d8f2 100644 --- a/wgengine/router/router_default.go +++ b/wgengine/router/router_default.go @@ -10,11 +10,11 @@ import ( "runtime" "github.com/tailscale/wireguard-go/tun" + "tailscale.com/net/netmon" "tailscale.com/types/logger" - "tailscale.com/wgengine/monitor" ) -func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, linkMon *monitor.Mon) (Router, error) { +func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor) (Router, error) { return nil, fmt.Errorf("unsupported OS %q", runtime.GOOS) } diff --git a/wgengine/router/router_freebsd.go b/wgengine/router/router_freebsd.go index 13e886969..84dccbca0 100644 --- a/wgengine/router/router_freebsd.go +++ b/wgengine/router/router_freebsd.go @@ -5,8 +5,8 @@ package router import ( "github.com/tailscale/wireguard-go/tun" + "tailscale.com/net/netmon" "tailscale.com/types/logger" - "tailscale.com/wgengine/monitor" ) // For now this router only supports the userspace WireGuard implementations. @@ -14,8 +14,8 @@ import ( // Work is currently underway for an in-kernel FreeBSD implementation of wireguard // https://svnweb.freebsd.org/base?view=revision&revision=357986 -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) { - return newUserspaceBSDRouter(logf, tundev, linkMon) +func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor) (Router, error) { + return newUserspaceBSDRouter(logf, tundev, netMon) } func cleanup(logf logger.Logf, interfaceName string) { diff --git a/wgengine/router/router_linux.go b/wgengine/router/router_linux.go index 1fd733fa0..85c3799c4 100644 --- a/wgengine/router/router_linux.go +++ b/wgengine/router/router_linux.go @@ -24,12 +24,12 @@ import ( "golang.org/x/sys/unix" "golang.org/x/time/rate" "tailscale.com/envknob" + "tailscale.com/net/netmon" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" "tailscale.com/types/preftype" "tailscale.com/util/multierr" "tailscale.com/version/distro" - "tailscale.com/wgengine/monitor" ) const ( @@ -94,8 +94,8 @@ type linuxRouter struct { closed atomic.Bool logf func(fmt string, args ...any) tunname string - linkMon *monitor.Mon - unregLinkMon func() + netMon *netmon.Monitor + unregNetMon func() addrs map[netip.Prefix]bool routes map[netip.Prefix]bool localRoutes map[netip.Prefix]bool @@ -121,7 +121,7 @@ type linuxRouter struct { cmd commandRunner } -func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, linkMon *monitor.Mon) (Router, error) { +func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor) (Router, error) { tunname, err := tunDev.Name() if err != nil { return nil, err @@ -156,15 +156,15 @@ func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, linkMon *monitor.Mo ambientCapNetAdmin: useAmbientCaps(), } - return newUserspaceRouterAdvanced(logf, tunname, linkMon, ipt4, ipt6, cmd, supportsV6, supportsV6NAT) + return newUserspaceRouterAdvanced(logf, tunname, netMon, ipt4, ipt6, cmd, supportsV6, supportsV6NAT) } -func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, linkMon *monitor.Mon, netfilter4, netfilter6 netfilterRunner, cmd commandRunner, supportsV6, supportsV6NAT bool) (Router, error) { +func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon.Monitor, netfilter4, netfilter6 netfilterRunner, cmd commandRunner, supportsV6, supportsV6NAT bool) (Router, error) { r := &linuxRouter{ logf: logf, tunname: tunname, netfilterMode: netfilterOff, - linkMon: linkMon, + netMon: netMon, v6Available: supportsV6, v6NATAvailable: supportsV6NAT, @@ -336,8 +336,8 @@ func (r *linuxRouter) useIPCommand() bool { return !ok } -// onIPRuleDeleted is the callback from the link monitor for when an IP policy -// rule is deleted. See Issue 1591. +// onIPRuleDeleted is the callback from the network monitor for when an IP +// policy rule is deleted. See Issue 1591. // // If an ip rule is deleted (with pref number 52xx, as Tailscale sets), then // set a timer to restore our rules, in case they were deleted. The timer lets @@ -372,8 +372,8 @@ func (r *linuxRouter) onIPRuleDeleted(table uint8, priority uint32) { } func (r *linuxRouter) Up() error { - if r.unregLinkMon == nil && r.linkMon != nil { - r.unregLinkMon = r.linkMon.RegisterRuleDeleteCallback(r.onIPRuleDeleted) + if r.unregNetMon == nil && r.netMon != nil { + r.unregNetMon = r.netMon.RegisterRuleDeleteCallback(r.onIPRuleDeleted) } if err := r.addIPRules(); err != nil { return fmt.Errorf("adding IP rules: %w", err) @@ -390,8 +390,8 @@ func (r *linuxRouter) Up() error { func (r *linuxRouter) Close() error { r.closed.Store(true) - if r.unregLinkMon != nil { - r.unregLinkMon() + if r.unregNetMon != nil { + r.unregNetMon() } if err := r.downInterface(); err != nil { return err diff --git a/wgengine/router/router_linux_test.go b/wgengine/router/router_linux_test.go index 1883e6b4b..acd2e6c10 100644 --- a/wgengine/router/router_linux_test.go +++ b/wgengine/router/router_linux_test.go @@ -21,9 +21,9 @@ import ( "github.com/tailscale/wireguard-go/tun" "github.com/vishvananda/netlink" "golang.org/x/exp/slices" + "tailscale.com/net/netmon" "tailscale.com/tstest" "tailscale.com/types/logger" - "tailscale.com/wgengine/monitor" ) func TestRouterStates(t *testing.T) { @@ -320,7 +320,7 @@ ip route add throw 192.168.0.0/24 table 52` + basic, }, } - mon, err := monitor.New(logger.Discard) + mon, err := netmon.New(logger.Discard) if err != nil { t.Fatal(err) } @@ -659,7 +659,7 @@ func createTestTUN(t *testing.T) tun.Device { type linuxTest struct { tun tun.Device - mon *monitor.Mon + mon *netmon.Monitor r *linuxRouter logOutput tstest.MemLogger } @@ -684,7 +684,7 @@ func newLinuxRootTest(t *testing.T) *linuxTest { logf := lt.logOutput.Logf - mon, err := monitor.New(logger.Discard) + mon, err := netmon.New(logger.Discard) if err != nil { lt.Close() t.Fatal(err) diff --git a/wgengine/router/router_openbsd.go b/wgengine/router/router_openbsd.go index 6bbd0e06c..c23d37e47 100644 --- a/wgengine/router/router_openbsd.go +++ b/wgengine/router/router_openbsd.go @@ -12,8 +12,8 @@ import ( "github.com/tailscale/wireguard-go/tun" "go4.org/netipx" + "tailscale.com/net/netmon" "tailscale.com/types/logger" - "tailscale.com/wgengine/monitor" ) // For now this router only supports the WireGuard userspace implementation. @@ -22,14 +22,14 @@ import ( type openbsdRouter struct { logf logger.Logf - linkMon *monitor.Mon + netMon *netmon.Monitor tunname string local4 netip.Prefix local6 netip.Prefix routes map[netip.Prefix]struct{} } -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) { +func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor) (Router, error) { tunname, err := tundev.Name() if err != nil { return nil, err @@ -37,7 +37,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mo return &openbsdRouter{ logf: logf, - linkMon: linkMon, + netMon: netMon, tunname: tunname, }, nil } diff --git a/wgengine/router/router_userspace_bsd.go b/wgengine/router/router_userspace_bsd.go index b1f2d6367..61c06037d 100644 --- a/wgengine/router/router_userspace_bsd.go +++ b/wgengine/router/router_userspace_bsd.go @@ -14,21 +14,21 @@ import ( "github.com/tailscale/wireguard-go/tun" "go4.org/netipx" + "tailscale.com/net/netmon" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" "tailscale.com/version" - "tailscale.com/wgengine/monitor" ) type userspaceBSDRouter struct { logf logger.Logf - linkMon *monitor.Mon + netMon *netmon.Monitor tunname string local []netip.Prefix routes map[netip.Prefix]bool } -func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) { +func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor) (Router, error) { tunname, err := tundev.Name() if err != nil { return nil, err @@ -36,7 +36,7 @@ func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor return &userspaceBSDRouter{ logf: logf, - linkMon: linkMon, + netMon: netMon, tunname: tunname, }, nil } diff --git a/wgengine/router/router_windows.go b/wgengine/router/router_windows.go index 8657bf26b..155c29b46 100644 --- a/wgengine/router/router_windows.go +++ b/wgengine/router/router_windows.go @@ -22,19 +22,19 @@ import ( "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" "tailscale.com/logtail/backoff" "tailscale.com/net/dns" + "tailscale.com/net/netmon" "tailscale.com/types/logger" - "tailscale.com/wgengine/monitor" ) type winRouter struct { logf func(fmt string, args ...any) - linkMon *monitor.Mon // may be nil + netMon *netmon.Monitor // may be nil nativeTun *tun.NativeTun routeChangeCallback *winipcfg.RouteChangeCallback firewall *firewallTweaker } -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) { +func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor) (Router, error) { nativeTun := tundev.(*tun.NativeTun) luid := winipcfg.LUID(nativeTun.LUID()) guid, err := luid.GUID() @@ -44,7 +44,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mo return &winRouter{ logf: logf, - linkMon: linkMon, + netMon: netMon, nativeTun: nativeTun, firewall: &firewallTweaker{ logf: logger.WithPrefix(logf, "firewall: "), diff --git a/wgengine/userspace.go b/wgengine/userspace.go index d60c12dff..c7caf1492 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -28,6 +28,7 @@ import ( "tailscale.com/net/dns/resolver" "tailscale.com/net/flowtrack" "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" "tailscale.com/net/packet" "tailscale.com/net/sockstats" "tailscale.com/net/tsaddr" @@ -48,7 +49,6 @@ import ( "tailscale.com/wgengine/capture" "tailscale.com/wgengine/filter" "tailscale.com/wgengine/magicsock" - "tailscale.com/wgengine/monitor" "tailscale.com/wgengine/netlog" "tailscale.com/wgengine/router" "tailscale.com/wgengine/wgcfg" @@ -84,21 +84,21 @@ const statusPollInterval = 1 * time.Minute const networkLoggerUploadTimeout = 5 * time.Second type userspaceEngine struct { - logf logger.Logf - wgLogger *wglog.Logger //a wireguard-go logging wrapper - reqCh chan struct{} - waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool - timeNow func() mono.Time - tundev *tstun.Wrapper - wgdev *device.Device - router router.Router - confListenPort uint16 // original conf.ListenPort - dns *dns.Manager - magicConn *magicsock.Conn - linkMon *monitor.Mon - linkMonOwned bool // whether we created linkMon (and thus need to close it) - linkMonUnregister func() // unsubscribes from changes; used regardless of linkMonOwned - birdClient BIRDClient // or nil + logf logger.Logf + wgLogger *wglog.Logger //a wireguard-go logging wrapper + reqCh chan struct{} + waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool + timeNow func() mono.Time + tundev *tstun.Wrapper + wgdev *device.Device + router router.Router + confListenPort uint16 // original conf.ListenPort + dns *dns.Manager + magicConn *magicsock.Conn + netMon *netmon.Monitor + netMonOwned bool // whether we created netMon (and thus need to close it) + netMonUnregister func() // unsubscribes from changes; used regardless of netMonOwned + birdClient BIRDClient // or nil testMaybeReconfigHook func() // for tests; if non-nil, fires if maybeReconfigWireguardLocked called @@ -199,9 +199,9 @@ type Config struct { // If nil, a fake OSConfigurator that does nothing is used. DNS dns.OSConfigurator - // LinkMonitor optionally provides an existing link monitor to re-use. - // If nil, a new link monitor is created. - LinkMonitor *monitor.Mon + // NetMon optionally provides an existing network monitor to re-use. + // If nil, a new network monitor is created. + NetMon *netmon.Monitor // Dialer is the dialer to use for outbound connections. // If nil, a new Dialer is created @@ -316,34 +316,34 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) e.isLocalAddr.Store(tsaddr.NewContainsIPFunc(nil)) e.isDNSIPOverTailscale.Store(tsaddr.NewContainsIPFunc(nil)) - if conf.LinkMonitor != nil { - e.linkMon = conf.LinkMonitor + if conf.NetMon != nil { + e.netMon = conf.NetMon } else { - mon, err := monitor.New(logf) + mon, err := netmon.New(logf) if err != nil { return nil, err } closePool.add(mon) - e.linkMon = mon - e.linkMonOwned = true + e.netMon = mon + e.netMonOwned = true } tunName, _ := conf.Tun.Name() conf.Dialer.SetTUNName(tunName) - conf.Dialer.SetLinkMonitor(e.linkMon) - e.dns = dns.NewManager(logf, conf.DNS, e.linkMon, conf.Dialer, fwdDNSLinkSelector{e, tunName}) + conf.Dialer.SetNetMon(e.netMon) + e.dns = dns.NewManager(logf, conf.DNS, e.netMon, conf.Dialer, fwdDNSLinkSelector{e, tunName}) // TODO: there's probably a better place for this - sockstats.SetLinkMonitor(e.linkMon) + sockstats.SetNetMon(e.netMon) - logf("link state: %+v", e.linkMon.InterfaceState()) + logf("link state: %+v", e.netMon.InterfaceState()) - unregisterMonWatch := e.linkMon.RegisterChangeCallback(func(changed bool, st *interfaces.State) { + unregisterMonWatch := e.netMon.RegisterChangeCallback(func(changed bool, st *interfaces.State) { tshttpproxy.InvalidateCache() e.linkChange(changed, st) }) closePool.addFunc(unregisterMonWatch) - e.linkMonUnregister = unregisterMonWatch + e.netMonUnregister = unregisterMonWatch endpointsFn := func(endpoints []tailcfg.Endpoint) { e.mu.Lock() @@ -359,7 +359,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) DERPActiveFunc: e.RequestStatus, IdleFunc: e.tundev.IdleDuration, NoteRecvActivity: e.noteRecvActivity, - LinkMonitor: e.linkMon, + NetMon: e.netMon, } var err error @@ -368,7 +368,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) return nil, fmt.Errorf("wgengine: %v", err) } closePool.add(e.magicConn) - e.magicConn.SetNetworkUp(e.linkMon.InterfaceState().AnyInterfaceUp()) + e.magicConn.SetNetworkUp(e.netMon.InterfaceState().AnyInterfaceUp()) tsTUNDev.SetDiscoKey(e.magicConn.DiscoPublicKey()) @@ -455,8 +455,8 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) if err := e.router.Set(nil); err != nil { return nil, fmt.Errorf("router.Set(nil): %w", err) } - e.logf("Starting link monitor...") - e.linkMon.Start() + e.logf("Starting network monitor...") + e.netMon.Start() e.logf("Engine created.") return e, nil @@ -1094,9 +1094,9 @@ func (e *userspaceEngine) Close() { r := bufio.NewReader(strings.NewReader("")) e.wgdev.IpcSetOperation(r) e.magicConn.Close() - e.linkMonUnregister() - if e.linkMonOwned { - e.linkMon.Close() + e.netMonUnregister() + if e.netMonOwned { + e.netMon.Close() } e.dns.Down() e.router.Close() @@ -1119,15 +1119,15 @@ func (e *userspaceEngine) Wait() { <-e.waitCh } -func (e *userspaceEngine) GetLinkMonitor() *monitor.Mon { - return e.linkMon +func (e *userspaceEngine) GetNetMon() *netmon.Monitor { + return e.netMon } // LinkChange signals a network change event. It's currently -// (2021-03-03) only called on Android. On other platforms, linkMon +// (2021-03-03) only called on Android. On other platforms, netMon // generates link change events for us. func (e *userspaceEngine) LinkChange(_ bool) { - e.linkMon.InjectEvent() + e.netMon.InjectEvent() } func (e *userspaceEngine) linkChange(changed bool, cur *interfaces.State) { diff --git a/wgengine/watchdog.go b/wgengine/watchdog.go index c0129bd14..76abfa8cc 100644 --- a/wgengine/watchdog.go +++ b/wgengine/watchdog.go @@ -18,6 +18,7 @@ import ( "tailscale.com/ipn/ipnstate" "tailscale.com/net/dns" "tailscale.com/net/dns/resolver" + "tailscale.com/net/netmon" "tailscale.com/net/tstun" "tailscale.com/tailcfg" "tailscale.com/types/key" @@ -25,7 +26,6 @@ import ( "tailscale.com/wgengine/capture" "tailscale.com/wgengine/filter" "tailscale.com/wgengine/magicsock" - "tailscale.com/wgengine/monitor" "tailscale.com/wgengine/router" "tailscale.com/wgengine/wgcfg" ) @@ -126,8 +126,8 @@ func (e *watchdogEngine) watchdog(name string, fn func()) { func (e *watchdogEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCfg *dns.Config, debug *tailcfg.Debug) error { return e.watchdogErr("Reconfig", func() error { return e.wrap.Reconfig(cfg, routerCfg, dnsCfg, debug) }) } -func (e *watchdogEngine) GetLinkMonitor() *monitor.Mon { - return e.wrap.GetLinkMonitor() +func (e *watchdogEngine) GetNetMon() *netmon.Monitor { + return e.wrap.GetNetMon() } func (e *watchdogEngine) GetFilter() *filter.Filter { return e.wrap.GetFilter() diff --git a/wgengine/wgengine.go b/wgengine/wgengine.go index 4178ec619..4d4e240c1 100644 --- a/wgengine/wgengine.go +++ b/wgengine/wgengine.go @@ -10,12 +10,12 @@ import ( "tailscale.com/ipn/ipnstate" "tailscale.com/net/dns" + "tailscale.com/net/netmon" "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/types/netmap" "tailscale.com/wgengine/capture" "tailscale.com/wgengine/filter" - "tailscale.com/wgengine/monitor" "tailscale.com/wgengine/router" "tailscale.com/wgengine/wgcfg" ) @@ -92,8 +92,8 @@ type Engine interface { // WireGuard status changes. SetStatusCallback(StatusCallback) - // GetLinkMonitor returns the link monitor. - GetLinkMonitor() *monitor.Mon + // GetNetMon returns the network monitor. + GetNetMon() *netmon.Monitor // RequestStatus requests a WireGuard status update right // away, sent to the callback registered via SetStatusCallback. @@ -119,7 +119,7 @@ type Engine interface { // // Deprecated: don't use this method. It was removed shortly // before the Tailscale 1.6 release when we remembered that - // Android doesn't use the Linux-based link monitor and has + // Android doesn't use the Linux-based network monitor and has // its own mechanism that uses LinkChange. Android is the only // caller of this method now. Don't add more. LinkChange(isExpensive bool)