mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 11:05:45 +00:00
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>
This commit is contained in:
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 @@
|
||||
"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 @@
|
||||
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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
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 @@ func (m *Mon) RegisterChangeCallback(callback interfaces.ChangeFunc) (unregister
|
||||
// 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 @@ func (m *Mon) pollWallTime() {
|
||||
// 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 @@
|
||||
"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 @@
|
||||
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 @@
|
||||
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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
_ "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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
|
||||
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 @@
|
||||
"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 @@
|
||||
|
||||
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 @@
|
||||
// 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 @@
|
||||
"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 @@
|
||||
"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 @@ func TestRouterStates(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
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 @@
|
||||
|
||||
"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 @@
|
||||
|
||||
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 @@
|
||||
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
"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 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 @@
|
||||
"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 @@
|
||||
"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 @@
|
||||
|
||||
"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…
Reference in New Issue
Block a user