mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +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/golang/protobuf/ptypes/timestamp from github.com/prometheus/client_model/go
|
||||||
github.com/hdevalence/ed25519consensus from tailscale.com/tka
|
github.com/hdevalence/ed25519consensus from tailscale.com/tka
|
||||||
L github.com/josharian/native from github.com/mdlayher/netlink+
|
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
|
L github.com/jsimonetti/rtnetlink/internal/unix from github.com/jsimonetti/rtnetlink
|
||||||
github.com/klauspost/compress/flate from nhooyr.io/websocket
|
github.com/klauspost/compress/flate from nhooyr.io/websocket
|
||||||
github.com/matttproud/golang_protobuf_extensions/pbutil from github.com/prometheus/common/expfmt
|
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/interfaces from tailscale.com/net/netns+
|
||||||
tailscale.com/net/netaddr from tailscale.com/ipn+
|
tailscale.com/net/netaddr from tailscale.com/ipn+
|
||||||
tailscale.com/net/netknob from tailscale.com/net/netns
|
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/netns from tailscale.com/derp/derphttp
|
||||||
tailscale.com/net/netutil from tailscale.com/client/tailscale
|
tailscale.com/net/netutil from tailscale.com/client/tailscale
|
||||||
tailscale.com/net/packet from tailscale.com/wgengine/filter
|
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/lineread from tailscale.com/hostinfo+
|
||||||
tailscale.com/util/mak from tailscale.com/syncs+
|
tailscale.com/util/mak from tailscale.com/syncs+
|
||||||
tailscale.com/util/multierr from tailscale.com/health
|
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/singleflight from tailscale.com/net/dnscache
|
||||||
tailscale.com/util/slicesx from tailscale.com/cmd/derper+
|
tailscale.com/util/slicesx from tailscale.com/cmd/derper+
|
||||||
tailscale.com/util/vizerror from tailscale.com/tsweb
|
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/google/uuid from tailscale.com/util/quarantine+
|
||||||
github.com/hdevalence/ed25519consensus from tailscale.com/tka
|
github.com/hdevalence/ed25519consensus from tailscale.com/tka
|
||||||
L github.com/josharian/native from github.com/mdlayher/netlink+
|
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
|
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/kballard/go-shellquote from tailscale.com/cmd/tailscale/cli
|
||||||
github.com/klauspost/compress/flate from nhooyr.io/websocket
|
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/netcheck from tailscale.com/cmd/tailscale/cli
|
||||||
tailscale.com/net/neterror from tailscale.com/net/netcheck+
|
tailscale.com/net/neterror from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/netknob from tailscale.com/net/netns
|
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/netns from tailscale.com/derp/derphttp+
|
||||||
tailscale.com/net/netutil from tailscale.com/client/tailscale+
|
tailscale.com/net/netutil from tailscale.com/client/tailscale+
|
||||||
tailscale.com/net/packet from tailscale.com/wgengine/filter+
|
tailscale.com/net/packet from tailscale.com/wgengine/filter+
|
||||||
|
@ -23,10 +23,10 @@
|
|||||||
"tailscale.com/derp/derphttp"
|
"tailscale.com/derp/derphttp"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tshttpproxy"
|
"tailscale.com/net/tshttpproxy"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var debugArgs struct {
|
var debugArgs struct {
|
||||||
@ -42,7 +42,7 @@
|
|||||||
func debugMode(args []string) error {
|
func debugMode(args []string) error {
|
||||||
fs := flag.NewFlagSet("debug", flag.ExitOnError)
|
fs := flag.NewFlagSet("debug", flag.ExitOnError)
|
||||||
fs.BoolVar(&debugArgs.ifconfig, "ifconfig", false, "If true, print network interface state")
|
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.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.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")
|
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, "", " ")
|
j, _ := json.MarshalIndent(st, "", " ")
|
||||||
os.Stderr.Write(j)
|
os.Stderr.Write(j)
|
||||||
}
|
}
|
||||||
mon, err := monitor.New(log.Printf)
|
mon, err := netmon.New(log.Printf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -84,10 +84,10 @@ func runMonitor(ctx context.Context, loop bool) error {
|
|||||||
|
|
||||||
mon.RegisterChangeCallback(func(changed bool, st *interfaces.State) {
|
mon.RegisterChangeCallback(func(changed bool, st *interfaces.State) {
|
||||||
if !changed {
|
if !changed {
|
||||||
log.Printf("Link monitor fired; no change")
|
log.Printf("Network monitor fired; no change")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("Link monitor fired. New state:")
|
log.Printf("Network monitor fired. New state:")
|
||||||
dump(st)
|
dump(st)
|
||||||
})
|
})
|
||||||
if loop {
|
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/netcheck from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/neterror from tailscale.com/net/dns/resolver+
|
tailscale.com/net/neterror from tailscale.com/net/dns/resolver+
|
||||||
tailscale.com/net/netknob from tailscale.com/net/netns+
|
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/netns from tailscale.com/derp/derphttp+
|
||||||
💣 tailscale.com/net/netstat from tailscale.com/ipn/ipnauth+
|
💣 tailscale.com/net/netstat from tailscale.com/ipn/ipnauth+
|
||||||
tailscale.com/net/netutil from tailscale.com/ipn/ipnlocal+
|
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/capture from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/wgengine/filter from tailscale.com/control/controlclient+
|
tailscale.com/wgengine/filter from tailscale.com/control/controlclient+
|
||||||
💣 tailscale.com/wgengine/magicsock from tailscale.com/ipn/ipnlocal+
|
💣 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/netlog from tailscale.com/wgengine
|
||||||
tailscale.com/wgengine/netstack from tailscale.com/cmd/tailscaled
|
tailscale.com/wgengine/netstack from tailscale.com/cmd/tailscaled
|
||||||
tailscale.com/wgengine/router from tailscale.com/ipn/ipnlocal+
|
tailscale.com/wgengine/router from tailscale.com/ipn/ipnlocal+
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/dnsfallback"
|
"tailscale.com/net/dnsfallback"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/proxymux"
|
"tailscale.com/net/proxymux"
|
||||||
"tailscale.com/net/socks5"
|
"tailscale.com/net/socks5"
|
||||||
@ -59,7 +60,6 @@
|
|||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
"tailscale.com/wgengine"
|
"tailscale.com/wgengine"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
"tailscale.com/wgengine/netstack"
|
"tailscale.com/wgengine/netstack"
|
||||||
"tailscale.com/wgengine/router"
|
"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) {
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("monitor.New: %w", err)
|
return nil, fmt.Errorf("netmon.New: %w", err)
|
||||||
}
|
}
|
||||||
if logPol != nil {
|
if logPol != nil {
|
||||||
logPol.Logtail.SetLinkMonitor(linkMon)
|
logPol.Logtail.SetNetMon(netMon)
|
||||||
}
|
}
|
||||||
|
|
||||||
socksListener, httpProxyListener := mustStartProxyListeners(args.socksAddr, args.httpProxyAddr)
|
socksListener, httpProxyListener := mustStartProxyListeners(args.socksAddr, args.httpProxyAddr)
|
||||||
|
|
||||||
dialer := &tsdial.Dialer{Logf: logf} // mutated below (before used)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("createEngine: %w", err)
|
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
|
// onlyNetstack is true if the user has explicitly requested that we use netstack
|
||||||
// for all networking.
|
// 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 == "" {
|
if args.tunname == "" {
|
||||||
return nil, false, errors.New("no --tun value specified")
|
return nil, false, errors.New("no --tun value specified")
|
||||||
}
|
}
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, name := range strings.Split(args.tunname, ",") {
|
for _, name := range strings.Split(args.tunname, ",") {
|
||||||
logf("wgengine.NewUserspaceEngine(tun %q) ...", name)
|
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 {
|
if err == nil {
|
||||||
return e, onlyNetstack, nil
|
return e, onlyNetstack, nil
|
||||||
}
|
}
|
||||||
@ -590,11 +590,11 @@ func handleSubnetsInNetstack() bool {
|
|||||||
|
|
||||||
var tstunNew = tstun.New
|
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{
|
conf := wgengine.Config{
|
||||||
ListenPort: args.port,
|
ListenPort: args.port,
|
||||||
LinkMonitor: linkMon,
|
NetMon: netMon,
|
||||||
Dialer: dialer,
|
Dialer: dialer,
|
||||||
}
|
}
|
||||||
|
|
||||||
onlyNetstack = name == "userspace-networking"
|
onlyNetstack = name == "userspace-networking"
|
||||||
@ -633,7 +633,7 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, dialer *tsdial.Dialer, na
|
|||||||
return e, false, err
|
return e, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := router.New(logf, dev, linkMon)
|
r, err := router.New(logf, dev, netMon)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dev.Close()
|
dev.Close()
|
||||||
return nil, false, fmt.Errorf("creating router: %w", err)
|
return nil, false, fmt.Errorf("creating router: %w", err)
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
"tailscale.com/net/dnscache"
|
"tailscale.com/net/dnscache"
|
||||||
"tailscale.com/net/dnsfallback"
|
"tailscale.com/net/dnsfallback"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/net/tlsdial"
|
"tailscale.com/net/tlsdial"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -54,7 +55,6 @@
|
|||||||
"tailscale.com/util/multierr"
|
"tailscale.com/util/multierr"
|
||||||
"tailscale.com/util/singleflight"
|
"tailscale.com/util/singleflight"
|
||||||
"tailscale.com/util/systemd"
|
"tailscale.com/util/systemd"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Direct is the client that connects to a tailcontrol server for a node.
|
// Direct is the client that connects to a tailcontrol server for a node.
|
||||||
@ -67,7 +67,7 @@ type Direct struct {
|
|||||||
newDecompressor func() (Decompressor, error)
|
newDecompressor func() (Decompressor, error)
|
||||||
keepAlive bool
|
keepAlive bool
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
linkMon *monitor.Mon // or nil
|
netMon *netmon.Monitor // or nil
|
||||||
discoPubKey key.DiscoPublic
|
discoPubKey key.DiscoPublic
|
||||||
getMachinePrivKey func() (key.MachinePrivate, error)
|
getMachinePrivKey func() (key.MachinePrivate, error)
|
||||||
debugFlags []string
|
debugFlags []string
|
||||||
@ -113,7 +113,7 @@ type Options struct {
|
|||||||
HTTPTestClient *http.Client // optional HTTP client to use (for tests only)
|
HTTPTestClient *http.Client // optional HTTP client to use (for tests only)
|
||||||
NoiseTestClient *http.Client // optional HTTP client to use for noise RPCs (tests only)
|
NoiseTestClient *http.Client // optional HTTP client to use for noise RPCs (tests only)
|
||||||
DebugFlags []string // debug settings to send to control
|
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
|
PopBrowserURL func(url string) // optional func to open browser
|
||||||
OnClientVersion func(*tailcfg.ClientVersion) // optional func to inform GUI of client version status
|
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
|
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,
|
discoPubKey: opts.DiscoPublicKey,
|
||||||
debugFlags: opts.DebugFlags,
|
debugFlags: opts.DebugFlags,
|
||||||
keepSharerAndUserSplit: opts.KeepSharerAndUserSplit,
|
keepSharerAndUserSplit: opts.KeepSharerAndUserSplit,
|
||||||
linkMon: opts.LinkMonitor,
|
netMon: opts.NetMon,
|
||||||
skipIPForwardingCheck: opts.SkipIPForwardingCheck,
|
skipIPForwardingCheck: opts.SkipIPForwardingCheck,
|
||||||
pinger: opts.Pinger,
|
pinger: opts.Pinger,
|
||||||
popBrowser: opts.PopBrowserURL,
|
popBrowser: opts.PopBrowserURL,
|
||||||
@ -871,8 +871,8 @@ func (c *Direct) sendMapRequest(ctx context.Context, maxPolls int, readOnly bool
|
|||||||
ReadOnly: readOnly && !allowStream,
|
ReadOnly: readOnly && !allowStream,
|
||||||
}
|
}
|
||||||
var extraDebugFlags []string
|
var extraDebugFlags []string
|
||||||
if hi != nil && c.linkMon != nil && !c.skipIPForwardingCheck &&
|
if hi != nil && c.netMon != nil && !c.skipIPForwardingCheck &&
|
||||||
ipForwardingBroken(hi.RoutableIPs, c.linkMon.InterfaceState()) {
|
ipForwardingBroken(hi.RoutableIPs, c.netMon.InterfaceState()) {
|
||||||
extraDebugFlags = append(extraDebugFlags, "warn-ip-forwarding-off")
|
extraDebugFlags = append(extraDebugFlags, "warn-ip-forwarding-off")
|
||||||
}
|
}
|
||||||
if health.RouterHealth() != nil {
|
if health.RouterHealth() != nil {
|
||||||
|
@ -142,7 +142,7 @@ type LocalBackend struct {
|
|||||||
store ipn.StateStore
|
store ipn.StateStore
|
||||||
dialer *tsdial.Dialer // non-nil
|
dialer *tsdial.Dialer // non-nil
|
||||||
backendLogID logid.PublicID
|
backendLogID logid.PublicID
|
||||||
unregisterLinkMon func()
|
unregisterNetMon func()
|
||||||
unregisterHealthWatch func()
|
unregisterHealthWatch func()
|
||||||
portpoll *portlist.Poller // may be nil
|
portpoll *portlist.Poller // may be nil
|
||||||
portpollOnce sync.Once // guards starting readPoller
|
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.statusChanged = sync.NewCond(&b.statusLock)
|
||||||
b.e.SetStatusCallback(b.setWgengineStatus)
|
b.e.SetStatusCallback(b.setWgengineStatus)
|
||||||
|
|
||||||
linkMon := e.GetLinkMonitor()
|
netMon := e.GetNetMon()
|
||||||
b.prevIfState = linkMon.InterfaceState()
|
b.prevIfState = netMon.InterfaceState()
|
||||||
// Call our linkChange code once with the current state, and
|
// Call our linkChange code once with the current state, and
|
||||||
// then also whenever it changes:
|
// then also whenever it changes:
|
||||||
b.linkChange(false, linkMon.InterfaceState())
|
b.linkChange(false, netMon.InterfaceState())
|
||||||
b.unregisterLinkMon = linkMon.RegisterChangeCallback(b.linkChange)
|
b.unregisterNetMon = netMon.RegisterChangeCallback(b.linkChange)
|
||||||
|
|
||||||
b.unregisterHealthWatch = health.RegisterWatcher(b.onHealthChange)
|
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)
|
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.
|
// major is whether ifst is different than earlier.
|
||||||
func (b *LocalBackend) linkChange(major bool, ifst *interfaces.State) {
|
func (b *LocalBackend) linkChange(major bool, ifst *interfaces.State) {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
@ -576,7 +576,7 @@ func (b *LocalBackend) Shutdown() {
|
|||||||
b.sockstatLogger.Shutdown()
|
b.sockstatLogger.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
b.unregisterLinkMon()
|
b.unregisterNetMon()
|
||||||
b.unregisterHealthWatch()
|
b.unregisterHealthWatch()
|
||||||
if cc != nil {
|
if cc != nil {
|
||||||
cc.Shutdown()
|
cc.Shutdown()
|
||||||
@ -1423,7 +1423,7 @@ func (b *LocalBackend) Start(opts ipn.Options) error {
|
|||||||
HTTPTestClient: httpTestClient,
|
HTTPTestClient: httpTestClient,
|
||||||
DiscoPublicKey: discoPublic,
|
DiscoPublicKey: discoPublic,
|
||||||
DebugFlags: debugFlags,
|
DebugFlags: debugFlags,
|
||||||
LinkMonitor: b.e.GetLinkMonitor(),
|
NetMon: b.e.GetNetMon(),
|
||||||
Pinger: b,
|
Pinger: b,
|
||||||
PopBrowserURL: b.tellClientToBrowseToURL,
|
PopBrowserURL: b.tellClientToBrowseToURL,
|
||||||
OnClientVersion: b.onClientVersion,
|
OnClientVersion: b.onClientVersion,
|
||||||
|
@ -143,7 +143,7 @@ func (s *serveListener) Run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *serveListener) shouldWarnAboutListenError(err error) bool {
|
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
|
// Machine likely doesn't have IPv6 enabled (or the IP is still being
|
||||||
// assigned). No need to warn. Notably, WSL2 (Issue 6303).
|
// assigned). No need to warn. Notably, WSL2 (Issue 6303).
|
||||||
return false
|
return false
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
"tailscale.com/ipn/ipnlocal"
|
"tailscale.com/ipn/ipnlocal"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/net/portmapper"
|
"tailscale.com/net/portmapper"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
@ -46,7 +47,6 @@
|
|||||||
"tailscale.com/util/httpm"
|
"tailscale.com/util/httpm"
|
||||||
"tailscale.com/util/mak"
|
"tailscale.com/util/mak"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type localAPIHandler func(*Handler, http.ResponseWriter, *http.Request)
|
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()
|
defer c.Close()
|
||||||
|
|
||||||
linkMon, err := monitor.New(logger.WithPrefix(logf, "monitor: "))
|
netMon, err := netmon.New(logger.WithPrefix(logf, "monitor: "))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf("error creating monitor: %v", err)
|
logf("error creating monitor: %v", err)
|
||||||
return
|
return
|
||||||
@ -707,14 +707,14 @@ func (h *Handler) serveDebugPortmap(w http.ResponseWriter, r *http.Request) {
|
|||||||
self = netip.MustParseAddr(b)
|
self = netip.MustParseAddr(b)
|
||||||
return gw, self, true
|
return gw, self, true
|
||||||
}
|
}
|
||||||
return linkMon.GatewayAndSelfIP()
|
return netMon.GatewayAndSelfIP()
|
||||||
}
|
}
|
||||||
|
|
||||||
c.SetGatewayLookupFunc(gatewayAndSelfIP)
|
c.SetGatewayLookupFunc(gatewayAndSelfIP)
|
||||||
|
|
||||||
gw, selfIP, ok := gatewayAndSelfIP()
|
gw, selfIP, ok := gatewayAndSelfIP()
|
||||||
if !ok {
|
if !ok {
|
||||||
logf("no gateway or self IP; %v", linkMon.InterfaceState())
|
logf("no gateway or self IP; %v", netMon.InterfaceState())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logf("gw=%v; self=%v", gw, selfIP)
|
logf("gw=%v; self=%v", gw, selfIP)
|
||||||
|
@ -24,11 +24,11 @@
|
|||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/logtail/backoff"
|
"tailscale.com/logtail/backoff"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/sockstats"
|
"tailscale.com/net/sockstats"
|
||||||
tslogger "tailscale.com/types/logger"
|
tslogger "tailscale.com/types/logger"
|
||||||
"tailscale.com/types/logid"
|
"tailscale.com/types/logid"
|
||||||
"tailscale.com/util/set"
|
"tailscale.com/util/set"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultHost is the default host name to upload logs to when
|
// DefaultHost is the default host name to upload logs to when
|
||||||
@ -179,7 +179,7 @@ type Logger struct {
|
|||||||
url string
|
url string
|
||||||
lowMem bool
|
lowMem bool
|
||||||
skipClientTime bool
|
skipClientTime bool
|
||||||
linkMonitor *monitor.Mon
|
netMonitor *netmon.Monitor
|
||||||
buffer Buffer
|
buffer Buffer
|
||||||
drainWake chan struct{} // signal to speed up drain
|
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
|
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))
|
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
|
// It should not be changed concurrently with log writes and should
|
||||||
// only be set once.
|
// only be set once.
|
||||||
func (l *Logger) SetLinkMonitor(lm *monitor.Mon) {
|
func (l *Logger) SetNetMon(lm *netmon.Monitor) {
|
||||||
l.linkMonitor = lm
|
l.netMonitor = lm
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSockstatsLabel sets the label used in sockstat logs to identify network traffic from this logger.
|
// 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 {
|
func (l *Logger) internetUp() bool {
|
||||||
if l.linkMonitor == nil {
|
if l.netMonitor == nil {
|
||||||
// No way to tell, so assume it is.
|
// No way to tell, so assume it is.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return l.linkMonitor.InterfaceState().AnyInterfaceUp()
|
return l.netMonitor.InterfaceState().AnyInterfaceUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) awaitInternetUp(ctx context.Context) {
|
func (l *Logger) awaitInternetUp(ctx context.Context) {
|
||||||
upc := make(chan bool, 1)
|
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() {
|
if st.AnyInterfaceUp() {
|
||||||
select {
|
select {
|
||||||
case upc <- true:
|
case upc <- true:
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -64,14 +64,14 @@ type Manager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewManagers created a new manager from the given config.
|
// 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 {
|
if dialer == nil {
|
||||||
panic("nil Dialer")
|
panic("nil Dialer")
|
||||||
}
|
}
|
||||||
logf = logger.WithPrefix(logf, "dns: ")
|
logf = logger.WithPrefix(logf, "dns: ")
|
||||||
m := &Manager{
|
m := &Manager{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
resolver: resolver.New(logf, linkMon, linkSel, dialer),
|
resolver: resolver.New(logf, netMon, linkSel, dialer),
|
||||||
os: oscfg,
|
os: oscfg,
|
||||||
}
|
}
|
||||||
m.ctx, m.ctxCancel = context.WithCancel(context.Background())
|
m.ctx, m.ctxCancel = context.WithCancel(context.Background())
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"tailscale.com/net/dns/publicdns"
|
"tailscale.com/net/dns/publicdns"
|
||||||
"tailscale.com/net/dnscache"
|
"tailscale.com/net/dnscache"
|
||||||
"tailscale.com/net/neterror"
|
"tailscale.com/net/neterror"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/sockstats"
|
"tailscale.com/net/sockstats"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -34,7 +35,6 @@
|
|||||||
"tailscale.com/util/cloudenv"
|
"tailscale.com/util/cloudenv"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// headerBytes is the number of bytes in a DNS message header.
|
// 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.
|
// forwarder forwards DNS packets to a number of upstream nameservers.
|
||||||
type forwarder struct {
|
type forwarder struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
linkMon *monitor.Mon
|
netMon *netmon.Monitor
|
||||||
linkSel ForwardLinkSelector // TODO(bradfitz): remove this when tsdial.Dialer absorbs it
|
linkSel ForwardLinkSelector // TODO(bradfitz): remove this when tsdial.Dialer absorbs it
|
||||||
dialer *tsdial.Dialer
|
dialer *tsdial.Dialer
|
||||||
|
|
||||||
@ -206,10 +206,10 @@ func init() {
|
|||||||
rand.Seed(time.Now().UnixNano())
|
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{
|
f := &forwarder{
|
||||||
logf: logger.WithPrefix(logf, "forward: "),
|
logf: logger.WithPrefix(logf, "forward: "),
|
||||||
linkMon: linkMon,
|
netMon: netMon,
|
||||||
linkSel: linkSel,
|
linkSel: linkSel,
|
||||||
dialer: dialer,
|
dialer: dialer,
|
||||||
}
|
}
|
||||||
@ -355,7 +355,7 @@ func (f *forwarder) packetListener(ip netip.Addr) (nettype.PacketListenerWithNet
|
|||||||
return stdNetPacketListener, nil
|
return stdNetPacketListener, nil
|
||||||
}
|
}
|
||||||
lc := new(net.ListenConfig)
|
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 nil, err
|
||||||
}
|
}
|
||||||
return nettype.MakePacketListenerWithNetIP(lc), nil
|
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.
|
// nameFromQuery extracts the normalized query name from bs.
|
||||||
func nameFromQuery(bs []byte) (dnsname.FQDN, error) {
|
func nameFromQuery(bs []byte) (dnsname.FQDN, error) {
|
||||||
|
@ -9,15 +9,15 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initListenConfig = initListenConfigNetworkExtension
|
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]
|
nif, ok := mon.InterfaceState().Interface[tunName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("utun not found")
|
return errors.New("utun not found")
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/dns/resolvconffile"
|
"tailscale.com/net/dns/resolvconffile"
|
||||||
"tailscale.com/net/netaddr"
|
"tailscale.com/net/netaddr"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/syncs"
|
"tailscale.com/syncs"
|
||||||
@ -34,7 +35,6 @@
|
|||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
"tailscale.com/util/cloudenv"
|
"tailscale.com/util/cloudenv"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const dnsSymbolicFQDN = "magicdns.localhost-tailscale-daemon."
|
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.
|
// it delegates to upstream nameservers if any are set.
|
||||||
type Resolver struct {
|
type Resolver struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
linkMon *monitor.Mon // or nil
|
netMon *netmon.Monitor // or nil
|
||||||
dialer *tsdial.Dialer // non-nil
|
dialer *tsdial.Dialer // non-nil
|
||||||
saveConfigForTests func(cfg Config) // used in tests to capture resolver config
|
saveConfigForTests func(cfg Config) // used in tests to capture resolver config
|
||||||
// forwarder forwards requests to upstream nameservers.
|
// forwarder forwards requests to upstream nameservers.
|
||||||
@ -205,20 +205,20 @@ type ForwardLinkSelector interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new resolver.
|
// New returns a new resolver.
|
||||||
// linkMon optionally specifies a link monitor to use for socket rebinding.
|
// netMon optionally specifies a network monitor to use for socket rebinding.
|
||||||
func New(logf logger.Logf, linkMon *monitor.Mon, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *Resolver {
|
func New(logf logger.Logf, netMon *netmon.Monitor, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *Resolver {
|
||||||
if dialer == nil {
|
if dialer == nil {
|
||||||
panic("nil Dialer")
|
panic("nil Dialer")
|
||||||
}
|
}
|
||||||
r := &Resolver{
|
r := &Resolver{
|
||||||
logf: logger.WithPrefix(logf, "resolver: "),
|
logf: logger.WithPrefix(logf, "resolver: "),
|
||||||
linkMon: linkMon,
|
netMon: netMon,
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
hostToIP: map[dnsname.FQDN][]netip.Addr{},
|
hostToIP: map[dnsname.FQDN][]netip.Addr{},
|
||||||
ipToHost: map[netip.Addr]dnsname.FQDN{},
|
ipToHost: map[netip.Addr]dnsname.FQDN{},
|
||||||
dialer: dialer,
|
dialer: dialer,
|
||||||
}
|
}
|
||||||
r.forwarder = newForwarder(r.logf, linkMon, linkSel, dialer)
|
r.forwarder = newForwarder(r.logf, netMon, linkSel, dialer)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,11 @@
|
|||||||
miekdns "github.com/miekg/dns"
|
miekdns "github.com/miekg/dns"
|
||||||
dns "golang.org/x/net/dns/dnsmessage"
|
dns "golang.org/x/net/dns/dnsmessage"
|
||||||
"tailscale.com/net/netaddr"
|
"tailscale.com/net/netaddr"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -315,7 +315,7 @@ func TestRDNSNameToIPv6(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newResolver(t testing.TB) *Resolver {
|
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) {
|
func TestResolveLocal(t *testing.T) {
|
||||||
@ -997,7 +997,7 @@ func TestMarshalResponseFormatError(t *testing.T) {
|
|||||||
|
|
||||||
func TestForwardLinkSelection(t *testing.T) {
|
func TestForwardLinkSelection(t *testing.T) {
|
||||||
configCall := make(chan string, 1)
|
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 {
|
select {
|
||||||
case configCall <- tunName:
|
case configCall <- tunName:
|
||||||
return nil
|
return nil
|
||||||
|
@ -351,12 +351,6 @@ func (s *State) String() string {
|
|||||||
return sb.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.
|
// An InterfaceFilter indicates whether EqualFiltered should use i when deciding whether two States are equal.
|
||||||
// ips are all the IPPrefixes associated with i.
|
// ips are all the IPPrefixes associated with i.
|
||||||
type InterfaceFilter func(i Interface, ips []netip.Prefix) bool
|
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.
|
// /proc/net/route. Use netlink to find the default route.
|
||||||
//
|
//
|
||||||
// TODO(bradfitz): this allocates a fair bit. We should track
|
// TODO(bradfitz): this allocates a fair bit. We should track
|
||||||
// this in wgengine/monitor instead and have
|
// this in net/interfaces/monitor instead and have
|
||||||
// interfaces.GetState take a link monitor or similar so the
|
// interfaces.GetState take a netmon.Monitor or similar so the
|
||||||
// routing table can be cached and the monitor's existing
|
// routing table can be cached and the monitor's existing
|
||||||
// subscription to route changes can update the cached state,
|
// subscription to route changes can update the cached state,
|
||||||
// rather than querying the whole thing every time like
|
// rather than querying the whole thing every time like
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// Package monitor provides facilities for monitoring network
|
// Package monitor provides facilities for monitoring network
|
||||||
// interface and route changes. It primarily exists to know when
|
// interface and route changes. It primarily exists to know when
|
||||||
// portable devices move between different networks.
|
// portable devices move between different networks.
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -48,15 +48,15 @@ type osMon interface {
|
|||||||
IsInterestingInterface(iface string) bool
|
IsInterestingInterface(iface string) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mon represents a monitoring instance.
|
// Monitor represents a monitoring instance.
|
||||||
type Mon struct {
|
type Monitor struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
om osMon // nil means not supported on this platform
|
om osMon // nil means not supported on this platform
|
||||||
change chan struct{}
|
change chan struct{}
|
||||||
stop chan struct{} // closed on Stop
|
stop chan struct{} // closed on Stop
|
||||||
|
|
||||||
mu sync.Mutex // guards all following fields
|
mu sync.Mutex // guards all following fields
|
||||||
cbs set.HandleSet[interfaces.ChangeFunc]
|
cbs set.HandleSet[ChangeFunc]
|
||||||
ruleDelCB set.HandleSet[RuleDeleteCallback]
|
ruleDelCB set.HandleSet[RuleDeleteCallback]
|
||||||
ifState *interfaces.State
|
ifState *interfaces.State
|
||||||
gwValid bool // whether gw and gwSelfIP are valid
|
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
|
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.
|
// New instantiates and starts a monitoring instance.
|
||||||
// The returned monitor is inactive until it's started by the Start method.
|
// The returned monitor is inactive until it's started by the Start method.
|
||||||
// Use RegisterChangeCallback to get notified of network changes.
|
// 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: ")
|
logf = logger.WithPrefix(logf, "monitor: ")
|
||||||
m := &Mon{
|
m := &Monitor{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
change: make(chan struct{}, 1),
|
change: make(chan struct{}, 1),
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
@ -102,13 +107,13 @@ func New(logf logger.Logf) (*Mon, error) {
|
|||||||
// interfaces.
|
// interfaces.
|
||||||
//
|
//
|
||||||
// The returned value is owned by Mon; it must not be modified.
|
// 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()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
return m.ifState
|
return m.ifState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mon) interfaceStateUncached() (*interfaces.State, error) {
|
func (m *Monitor) interfaceStateUncached() (*interfaces.State, error) {
|
||||||
return interfaces.GetState()
|
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
|
// It's the same as interfaces.LikelyHomeRouterIP, but it caches the
|
||||||
// result until the monitor detects a network change.
|
// 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()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
if m.gwValid {
|
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
|
// RegisterChangeCallback adds callback to the set of parties to be
|
||||||
// notified (in their own goroutine) when the network state changes.
|
// notified (in their own goroutine) when the network state changes.
|
||||||
// To remove this callback, call unregister (or close the monitor).
|
// 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()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
handle := m.cbs.Add(callback)
|
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
|
// RegisterRuleDeleteCallback adds callback to the set of parties to be
|
||||||
// notified (in their own goroutine) when a Linux ip rule is deleted.
|
// notified (in their own goroutine) when a Linux ip rule is deleted.
|
||||||
// To remove this callback, call unregister (or close the monitor).
|
// 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()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
handle := m.ruleDelCB.Add(callback)
|
handle := m.ruleDelCB.Add(callback)
|
||||||
@ -166,7 +171,7 @@ func (m *Mon) RegisterRuleDeleteCallback(callback RuleDeleteCallback) (unregiste
|
|||||||
|
|
||||||
// Start starts the monitor.
|
// Start starts the monitor.
|
||||||
// A monitor can only be started & closed once.
|
// A monitor can only be started & closed once.
|
||||||
func (m *Mon) Start() {
|
func (m *Monitor) Start() {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
if m.started || m.closed {
|
if m.started || m.closed {
|
||||||
@ -187,7 +192,7 @@ func (m *Mon) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the monitor.
|
// Close closes the monitor.
|
||||||
func (m *Mon) Close() error {
|
func (m *Monitor) Close() error {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
if m.closed {
|
if m.closed {
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
@ -218,7 +223,7 @@ func (m *Mon) Close() error {
|
|||||||
// change and re-check the state of the network. Any registered
|
// change and re-check the state of the network. Any registered
|
||||||
// ChangeFunc callbacks will be called within the event coalescing
|
// ChangeFunc callbacks will be called within the event coalescing
|
||||||
// period (under a fraction of a second).
|
// period (under a fraction of a second).
|
||||||
func (m *Mon) InjectEvent() {
|
func (m *Monitor) InjectEvent() {
|
||||||
select {
|
select {
|
||||||
case m.change <- struct{}{}:
|
case m.change <- struct{}{}:
|
||||||
default:
|
default:
|
||||||
@ -228,7 +233,7 @@ func (m *Mon) InjectEvent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mon) stopped() bool {
|
func (m *Monitor) stopped() bool {
|
||||||
select {
|
select {
|
||||||
case <-m.stop:
|
case <-m.stop:
|
||||||
return true
|
return true
|
||||||
@ -239,7 +244,7 @@ func (m *Mon) stopped() bool {
|
|||||||
|
|
||||||
// pump continuously retrieves messages from the connection, notifying
|
// pump continuously retrieves messages from the connection, notifying
|
||||||
// the change channel of changes, and stopping when a stop is issued.
|
// the change channel of changes, and stopping when a stop is issued.
|
||||||
func (m *Mon) pump() {
|
func (m *Monitor) pump() {
|
||||||
defer m.goroutines.Done()
|
defer m.goroutines.Done()
|
||||||
for !m.stopped() {
|
for !m.stopped() {
|
||||||
msg, err := m.om.Receive()
|
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()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
for _, cb := range m.ruleDelCB {
|
for _, cb := range m.ruleDelCB {
|
||||||
@ -274,13 +279,13 @@ func (m *Mon) notifyRuleDeleted(rdm ipRuleDeletedMessage) {
|
|||||||
// isInterestingInterface reports whether the provided interface should be
|
// isInterestingInterface reports whether the provided interface should be
|
||||||
// considered when checking for network state changes.
|
// considered when checking for network state changes.
|
||||||
// The ips parameter should be the IPs of the provided interface.
|
// 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)
|
return m.om.IsInterestingInterface(i.Name) && interfaces.UseInterestingInterfaces(i, ips)
|
||||||
}
|
}
|
||||||
|
|
||||||
// debounce calls the callback function with a delay between events
|
// debounce calls the callback function with a delay between events
|
||||||
// and exits when a stop is issued.
|
// and exits when a stop is issued.
|
||||||
func (m *Mon) debounce() {
|
func (m *Monitor) debounce() {
|
||||||
defer m.goroutines.Done()
|
defer m.goroutines.Done()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@ -343,7 +348,7 @@ func wallTime() time.Time {
|
|||||||
return time.Now().Round(0)
|
return time.Now().Round(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mon) pollWallTime() {
|
func (m *Monitor) pollWallTime() {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
if m.closed {
|
if m.closed {
|
||||||
@ -365,7 +370,7 @@ func (m *Mon) pollWallTime() {
|
|||||||
// checkWallTimeAdvanceLocked reports whether wall time jumped more than 150% of
|
// checkWallTimeAdvanceLocked reports whether wall time jumped more than 150% of
|
||||||
// pollWallTimeInterval, indicating we probably just came out of sleep. Once a
|
// pollWallTimeInterval, indicating we probably just came out of sleep. Once a
|
||||||
// time jump is detected it must be reset by calling resetTimeJumpedLocked.
|
// time jump is detected it must be reset by calling resetTimeJumpedLocked.
|
||||||
func (m *Mon) checkWallTimeAdvanceLocked() bool {
|
func (m *Monitor) checkWallTimeAdvanceLocked() bool {
|
||||||
if !shouldMonitorTimeJump {
|
if !shouldMonitorTimeJump {
|
||||||
panic("unreachable") // if callers are correct
|
panic("unreachable") // if callers are correct
|
||||||
}
|
}
|
||||||
@ -378,7 +383,7 @@ func (m *Mon) checkWallTimeAdvanceLocked() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resetTimeJumpedLocked consumes the signal set by checkWallTimeAdvanceLocked.
|
// resetTimeJumpedLocked consumes the signal set by checkWallTimeAdvanceLocked.
|
||||||
func (m *Mon) resetTimeJumpedLocked() {
|
func (m *Monitor) resetTimeJumpedLocked() {
|
||||||
m.timeJumped = false
|
m.timeJumped = false
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -24,7 +24,7 @@ type unspecifiedMessage struct{
|
|||||||
|
|
||||||
func (unspecifiedMessage) ignore() bool { return false }
|
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)
|
fd, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@ -24,7 +24,7 @@ type devdConn struct {
|
|||||||
conn net.Conn
|
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")
|
conn, err := net.Dial("unixpacket", "/var/run/devd.seqpacket.pipe")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf("devd dial error: %v, falling back to polling method", err)
|
logf("devd dial error: %v, falling back to polling method", err)
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
//go:build !android
|
//go:build !android
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
@ -44,7 +44,7 @@ type nlConn struct {
|
|||||||
addrCache map[uint32]map[netip.Addr]bool
|
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{
|
conn, err := netlink.Dial(unix.NETLINK_ROUTE, &netlink.Config{
|
||||||
// Routes get us most of the events of interest, but we need
|
// Routes get us most of the events of interest, but we need
|
||||||
// address as well to cover things like DHCP deciding to give
|
// address as well to cover things like DHCP deciding to give
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
//go:build (!linux && !freebsd && !windows && !darwin) || android
|
//go:build (!linux && !freebsd && !windows && !darwin) || android
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"tailscale.com/types/logger"
|
"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)
|
return newPollingMon(logf, m)
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -44,7 +44,7 @@ type winMon struct {
|
|||||||
noDeadlockTicker *time.Ticker
|
noDeadlockTicker *time.Ticker
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOSMon(logf logger.Logf, _ *Mon) (osMon, error) {
|
func newOSMon(logf logger.Logf, _ *Monitor) (osMon, error) {
|
||||||
m := &winMon{
|
m := &winMon{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
messagec: make(chan eventMessage, 1),
|
messagec: make(chan eventMessage, 1),
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
//go:build !windows && !darwin
|
//go:build !windows && !darwin
|
||||||
|
|
||||||
package monitor
|
package netmon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -17,7 +17,7 @@
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newPollingMon(logf logger.Logf, m *Mon) (osMon, error) {
|
func newPollingMon(logf logger.Logf, m *Monitor) (osMon, error) {
|
||||||
return &pollingMon{
|
return &pollingMon{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
m: m,
|
m: m,
|
||||||
@ -30,7 +30,7 @@ func newPollingMon(logf logger.Logf, m *Mon) (osMon, error) {
|
|||||||
// of anything to subscribe to.
|
// of anything to subscribe to.
|
||||||
type pollingMon struct {
|
type pollingMon struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
m *Mon
|
m *Monitor
|
||||||
|
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
stop chan struct{}
|
stop chan struct{}
|
@ -11,7 +11,7 @@
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -107,17 +107,10 @@ func GetValidation() *ValidationSockStats {
|
|||||||
return getValidation()
|
return getValidation()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkMonitor is the interface for the parts of wgengine/mointor's Mon that we
|
// SetNetMon configures the sockstats package to monitor the active
|
||||||
// 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
|
|
||||||
// interface, so that per-interface stats can be collected.
|
// interface, so that per-interface stats can be collected.
|
||||||
func SetLinkMonitor(lm LinkMonitor) {
|
func SetNetMon(lm *netmon.Monitor) {
|
||||||
setLinkMonitor(lm)
|
setNetMon(lm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DebugInfo returns a string containing debug information about the tracked
|
// DebugInfo returns a string containing debug information about the tracked
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ func getValidation() *ValidationSockStats {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLinkMonitor(lm LinkMonitor) {
|
func setNetMon(lm *netmon.Monitor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugInfo() string {
|
func debugInfo() string {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/util/clientmetric"
|
"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)),
|
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
|
// had a chance to populate knownInterfaces). In that case, we'll have
|
||||||
// to get the list of interfaces ourselves.
|
// to get the list of interfaces ourselves.
|
||||||
if len(sockStats.knownInterfaces) == 0 {
|
if len(sockStats.knownInterfaces) == 0 {
|
||||||
@ -248,7 +249,7 @@ func getValidation() *ValidationSockStats {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLinkMonitor(lm LinkMonitor) {
|
func setNetMon(lm *netmon.Monitor) {
|
||||||
sockStats.mu.Lock()
|
sockStats.mu.Lock()
|
||||||
defer sockStats.mu.Unlock()
|
defer sockStats.mu.Unlock()
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@
|
|||||||
"tailscale.com/net/dnscache"
|
"tailscale.com/net/dnscache"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netknob"
|
"tailscale.com/net/netknob"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/netmap"
|
"tailscale.com/types/netmap"
|
||||||
"tailscale.com/util/mak"
|
"tailscale.com/util/mak"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dialer dials out of tailscaled, while taking care of details while
|
// Dialer dials out of tailscaled, while taking care of details while
|
||||||
@ -50,16 +50,16 @@ type Dialer struct {
|
|||||||
netnsDialerOnce sync.Once
|
netnsDialerOnce sync.Once
|
||||||
netnsDialer netns.Dialer
|
netnsDialer netns.Dialer
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
closed bool
|
closed bool
|
||||||
dns dnsMap
|
dns dnsMap
|
||||||
tunName string // tun device name
|
tunName string // tun device name
|
||||||
linkMon *monitor.Mon
|
netMon *netmon.Monitor
|
||||||
linkMonUnregister func()
|
netMonUnregister func()
|
||||||
exitDNSDoHBase string // non-empty if DoH-proxying exit node in use; base URL+path (without '?')
|
exitDNSDoHBase string // non-empty if DoH-proxying exit node in use; base URL+path (without '?')
|
||||||
dnsCache *dnscache.MessageCache // nil until first non-empty SetExitDNSDoH
|
dnsCache *dnscache.MessageCache // nil until first non-empty SetExitDNSDoH
|
||||||
nextSysConnID int
|
nextSysConnID int
|
||||||
activeSysConns map[int]net.Conn // active connections not yet closed
|
activeSysConns map[int]net.Conn // active connections not yet closed
|
||||||
}
|
}
|
||||||
|
|
||||||
// sysConn wraps a net.Conn that was created using d.SystemDial.
|
// sysConn wraps a net.Conn that was created using d.SystemDial.
|
||||||
@ -117,9 +117,9 @@ func (d *Dialer) Close() error {
|
|||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
d.closed = true
|
d.closed = true
|
||||||
if d.linkMonUnregister != nil {
|
if d.netMonUnregister != nil {
|
||||||
d.linkMonUnregister()
|
d.netMonUnregister()
|
||||||
d.linkMonUnregister = nil
|
d.netMonUnregister = nil
|
||||||
}
|
}
|
||||||
for _, c := range d.activeSysConns {
|
for _, c := range d.activeSysConns {
|
||||||
c.Close()
|
c.Close()
|
||||||
@ -128,15 +128,15 @@ func (d *Dialer) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dialer) SetLinkMonitor(mon *monitor.Mon) {
|
func (d *Dialer) SetNetMon(mon *netmon.Monitor) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
if d.linkMonUnregister != nil {
|
if d.netMonUnregister != nil {
|
||||||
go d.linkMonUnregister()
|
go d.netMonUnregister()
|
||||||
d.linkMonUnregister = nil
|
d.netMonUnregister = nil
|
||||||
}
|
}
|
||||||
d.linkMon = mon
|
d.netMon = mon
|
||||||
d.linkMonUnregister = d.linkMon.RegisterChangeCallback(d.linkChanged)
|
d.netMonUnregister = d.netMon.RegisterChangeCallback(d.linkChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dialer) linkChanged(major bool, state *interfaces.State) {
|
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) {
|
func (d *Dialer) interfaceIndexLocked(ifName string) (index int, ok bool) {
|
||||||
if d.linkMon == nil {
|
if d.netMon == nil {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
st := d.linkMon.InterfaceState()
|
st := d.netMon.InterfaceState()
|
||||||
iface, ok := st.Interface[ifName]
|
iface, ok := st.Interface[ifName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, false
|
return 0, false
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
"tailscale.com/logtail/filch"
|
"tailscale.com/logtail/filch"
|
||||||
"tailscale.com/net/memnet"
|
"tailscale.com/net/memnet"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/proxymux"
|
"tailscale.com/net/proxymux"
|
||||||
"tailscale.com/net/socks5"
|
"tailscale.com/net/socks5"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -51,7 +52,6 @@
|
|||||||
"tailscale.com/types/nettype"
|
"tailscale.com/types/nettype"
|
||||||
"tailscale.com/util/mak"
|
"tailscale.com/util/mak"
|
||||||
"tailscale.com/wgengine"
|
"tailscale.com/wgengine"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
"tailscale.com/wgengine/netstack"
|
"tailscale.com/wgengine/netstack"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ type Server struct {
|
|||||||
initErr error
|
initErr error
|
||||||
lb *ipnlocal.LocalBackend
|
lb *ipnlocal.LocalBackend
|
||||||
netstack *netstack.Impl
|
netstack *netstack.Impl
|
||||||
linkMon *monitor.Mon
|
netMon *netmon.Monitor
|
||||||
rootPath string // the state directory
|
rootPath string // the state directory
|
||||||
hostname string
|
hostname string
|
||||||
shutdownCtx context.Context
|
shutdownCtx context.Context
|
||||||
@ -356,8 +356,8 @@ func (s *Server) Close() error {
|
|||||||
if s.lb != nil {
|
if s.lb != nil {
|
||||||
s.lb.Shutdown()
|
s.lb.Shutdown()
|
||||||
}
|
}
|
||||||
if s.linkMon != nil {
|
if s.netMon != nil {
|
||||||
s.linkMon.Close()
|
s.netMon.Close()
|
||||||
}
|
}
|
||||||
if s.dialer != nil {
|
if s.dialer != nil {
|
||||||
s.dialer.Close()
|
s.dialer.Close()
|
||||||
@ -476,17 +476,17 @@ func (s *Server) start() (reterr error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.linkMon, err = monitor.New(logf)
|
s.netMon, err = netmon.New(logf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
closePool.add(s.linkMon)
|
closePool.add(s.netMon)
|
||||||
|
|
||||||
s.dialer = &tsdial.Dialer{Logf: logf} // mutated below (before used)
|
s.dialer = &tsdial.Dialer{Logf: logf} // mutated below (before used)
|
||||||
eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{
|
eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{
|
||||||
ListenPort: 0,
|
ListenPort: 0,
|
||||||
LinkMonitor: s.linkMon,
|
NetMon: s.netMon,
|
||||||
Dialer: s.dialer,
|
Dialer: s.dialer,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/dnsfallback"
|
_ "tailscale.com/net/dnsfallback"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
|
_ "tailscale.com/net/netmon"
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
_ "tailscale.com/net/socks5"
|
_ "tailscale.com/net/socks5"
|
||||||
@ -47,7 +48,6 @@
|
|||||||
_ "tailscale.com/version"
|
_ "tailscale.com/version"
|
||||||
_ "tailscale.com/version/distro"
|
_ "tailscale.com/version/distro"
|
||||||
_ "tailscale.com/wgengine"
|
_ "tailscale.com/wgengine"
|
||||||
_ "tailscale.com/wgengine/monitor"
|
|
||||||
_ "tailscale.com/wgengine/netstack"
|
_ "tailscale.com/wgengine/netstack"
|
||||||
_ "tailscale.com/wgengine/router"
|
_ "tailscale.com/wgengine/router"
|
||||||
)
|
)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/dnsfallback"
|
_ "tailscale.com/net/dnsfallback"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
|
_ "tailscale.com/net/netmon"
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
_ "tailscale.com/net/socks5"
|
_ "tailscale.com/net/socks5"
|
||||||
@ -47,7 +48,6 @@
|
|||||||
_ "tailscale.com/version"
|
_ "tailscale.com/version"
|
||||||
_ "tailscale.com/version/distro"
|
_ "tailscale.com/version/distro"
|
||||||
_ "tailscale.com/wgengine"
|
_ "tailscale.com/wgengine"
|
||||||
_ "tailscale.com/wgengine/monitor"
|
|
||||||
_ "tailscale.com/wgengine/netstack"
|
_ "tailscale.com/wgengine/netstack"
|
||||||
_ "tailscale.com/wgengine/router"
|
_ "tailscale.com/wgengine/router"
|
||||||
)
|
)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/dnsfallback"
|
_ "tailscale.com/net/dnsfallback"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
|
_ "tailscale.com/net/netmon"
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
_ "tailscale.com/net/socks5"
|
_ "tailscale.com/net/socks5"
|
||||||
@ -47,7 +48,6 @@
|
|||||||
_ "tailscale.com/version"
|
_ "tailscale.com/version"
|
||||||
_ "tailscale.com/version/distro"
|
_ "tailscale.com/version/distro"
|
||||||
_ "tailscale.com/wgengine"
|
_ "tailscale.com/wgengine"
|
||||||
_ "tailscale.com/wgengine/monitor"
|
|
||||||
_ "tailscale.com/wgengine/netstack"
|
_ "tailscale.com/wgengine/netstack"
|
||||||
_ "tailscale.com/wgengine/router"
|
_ "tailscale.com/wgengine/router"
|
||||||
)
|
)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/dnsfallback"
|
_ "tailscale.com/net/dnsfallback"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
|
_ "tailscale.com/net/netmon"
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
_ "tailscale.com/net/socks5"
|
_ "tailscale.com/net/socks5"
|
||||||
@ -47,7 +48,6 @@
|
|||||||
_ "tailscale.com/version"
|
_ "tailscale.com/version"
|
||||||
_ "tailscale.com/version/distro"
|
_ "tailscale.com/version/distro"
|
||||||
_ "tailscale.com/wgengine"
|
_ "tailscale.com/wgengine"
|
||||||
_ "tailscale.com/wgengine/monitor"
|
|
||||||
_ "tailscale.com/wgengine/netstack"
|
_ "tailscale.com/wgengine/netstack"
|
||||||
_ "tailscale.com/wgengine/router"
|
_ "tailscale.com/wgengine/router"
|
||||||
)
|
)
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/dnsfallback"
|
_ "tailscale.com/net/dnsfallback"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
|
_ "tailscale.com/net/netmon"
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
_ "tailscale.com/net/socks5"
|
_ "tailscale.com/net/socks5"
|
||||||
@ -56,7 +57,6 @@
|
|||||||
_ "tailscale.com/version/distro"
|
_ "tailscale.com/version/distro"
|
||||||
_ "tailscale.com/wf"
|
_ "tailscale.com/wf"
|
||||||
_ "tailscale.com/wgengine"
|
_ "tailscale.com/wgengine"
|
||||||
_ "tailscale.com/wgengine/monitor"
|
|
||||||
_ "tailscale.com/wgengine/netstack"
|
_ "tailscale.com/wgengine/netstack"
|
||||||
_ "tailscale.com/wgengine/router"
|
_ "tailscale.com/wgengine/router"
|
||||||
)
|
)
|
||||||
|
@ -39,10 +39,10 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip.
|
|||||||
traf: traf,
|
traf: traf,
|
||||||
}
|
}
|
||||||
e1, err := wgengine.NewUserspaceEngine(l1, wgengine.Config{
|
e1, err := wgengine.NewUserspaceEngine(l1, wgengine.Config{
|
||||||
Router: router.NewFake(l1),
|
Router: router.NewFake(l1),
|
||||||
LinkMonitor: nil,
|
NetMon: nil,
|
||||||
ListenPort: 0,
|
ListenPort: 0,
|
||||||
Tun: t1,
|
Tun: t1,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("e1 init: %v", err)
|
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,
|
traf: traf,
|
||||||
}
|
}
|
||||||
e2, err := wgengine.NewUserspaceEngine(l2, wgengine.Config{
|
e2, err := wgengine.NewUserspaceEngine(l2, wgengine.Config{
|
||||||
Router: router.NewFake(l2),
|
Router: router.NewFake(l2),
|
||||||
LinkMonitor: nil,
|
NetMon: nil,
|
||||||
ListenPort: 0,
|
ListenPort: 0,
|
||||||
Tun: t2,
|
Tun: t2,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("e2 init: %v", err)
|
log.Fatalf("e2 init: %v", err)
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
"tailscale.com/net/netaddr"
|
"tailscale.com/net/netaddr"
|
||||||
"tailscale.com/net/netcheck"
|
"tailscale.com/net/netcheck"
|
||||||
"tailscale.com/net/neterror"
|
"tailscale.com/net/neterror"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/packet"
|
"tailscale.com/net/packet"
|
||||||
"tailscale.com/net/portmapper"
|
"tailscale.com/net/portmapper"
|
||||||
@ -69,7 +70,6 @@
|
|||||||
"tailscale.com/util/uniq"
|
"tailscale.com/util/uniq"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
"tailscale.com/wgengine/capture"
|
"tailscale.com/wgengine/capture"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -279,7 +279,7 @@ type Conn struct {
|
|||||||
idleFunc func() time.Duration // nil means unknown
|
idleFunc func() time.Duration // nil means unknown
|
||||||
testOnlyPacketListener nettype.PacketListener
|
testOnlyPacketListener nettype.PacketListener
|
||||||
noteRecvActivity func(key.NodePublic) // or nil, see Options.NoteRecvActivity
|
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
|
// No locking required to access these fields, either because
|
||||||
@ -573,9 +573,9 @@ type Options struct {
|
|||||||
// not hold Conn.mu while calling it.
|
// not hold Conn.mu while calling it.
|
||||||
NoteRecvActivity func(key.NodePublic)
|
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.
|
// With one, the portmapper won't be used.
|
||||||
LinkMonitor *monitor.Mon
|
NetMon *netmon.Monitor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Options) logf() logger.Logf {
|
func (o *Options) logf() logger.Logf {
|
||||||
@ -643,10 +643,10 @@ func NewConn(opts Options) (*Conn, error) {
|
|||||||
c.testOnlyPacketListener = opts.TestOnlyPacketListener
|
c.testOnlyPacketListener = opts.TestOnlyPacketListener
|
||||||
c.noteRecvActivity = opts.NoteRecvActivity
|
c.noteRecvActivity = opts.NoteRecvActivity
|
||||||
c.portMapper = portmapper.NewClient(logger.WithPrefix(c.logf, "portmapper: "), nil, c.onPortMapChanged)
|
c.portMapper = portmapper.NewClient(logger.WithPrefix(c.logf, "portmapper: "), nil, c.onPortMapChanged)
|
||||||
if opts.LinkMonitor != nil {
|
if opts.NetMon != nil {
|
||||||
c.portMapper.SetGatewayLookupFunc(opts.LinkMonitor.GatewayAndSelfIP)
|
c.portMapper.SetGatewayLookupFunc(opts.NetMon.GatewayAndSelfIP)
|
||||||
}
|
}
|
||||||
c.linkMon = opts.LinkMonitor
|
c.netMon = opts.NetMon
|
||||||
|
|
||||||
if err := c.rebind(keepCurrentPort); err != nil {
|
if err := c.rebind(keepCurrentPort); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -3369,8 +3369,8 @@ func (c *Conn) Rebind() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var ifIPs []netip.Prefix
|
var ifIPs []netip.Prefix
|
||||||
if c.linkMon != nil {
|
if c.netMon != nil {
|
||||||
st := c.linkMon.InterfaceState()
|
st := c.netMon.InterfaceState()
|
||||||
defIf := st.DefaultRouteInterface
|
defIf := st.DefaultRouteInterface
|
||||||
ifIPs = st.InterfaceIPs[defIf]
|
ifIPs = st.InterfaceIPs[defIf]
|
||||||
c.logf("Rebind; defIf=%q, ips=%v", defIf, ifIPs)
|
c.logf("Rebind; defIf=%q, ips=%v", defIf, ifIPs)
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/preftype"
|
"tailscale.com/types/preftype"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Router is responsible for managing the system network stack.
|
// 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
|
// New returns a new Router for the current platform, using the
|
||||||
// provided tun device.
|
// 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.
|
// 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: ")
|
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
|
// Cleanup restores the system network configuration to its original state
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"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 newUserspaceBSDRouter(logf, tundev, linkMon)
|
return newUserspaceBSDRouter(logf, tundev, netMon)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanup(logger.Logf, string) {
|
func cleanup(logger.Logf, string) {
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"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)
|
return nil, fmt.Errorf("unsupported OS %q", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// For now this router only supports the userspace WireGuard implementations.
|
// 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
|
// Work is currently underway for an in-kernel FreeBSD implementation of wireguard
|
||||||
// https://svnweb.freebsd.org/base?view=revision&revision=357986
|
// https://svnweb.freebsd.org/base?view=revision&revision=357986
|
||||||
|
|
||||||
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 newUserspaceBSDRouter(logf, tundev, linkMon)
|
return newUserspaceBSDRouter(logf, tundev, netMon)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanup(logf logger.Logf, interfaceName string) {
|
func cleanup(logf logger.Logf, interfaceName string) {
|
||||||
|
@ -24,12 +24,12 @@
|
|||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/preftype"
|
"tailscale.com/types/preftype"
|
||||||
"tailscale.com/util/multierr"
|
"tailscale.com/util/multierr"
|
||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -94,8 +94,8 @@ type linuxRouter struct {
|
|||||||
closed atomic.Bool
|
closed atomic.Bool
|
||||||
logf func(fmt string, args ...any)
|
logf func(fmt string, args ...any)
|
||||||
tunname string
|
tunname string
|
||||||
linkMon *monitor.Mon
|
netMon *netmon.Monitor
|
||||||
unregLinkMon func()
|
unregNetMon func()
|
||||||
addrs map[netip.Prefix]bool
|
addrs map[netip.Prefix]bool
|
||||||
routes map[netip.Prefix]bool
|
routes map[netip.Prefix]bool
|
||||||
localRoutes map[netip.Prefix]bool
|
localRoutes map[netip.Prefix]bool
|
||||||
@ -121,7 +121,7 @@ type linuxRouter struct {
|
|||||||
cmd commandRunner
|
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()
|
tunname, err := tunDev.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -156,15 +156,15 @@ func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, linkMon *monitor.Mo
|
|||||||
ambientCapNetAdmin: useAmbientCaps(),
|
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{
|
r := &linuxRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
netfilterMode: netfilterOff,
|
netfilterMode: netfilterOff,
|
||||||
linkMon: linkMon,
|
netMon: netMon,
|
||||||
|
|
||||||
v6Available: supportsV6,
|
v6Available: supportsV6,
|
||||||
v6NATAvailable: supportsV6NAT,
|
v6NATAvailable: supportsV6NAT,
|
||||||
@ -336,8 +336,8 @@ func (r *linuxRouter) useIPCommand() bool {
|
|||||||
return !ok
|
return !ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// onIPRuleDeleted is the callback from the link monitor for when an IP policy
|
// onIPRuleDeleted is the callback from the network monitor for when an IP
|
||||||
// rule is deleted. See Issue 1591.
|
// policy rule is deleted. See Issue 1591.
|
||||||
//
|
//
|
||||||
// If an ip rule is deleted (with pref number 52xx, as Tailscale sets), then
|
// 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
|
// 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 {
|
func (r *linuxRouter) Up() error {
|
||||||
if r.unregLinkMon == nil && r.linkMon != nil {
|
if r.unregNetMon == nil && r.netMon != nil {
|
||||||
r.unregLinkMon = r.linkMon.RegisterRuleDeleteCallback(r.onIPRuleDeleted)
|
r.unregNetMon = r.netMon.RegisterRuleDeleteCallback(r.onIPRuleDeleted)
|
||||||
}
|
}
|
||||||
if err := r.addIPRules(); err != nil {
|
if err := r.addIPRules(); err != nil {
|
||||||
return fmt.Errorf("adding IP rules: %w", err)
|
return fmt.Errorf("adding IP rules: %w", err)
|
||||||
@ -390,8 +390,8 @@ func (r *linuxRouter) Up() error {
|
|||||||
|
|
||||||
func (r *linuxRouter) Close() error {
|
func (r *linuxRouter) Close() error {
|
||||||
r.closed.Store(true)
|
r.closed.Store(true)
|
||||||
if r.unregLinkMon != nil {
|
if r.unregNetMon != nil {
|
||||||
r.unregLinkMon()
|
r.unregNetMon()
|
||||||
}
|
}
|
||||||
if err := r.downInterface(); err != nil {
|
if err := r.downInterface(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRouterStates(t *testing.T) {
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -659,7 +659,7 @@ func createTestTUN(t *testing.T) tun.Device {
|
|||||||
|
|
||||||
type linuxTest struct {
|
type linuxTest struct {
|
||||||
tun tun.Device
|
tun tun.Device
|
||||||
mon *monitor.Mon
|
mon *netmon.Monitor
|
||||||
r *linuxRouter
|
r *linuxRouter
|
||||||
logOutput tstest.MemLogger
|
logOutput tstest.MemLogger
|
||||||
}
|
}
|
||||||
@ -684,7 +684,7 @@ func newLinuxRootTest(t *testing.T) *linuxTest {
|
|||||||
|
|
||||||
logf := lt.logOutput.Logf
|
logf := lt.logOutput.Logf
|
||||||
|
|
||||||
mon, err := monitor.New(logger.Discard)
|
mon, err := netmon.New(logger.Discard)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lt.Close()
|
lt.Close()
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
"go4.org/netipx"
|
"go4.org/netipx"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// For now this router only supports the WireGuard userspace implementation.
|
// For now this router only supports the WireGuard userspace implementation.
|
||||||
@ -22,14 +22,14 @@
|
|||||||
|
|
||||||
type openbsdRouter struct {
|
type openbsdRouter struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
linkMon *monitor.Mon
|
netMon *netmon.Monitor
|
||||||
tunname string
|
tunname string
|
||||||
local4 netip.Prefix
|
local4 netip.Prefix
|
||||||
local6 netip.Prefix
|
local6 netip.Prefix
|
||||||
routes map[netip.Prefix]struct{}
|
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()
|
tunname, err := tundev.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -37,7 +37,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mo
|
|||||||
|
|
||||||
return &openbsdRouter{
|
return &openbsdRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
linkMon: linkMon,
|
netMon: netMon,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -14,21 +14,21 @@
|
|||||||
|
|
||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
"go4.org/netipx"
|
"go4.org/netipx"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type userspaceBSDRouter struct {
|
type userspaceBSDRouter struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
linkMon *monitor.Mon
|
netMon *netmon.Monitor
|
||||||
tunname string
|
tunname string
|
||||||
local []netip.Prefix
|
local []netip.Prefix
|
||||||
routes map[netip.Prefix]bool
|
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()
|
tunname, err := tundev.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -36,7 +36,7 @@ func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor
|
|||||||
|
|
||||||
return &userspaceBSDRouter{
|
return &userspaceBSDRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
linkMon: linkMon,
|
netMon: netMon,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -22,19 +22,19 @@
|
|||||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||||
"tailscale.com/logtail/backoff"
|
"tailscale.com/logtail/backoff"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type winRouter struct {
|
type winRouter struct {
|
||||||
logf func(fmt string, args ...any)
|
logf func(fmt string, args ...any)
|
||||||
linkMon *monitor.Mon // may be nil
|
netMon *netmon.Monitor // may be nil
|
||||||
nativeTun *tun.NativeTun
|
nativeTun *tun.NativeTun
|
||||||
routeChangeCallback *winipcfg.RouteChangeCallback
|
routeChangeCallback *winipcfg.RouteChangeCallback
|
||||||
firewall *firewallTweaker
|
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)
|
nativeTun := tundev.(*tun.NativeTun)
|
||||||
luid := winipcfg.LUID(nativeTun.LUID())
|
luid := winipcfg.LUID(nativeTun.LUID())
|
||||||
guid, err := luid.GUID()
|
guid, err := luid.GUID()
|
||||||
@ -44,7 +44,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mo
|
|||||||
|
|
||||||
return &winRouter{
|
return &winRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
linkMon: linkMon,
|
netMon: netMon,
|
||||||
nativeTun: nativeTun,
|
nativeTun: nativeTun,
|
||||||
firewall: &firewallTweaker{
|
firewall: &firewallTweaker{
|
||||||
logf: logger.WithPrefix(logf, "firewall: "),
|
logf: logger.WithPrefix(logf, "firewall: "),
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
"tailscale.com/net/flowtrack"
|
"tailscale.com/net/flowtrack"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/packet"
|
"tailscale.com/net/packet"
|
||||||
"tailscale.com/net/sockstats"
|
"tailscale.com/net/sockstats"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
@ -48,7 +49,6 @@
|
|||||||
"tailscale.com/wgengine/capture"
|
"tailscale.com/wgengine/capture"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
"tailscale.com/wgengine/magicsock"
|
"tailscale.com/wgengine/magicsock"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
"tailscale.com/wgengine/netlog"
|
"tailscale.com/wgengine/netlog"
|
||||||
"tailscale.com/wgengine/router"
|
"tailscale.com/wgengine/router"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
"tailscale.com/wgengine/wgcfg"
|
||||||
@ -84,21 +84,21 @@
|
|||||||
const networkLoggerUploadTimeout = 5 * time.Second
|
const networkLoggerUploadTimeout = 5 * time.Second
|
||||||
|
|
||||||
type userspaceEngine struct {
|
type userspaceEngine struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
wgLogger *wglog.Logger //a wireguard-go logging wrapper
|
wgLogger *wglog.Logger //a wireguard-go logging wrapper
|
||||||
reqCh chan struct{}
|
reqCh chan struct{}
|
||||||
waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool
|
waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool
|
||||||
timeNow func() mono.Time
|
timeNow func() mono.Time
|
||||||
tundev *tstun.Wrapper
|
tundev *tstun.Wrapper
|
||||||
wgdev *device.Device
|
wgdev *device.Device
|
||||||
router router.Router
|
router router.Router
|
||||||
confListenPort uint16 // original conf.ListenPort
|
confListenPort uint16 // original conf.ListenPort
|
||||||
dns *dns.Manager
|
dns *dns.Manager
|
||||||
magicConn *magicsock.Conn
|
magicConn *magicsock.Conn
|
||||||
linkMon *monitor.Mon
|
netMon *netmon.Monitor
|
||||||
linkMonOwned bool // whether we created linkMon (and thus need to close it)
|
netMonOwned bool // whether we created netMon (and thus need to close it)
|
||||||
linkMonUnregister func() // unsubscribes from changes; used regardless of linkMonOwned
|
netMonUnregister func() // unsubscribes from changes; used regardless of netMonOwned
|
||||||
birdClient BIRDClient // or nil
|
birdClient BIRDClient // or nil
|
||||||
|
|
||||||
testMaybeReconfigHook func() // for tests; if non-nil, fires if maybeReconfigWireguardLocked called
|
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.
|
// If nil, a fake OSConfigurator that does nothing is used.
|
||||||
DNS dns.OSConfigurator
|
DNS dns.OSConfigurator
|
||||||
|
|
||||||
// LinkMonitor optionally provides an existing link monitor to re-use.
|
// NetMon optionally provides an existing network monitor to re-use.
|
||||||
// If nil, a new link monitor is created.
|
// If nil, a new network monitor is created.
|
||||||
LinkMonitor *monitor.Mon
|
NetMon *netmon.Monitor
|
||||||
|
|
||||||
// Dialer is the dialer to use for outbound connections.
|
// Dialer is the dialer to use for outbound connections.
|
||||||
// If nil, a new Dialer is created
|
// 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.isLocalAddr.Store(tsaddr.NewContainsIPFunc(nil))
|
||||||
e.isDNSIPOverTailscale.Store(tsaddr.NewContainsIPFunc(nil))
|
e.isDNSIPOverTailscale.Store(tsaddr.NewContainsIPFunc(nil))
|
||||||
|
|
||||||
if conf.LinkMonitor != nil {
|
if conf.NetMon != nil {
|
||||||
e.linkMon = conf.LinkMonitor
|
e.netMon = conf.NetMon
|
||||||
} else {
|
} else {
|
||||||
mon, err := monitor.New(logf)
|
mon, err := netmon.New(logf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
closePool.add(mon)
|
closePool.add(mon)
|
||||||
e.linkMon = mon
|
e.netMon = mon
|
||||||
e.linkMonOwned = true
|
e.netMonOwned = true
|
||||||
}
|
}
|
||||||
|
|
||||||
tunName, _ := conf.Tun.Name()
|
tunName, _ := conf.Tun.Name()
|
||||||
conf.Dialer.SetTUNName(tunName)
|
conf.Dialer.SetTUNName(tunName)
|
||||||
conf.Dialer.SetLinkMonitor(e.linkMon)
|
conf.Dialer.SetNetMon(e.netMon)
|
||||||
e.dns = dns.NewManager(logf, conf.DNS, e.linkMon, conf.Dialer, fwdDNSLinkSelector{e, tunName})
|
e.dns = dns.NewManager(logf, conf.DNS, e.netMon, conf.Dialer, fwdDNSLinkSelector{e, tunName})
|
||||||
|
|
||||||
// TODO: there's probably a better place for this
|
// 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()
|
tshttpproxy.InvalidateCache()
|
||||||
e.linkChange(changed, st)
|
e.linkChange(changed, st)
|
||||||
})
|
})
|
||||||
closePool.addFunc(unregisterMonWatch)
|
closePool.addFunc(unregisterMonWatch)
|
||||||
e.linkMonUnregister = unregisterMonWatch
|
e.netMonUnregister = unregisterMonWatch
|
||||||
|
|
||||||
endpointsFn := func(endpoints []tailcfg.Endpoint) {
|
endpointsFn := func(endpoints []tailcfg.Endpoint) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
@ -359,7 +359,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
DERPActiveFunc: e.RequestStatus,
|
DERPActiveFunc: e.RequestStatus,
|
||||||
IdleFunc: e.tundev.IdleDuration,
|
IdleFunc: e.tundev.IdleDuration,
|
||||||
NoteRecvActivity: e.noteRecvActivity,
|
NoteRecvActivity: e.noteRecvActivity,
|
||||||
LinkMonitor: e.linkMon,
|
NetMon: e.netMon,
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -368,7 +368,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
return nil, fmt.Errorf("wgengine: %v", err)
|
return nil, fmt.Errorf("wgengine: %v", err)
|
||||||
}
|
}
|
||||||
closePool.add(e.magicConn)
|
closePool.add(e.magicConn)
|
||||||
e.magicConn.SetNetworkUp(e.linkMon.InterfaceState().AnyInterfaceUp())
|
e.magicConn.SetNetworkUp(e.netMon.InterfaceState().AnyInterfaceUp())
|
||||||
|
|
||||||
tsTUNDev.SetDiscoKey(e.magicConn.DiscoPublicKey())
|
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 {
|
if err := e.router.Set(nil); err != nil {
|
||||||
return nil, fmt.Errorf("router.Set(nil): %w", err)
|
return nil, fmt.Errorf("router.Set(nil): %w", err)
|
||||||
}
|
}
|
||||||
e.logf("Starting link monitor...")
|
e.logf("Starting network monitor...")
|
||||||
e.linkMon.Start()
|
e.netMon.Start()
|
||||||
|
|
||||||
e.logf("Engine created.")
|
e.logf("Engine created.")
|
||||||
return e, nil
|
return e, nil
|
||||||
@ -1094,9 +1094,9 @@ func (e *userspaceEngine) Close() {
|
|||||||
r := bufio.NewReader(strings.NewReader(""))
|
r := bufio.NewReader(strings.NewReader(""))
|
||||||
e.wgdev.IpcSetOperation(r)
|
e.wgdev.IpcSetOperation(r)
|
||||||
e.magicConn.Close()
|
e.magicConn.Close()
|
||||||
e.linkMonUnregister()
|
e.netMonUnregister()
|
||||||
if e.linkMonOwned {
|
if e.netMonOwned {
|
||||||
e.linkMon.Close()
|
e.netMon.Close()
|
||||||
}
|
}
|
||||||
e.dns.Down()
|
e.dns.Down()
|
||||||
e.router.Close()
|
e.router.Close()
|
||||||
@ -1119,15 +1119,15 @@ func (e *userspaceEngine) Wait() {
|
|||||||
<-e.waitCh
|
<-e.waitCh
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *userspaceEngine) GetLinkMonitor() *monitor.Mon {
|
func (e *userspaceEngine) GetNetMon() *netmon.Monitor {
|
||||||
return e.linkMon
|
return e.netMon
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkChange signals a network change event. It's currently
|
// 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.
|
// generates link change events for us.
|
||||||
func (e *userspaceEngine) LinkChange(_ bool) {
|
func (e *userspaceEngine) LinkChange(_ bool) {
|
||||||
e.linkMon.InjectEvent()
|
e.netMon.InjectEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *userspaceEngine) linkChange(changed bool, cur *interfaces.State) {
|
func (e *userspaceEngine) linkChange(changed bool, cur *interfaces.State) {
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tstun"
|
"tailscale.com/net/tstun"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
@ -25,7 +26,6 @@
|
|||||||
"tailscale.com/wgengine/capture"
|
"tailscale.com/wgengine/capture"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
"tailscale.com/wgengine/magicsock"
|
"tailscale.com/wgengine/magicsock"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
"tailscale.com/wgengine/router"
|
"tailscale.com/wgengine/router"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
"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 {
|
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) })
|
return e.watchdogErr("Reconfig", func() error { return e.wrap.Reconfig(cfg, routerCfg, dnsCfg, debug) })
|
||||||
}
|
}
|
||||||
func (e *watchdogEngine) GetLinkMonitor() *monitor.Mon {
|
func (e *watchdogEngine) GetNetMon() *netmon.Monitor {
|
||||||
return e.wrap.GetLinkMonitor()
|
return e.wrap.GetNetMon()
|
||||||
}
|
}
|
||||||
func (e *watchdogEngine) GetFilter() *filter.Filter {
|
func (e *watchdogEngine) GetFilter() *filter.Filter {
|
||||||
return e.wrap.GetFilter()
|
return e.wrap.GetFilter()
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
|
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/netmap"
|
"tailscale.com/types/netmap"
|
||||||
"tailscale.com/wgengine/capture"
|
"tailscale.com/wgengine/capture"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
"tailscale.com/wgengine/monitor"
|
|
||||||
"tailscale.com/wgengine/router"
|
"tailscale.com/wgengine/router"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
"tailscale.com/wgengine/wgcfg"
|
||||||
)
|
)
|
||||||
@ -92,8 +92,8 @@ type Engine interface {
|
|||||||
// WireGuard status changes.
|
// WireGuard status changes.
|
||||||
SetStatusCallback(StatusCallback)
|
SetStatusCallback(StatusCallback)
|
||||||
|
|
||||||
// GetLinkMonitor returns the link monitor.
|
// GetNetMon returns the network monitor.
|
||||||
GetLinkMonitor() *monitor.Mon
|
GetNetMon() *netmon.Monitor
|
||||||
|
|
||||||
// RequestStatus requests a WireGuard status update right
|
// RequestStatus requests a WireGuard status update right
|
||||||
// away, sent to the callback registered via SetStatusCallback.
|
// 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
|
// Deprecated: don't use this method. It was removed shortly
|
||||||
// before the Tailscale 1.6 release when we remembered that
|
// 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
|
// its own mechanism that uses LinkChange. Android is the only
|
||||||
// caller of this method now. Don't add more.
|
// caller of this method now. Don't add more.
|
||||||
LinkChange(isExpensive bool)
|
LinkChange(isExpensive bool)
|
||||||
|
Loading…
Reference in New Issue
Block a user