|
|
|
@ -268,11 +268,13 @@ func (c *Client) authRoutine() {
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
c.mu.Lock()
|
|
|
|
|
c.logf("authRoutine: %s", c.state)
|
|
|
|
|
expiry := c.expiry
|
|
|
|
|
goal := c.loginGoal
|
|
|
|
|
ctx := c.authCtx
|
|
|
|
|
synced := c.synced
|
|
|
|
|
if goal != nil {
|
|
|
|
|
c.logf("authRoutine: %s; wantLoggedIn=%v", c.state, goal.wantLoggedIn)
|
|
|
|
|
} else {
|
|
|
|
|
c.logf("authRoutine: %s; goal=nil", c.state)
|
|
|
|
|
}
|
|
|
|
|
c.mu.Unlock()
|
|
|
|
|
|
|
|
|
|
select {
|
|
|
|
@ -293,51 +295,13 @@ func (c *Client) authRoutine() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if goal == nil {
|
|
|
|
|
// Wait for something interesting to happen
|
|
|
|
|
var exp <-chan time.Time
|
|
|
|
|
var expTimer *time.Timer
|
|
|
|
|
if expiry != nil && !expiry.IsZero() {
|
|
|
|
|
// if expiry is in the future, don't delay
|
|
|
|
|
// past that time.
|
|
|
|
|
// If it's in the past, then it's already
|
|
|
|
|
// being handled by someone, so no need to
|
|
|
|
|
// wake ourselves up again.
|
|
|
|
|
now := c.timeNow()
|
|
|
|
|
if expiry.Before(now) {
|
|
|
|
|
delay := expiry.Sub(now)
|
|
|
|
|
if delay > 5*time.Second {
|
|
|
|
|
delay = time.Second
|
|
|
|
|
}
|
|
|
|
|
expTimer = time.NewTimer(delay)
|
|
|
|
|
exp = expTimer.C
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
|
|
|
|
if expTimer != nil {
|
|
|
|
|
expTimer.Stop()
|
|
|
|
|
}
|
|
|
|
|
c.logf("authRoutine: context done.")
|
|
|
|
|
case <-exp:
|
|
|
|
|
// Unfortunately the key expiry isn't provided
|
|
|
|
|
// by the control server until mapRequest.
|
|
|
|
|
// So we have to do some hackery with c.expiry
|
|
|
|
|
// in here.
|
|
|
|
|
// TODO(apenwarr): add a key expiry field in RegisterResponse.
|
|
|
|
|
c.logf("authRoutine: key expiration check.")
|
|
|
|
|
if synced && expiry != nil && !expiry.IsZero() && expiry.Before(c.timeNow()) {
|
|
|
|
|
c.logf("Key expired; setting loggedIn=false.")
|
|
|
|
|
|
|
|
|
|
c.mu.Lock()
|
|
|
|
|
c.loginGoal = &LoginGoal{
|
|
|
|
|
wantLoggedIn: c.loggedIn,
|
|
|
|
|
}
|
|
|
|
|
c.loggedIn = false
|
|
|
|
|
c.expiry = nil
|
|
|
|
|
c.mu.Unlock()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if !goal.wantLoggedIn {
|
|
|
|
|
// Wait for user to Login or Logout.
|
|
|
|
|
<-ctx.Done()
|
|
|
|
|
c.logf("authRoutine: context done.")
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !goal.wantLoggedIn {
|
|
|
|
|
err := c.direct.TryLogout(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
report(err, "TryLogout")
|
|
|
|
|