control/controlclient: fix deadlock in timeout+keepalive race
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>pull/321/head
parent
d052586da7
commit
b8594dc937
|
@ -499,21 +499,25 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
|
||||||
const pollTimeout = 120 * time.Second
|
const pollTimeout = 120 * time.Second
|
||||||
timeout := time.NewTimer(pollTimeout)
|
timeout := time.NewTimer(pollTimeout)
|
||||||
timeoutReset := make(chan struct{})
|
timeoutReset := make(chan struct{})
|
||||||
defer close(timeoutReset)
|
pollDone := make(chan struct{})
|
||||||
|
defer close(pollDone)
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
case <-pollDone:
|
||||||
|
vlogf("netmap: ending timeout goroutine")
|
||||||
|
return
|
||||||
case <-timeout.C:
|
case <-timeout.C:
|
||||||
c.logf("map response long-poll timed out!")
|
c.logf("map response long-poll timed out!")
|
||||||
cancel()
|
cancel()
|
||||||
return
|
return
|
||||||
case _, ok := <-timeoutReset:
|
case <-timeoutReset:
|
||||||
if !ok {
|
|
||||||
vlogf("netmap: ending timeout goroutine")
|
|
||||||
return // channel closed, shut down goroutine
|
|
||||||
}
|
|
||||||
if !timeout.Stop() {
|
if !timeout.Stop() {
|
||||||
<-timeout.C
|
select {
|
||||||
|
case <-timeout.C:
|
||||||
|
case <-pollDone:
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vlogf("netmap: reset timeout timer")
|
vlogf("netmap: reset timeout timer")
|
||||||
timeout.Reset(pollTimeout)
|
timeout.Reset(pollTimeout)
|
||||||
|
@ -551,7 +555,13 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
|
||||||
}
|
}
|
||||||
if resp.KeepAlive {
|
if resp.KeepAlive {
|
||||||
vlogf("netmap: got keep-alive")
|
vlogf("netmap: got keep-alive")
|
||||||
timeoutReset <- struct{}{}
|
select {
|
||||||
|
case timeoutReset <- struct{}{}:
|
||||||
|
vlogf("netmap: sent keep-alive timer reset")
|
||||||
|
case <-ctx.Done():
|
||||||
|
c.logf("netmap: not resetting timer for keep-alive due to: %v", ctx.Err())
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
vlogf("netmap: got new map")
|
vlogf("netmap: got new map")
|
||||||
|
|
Loading…
Reference in New Issue