package iface import ( "strings" "github.com/pion/transport/v2" log "github.com/sirupsen/logrus" "golang.org/x/sys/unix" "golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/tun" "github.com/netbirdio/netbird/iface/bind" ) type tunDevice struct { address WGAddress mtu int routes []string tunAdapter TunAdapter fd int name string device *device.Device iceBind *bind.ICEBind } func newTunDevice(address WGAddress, mtu int, routes []string, tunAdapter TunAdapter, transportNet transport.Net) *tunDevice { return &tunDevice{ address: address, mtu: mtu, routes: routes, tunAdapter: tunAdapter, iceBind: bind.NewICEBind(transportNet), } } func (t *tunDevice) Create() error { var err error routesString := t.routesToString() t.fd, err = t.tunAdapter.ConfigureInterface(t.address.String(), t.mtu, routesString) 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] ")) // without this property mobile devices can discover remote endpoints if the configured one was wrong. // this helps with support for the older NetBird clients that had a hardcoded direct mode //t.device.DisableSomeRoamingForBrokenMobileSemantics() err = t.device.Up() if err != nil { 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.device != nil { t.device.Close() } return } func (t *tunDevice) routesToString() string { return strings.Join(t.routes, ";") }