Procházet zdrojové kódy

block less I guess

JackDoan před 8 měsíci
rodič
revize
3086364246
3 změnil soubory, kde provedl 41 přidání a 36 odebrání
  1. 7 5
      interface.go
  2. 29 26
      overlay/tun_linux.go
  3. 5 5
      udp/udp_linux.go

+ 7 - 5
interface.go

@@ -507,12 +507,14 @@ func (f *Interface) Close() error {
 	}
 
 	// Release the tun readers
-	for i, u := range f.readers {
-		err := u.Close()
-		if err != nil {
-			f.l.WithError(err).WithField("i", i).Error("Error while closing tun device")
+	for i, r := range f.readers {
+		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")
 		}
 	}
 
-	return nil
+	return f.inside.Close()
 }

+ 29 - 26
overlay/tun_linux.go

@@ -72,6 +72,11 @@ type ifreqQLEN struct {
 }
 
 func newTunFromFd(c *config.C, l *logrus.Logger, deviceFd int, vpnNetworks []netip.Prefix) (*tun, error) {
+	err := unix.SetNonblock(deviceFd, true)
+	if err != nil {
+		return nil, err
+	}
+
 	file := os.NewFile(uintptr(deviceFd), "/dev/net/tun")
 
 	t, err := newTunGeneric(c, l, file, vpnNetworks)
@@ -122,6 +127,11 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueu
 	}
 	name := strings.Trim(string(req.Name[:]), "\x00")
 
+	err = unix.SetNonblock(fd, true)
+	if err != nil {
+		return nil, err
+	}
+
 	file := os.NewFile(uintptr(fd), "/dev/net/tun")
 	t, err := newTunGeneric(c, l, file, vpnNetworks)
 	if err != nil {
@@ -145,7 +155,12 @@ func newTunGeneric(c *config.C, l *logrus.Logger, file *os.File, vpnNetworks []n
 		l:                         l,
 	}
 
-	err := t.reload(c, true)
+	err := unix.SetNonblock(t.fd, true)
+	if err != nil {
+		return nil, err
+	}
+
+	err = t.reload(c, true)
 	if err != nil {
 		return nil, err
 	}
@@ -251,6 +266,11 @@ func (t *tun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
 		return nil, err
 	}
 
+	err = unix.SetNonblock(fd, true)
+	if err != nil {
+		return nil, err
+	}
+
 	file := os.NewFile(uintptr(fd), "/dev/net/tun")
 
 	return file, nil
@@ -261,29 +281,6 @@ func (t *tun) RoutesFor(ip netip.Addr) routing.Gateways {
 	return r
 }
 
-func (t *tun) Write(b []byte) (int, error) {
-	var nn int
-	maximum := len(b)
-
-	for {
-		n, err := unix.Write(t.fd, b[nn:maximum])
-		if n > 0 {
-			nn += n
-		}
-		if nn == len(b) {
-			return nn, err
-		}
-
-		if err != nil {
-			return nn, err
-		}
-
-		if n == 0 {
-			return nn, io.ErrUnexpectedEOF
-		}
-	}
-}
-
 func (t *tun) deviceBytes() (o [16]byte) {
 	for i, c := range t.Device {
 		o[i] = byte(c)
@@ -712,11 +709,17 @@ func (t *tun) Close() error {
 	}
 
 	if t.ReadWriteCloser != nil {
-		_ = t.ReadWriteCloser.Close()
+		err := t.ReadWriteCloser.Close()
+		if err != nil {
+			t.l.WithField("error", err).Error("Failed to close read/write connection")
+		}
 	}
 
 	if t.ioctlFd > 0 {
-		_ = os.NewFile(t.ioctlFd, "ioctlFd").Close()
+		err := os.NewFile(t.ioctlFd, "ioctlFd").Close()
+		if err != nil {
+			t.l.WithField("error", err).Error("Failed to close ioctl fd")
+		}
 		t.ioctlFd = 0
 	}
 

+ 5 - 5
udp/udp_linux.go

@@ -162,7 +162,7 @@ func (u *StdConn) ReadSingle(msgs []rawMessage) (int, error) {
 		)
 
 		if err != 0 {
-			if err == unix.EAGAIN || err == unix.EINTR {
+			if err == unix.EAGAIN || err == unix.EINTR || err == unix.EWOULDBLOCK {
 				continue
 			}
 			return 0, &net.OpError{Op: "recvmsg", Err: err}
@@ -184,12 +184,12 @@ func (u *StdConn) ReadMulti(msgs []rawMessage) (int, error) {
 			0,
 			0,
 		)
-		if err == unix.EAGAIN || err == unix.EINTR {
-			if n == 0 {
-				continue
-			} else {
+		if err == unix.EAGAIN || err == unix.EINTR || err == unix.EWOULDBLOCK {
+			if int64(n) > 0 {
 				//ran out of time, but have some messages to return
 				return int(n), nil
+			} else {
+				continue
 			}
 		} else if err != 0 {
 			return 0, &net.OpError{Op: "recvmmsg", Err: err}