summaryrefslogtreecommitdiffhomepage
path: root/tun/tun_linux.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@tailscale.com>2021-02-18 14:53:22 -0800
committerJason A. Donenfeld <Jason@zx2c4.com>2021-02-22 15:26:29 +0100
commit0f4809f366daa77c6e2f5b09d3f05771fe9bf188 (patch)
tree51fcba51b8d65b559e4ac2da16bd045ec8b6d730 /tun/tun_linux.go
parentfecb8f482ad8bc4d56fa6202fe15d2a221d0dbe5 (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.go23
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
}