@@ -182,6 +182,7 @@ func NewConn(options *Options) (*Conn, error) {
182
182
magicConn : magicConn ,
183
183
dialer : dialer ,
184
184
listeners : map [listenKey ]* listener {},
185
+ peerMap : map [tailcfg.NodeID ]* tailcfg.Node {},
185
186
tunDevice : tunDevice ,
186
187
netMap : netMap ,
187
188
netStack : netStack ,
@@ -192,10 +193,17 @@ func NewConn(options *Options) (*Conn, error) {
192
193
wireguardEngine : wireguardEngine ,
193
194
}
194
195
wireguardEngine .SetStatusCallback (func (s * wgengine.Status , err error ) {
196
+ server .logger .Info (context .Background (), "wireguard status" , slog .F ("status" , s ), slog .F ("err" , err ))
195
197
if err != nil {
196
198
return
197
199
}
198
200
server .lastMutex .Lock ()
201
+ if s .AsOf .Before (server .lastStatus ) {
202
+ // Don't process outdated status!
203
+ server .lastMutex .Unlock ()
204
+ return
205
+ }
206
+ server .lastStatus = s .AsOf
199
207
server .lastEndpoints = make ([]string , 0 , len (s .LocalAddrs ))
200
208
for _ , addr := range s .LocalAddrs {
201
209
server .lastEndpoints = append (server .lastEndpoints , addr .Addr .String ())
@@ -240,6 +248,7 @@ type Conn struct {
240
248
241
249
dialer * tsdial.Dialer
242
250
tunDevice * tstun.Wrapper
251
+ peerMap map [tailcfg.NodeID ]* tailcfg.Node
243
252
netMap * netmap.NetworkMap
244
253
netStack * netstack.Impl
245
254
magicConn * magicsock.Conn
@@ -254,6 +263,7 @@ type Conn struct {
254
263
nodeChanged bool
255
264
// It's only possible to store these values via status functions,
256
265
// so the values must be stored for retrieval later on.
266
+ lastStatus time.Time
257
267
lastEndpoints []string
258
268
lastPreferredDERP int
259
269
lastDERPLatency map [string ]float64
@@ -282,8 +292,9 @@ func (c *Conn) SetNodeCallback(callback func(node *Node)) {
282
292
func (c * Conn ) SetDERPMap (derpMap * tailcfg.DERPMap ) {
283
293
c .mutex .Lock ()
284
294
defer c .mutex .Unlock ()
285
- c .netMap .DERPMap = derpMap
286
295
c .logger .Debug (context .Background (), "updating derp map" , slog .F ("derp_map" , derpMap ))
296
+ c .netMap .DERPMap = derpMap
297
+ c .wireguardEngine .SetNetworkMap (c .netMap )
287
298
c .wireguardEngine .SetDERPMap (derpMap )
288
299
}
289
300
@@ -292,18 +303,24 @@ func (c *Conn) SetDERPMap(derpMap *tailcfg.DERPMap) {
292
303
func (c * Conn ) UpdateNodes (nodes []* Node ) error {
293
304
c .mutex .Lock ()
294
305
defer c .mutex .Unlock ()
295
- peerMap := map [tailcfg.NodeID ]* tailcfg.Node {}
296
306
status := c .Status ()
297
307
for _ , peer := range c .netMap .Peers {
298
- if peerStatus , ok := status .Peer [peer .Key ]; ok {
299
- // Clear out inactive connections!
300
- // If a connection hasn't been active for a minute post creation, we assume it's dead.
301
- if ! peerStatus .Active && peer .Created .Before (time .Now ().Add (- time .Minute )) {
302
- c .logger .Debug (context .Background (), "clearing peer" , slog .F ("peerStatus" , peerStatus ))
303
- continue
304
- }
308
+ peerStatus , ok := status .Peer [peer .Key ]
309
+ if ! ok {
310
+ continue
305
311
}
306
- peerMap [peer .ID ] = peer
312
+ // If this peer was added in the last 5 minutes, assume it
313
+ // could still be active.
314
+ if time .Since (peer .Created ) < 5 * time .Minute {
315
+ continue
316
+ }
317
+ // We double-check that it's safe to remove by ensuring no
318
+ // handshake has been sent in the past 5 minutes as well. Connections that
319
+ // are actively exchanging IP traffic will handshake every 2 minutes.
320
+ if time .Since (peerStatus .LastHandshake ) < 5 * time .Minute {
321
+ continue
322
+ }
323
+ delete (c .peerMap , peer .ID )
307
324
}
308
325
for _ , node := range nodes {
309
326
peerStatus , ok := status .Peer [node .Key ]
@@ -322,18 +339,11 @@ func (c *Conn) UpdateNodes(nodes []*Node) error {
322
339
// reason. TODO: @kylecarbs debug this!
323
340
KeepAlive : ok && peerStatus .Active ,
324
341
}
325
- existingNode , ok := peerMap [node .ID ]
326
- if ok {
327
- peerNode .Created = existingNode .Created
328
- c .logger .Debug (context .Background (), "updating peer" , slog .F ("peer" , peerNode ))
329
- } else {
330
- c .logger .Debug (context .Background (), "adding peer" , slog .F ("peer" , peerNode ))
331
- }
332
- peerMap [node .ID ] = peerNode
342
+ c .peerMap [node .ID ] = peerNode
333
343
}
334
- c .netMap .Peers = make ([]* tailcfg.Node , 0 , len (peerMap ))
335
- for _ , peer := range peerMap {
336
- c .netMap .Peers = append (c .netMap .Peers , peer )
344
+ c .netMap .Peers = make ([]* tailcfg.Node , 0 , len (c . peerMap ))
345
+ for _ , peer := range c . peerMap {
346
+ c .netMap .Peers = append (c .netMap .Peers , peer . Clone () )
337
347
}
338
348
netMapCopy := * c .netMap
339
349
c .wireguardEngine .SetNetworkMap (& netMapCopy )
@@ -425,6 +435,7 @@ func (c *Conn) sendNode() {
425
435
}
426
436
c .nodeSending = true
427
437
go func () {
438
+ c .logger .Info (context .Background (), "sending node" , slog .F ("node" , node ))
428
439
nodeCallback (node )
429
440
c .lastMutex .Lock ()
430
441
c .nodeSending = false
0 commit comments