wgengine: fix a data race on StatusCallback

Updates tailscale/tailscale#112

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/115/head
Brad Fitzpatrick 5 years ago
parent c576a57067
commit 19b54d0ae7

@ -28,25 +28,25 @@ import (
) )
type userspaceEngine struct { type userspaceEngine struct {
logf logger.Logf logf logger.Logf
statusCallback StatusCallback reqCh chan struct{}
reqCh chan struct{} waitCh chan struct{}
waitCh chan struct{} tundev tun.Device
tundev tun.Device wgdev *device.Device
wgdev *device.Device router Router
router Router magicConn *magicsock.Conn
magicConn *magicsock.Conn linkMon *monitor.Mon
linkMon *monitor.Mon
wgLock sync.Mutex // serializes all wgdev operations wgLock sync.Mutex // serializes all wgdev operations
lastReconfig string lastReconfig string
lastCfg wgcfg.Config lastCfg wgcfg.Config
lastRoutes string lastRoutes string
mu sync.Mutex mu sync.Mutex
peerSequence []wgcfg.Key statusCallback StatusCallback
endpoints []string peerSequence []wgcfg.Key
pingers map[wgcfg.Key]context.CancelFunc // mu must be held to call CancelFunc endpoints []string
pingers map[wgcfg.Key]context.CancelFunc // mu must be held to call CancelFunc
} }
type Loggify struct { type Loggify struct {
@ -416,9 +416,17 @@ func (e *userspaceEngine) SetFilter(filt *filter.Filter) {
} }
func (e *userspaceEngine) SetStatusCallback(cb StatusCallback) { func (e *userspaceEngine) SetStatusCallback(cb StatusCallback) {
e.mu.Lock()
defer e.mu.Unlock()
e.statusCallback = cb e.statusCallback = cb
} }
func (e *userspaceEngine) getStatusCallback() StatusCallback {
e.mu.Lock()
defer e.mu.Unlock()
return e.statusCallback
}
func (e *userspaceEngine) getStatus() (*Status, error) { func (e *userspaceEngine) getStatus() (*Status, error) {
e.wgLock.Lock() e.wgLock.Lock()
defer e.wgLock.Unlock() defer e.wgLock.Unlock()
@ -543,8 +551,8 @@ func (e *userspaceEngine) RequestStatus() {
e.logf("RequestStatus: weird: both s and err are nil\n") e.logf("RequestStatus: weird: both s and err are nil\n")
return return
} }
if e.statusCallback != nil { if cb := e.getStatusCallback(); cb != nil {
e.statusCallback(s, err) cb(s, err)
} }
default: default:
} }

Loading…
Cancel
Save