ipn: always guard LocalBackend.prefs with mu

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This commit is contained in:
David Crawshaw 2020-02-28 21:34:56 -05:00
parent bcf3719b9e
commit d133339216

View File

@ -167,12 +167,12 @@ func (b *LocalBackend) Start(opts Options) error {
b.notify = opts.Notify b.notify = opts.Notify
b.netMapCache = nil b.netMapCache = nil
persist := b.prefs.Persist
b.mu.Unlock() b.mu.Unlock()
b.updateFilter(nil) b.updateFilter(nil)
var err error var err error
persist := b.prefs.Persist
if persist == nil { if persist == nil {
// let controlclient initialize it // let controlclient initialize it
persist = &controlclient.Persist{} persist = &controlclient.Persist{}
@ -207,13 +207,19 @@ func (b *LocalBackend) Start(opts Options) error {
} }
if newSt.Persist != nil { if newSt.Persist != nil {
persist := *newSt.Persist // copy persist := *newSt.Persist // copy
b.mu.Lock()
b.prefs.Persist = &persist b.prefs.Persist = &persist
if b.stateKey != "" { // TODO: accessed without b.mu held? prefs := b.prefs.Clone()
if err := b.store.WriteState(b.stateKey, b.prefs.ToBytes()); err != nil { stateKey := b.stateKey
b.mu.Unlock()
if stateKey != "" {
if err := b.store.WriteState(stateKey, prefs.ToBytes()); err != nil {
b.logf("Failed to save new controlclient state: %v", err) b.logf("Failed to save new controlclient state: %v", err)
} }
} }
b.send(Notify{Prefs: b.prefs.Clone()}) b.send(Notify{Prefs: prefs})
} }
if newSt.NetMap != nil { if newSt.NetMap != nil {
b.mu.Lock() b.mu.Lock()
@ -246,10 +252,14 @@ func (b *LocalBackend) Start(opts Options) error {
return return
} }
if newSt.NetMap != nil { if newSt.NetMap != nil {
if b.prefs.WantRunning || b.State() == NeedsLogin { b.mu.Lock()
if b.state == NeedsLogin {
b.prefs.WantRunning = true b.prefs.WantRunning = true
} }
b.SetPrefs(b.prefs) prefs := b.prefs
b.mu.Unlock()
b.SetPrefs(prefs)
} }
b.stateMachine() b.stateMachine()
}) })
@ -283,10 +293,14 @@ func (b *LocalBackend) Start(opts Options) error {
b.send(Notify{Engine: &es}) b.send(Notify{Engine: &es})
}) })
b.mu.Lock()
prefs := b.prefs.Clone()
b.mu.Unlock()
blid := b.backendLogID blid := b.backendLogID
b.logf("Backend: logs: be:%v fe:%v\n", blid, opts.FrontendLogID) b.logf("Backend: logs: be:%v fe:%v\n", blid, opts.FrontendLogID)
b.send(Notify{BackendLogID: &blid}) b.send(Notify{BackendLogID: &blid})
b.send(Notify{Prefs: b.prefs.Clone()}) b.send(Notify{Prefs: prefs})
cli.Login(nil, controlclient.LoginDefault) cli.Login(nil, controlclient.LoginDefault)
return nil return nil
@ -671,12 +685,14 @@ func (b *LocalBackend) enterState(newState State) {
func (b *LocalBackend) nextState() State { func (b *LocalBackend) nextState() State {
b.mu.Lock() b.mu.Lock()
b.assertClientLocked() b.assertClientLocked()
c := b.c var (
netMap := b.netMapCache c = b.c
netMap = b.netMapCache
state = b.state
wantRunning = b.prefs.WantRunning
)
b.mu.Unlock() b.mu.Unlock()
state := b.State()
if netMap == nil { if netMap == nil {
if c.AuthCantContinue() { if c.AuthCantContinue() {
// Auth was interrupted or waiting for URL visit, // Auth was interrupted or waiting for URL visit,
@ -686,7 +702,7 @@ func (b *LocalBackend) nextState() State {
// Auth or map request needs to finish // Auth or map request needs to finish
return state return state
} }
} else if !b.prefs.WantRunning { } else if !wantRunning {
return Stopped return Stopped
} else if e := netMap.Expiry; !e.IsZero() && time.Until(e) <= 0 { } else if e := netMap.Expiry; !e.IsZero() && time.Until(e) <= 0 {
return NeedsLogin return NeedsLogin