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 <mihai@tailscale.com>
pull/7908/head
Mihai Parparita 2 years ago committed by Mihai Parparita
parent 3ede3aafe4
commit 4722f7e322

@ -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

@ -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+

@ -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 {

@ -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+

@ -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)

@ -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 {

@ -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,

@ -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

@ -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)

@ -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:

@ -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())

@ -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) {

@ -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")

@ -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
}

@ -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

@ -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

@ -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

@ -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
}

@ -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

@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package monitor
package netmon
import (
"encoding/hex"

@ -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)

@ -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

@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package monitor
package netmon
import (
"net"

@ -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)
}

@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package monitor
package netmon
import (
"flag"

@ -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),

@ -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{}

@ -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

@ -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 {

@ -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()

@ -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

@ -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

@ -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"
)

@ -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"
)

@ -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"
)

@ -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"
)

@ -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"
)

@ -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)

@ -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)

@ -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

@ -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) {

@ -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)
}

@ -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) {

@ -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

@ -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)

@ -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
}

@ -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
}

@ -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: "),

@ -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) {

@ -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()

@ -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)

Loading…
Cancel
Save