Skip to content

Commit c0c83f1

Browse files
authored
fix: follow tailscale idioms for when to update nodes (coder#6164)
1 parent b171cb5 commit c0c83f1

File tree

1 file changed

+38
-21
lines changed

1 file changed

+38
-21
lines changed

tailnet/conn.go

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io"
88
"net"
99
"net/netip"
10+
"reflect"
1011
"strconv"
1112
"sync"
1213
"time"
@@ -214,28 +215,23 @@ func NewConn(options *Options) (*Conn, error) {
214215
return
215216
}
216217
server.lastStatus = s.AsOf
217-
server.lastEndpoints = make([]string, 0, len(s.LocalAddrs))
218-
for _, addr := range s.LocalAddrs {
219-
server.lastEndpoints = append(server.lastEndpoints, addr.Addr.String())
218+
if endpointsEqual(s.LocalAddrs, server.lastEndpoints) {
219+
// No need to update the node if nothing changed!
220+
server.lastMutex.Unlock()
221+
return
220222
}
223+
server.lastEndpoints = append([]tailcfg.Endpoint{}, s.LocalAddrs...)
221224
server.lastMutex.Unlock()
222225
server.sendNode()
223226
})
224227
wireguardEngine.SetNetInfoCallback(func(ni *tailcfg.NetInfo) {
225228
server.logger.Debug(context.Background(), "netinfo callback", slog.F("netinfo", ni))
226-
// If the lastMutex is blocked, it's possible that
227-
// multiple NetInfo callbacks occur at the same time.
228-
//
229-
// We need to ensure only the latest is sent!
230-
asOf := time.Now()
231229
server.lastMutex.Lock()
232-
if asOf.Before(server.lastNetInfo) {
230+
if reflect.DeepEqual(server.lastNetInfo, ni) {
233231
server.lastMutex.Unlock()
234232
return
235233
}
236-
server.lastNetInfo = asOf
237-
server.lastPreferredDERP = ni.PreferredDERP
238-
server.lastDERPLatency = ni.DERPLatency
234+
server.lastNetInfo = ni.Clone()
239235
server.lastMutex.Unlock()
240236
server.sendNode()
241237
})
@@ -285,12 +281,10 @@ type Conn struct {
285281
nodeChanged bool
286282
// It's only possible to store these values via status functions,
287283
// so the values must be stored for retrieval later on.
288-
lastStatus time.Time
289-
lastNetInfo time.Time
290-
lastEndpoints []string
291-
lastPreferredDERP int
292-
lastDERPLatency map[string]float64
293-
nodeCallback func(node *Node)
284+
lastStatus time.Time
285+
lastEndpoints []tailcfg.Endpoint
286+
lastNetInfo *tailcfg.NetInfo
287+
nodeCallback func(node *Node)
294288

295289
trafficStats *connstats.Statistics
296290
}
@@ -589,16 +583,27 @@ func (c *Conn) Node() *Node {
589583
}
590584

591585
func (c *Conn) selfNode() *Node {
586+
endpoints := make([]string, 0, len(c.lastEndpoints))
587+
for _, addr := range c.lastEndpoints {
588+
endpoints = append(endpoints, addr.Addr.String())
589+
}
590+
var preferredDERP int
591+
var derpLatency map[string]float64
592+
if c.lastNetInfo != nil {
593+
preferredDERP = c.lastNetInfo.PreferredDERP
594+
derpLatency = c.lastNetInfo.DERPLatency
595+
}
596+
592597
node := &Node{
593598
ID: c.netMap.SelfNode.ID,
594599
AsOf: database.Now(),
595600
Key: c.netMap.SelfNode.Key,
596601
Addresses: c.netMap.SelfNode.Addresses,
597602
AllowedIPs: c.netMap.SelfNode.AllowedIPs,
598603
DiscoKey: c.magicConn.DiscoPublicKey(),
599-
Endpoints: c.lastEndpoints,
600-
PreferredDERP: c.lastPreferredDERP,
601-
DERPLatency: c.lastDERPLatency,
604+
Endpoints: endpoints,
605+
PreferredDERP: preferredDERP,
606+
DERPLatency: derpLatency,
602607
}
603608
if c.blockEndpoints {
604609
node.Endpoints = nil
@@ -774,3 +779,15 @@ func Logger(logger slog.Logger) tslogger.Logf {
774779
logger.Debug(context.Background(), fmt.Sprintf(format, args...))
775780
})
776781
}
782+
783+
func endpointsEqual(x, y []tailcfg.Endpoint) bool {
784+
if len(x) != len(y) {
785+
return false
786+
}
787+
for i := range x {
788+
if x[i] != y[i] {
789+
return false
790+
}
791+
}
792+
return true
793+
}

0 commit comments

Comments
 (0)