From abe095f036dd14a6a6cea44eabc599ee89db701d Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 18 Sep 2020 08:03:10 -0700 Subject: [PATCH] wgengine/tstun: make Close safe for concurrent use --- wgengine/tstun/tun.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wgengine/tstun/tun.go b/wgengine/tstun/tun.go index fb1804a14..95421f2a3 100644 --- a/wgengine/tstun/tun.go +++ b/wgengine/tstun/tun.go @@ -63,6 +63,8 @@ type TUN struct { // tdev is the underlying TUN device. tdev tun.Device + closeOnce sync.Once + _ [4]byte // force 64-bit alignment of following field on 32-bit lastActivityAtomic int64 // unix seconds of last send or receive @@ -140,15 +142,14 @@ func (t *TUN) SetDestIPActivityFuncs(m map[packet.IP]func()) { } func (t *TUN) Close() error { - select { - case <-t.closed: - // continue - default: + var err error + t.closeOnce.Do(func() { // Other channels need not be closed: poll will exit gracefully after this. close(t.closed) - } - return t.tdev.Close() + err = t.tdev.Close() + }) + return err } func (t *TUN) Events() chan tun.Event {