Skip to content

Commit

Permalink
feature: add feature to determine when to run wireguard userspace imp…
Browse files Browse the repository at this point in the history
…lementation or native one (linux)
  • Loading branch information
braginini committed Jun 23, 2021
1 parent dd72a01 commit 4216cd2
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 87 deletions.
46 changes: 1 addition & 45 deletions iface/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
46 changes: 46 additions & 0 deletions iface/iface_configuration.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package iface

import (
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
"net"
"time"

Expand All @@ -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 {
Expand Down
4 changes: 1 addition & 3 deletions iface/iface_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package iface

import (
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/tun"
"net"
"os/exec"
"strings"
Expand All @@ -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 {
Expand Down
80 changes: 43 additions & 37 deletions iface/iface_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

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
}
link := wgLink{
attrs: &attrs,
}

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
}
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
}

// 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("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
}

log.Debugf("bringing up interface: %s", iface)
err = netlink.LinkSetUp(&link)
if err != nil {
log.Errorf("error bringing up interface: %s", iface)
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)
}

return nil
}

// assignAddr Adds IP address to the tunnel interface
Expand Down
4 changes: 2 additions & 2 deletions iface/iface_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand Down

0 comments on commit 4216cd2

Please sign in to comment.