From 810e07a998a6e3986bb3526dc8353f72046d5345 Mon Sep 17 00:00:00 2001 From: JackDoan Date: Wed, 15 Apr 2026 14:01:55 -0500 Subject: [PATCH] nbio for tun --- interface.go | 16 ++++++++-------- overlay/tun_linux.go | 6 ++---- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/interface.go b/interface.go index 03542f54..61c8cc3e 100644 --- a/interface.go +++ b/interface.go @@ -294,7 +294,7 @@ func (f *Interface) listenOut(i int) { //TODO: Trigger Control to close } - f.l.Debugf("underlay reader %v is done", i) + f.l.Infof("underlay reader %v is done", i) } func (f *Interface) listenIn(reader io.ReadWriteCloser, i int) { @@ -318,7 +318,7 @@ func (f *Interface) listenIn(reader io.ReadWriteCloser, i int) { f.consumeInsidePacket(packet[:n], fwPacket, nb, out, i, conntrackCache.Get(f.l)) } - f.l.Debugf("overlay reader %v is done", i) + f.l.Infof("overlay reader %v is done", i) } func (f *Interface) RegisterConfigChangeCallbacks(c *config.C) { @@ -493,13 +493,14 @@ func (f *Interface) GetCertState() *CertState { } func (f *Interface) Close() error { + var err error f.closed.Store(true) // Release the udp readers - for _, u := range f.writers { - err := u.Close() + for i, u := range f.writers { + err = u.Close() if err != nil { - f.l.WithError(err).Error("Error while closing udp socket") + f.l.WithError(err).WithField("writer", i).Error("Error while closing udp socket") } } @@ -508,11 +509,10 @@ func (f *Interface) Close() error { if i == 0 { continue // f.readers[0] is f.inside, which we want to save for last, since it closes other stuff too } - if err := r.Close(); err != nil { - f.l.WithError(err).Error("Error while closing tun reader") + if err = r.Close(); err != nil { + f.l.WithError(err).WithField("reader", i).Error("Error while closing tun reader") } } - // Release the tun device return f.inside.Close() } diff --git a/overlay/tun_linux.go b/overlay/tun_linux.go index 0fa5a51d..c9586b6b 100644 --- a/overlay/tun_linux.go +++ b/overlay/tun_linux.go @@ -26,7 +26,6 @@ import ( type tun struct { io.ReadWriteCloser - fd int Device string vpnNetworks []netip.Prefix MaxMTU int @@ -85,7 +84,7 @@ func newTunFromFd(c *config.C, l *logrus.Logger, deviceFd int, vpnNetworks []net } func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueue bool) (*tun, error) { - fd, err := unix.Open("/dev/net/tun", os.O_RDWR, 0) + fd, err := unix.Open("/dev/net/tun", os.O_RDWR|unix.O_NONBLOCK, 0) if err != nil { // If /dev/net/tun doesn't exist, try to create it (will happen in docker) if os.IsNotExist(err) { @@ -98,7 +97,7 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueu return nil, fmt.Errorf("failed to create /dev/net/tun: %w", err) } - fd, err = unix.Open("/dev/net/tun", os.O_RDWR, 0) + fd, err = unix.Open("/dev/net/tun", os.O_RDWR|unix.O_NONBLOCK, 0) if err != nil { return nil, fmt.Errorf("created /dev/net/tun, but still failed: %w", err) } @@ -136,7 +135,6 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueu func newTunGeneric(c *config.C, l *logrus.Logger, file *os.File, vpnNetworks []netip.Prefix) (*tun, error) { t := &tun{ ReadWriteCloser: file, - fd: int(file.Fd()), vpnNetworks: vpnNetworks, TXQueueLen: c.GetInt("tun.tx_queue", 500), useSystemRoutes: c.GetBool("tun.use_system_route_table", false),