wgengine: fix a data race on StatusCallback
Updates tailscale/tailscale#112
type userspaceEngine struct {
logf logger.Logf
- statusCallback StatusCallback
reqCh chan struct{}
waitCh chan struct{}
tundev tun.Device
@@ -44,6 +43,7 @@ type userspaceEngine struct {
lastRoutes string
mu sync.Mutex
+ statusCallback StatusCallback
peerSequence []wgcfg.Key
endpoints []string
pingers map[wgcfg.Key]context.CancelFunc // mu must be held to call CancelFunc
@@ -416,9 +416,17 @@ func (e *userspaceEngine) SetFilter(filt *filter.Filter) {
}
func (e *userspaceEngine) SetStatusCallback(cb StatusCallback) {
+ e.mu.Lock()
+ defer e.mu.Unlock()
e.statusCallback = cb
}
+func (e *userspaceEngine) getStatusCallback() StatusCallback {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ return e.statusCallback
+}
+
func (e *userspaceEngine) getStatus() (*Status, error) {
e.wgLock.Lock()
defer e.wgLock.Unlock()
@@ -543,8 +551,8 @@ func (e *userspaceEngine) RequestStatus() {
e.logf("RequestStatus: weird: both s and err are nil\n")
return
}
- if e.statusCallback != nil {
- e.statusCallback(s, err)
+ if cb := e.getStatusCallback(); cb != nil {
+ cb(s, err)
}
default:
}
