diff --git a/usrwg/tun_darwin.go b/usrwg/tun_darwin.go index a9701b3..6f09f5a 100644 --- a/usrwg/tun_darwin.go +++ b/usrwg/tun_darwin.go @@ -1,7 +1,19 @@ package usrwg -import "golang.zx2c4.com/wireguard/tun" +import ( + "os" + + "golang.zx2c4.com/wireguard/tun" +) func createTUN(mtu int) (tun.Device, error) { return tun.CreateTUN("utun", mtu) } + +func createTUNFromFile(file *os.File, mtu int) (tun.Device, error) { + return tun.CreateTUNFromFile(file, mtu) +} + +func createTUNFromFD(fd uintptr, mtu int) (tun.Device, error) { + return createTUNFromFile(os.NewFile(fd, "tun"), mtu) +} diff --git a/usrwg/tun_linux.go b/usrwg/tun_linux.go index b056a1a..53dffa5 100644 --- a/usrwg/tun_linux.go +++ b/usrwg/tun_linux.go @@ -1,7 +1,20 @@ package usrwg -import "golang.zx2c4.com/wireguard/tun" +import ( + "os" + + "golang.zx2c4.com/wireguard/tun" +) func createTUN(mtu int) (tun.Device, error) { return tun.CreateTUN("ts0", mtu) } + +func createTUNFromFile(file *os.File, mtu int) (tun.Device, error) { + return tun.CreateTUNFromFile(file, mtu) +} + +func createTUNFromFD(fd uintptr, _ int) (tun.Device, error) { + dev, _, err := tun.CreateUnmonitoredTUNFromFD(int(fd)) + return dev, err +} diff --git a/usrwg/tun_windows.go b/usrwg/tun_windows.go index 1d09998..c22e0e3 100644 --- a/usrwg/tun_windows.go +++ b/usrwg/tun_windows.go @@ -9,6 +9,14 @@ func createTUN(mtu int) (tun.Device, error) { return tun.CreateTUN("toversok", mtu) } +func createTUNFromFile(file *os.File, mtu int) (tun.Device, error) { + return nil, errors.New("not implemented on windows") +} + +func createTUNFromFD(_ uintptr, _ int) (tun.Device, error) { + return nil, errors.New("not implemented on windows") +} + func init() { tun.WintunTunnelType = "ToverSok" guid, err := windows.GUIDFromString("{37217669-42da-4657-a55b-13375d328250}") diff --git a/usrwg/wgusp.go b/usrwg/wgusp.go index d062e35..5f60524 100644 --- a/usrwg/wgusp.go +++ b/usrwg/wgusp.go @@ -5,6 +5,7 @@ import ( "log/slog" "net" "net/netip" + "os" "slices" "syscall" @@ -27,6 +28,26 @@ func NewUsrWGHost() *UserSpaceWireGuardHost { type UserSpaceWireGuardHost struct { running *UserSpaceWireGuardController + tunFile *os.File + tunFD uintptr +} + +func (u *UserSpaceWireGuardHost) SetTUNFile(f *os.File) { + u.tunFile = f + if f == nil { + u.tunFD = 0 + } else { + u.tunFD = f.Fd() + } +} + +func (u *UserSpaceWireGuardHost) SetTUNFD(fd uintptr) { + // TODO: this has the side-effect on linux to use the "unmonitored" creation step, + // instead of a monitored creation step, needs to be made explicit + u.tunFD = fd + if u.tunFile != nil { + u.tunFD = 0 + } } func (u *UserSpaceWireGuardHost) Reset() error { @@ -47,9 +68,7 @@ func (u *UserSpaceWireGuardHost) Controller(privateKey key.NodePrivate, addr4, a } } - // TODO set this to 1392 per https://docs.eduvpn.org/server/v3/wireguard.html - // and make adjustable by environment variable - tunDev, err := createTUN(1280) + tunDev, err := u.createTUN() if err != nil { return nil, fmt.Errorf("failed to create TUN device: %w", err) } @@ -111,6 +130,21 @@ func (u *UserSpaceWireGuardHost) Controller(privateKey key.NodePrivate, addr4, a return usrwgc, nil } +// TODO set this to 1392 per https://docs.eduvpn.org/server/v3/wireguard.html +// and make adjustable by environment variable + +const tunMtu = 1280 + +func (u *UserSpaceWireGuardHost) createTUN() (tun.Device, error) { + if u.tunFile != nil { + return createTUNFromFile(u.tunFile, tunMtu) + } else if u.tunFD != 0 { + return createTUNFromFD(u.tunFD, tunMtu) + } + + return createTUN(tunMtu) +} + type UserSpaceWireGuardController struct { wgDev *device.Device bind *ToverSokBind