diff options
author | Brad Fitzpatrick <bradfitz@tailscale.com> | 2021-02-18 14:53:22 -0800 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-02-22 15:26:29 +0100 |
commit | 0f4809f366daa77c6e2f5b09d3f05771fe9bf188 (patch) | |
tree | 51fcba51b8d65b559e4ac2da16bd045ec8b6d730 /tun/tun_linux.go | |
parent | fecb8f482ad8bc4d56fa6202fe15d2a221d0dbe5 (diff) |
tun: make NativeTun.Close well behaved, not crash on double close
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Diffstat (limited to 'tun/tun_linux.go')
-rw-r--r-- | tun/tun_linux.go | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/tun/tun_linux.go b/tun/tun_linux.go index 501f3a3..e0c9878 100644 --- a/tun/tun_linux.go +++ b/tun/tun_linux.go @@ -39,6 +39,8 @@ type NativeTun struct { hackListenerClosed sync.Mutex statusListenersShutdown chan struct{} + closeOnce sync.Once + nameOnce sync.Once // guards calling initNameCache, which sets following fields nameCache string // name of interface nameErr error @@ -372,17 +374,18 @@ func (tun *NativeTun) Events() chan Event { } func (tun *NativeTun) Close() error { - var err1 error - if tun.statusListenersShutdown != nil { - close(tun.statusListenersShutdown) - if tun.netlinkCancel != nil { - err1 = tun.netlinkCancel.Cancel() + var err1, err2 error + tun.closeOnce.Do(func() { + if tun.statusListenersShutdown != nil { + close(tun.statusListenersShutdown) + if tun.netlinkCancel != nil { + err1 = tun.netlinkCancel.Cancel() + } + } else if tun.events != nil { + close(tun.events) } - } else if tun.events != nil { - close(tun.events) - } - err2 := tun.tunFile.Close() - + err2 = tun.tunFile.Close() + }) if err1 != nil { return err1 } |