fixup! net/routecheck: introduce new package for checking peer reachability

@illotum points out that there was a race between atomic.Pointer.Load
and Store. Of course, we should have used Swap.

Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit is contained in:
Simon Law
2026-05-27 21:46:43 -07:00
parent 2de851c428
commit 4d980a77c5

View File

@@ -114,9 +114,21 @@ func (c *Client) NotifyNetMapAvailable(nm *netmap.NetworkMap) {
if nm == nil {
return // client disconnected
}
ch := c.hasNetMap.Load()
c.hasNetMap.Store(new(make(chan struct{}))) // prepare for next non-nil netmap
close(*ch) // broadcast to waitForNetMap
var nextCh *chan struct{}
for {
ch := c.hasNetMap.Load()
if *ch == nil {
return // Client has been Closed
}
if nextCh == nil {
nextCh = new(make(chan struct{})) // prepare for next non-nil netmap
}
if c.hasNetMap.CompareAndSwap(ch, nextCh) {
close(*ch)
return
}
}
}
func (c *Client) waitForNetMap(ctx context.Context) (*netmap.NetworkMap, error) {
@@ -144,9 +156,9 @@ func (c *Client) Close() error {
return nil
}
ch := c.hasNetMap.Load()
c.hasNetMap.Store(new(chan struct{})) // clear and unlock before waking anything up
if ch != nil {
nilCh := new(chan struct{})
ch := c.hasNetMap.Swap(nilCh) // clear before waking anything up
if *ch != nil {
close(*ch)
}