"fmt"
"net"
"os"
+ "sync"
"syscall"
"time"
"unsafe"
events chan Event
errors chan error
routeSocket int
+ closeOnce sync.Once
}
func retryInterfaceByIndex(index int) (iface *net.Interface, err error) {
}
func (tun *NativeTun) Close() error {
- var err2 error
- err1 := tun.tunFile.Close()
- if tun.routeSocket != -1 {
- unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
- err2 = unix.Close(tun.routeSocket)
- } else if tun.events != nil {
- close(tun.events)
- }
+ var err1, err2 error
+ tun.closeOnce.Do(func() {
+ err1 = tun.tunFile.Close()
+ if tun.routeSocket != -1 {
+ unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
+ err2 = unix.Close(tun.routeSocket)
+ } else if tun.events != nil {
+ close(tun.events)
+ }
+ })
if err1 != nil {
return err1
}
"fmt"
"net"
"os"
+ "sync"
"syscall"
"unsafe"
events chan Event
errors chan error
routeSocket int
+ closeOnce sync.Once
}
func (tun *NativeTun) routineRouteListener(tunIfindex int) {
}
func (tun *NativeTun) Close() error {
- var err3 error
- err1 := tun.tunFile.Close()
- err2 := tunDestroy(tun.name)
- if tun.routeSocket != -1 {
- unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
- err3 = unix.Close(tun.routeSocket)
- tun.routeSocket = -1
- } else if tun.events != nil {
- close(tun.events)
- }
+ var err1, err2, err3 error
+ tun.closeOnce.Do(func() {
+ err1 = tun.tunFile.Close()
+ err2 = tunDestroy(tun.name)
+ if tun.routeSocket != -1 {
+ unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
+ err3 = unix.Close(tun.routeSocket)
+ tun.routeSocket = -1
+ } else if tun.events != nil {
+ close(tun.events)
+ }
+ })
if err1 != nil {
return err1
}
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
}
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
}
"fmt"
"net"
"os"
+ "sync"
"syscall"
"unsafe"
events chan Event
errors chan error
routeSocket int
+ closeOnce sync.Once
}
func (tun *NativeTun) routineRouteListener(tunIfindex int) {
}
func (tun *NativeTun) Close() error {
- var err2 error
- err1 := tun.tunFile.Close()
- if tun.routeSocket != -1 {
- unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
- err2 = unix.Close(tun.routeSocket)
- tun.routeSocket = -1
- } else if tun.events != nil {
- close(tun.events)
- }
+ var err1, err2 error
+ tun.closeOnce.Do(func() {
+ err1 = tun.tunFile.Close()
+ if tun.routeSocket != -1 {
+ unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
+ err2 = unix.Close(tun.routeSocket)
+ tun.routeSocket = -1
+ } else if tun.events != nil {
+ close(tun.events)
+ }
+ })
if err1 != nil {
return err1
}
"fmt"
"log"
"os"
+ "sync"
"sync/atomic"
"time"
_ "unsafe"
rate rateJuggler
session wintun.Session
readWait windows.Handle
+ closeOnce sync.Once
}
var WintunPool, _ = wintun.MakePool("WireGuard")
}
func (tun *NativeTun) Close() error {
- tun.close = true
- tun.session.End()
var err error
- if tun.wt != nil {
- _, err = tun.wt.Delete(false)
- }
- close(tun.events)
+ tun.closeOnce.Do(func() {
+ tun.close = true
+ tun.session.End()
+ if tun.wt != nil {
+ _, err = tun.wt.Delete(false)
+ }
+ close(tun.events)
+ })
return err
}