mirror of
https://github.com/netbirdio/netbird.git
synced 2025-05-29 14:22:41 +02:00
This PR adds supports for the WireGuard userspace implementation using Bind interface from wireguard-go. The newly introduced ICEBind struct implements Bind with UDPMux-based structs from pion/ice to handle hole punching using ICE. The core implementation was taken from StdBind of wireguard-go. The result is a single WireGuard port that is used for host and server reflexive candidates. Relay candidates are still handled separately and will be integrated in the following PRs. ICEBind checks the incoming packets for being STUN or WireGuard ones and routes them to UDPMux (to handle hole punching) or to WireGuard respectively.
118 lines
2.1 KiB
Go
118 lines
2.1 KiB
Go
package iface
|
|
|
|
import (
|
|
"net"
|
|
|
|
"github.com/pion/transport/v2"
|
|
|
|
"github.com/netbirdio/netbird/iface/bind"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"golang.org/x/sys/unix"
|
|
"golang.zx2c4.com/wireguard/device"
|
|
"golang.zx2c4.com/wireguard/ipc"
|
|
"golang.zx2c4.com/wireguard/tun"
|
|
)
|
|
|
|
type tunDevice struct {
|
|
address WGAddress
|
|
mtu int
|
|
tunAdapter TunAdapter
|
|
|
|
fd int
|
|
name string
|
|
device *device.Device
|
|
uapi net.Listener
|
|
iceBind *bind.ICEBind
|
|
}
|
|
|
|
func newTunDevice(address WGAddress, mtu int, tunAdapter TunAdapter, transportNet transport.Net) *tunDevice {
|
|
return &tunDevice{
|
|
address: address,
|
|
mtu: mtu,
|
|
tunAdapter: tunAdapter,
|
|
iceBind: bind.NewICEBind(transportNet),
|
|
}
|
|
}
|
|
|
|
func (t *tunDevice) Create() error {
|
|
var err error
|
|
t.fd, err = t.tunAdapter.ConfigureInterface(t.address.String(), t.mtu)
|
|
if err != nil {
|
|
log.Errorf("failed to create Android interface: %s", err)
|
|
return err
|
|
}
|
|
|
|
tunDevice, name, err := tun.CreateUnmonitoredTUNFromFD(t.fd)
|
|
if err != nil {
|
|
unix.Close(t.fd)
|
|
return err
|
|
}
|
|
t.name = name
|
|
|
|
log.Debugf("attaching to interface %v", name)
|
|
t.device = device.NewDevice(tunDevice, t.iceBind, device.NewLogger(device.LogLevelSilent, "[wiretrustee] "))
|
|
t.device.DisableSomeRoamingForBrokenMobileSemantics()
|
|
|
|
log.Debugf("create uapi")
|
|
tunSock, err := ipc.UAPIOpen(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
t.uapi, err = ipc.UAPIListen(name, tunSock)
|
|
if err != nil {
|
|
tunSock.Close()
|
|
unix.Close(t.fd)
|
|
return err
|
|
}
|
|
|
|
go func() {
|
|
for {
|
|
uapiConn, err := t.uapi.Accept()
|
|
if err != nil {
|
|
return
|
|
}
|
|
go t.device.IpcHandle(uapiConn)
|
|
}
|
|
}()
|
|
|
|
err = t.device.Up()
|
|
if err != nil {
|
|
tunSock.Close()
|
|
t.device.Close()
|
|
return err
|
|
}
|
|
log.Debugf("device is ready to use: %s", name)
|
|
return nil
|
|
}
|
|
|
|
func (t *tunDevice) Device() *device.Device {
|
|
return t.device
|
|
}
|
|
|
|
func (t *tunDevice) DeviceName() string {
|
|
return t.name
|
|
}
|
|
|
|
func (t *tunDevice) WgAddress() WGAddress {
|
|
return t.address
|
|
}
|
|
|
|
func (t *tunDevice) UpdateAddr(addr WGAddress) error {
|
|
// todo implement
|
|
return nil
|
|
}
|
|
|
|
func (t *tunDevice) Close() (err error) {
|
|
if t.uapi != nil {
|
|
err = t.uapi.Close()
|
|
}
|
|
|
|
if t.device != nil {
|
|
t.device.Close()
|
|
}
|
|
|
|
return
|
|
}
|