Move linkstate boring change filtering to magicsock

So we can at least re-STUN on boring updates.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2020-03-10 12:25:42 -07:00
committed by Brad Fitzpatrick
parent 592fec7606
commit 023df9239e
3 changed files with 64 additions and 29 deletions

View File

@@ -63,6 +63,9 @@ type Conn struct {
connCtx context.Context // closed on Conn.Close
connCtxCancel func() // closes connCtx
linkChangeMu sync.Mutex
linkState *interfaces.State
// addrsByUDP is a map of every remote ip:port to a priority
// list of endpoint addresses for a peer.
// The priority list is provided by wgengine configuration.
@@ -201,6 +204,7 @@ func Listen(opts Options) (*Conn, error) {
derpTLSConfig: opts.derpTLSConfig,
derps: derpmap.Prod(),
}
c.linkState, _ = getLinkState()
if len(opts.STUN) > 0 {
c.derps = derpmap.NewTestWorld(opts.STUN...)
}
@@ -1080,9 +1084,35 @@ func (c *Conn) reSTUN() {
}
}
// LinkChange should be called whenever something changed with the
// network, no matter how minor. The LinkChange method then looks
// at the state of the network and decides whether the change from
// before is interesting enough to warrant taking action on.
func (c *Conn) LinkChange() {
defer c.reSTUN()
c.linkChangeMu.Lock()
defer c.linkChangeMu.Unlock()
cur, err := getLinkState()
if err != nil {
return
}
if c.linkState != nil && !cur.Equal(c.linkState) {
c.linkState = cur
c.rebind()
}
}
func getLinkState() (*interfaces.State, error) {
s, err := interfaces.GetState()
if s != nil {
s.RemoveTailscaleInterfaces()
}
return s, err
}
func (c *Conn) rebind() {
if c.pconnPort != 0 {
c.pconn.mu.Lock()
if err := c.pconn.pconn.Close(); err != nil {
@@ -1098,7 +1128,6 @@ func (c *Conn) LinkChange() {
c.logf("magicsock: link change unable to bind fixed port %d: %v, falling back to random port", c.pconnPort, err)
c.pconn.mu.Unlock()
}
c.logf("magicsock: link change, binding new port")
packetConn, err := net.ListenPacket("udp4", ":0")
if err != nil {