net/tsdial: also plumb TUN name and monitor into tsdial.Dialer

In prep for moving stuff out of LocalBackend.

Change-Id: I9725aa9c3ebc7275f8c40e040b326483c0340127
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2021-12-01 09:18:17 -08:00 committed by Brad Fitzpatrick
parent c37af58ea4
commit c7fb26acdb
8 changed files with 48 additions and 19 deletions

View File

@ -308,6 +308,8 @@ func run() error {
socksListener, httpProxyListener := mustStartProxyListeners(args.socksAddr, args.httpProxyAddr) socksListener, httpProxyListener := mustStartProxyListeners(args.socksAddr, args.httpProxyAddr)
dialer := new(tsdial.Dialer) // mutated below (before used) dialer := new(tsdial.Dialer) // mutated below (before used)
dialer.SetLinkMonitor(linkMon)
e, useNetstack, err := createEngine(logf, linkMon, dialer) e, useNetstack, err := createEngine(logf, linkMon, dialer)
if err != nil { if err != nil {
logf("wgengine.New: %v", err) logf("wgengine.New: %v", err)

View File

@ -39,6 +39,7 @@
"tailscale.com/version" "tailscale.com/version"
"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"
) )
@ -177,6 +178,11 @@ func beFirewallKillswitch() bool {
func startIPNServer(ctx context.Context, logid string) error { func startIPNServer(ctx context.Context, logid string) error {
var logf logger.Logf = log.Printf var logf logger.Logf = log.Printf
linkMon, err := monitor.New(logf)
if err != nil {
return err
}
getEngineRaw := func() (wgengine.Engine, error) { getEngineRaw := func() (wgengine.Engine, error) {
dev, devName, err := tstun.New(logf, "Tailscale") dev, devName, err := tstun.New(logf, "Tailscale")
if err != nil { if err != nil {
@ -197,10 +203,11 @@ func startIPNServer(ctx context.Context, logid string) error {
return nil, fmt.Errorf("DNS: %w", err) return nil, fmt.Errorf("DNS: %w", err)
} }
eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{ eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{
Tun: dev, Tun: dev,
Router: r, Router: r,
DNS: d, DNS: d,
ListenPort: 41641, ListenPort: 41641,
LinkMonitor: linkMon,
}) })
if err != nil { if err != nil {
r.Close() r.Close()
@ -287,7 +294,7 @@ type engineOrError struct {
return fmt.Errorf("safesocket.Listen: %v", err) return fmt.Errorf("safesocket.Listen: %v", err)
} }
err = ipnserver.Run(ctx, logf, ln, store, logid, getEngine, ipnServerOpts()) err = ipnserver.Run(ctx, logf, ln, store, linkMon, logid, getEngine, ipnServerOpts())
if err != nil { if err != nil {
logf("ipnserver.Run: %v", err) logf("ipnserver.Run: %v", err)
} }

View File

@ -2185,17 +2185,9 @@ func (b *LocalBackend) initPeerAPIListener() {
return return
} }
var tunName string
if ge, ok := b.e.(wgengine.InternalsGetter); ok {
if tunWrap, _, ok := ge.GetInternals(); ok {
tunName, _ = tunWrap.Name()
}
}
ps := &peerAPIServer{ ps := &peerAPIServer{
b: b, b: b,
rootDir: fileRoot, rootDir: fileRoot,
tunName: tunName,
selfNode: selfNode, selfNode: selfNode,
directFileMode: b.directFileRoot != "", directFileMode: b.directFileRoot != "",
} }

View File

@ -49,7 +49,6 @@
type peerAPIServer struct { type peerAPIServer struct {
b *LocalBackend b *LocalBackend
rootDir string rootDir string
tunName string
selfNode *tailcfg.Node selfNode *tailcfg.Node
knownEmpty syncs.AtomicBool knownEmpty syncs.AtomicBool
resolver *resolver.Resolver resolver *resolver.Resolver
@ -363,7 +362,7 @@ func (s *peerAPIServer) listen(ip netaddr.IP, ifState *interfaces.State) (ln net
// On iOS/macOS, this sets the lc.Control hook to // On iOS/macOS, this sets the lc.Control hook to
// setsockopt the interface index to bind to, to get // setsockopt the interface index to bind to, to get
// out of the network sandbox. // out of the network sandbox.
if err := initListenConfig(&lc, ip, ifState, s.tunName); err != nil { if err := initListenConfig(&lc, ip, ifState, s.b.dialer.TUNName()); err != nil {
return nil, err return nil, err
} }
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {

View File

@ -50,6 +50,7 @@
"tailscale.com/version" "tailscale.com/version"
"tailscale.com/version/distro" "tailscale.com/version/distro"
"tailscale.com/wgengine" "tailscale.com/wgengine"
"tailscale.com/wgengine/monitor"
) )
// Options is the configuration of the Tailscale node agent. // Options is the configuration of the Tailscale node agent.
@ -653,7 +654,7 @@ func StateStore(path string, logf logger.Logf) (ipn.StateStore, error) {
// The getEngine func is called repeatedly, once per connection, until it returns an engine successfully. // The getEngine func is called repeatedly, once per connection, until it returns an engine successfully.
// //
// Deprecated: use New and Server.Run instead. // Deprecated: use New and Server.Run instead.
func Run(ctx context.Context, logf logger.Logf, ln net.Listener, store ipn.StateStore, logid string, getEngine func() (wgengine.Engine, error), opts Options) error { func Run(ctx context.Context, logf logger.Logf, ln net.Listener, store ipn.StateStore, linkMon *monitor.Mon, logid string, getEngine func() (wgengine.Engine, error), opts Options) error {
getEngine = getEngineUntilItWorksWrapper(getEngine) getEngine = getEngineUntilItWorksWrapper(getEngine)
runDone := make(chan struct{}) runDone := make(chan struct{})
defer close(runDone) defer close(runDone)
@ -738,6 +739,7 @@ func Run(ctx context.Context, logf logger.Logf, ln net.Listener, store ipn.State
} }
dialer := new(tsdial.Dialer) dialer := new(tsdial.Dialer)
dialer.SetLinkMonitor(linkMon)
eng.AddNetworkMapCallback(func(nm *netmap.NetworkMap) { eng.AddNetworkMapCallback(func(nm *netmap.NetworkMap) {
dialer.SetDNSMap(tsdial.DNSMapFromNetworkMap(nm)) dialer.SetDNSMap(tsdial.DNSMapFromNetworkMap(nm))
}) })

View File

@ -72,6 +72,6 @@ func TestRunMultipleAccepts(t *testing.T) {
} }
defer ln.Close() defer ln.Close()
err = ipnserver.Run(ctx, logTriggerTestf, ln, store, "dummy_logid", ipnserver.FixedEngine(eng), opts) err = ipnserver.Run(ctx, logTriggerTestf, ln, store, nil /* mon */, "dummy_logid", ipnserver.FixedEngine(eng), opts)
t.Logf("ipnserver.Run = %v", err) t.Logf("ipnserver.Run = %v", err)
} }

View File

@ -17,6 +17,7 @@
"inet.af/netaddr" "inet.af/netaddr"
"tailscale.com/net/netknob" "tailscale.com/net/netknob"
"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
@ -37,8 +38,33 @@ type Dialer struct {
peerClientOnce sync.Once peerClientOnce sync.Once
peerClient *http.Client peerClient *http.Client
mu sync.Mutex mu sync.Mutex
dns DNSMap dns DNSMap
tunName string // tun device name
linkMon *monitor.Mon
}
// SetTUNName sets the name of the tun device in use ("tailscale0", "utun6",
// etc). This is needed on some platforms to set sockopts to bind
// to the same interface index.
func (d *Dialer) SetTUNName(name string) {
d.mu.Lock()
defer d.mu.Unlock()
d.tunName = name
}
// TUNName returns the name of the tun device in use, if any.
// Example format ("tailscale0", "utun6").
func (d *Dialer) TUNName() string {
d.mu.Lock()
defer d.mu.Unlock()
return d.tunName
}
func (d *Dialer) SetLinkMonitor(mon *monitor.Mon) {
d.mu.Lock()
defer d.mu.Unlock()
d.linkMon = mon
} }
// PeerDialControlFunc returns a function // PeerDialControlFunc returns a function

View File

@ -318,6 +318,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
} }
tunName, _ := conf.Tun.Name() tunName, _ := conf.Tun.Name()
conf.Dialer.SetTUNName(tunName)
e.dns = dns.NewManager(logf, conf.DNS, e.linkMon, conf.Dialer, fwdDNSLinkSelector{e, tunName}) e.dns = dns.NewManager(logf, conf.DNS, e.linkMon, conf.Dialer, fwdDNSLinkSelector{e, tunName})
logf("link state: %+v", e.linkMon.InterfaceState()) logf("link state: %+v", e.linkMon.InterfaceState())