wgengine/magicsock: wait for derphttp client goroutine to exit

Signed-off-by: Dmytro Shynkevych <dmytro@tailscale.com>
reviewable/pr556/r1
Dmytro Shynkevych 4 years ago committed by Dmytro Shynkevych
parent fa45d606fa
commit 2f15894a10

@ -1887,6 +1887,17 @@ func (c *Conn) Close() error {
c.pconn6.Close()
}
err := c.pconn4.Close()
// The goroutine running dc.Connect in derpWriteChanOfAddr may linger
// and appear to leak, as observed in https://github.com/tailscale/tailscale/issues/554.
// This is despite the underlying context being cancelled by connCtxCancel above.
// To avoid this condition, we must wait on derpStarted here
// to ensure that this goroutine has exited by the time Close returns.
// We only do this if derpWriteChanOfAddr has executed at least once:
// on the first run, it sets firstDerp := true and spawns the aforementioned goroutine.
// To detect this, we check activeDerp, which is initialized to non-nil on the first run.
if c.activeDerp != nil {
<-c.derpStarted
}
// Wait on endpoints updating right at the end, once everything is
// already closed. We want everything else in the Conn to be
// consistently in the closed state before we release mu to wait

Loading…
Cancel
Save