diff --git a/interface.go b/interface.go index f69ed062..61b1f228 100644 --- a/interface.go +++ b/interface.go @@ -490,6 +490,14 @@ func (f *Interface) Close() error { f.l.WithError(err).Error("Error while closing udp socket") } } + for i, r := range f.readers { + if i == 0 { + continue // f.readers[0] is f.inside, which we want to save for last + } + if err := r.Close(); err != nil { + f.l.WithError(err).Error("Error while closing tun reader") + } + } // Release the tun device return f.inside.Close() diff --git a/overlay/tun.go b/overlay/tun.go index 3a61d186..e0bf69f6 100644 --- a/overlay/tun.go +++ b/overlay/tun.go @@ -12,6 +12,15 @@ import ( const DefaultMTU = 1300 +type NameError struct { + Name string + Underlying error +} + +func (e *NameError) Error() string { + return fmt.Sprintf("could not set tun device name: %s because %s", e.Name, e.Underlying) +} + // TODO: We may be able to remove routines type DeviceFactory func(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, routines int) (Device, error) diff --git a/overlay/tun_freebsd.go b/overlay/tun_freebsd.go index 8d292263..2f65b3a4 100644 --- a/overlay/tun_freebsd.go +++ b/overlay/tun_freebsd.go @@ -266,7 +266,7 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, _ bool) ( } // Set the device name - ioctl(fd, syscall.SIOCSIFNAME, uintptr(unsafe.Pointer(&ifrr))) + _ = ioctl(fd, syscall.SIOCSIFNAME, uintptr(unsafe.Pointer(&ifrr))) } t := &tun{ diff --git a/overlay/tun_linux.go b/overlay/tun_linux.go index ea666f86..7e4aa418 100644 --- a/overlay/tun_linux.go +++ b/overlay/tun_linux.go @@ -112,9 +112,13 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueu if multiqueue { req.Flags |= unix.IFF_MULTI_QUEUE } - copy(req.Name[:], c.GetString("tun.dev", "")) + nameStr := c.GetString("tun.dev", "") + copy(req.Name[:], nameStr) if err = ioctl(uintptr(fd), uintptr(unix.TUNSETIFF), uintptr(unsafe.Pointer(&req))); err != nil { - return nil, err + return nil, &NameError{ + Name: nameStr, + Underlying: err, + } } name := strings.Trim(string(req.Name[:]), "\x00") @@ -713,6 +717,7 @@ func (t *tun) Close() error { if t.ioctlFd > 0 { _ = os.NewFile(t.ioctlFd, "ioctlFd").Close() + t.ioctlFd = 0 } return nil diff --git a/overlay/tun_windows.go b/overlay/tun_windows.go index b4d78b66..223eabee 100644 --- a/overlay/tun_windows.go +++ b/overlay/tun_windows.go @@ -74,7 +74,10 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, _ bool) ( l.WithError(err).Debug("Failed to create wintun device, retrying") tunDevice, err = wintun.CreateTUNWithRequestedGUID(deviceName, guid, t.MTU) if err != nil { - return nil, fmt.Errorf("create TUN device failed: %w", err) + return nil, &NameError{ + Name: deviceName, + Underlying: fmt.Errorf("create TUN device failed: %w", err), + } } } t.tun = tunDevice.(*wintun.NativeTun)