Skip to content

Conversation

johnmaguire
Copy link
Collaborator

@johnmaguire johnmaguire commented Jun 14, 2023

Fixes #309.

If no name is specified, the system chooses one. If a name is specified, and the tun exists already, we'll try to use it. If it doesn't exist, we'll rename the one the system gives us.

This could've been done with ifconfig, but I figured this was a good start towards syscalls for FreeBSD.

@@ -95,15 +93,18 @@ func newTun(l *logrus.Logger, deviceName string, cidr *net.IPNet, defaultMTU int
return nil, err
}

fileFd := file.Fd()
err = syscall.SetNonblock(int(fileFd), true)
Copy link
Collaborator Author

@johnmaguire johnmaguire Jun 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call is necessary due to a side-effect of file.Fd(). By default, the FIle returned by OpenFile is in non-blocking mode. If we leave it in blocking mode, Nebula will hang when we try to destroy the interface in the Close method (part of cleanly shutting down Nebula.)

Based on discussion with Go maintainers, it seems that file.Fd() should only be called if you're done using the File object. In this case we are not, so it's better to use file.SyscallConn() which I've updated this PR to do.

We do also call syscall.SetNonblock in tun_darwin.go. I suspect this is because the fd returned by unix.Socket() is not non-blocking by default, and we want to place it in non-blocking mode before calling NewFile:

NewFile returns a new File with the given file descriptor and name. The returned value will be nil if fd is not a valid file descriptor. On Unix systems, if the file descriptor is in non-blocking mode, NewFile will attempt to return a pollable File (one for which the SetDeadline methods work).

The only surprising bit to me is that in tun_linux.go we call file.Fd() in both newTun and newTunFromFd. This means that the fd is now in blocking mode, and we continue to use the File object in Nebula... this seems wrong but I haven't heard anyone report hangs on Linux. It's possible that the tun.Write function could be re-written to use SyscallConn, negating the need to call file.Fd in newTun, but I'm not sure what implications this would have.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgive my naive question, but why don't you ask the file descriptor?

res = fcntl (FileFd, F_GETFL)

should return all you need to know; all you have to check is O_NONBLOCK.

Copy link
Collaborator

@nbrownus nbrownus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me, we should rebind iOS and get a test build out after this merges.

@johnmaguire johnmaguire merged commit 8ba5d64 into slackhq:master Jun 22, 2023
@johnmaguire johnmaguire deleted the freebsd-tun-name branch June 22, 2023 16:13
@wadey wadey added this to the v1.8.0 milestone Jul 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FreeBSD requires tunX
4 participants