feature: add feature to determine when to run wireguard userspace implementation or native one (linux)

This commit is contained in:
braginini 2021-06-23 16:11:54 +02:00
parent dd72a01ecf
commit 4216cd2986
5 changed files with 97 additions and 91 deletions

View File

@ -2,52 +2,8 @@
package iface
import (
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
)
// Saves tun device object - is it required?
var tunIface tun.Device
// Create Creates a new Wireguard interface, sets a given IP and brings it up.
// Will reuse an existing one.
func Create(iface string, address string) error {
var err error
tunIface, err = tun.CreateTUN(iface, defaultMTU)
if err != nil {
return err
}
// We need to create a wireguard-go device and listen to configuration requests
tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] "))
err = tunDevice.Up()
if err != nil {
return err
}
uapi, err := getUAPI(iface)
if err != nil {
return err
}
go func() {
for {
uapiConn, err := uapi.Accept()
if err != nil {
log.Debugln(err)
return
}
go tunDevice.IpcHandle(uapiConn)
}
}()
log.Debugln("UAPI listener started")
err = assignAddr(address, tunIface)
if err != nil {
return err
}
return nil
return CreateInUserspace(iface, address)
}

View File

@ -1,6 +1,9 @@
package iface
import (
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
"net"
"time"
@ -23,6 +26,49 @@ func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) {
return &key, Configure(iface, key.String())
}
// CreateInUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation
func CreateInUserspace(iface string, address string) error {
var err error
tunIface, err := tun.CreateTUN(iface, defaultMTU)
if err != nil {
return err
}
// We need to create a wireguard-go device and listen to configuration requests
tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] "))
err = tunDevice.Up()
if err != nil {
return err
}
uapi, err := getUAPI(iface)
if err != nil {
return err
}
go func() {
for {
uapiConn, err := uapi.Accept()
if err != nil {
log.Debugln(err)
return
}
go tunDevice.IpcHandle(uapiConn)
}
}()
log.Debugln("UAPI listener started")
ifaceName, err := tunIface.Name()
if err != nil {
return err
}
err = assignAddr(address, ifaceName)
if err != nil {
return err
}
return nil
}
// Configure configures a Wireguard interface
// The interface must exist before calling this method (e.g. call interface.Create() before)
func Configure(iface string, privateKey string) error {

View File

@ -2,7 +2,6 @@ package iface
import (
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/tun"
"net"
"os/exec"
"strings"
@ -13,8 +12,7 @@ import (
//)
// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
func assignAddr(address string, tunDevice tun.Device) error {
ifaceName, err := tunDevice.Name()
func assignAddr(address string, ifaceName string) error {
ip := strings.Split(address, "/")
cmd := exec.Command("ifconfig", ifaceName, "inet", address, ip[0])
if out, err := cmd.CombinedOutput(); err != nil {

View File

@ -9,50 +9,56 @@ import (
// Create Creates a new Wireguard interface, sets a given IP and brings it up.
// Will reuse an existing one.
func Create(iface string, address string) error {
attrs := netlink.NewLinkAttrs()
attrs.Name = iface
link := wgLink{
attrs: &attrs,
if WireguardModExists() {
attrs := netlink.NewLinkAttrs()
attrs.Name = iface
link := wgLink{
attrs: &attrs,
}
log.Debugf("adding device: %s", iface)
err := netlink.LinkAdd(&link)
if os.IsExist(err) {
log.Infof("interface %s already exists. Will reuse.", iface)
} else if err != nil {
return err
}
log.Debugf("adding address %s to interface: %s", address, iface)
addr, _ := netlink.ParseAddr(address)
err = netlink.AddrAdd(&link, addr)
if os.IsExist(err) {
log.Infof("interface %s already has the address: %s", iface, address)
} else if err != nil {
return err
}
err = assignAddr(address, iface)
if err != nil {
return err
}
// todo do a discovery
log.Debugf("setting MTU: %s", iface)
err = netlink.LinkSetMTU(&link, defaultMTU)
if err != nil {
log.Errorf("error setting MTU on interface: %s", iface)
return err
}
log.Debugf("bringing up interface: %s", iface)
err = netlink.LinkSetUp(&link)
if err != nil {
log.Errorf("error bringing up interface: %s", iface)
return err
}
return nil
} else {
return CreateInUserspace(iface, address)
}
log.Debugf("adding device: %s", iface)
err := netlink.LinkAdd(&link)
if os.IsExist(err) {
log.Infof("interface %s already exists. Will reuse.", iface)
} else if err != nil {
return err
}
log.Debugf("adding address %s to interface: %s", address, iface)
addr, _ := netlink.ParseAddr(address)
err = netlink.AddrAdd(&link, addr)
if os.IsExist(err) {
log.Infof("interface %s already has the address: %s", iface, address)
} else if err != nil {
return err
}
err = assignAddr(address, iface)
if err != nil {
return err
}
// todo do a discovery
log.Debugf("setting MTU: %s", iface)
err = netlink.LinkSetMTU(&link, defaultMTU)
if err != nil {
log.Errorf("error setting MTU on interface: %s", iface)
return err
}
log.Debugf("bringing up interface: %s", iface)
err = netlink.LinkSetUp(&link)
if err != nil {
log.Errorf("error bringing up interface: %s", iface)
return err
}
return nil
}
// assignAddr Adds IP address to the tunnel interface

View File

@ -9,8 +9,8 @@ import (
)
// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
func assignAddr(address string, tunDevice tun.Device) error {
ifaceName, err := tunDevice.Name()
func assignAddr(address string, ifaceName string) error {
nativeTunDevice := tunDevice.(*tun.NativeTun)
luid := winipcfg.LUID(nativeTunDevice.LUID())