mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-21 12:28:39 +00:00
net/portmapper, wgengine/monitor: cache gateway IP info until link changes
Cuts down allocs & CPU in steady state (on regular STUN probes) when network is unchanging. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
d580b3f09e
commit
44ab0acbdb
@ -50,7 +50,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
tailscale.com/types/wgkey from tailscale.com/types/netmap+
|
tailscale.com/types/wgkey from tailscale.com/types/netmap+
|
||||||
tailscale.com/util/dnsname from tailscale.com/cmd/tailscale/cli+
|
tailscale.com/util/dnsname from tailscale.com/cmd/tailscale/cli+
|
||||||
W tailscale.com/util/endian from tailscale.com/net/netns
|
W tailscale.com/util/endian from tailscale.com/net/netns
|
||||||
tailscale.com/util/lineread from tailscale.com/net/interfaces
|
LW tailscale.com/util/lineread from tailscale.com/net/interfaces
|
||||||
tailscale.com/version from tailscale.com/cmd/tailscale/cli+
|
tailscale.com/version from tailscale.com/cmd/tailscale/cli+
|
||||||
tailscale.com/version/distro from tailscale.com/cmd/tailscale/cli
|
tailscale.com/version/distro from tailscale.com/cmd/tailscale/cli
|
||||||
tailscale.com/wgengine/filter from tailscale.com/types/netmap
|
tailscale.com/wgengine/filter from tailscale.com/types/netmap
|
||||||
|
@ -126,7 +126,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/types/wgkey from tailscale.com/control/controlclient+
|
tailscale.com/types/wgkey from tailscale.com/control/controlclient+
|
||||||
tailscale.com/util/dnsname from tailscale.com/wgengine/tsdns+
|
tailscale.com/util/dnsname from tailscale.com/wgengine/tsdns+
|
||||||
LW tailscale.com/util/endian from tailscale.com/net/netns+
|
LW tailscale.com/util/endian from tailscale.com/net/netns+
|
||||||
tailscale.com/util/lineread from tailscale.com/control/controlclient+
|
LW tailscale.com/util/lineread from tailscale.com/control/controlclient+
|
||||||
tailscale.com/util/pidowner from tailscale.com/ipn/ipnserver
|
tailscale.com/util/pidowner from tailscale.com/ipn/ipnserver
|
||||||
tailscale.com/util/racebuild from tailscale.com/logpolicy
|
tailscale.com/util/racebuild from tailscale.com/logpolicy
|
||||||
tailscale.com/util/systemd from tailscale.com/control/controlclient+
|
tailscale.com/util/systemd from tailscale.com/control/controlclient+
|
||||||
|
@ -43,6 +43,7 @@ const trustServiceStillAvailableDuration = 10 * time.Minute
|
|||||||
// Client is a port mapping client.
|
// Client is a port mapping client.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
|
ipAndGateway func() (gw, ip netaddr.IP, ok bool)
|
||||||
|
|
||||||
mu sync.Mutex // guards following, and all fields thereof
|
mu sync.Mutex // guards following, and all fields thereof
|
||||||
|
|
||||||
@ -101,9 +102,17 @@ func (m *pmpMapping) release() {
|
|||||||
func NewClient(logf logger.Logf) *Client {
|
func NewClient(logf logger.Logf) *Client {
|
||||||
return &Client{
|
return &Client{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
|
ipAndGateway: interfaces.LikelyHomeRouterIP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetGatewayLookupFunc set the func that returns the machine's default gateway IP, and
|
||||||
|
// the primary IP address for that gateway. It must be called before the client is used.
|
||||||
|
// If not called, interfaces.LikelyHomeRouterIP is used.
|
||||||
|
func (c *Client) SetGatewayLookupFunc(f func() (gw, myIP netaddr.IP, ok bool)) {
|
||||||
|
c.ipAndGateway = f
|
||||||
|
}
|
||||||
|
|
||||||
// NoteNetworkDown should be called when the network has transitioned to a down state.
|
// NoteNetworkDown should be called when the network has transitioned to a down state.
|
||||||
// It's too late to release port mappings at this point (the user might've just turned off
|
// It's too late to release port mappings at this point (the user might've just turned off
|
||||||
// their wifi), but we can make sure we invalidate mappings for later when the network
|
// their wifi), but we can make sure we invalidate mappings for later when the network
|
||||||
@ -140,7 +149,7 @@ func (c *Client) SetLocalPort(localPort uint16) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) gatewayAndSelfIP() (gw, myIP netaddr.IP, ok bool) {
|
func (c *Client) gatewayAndSelfIP() (gw, myIP netaddr.IP, ok bool) {
|
||||||
gw, myIP, ok = interfaces.LikelyHomeRouterIP()
|
gw, myIP, ok = c.ipAndGateway()
|
||||||
if !ok {
|
if !ok {
|
||||||
gw = netaddr.IP{}
|
gw = netaddr.IP{}
|
||||||
myIP = netaddr.IP{}
|
myIP = netaddr.IP{}
|
||||||
|
@ -55,6 +55,7 @@ import (
|
|||||||
"tailscale.com/types/pad32"
|
"tailscale.com/types/pad32"
|
||||||
"tailscale.com/types/wgkey"
|
"tailscale.com/types/wgkey"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
"tailscale.com/wgengine/wgcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -423,6 +424,10 @@ type Options struct {
|
|||||||
// enabled, only active discovery-aware nodes will be able to
|
// enabled, only active discovery-aware nodes will be able to
|
||||||
// communicate with Conn.
|
// communicate with Conn.
|
||||||
DisableLegacyNetworking bool
|
DisableLegacyNetworking bool
|
||||||
|
|
||||||
|
// LinkMonitor is the link monitor to use.
|
||||||
|
// With one, the portmapper won't be used.
|
||||||
|
LinkMonitor *monitor.Mon
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Options) logf() logger.Logf {
|
func (o *Options) logf() logger.Logf {
|
||||||
@ -483,6 +488,9 @@ func NewConn(opts Options) (*Conn, error) {
|
|||||||
c.simulatedNetwork = opts.SimulatedNetwork
|
c.simulatedNetwork = opts.SimulatedNetwork
|
||||||
c.disableLegacy = opts.DisableLegacyNetworking
|
c.disableLegacy = opts.DisableLegacyNetworking
|
||||||
c.portMapper = portmapper.NewClient(logger.WithPrefix(c.logf, "portmapper: "))
|
c.portMapper = portmapper.NewClient(logger.WithPrefix(c.logf, "portmapper: "))
|
||||||
|
if opts.LinkMonitor != nil {
|
||||||
|
c.portMapper.SetGatewayLookupFunc(opts.LinkMonitor.GatewayAndSelfIP)
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.initialBind(); err != nil {
|
if err := c.initialBind(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"inet.af/netaddr"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
@ -54,6 +55,9 @@ type Mon struct {
|
|||||||
mu sync.Mutex // guards cbs
|
mu sync.Mutex // guards cbs
|
||||||
cbs map[*callbackHandle]ChangeFunc
|
cbs map[*callbackHandle]ChangeFunc
|
||||||
ifState *interfaces.State
|
ifState *interfaces.State
|
||||||
|
gwValid bool // whether gw and gwSelfIP are valid (cached)x
|
||||||
|
gw netaddr.IP
|
||||||
|
gwSelfIP netaddr.IP
|
||||||
|
|
||||||
onceStart sync.Once
|
onceStart sync.Once
|
||||||
started bool
|
started bool
|
||||||
@ -105,6 +109,24 @@ func (m *Mon) interfaceStateUncached() (*interfaces.State, error) {
|
|||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GatewayAndSelfIP returns the current network's default gateway, and
|
||||||
|
// the machine's default IP for that gateway.
|
||||||
|
//
|
||||||
|
// It's the same as interfaces.LikelyHomeRouterIP, but it caches the
|
||||||
|
// result until the monitor detects a network change.
|
||||||
|
func (m *Mon) GatewayAndSelfIP() (gw, myIP netaddr.IP, ok bool) {
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
if m.gwValid {
|
||||||
|
return m.gw, m.gwSelfIP, true
|
||||||
|
}
|
||||||
|
gw, myIP, ok = interfaces.LikelyHomeRouterIP()
|
||||||
|
if ok {
|
||||||
|
m.gw, m.gwSelfIP, m.gwValid = gw, myIP, true
|
||||||
|
}
|
||||||
|
return gw, myIP, ok
|
||||||
|
}
|
||||||
|
|
||||||
// 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).
|
||||||
@ -213,6 +235,7 @@ func (m *Mon) debounce() {
|
|||||||
oldState := m.ifState
|
oldState := m.ifState
|
||||||
changed := !curState.Equal(oldState)
|
changed := !curState.Equal(oldState)
|
||||||
if changed {
|
if changed {
|
||||||
|
m.gwValid = false
|
||||||
m.ifState = curState
|
m.ifState = curState
|
||||||
|
|
||||||
if s1, s2 := oldState.String(), curState.String(); s1 == s2 {
|
if s1, s2 := oldState.String(), curState.String(); s1 == s2 {
|
||||||
|
@ -270,6 +270,7 @@ func newUserspaceEngine(logf logger.Logf, rawTUNDev tun.Device, conf Config) (_
|
|||||||
DERPActiveFunc: e.RequestStatus,
|
DERPActiveFunc: e.RequestStatus,
|
||||||
IdleFunc: e.tundev.IdleDuration,
|
IdleFunc: e.tundev.IdleDuration,
|
||||||
NoteRecvActivity: e.noteReceiveActivity,
|
NoteRecvActivity: e.noteReceiveActivity,
|
||||||
|
LinkMonitor: e.linkMon,
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
e.magicConn, err = magicsock.NewConn(magicsockOpts)
|
e.magicConn, err = magicsock.NewConn(magicsockOpts)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user