Glue up all together

This commit is contained in:
braginini
2023-04-04 16:50:35 +02:00
parent 24cc5c4ef2
commit 87cbff1e7a
14 changed files with 184 additions and 80 deletions

View File

@@ -111,7 +111,7 @@ func RunClient(ctx context.Context, config *Config, statusRecorder *peer.Status,
localPeerState := peer.LocalPeerState{ localPeerState := peer.LocalPeerState{
IP: loginResp.GetPeerConfig().GetAddress(), IP: loginResp.GetPeerConfig().GetAddress(),
PubKey: myPrivateKey.PublicKey().String(), PubKey: myPrivateKey.PublicKey().String(),
KernelInterface: iface.WireguardModuleIsLoaded(), KernelInterface: iface.WireGuardModuleIsLoaded(),
FQDN: loginResp.GetPeerConfig().GetFqdn(), FQDN: loginResp.GetPeerConfig().GetFqdn(),
} }

View File

@@ -3,7 +3,6 @@ package internal
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/netbirdio/netbird/iface/bind"
"math/rand" "math/rand"
"net" "net"
"net/netip" "net/netip"
@@ -103,7 +102,8 @@ type Engine struct {
wgInterface *iface.WGIface wgInterface *iface.WGIface
udpMux *bind.UniversalUDPMuxDefault udpMux ice.UDPMux
udpMuxSrflx ice.UniversalUDPMux
udpMuxConn *net.UDPConn udpMuxConn *net.UDPConn
udpMuxConnSrflx *net.UDPConn udpMuxConnSrflx *net.UDPConn
@@ -118,6 +118,9 @@ type Engine struct {
routeManager routemanager.Manager routeManager routemanager.Manager
dnsServer dns.Server dnsServer dns.Server
// userspaceBind indicates whether a
userspaceBind bool
} }
// Peer is an instance of the Connection Peer // Peer is an instance of the Connection Peer
@@ -173,7 +176,7 @@ func (e *Engine) Start() error {
e.syncMsgMux.Lock() e.syncMsgMux.Lock()
defer e.syncMsgMux.Unlock() defer e.syncMsgMux.Unlock()
wgIfaceName := e.config.WgIfaceName wgIFaceName := e.config.WgIfaceName
wgAddr := e.config.WgAddr wgAddr := e.config.WgAddr
myPrivateKey := e.config.WgPrivateKey myPrivateKey := e.config.WgPrivateKey
var err error var err error
@@ -181,31 +184,60 @@ func (e *Engine) Start() error {
if err != nil { if err != nil {
log.Warnf("failed to create pion's stdnet: %s", err) log.Warnf("failed to create pion's stdnet: %s", err)
} }
e.wgInterface, err = iface.NewWGIFace(wgIfaceName, wgAddr, iface.DefaultMTU, e.config.TunAdapter, transportNet) e.wgInterface, err = iface.NewWGIFace(wgIFaceName, wgAddr, iface.DefaultMTU, e.config.TunAdapter, transportNet)
if err != nil { if err != nil {
log.Errorf("failed creating wireguard interface instance %s: [%s]", wgIfaceName, err.Error()) log.Errorf("failed creating wireguard interface instance %s: [%s]", wgIFaceName, err.Error())
return err return err
} }
err = e.wgInterface.Create() err = e.wgInterface.Create()
if err != nil { if err != nil {
log.Errorf("failed creating tunnel interface %s: [%s]", wgIfaceName, err.Error()) log.Errorf("failed creating tunnel interface %s: [%s]", wgIFaceName, err.Error())
e.close() e.close()
return err return err
} }
err = e.wgInterface.Configure(myPrivateKey.String(), e.config.WgPort) err = e.wgInterface.Configure(myPrivateKey.String(), e.config.WgPort)
if err != nil { if err != nil {
log.Errorf("failed configuring Wireguard interface [%s]: %s", wgIfaceName, err.Error()) log.Errorf("failed configuring Wireguard interface [%s]: %s", wgIFaceName, err.Error())
e.close() e.close()
return err return err
} }
iceBind := e.wgInterface.GetBind() if e.wgInterface.IsUserspaceBind() {
e.udpMux, err = iceBind.GetICEMux() iceBind := e.wgInterface.GetBind()
if err != nil { udpMux, err := iceBind.GetICEMux()
e.close() if err != nil {
return err e.close()
return err
}
e.udpMux = udpMux.UDPMuxDefault
e.udpMuxSrflx = udpMux
log.Infof("using userspace bind mode %s", udpMux.LocalAddr().String())
} else {
networkName := "udp"
if e.config.DisableIPv6Discovery {
networkName = "udp4"
}
e.udpMuxConn, err = net.ListenUDP(networkName, &net.UDPAddr{Port: e.config.UDPMuxPort})
if err != nil {
log.Errorf("failed listening on UDP port %d: [%s]", e.config.UDPMuxPort, err.Error())
e.close()
return err
}
udpMuxParams := ice.UDPMuxParams{
UDPConn: e.udpMuxConn,
Net: transportNet,
}
e.udpMux = ice.NewUDPMuxDefault(udpMuxParams)
e.udpMuxConnSrflx, err = net.ListenUDP(networkName, &net.UDPAddr{Port: e.config.UDPMuxSrflxPort})
if err != nil {
log.Errorf("failed listening on UDP port %d: [%s]", e.config.UDPMuxSrflxPort, err.Error())
e.close()
return err
}
e.udpMuxSrflx = ice.NewUniversalUDPMuxDefault(ice.UniversalUDPMuxParams{UDPConn: e.udpMuxConnSrflx, Net: transportNet})
} }
e.routeManager = routemanager.NewManager(e.ctx, e.config.WgPrivateKey.PublicKey().String(), e.wgInterface, e.statusRecorder) e.routeManager = routemanager.NewManager(e.ctx, e.config.WgPrivateKey.PublicKey().String(), e.wgInterface, e.statusRecorder)
@@ -476,7 +508,7 @@ func (e *Engine) updateConfig(conf *mgmProto.PeerConfig) error {
e.statusRecorder.UpdateLocalPeerState(peer.LocalPeerState{ e.statusRecorder.UpdateLocalPeerState(peer.LocalPeerState{
IP: e.config.WgAddr, IP: e.config.WgAddr,
PubKey: e.config.WgPrivateKey.PublicKey().String(), PubKey: e.config.WgPrivateKey.PublicKey().String(),
KernelInterface: iface.WireguardModuleIsLoaded(), KernelInterface: iface.WireGuardModuleIsLoaded(),
FQDN: conf.GetFqdn(), FQDN: conf.GetFqdn(),
}) })
@@ -797,11 +829,12 @@ func (e Engine) createPeerConn(pubKey string, allowedIPs string) (*peer.Conn, er
InterfaceBlackList: e.config.IFaceBlackList, InterfaceBlackList: e.config.IFaceBlackList,
DisableIPv6Discovery: e.config.DisableIPv6Discovery, DisableIPv6Discovery: e.config.DisableIPv6Discovery,
Timeout: timeout, Timeout: timeout,
UDPMux: e.udpMux.UDPMuxDefault, UDPMux: e.udpMux,
UDPMuxSrflx: e.udpMux, UDPMuxSrflx: e.udpMuxSrflx,
ProxyConfig: proxyConfig, ProxyConfig: proxyConfig,
LocalWgPort: e.config.WgPort, LocalWgPort: e.config.WgPort,
NATExternalIPs: e.parseNATExternalIPMappings(), NATExternalIPs: e.parseNATExternalIPMappings(),
UserspaceBind: e.wgInterface.IsUserspaceBind(),
} }
peerConn, err := peer.NewConn(config, e.statusRecorder, e.config.TunAdapter, e.config.IFaceDiscover) peerConn, err := peer.NewConn(config, e.statusRecorder, e.config.TunAdapter, e.config.IFaceDiscover)

View File

@@ -44,6 +44,9 @@ type ConnConfig struct {
LocalWgPort int LocalWgPort int
NATExternalIPs []string NATExternalIPs []string
// UsesBind indicates whether the WireGuard interface is userspace and uses bind.ICEBind
UserspaceBind bool
} }
// OfferAnswer represents a session establishment offer or answer // OfferAnswer represents a session establishment offer or answer
@@ -291,7 +294,7 @@ func (conn *Conn) Open() error {
return err return err
} }
if conn.proxy.Type() == proxy.TypeNoProxy { if conn.proxy.Type() == proxy.TypeDirectNoProxy {
host, _, _ := net.SplitHostPort(remoteConn.LocalAddr().String()) host, _, _ := net.SplitHostPort(remoteConn.LocalAddr().String())
rhost, _, _ := net.SplitHostPort(remoteConn.RemoteAddr().String()) rhost, _, _ := net.SplitHostPort(remoteConn.RemoteAddr().String())
// direct Wireguard connection // direct Wireguard connection
@@ -313,14 +316,21 @@ func (conn *Conn) Open() error {
// useProxy determines whether a direct connection (without a go proxy) is possible // useProxy determines whether a direct connection (without a go proxy) is possible
// //
// There are 2 cases: // There are 3 cases:
// //
// * When neither candidate is from hard nat and one of the peers has a public IP // * When neither candidate is from hard nat and one of the peers has a public IP
// //
// * both peers are in the same private network // * both peers are in the same private network
// //
// * Local peer uses userspace interface with bind.ICEBind and is not relayed
//
// Please note, that this check happens when peers were already able to ping each other using ICE layer. // Please note, that this check happens when peers were already able to ping each other using ICE layer.
func shouldUseProxy(pair *ice.CandidatePair) bool { func shouldUseProxy(pair *ice.CandidatePair, userspaceBind bool) bool {
if !isRelayCandidate(pair.Local) && userspaceBind {
return false
}
if !isHardNATCandidate(pair.Local) && isHostCandidateWithPublicIP(pair.Remote) { if !isHardNATCandidate(pair.Local) && isHostCandidateWithPublicIP(pair.Remote) {
return false return false
} }
@@ -336,6 +346,10 @@ func shouldUseProxy(pair *ice.CandidatePair) bool {
return true return true
} }
func isRelayCandidate(candidate ice.Candidate) bool {
return candidate.Type() == ice.CandidateTypeRelay
}
func isHardNATCandidate(candidate ice.Candidate) bool { func isHardNATCandidate(candidate ice.Candidate) bool {
return candidate.Type() == ice.CandidateTypeRelay || candidate.Type() == ice.CandidateTypePeerReflexive return candidate.Type() == ice.CandidateTypeRelay || candidate.Type() == ice.CandidateTypePeerReflexive
} }
@@ -384,7 +398,7 @@ func (conn *Conn) startProxy(remoteConn net.Conn, remoteWgPort int) error {
if pair.Local.Type() == ice.CandidateTypeRelay || pair.Remote.Type() == ice.CandidateTypeRelay { if pair.Local.Type() == ice.CandidateTypeRelay || pair.Remote.Type() == ice.CandidateTypeRelay {
peerState.Relayed = true peerState.Relayed = true
} }
peerState.Direct = p.Type() == proxy.TypeNoProxy peerState.Direct = p.Type() == proxy.TypeDirectNoProxy
err = conn.statusRecorder.UpdatePeerState(peerState) err = conn.statusRecorder.UpdatePeerState(peerState)
if err != nil { if err != nil {
@@ -395,8 +409,7 @@ func (conn *Conn) startProxy(remoteConn net.Conn, remoteWgPort int) error {
} }
func (conn *Conn) getProxyWithMessageExchange(pair *ice.CandidatePair, remoteWgPort int) proxy.Proxy { func (conn *Conn) getProxyWithMessageExchange(pair *ice.CandidatePair, remoteWgPort int) proxy.Proxy {
return proxy.NewWireGuardProxy(conn.config.ProxyConfig) useProxy := shouldUseProxy(pair, conn.config.UserspaceBind)
useProxy := shouldUseProxy(pair)
localDirectMode := !useProxy localDirectMode := !useProxy
remoteDirectMode := localDirectMode remoteDirectMode := localDirectMode
@@ -406,9 +419,14 @@ func (conn *Conn) getProxyWithMessageExchange(pair *ice.CandidatePair, remoteWgP
remoteDirectMode = conn.receiveRemoteDirectMode() remoteDirectMode = conn.receiveRemoteDirectMode()
} }
if conn.config.UserspaceBind {
log.Debugf("using WireGuard no proxy userspace bind mode with peer %s", conn.config.Key)
return proxy.NewNoProxy(conn.config.ProxyConfig)
}
if localDirectMode && remoteDirectMode { if localDirectMode && remoteDirectMode {
log.Debugf("using WireGuard direct mode with peer %s", conn.config.Key) log.Debugf("using WireGuard direct mode with peer %s", conn.config.Key)
return proxy.NewNoProxy(conn.config.ProxyConfig, remoteWgPort) return proxy.NewDirectNoProxy(conn.config.ProxyConfig, remoteWgPort)
} }
log.Debugf("falling back to local proxy mode with peer %s", conn.config.Key) log.Debugf("falling back to local proxy mode with peer %s", conn.config.Key)

View File

@@ -325,7 +325,7 @@ func TestConn_ShouldUseProxy(t *testing.T) {
for _, testCase := range testCases { for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) { t.Run(testCase.name, func(t *testing.T) {
result := shouldUseProxy(testCase.candatePair) result := shouldUseProxy(testCase.candatePair, false)
if result != testCase.expected { if result != testCase.expected {
t.Errorf("got a different result. Expected %t Got %t", testCase.expected, result) t.Errorf("got a different result. Expected %t Got %t", testCase.expected, result)
} }
@@ -366,7 +366,7 @@ func TestGetProxyWithMessageExchange(t *testing.T) {
}, },
inputDirectModeSupport: true, inputDirectModeSupport: true,
inputRemoteModeMessage: true, inputRemoteModeMessage: true,
expected: proxy.TypeWireguard, expected: proxy.TypeWireGuard,
}, },
{ {
name: "Should Result In Using Wireguard Proxy When Remote Eval Is Use Proxy", name: "Should Result In Using Wireguard Proxy When Remote Eval Is Use Proxy",
@@ -376,7 +376,7 @@ func TestGetProxyWithMessageExchange(t *testing.T) {
}, },
inputDirectModeSupport: true, inputDirectModeSupport: true,
inputRemoteModeMessage: false, inputRemoteModeMessage: false,
expected: proxy.TypeWireguard, expected: proxy.TypeWireGuard,
}, },
{ {
name: "Should Result In Using Wireguard Proxy When Remote Direct Mode Support Is False And Local Eval Is Use Proxy", name: "Should Result In Using Wireguard Proxy When Remote Direct Mode Support Is False And Local Eval Is Use Proxy",
@@ -386,7 +386,7 @@ func TestGetProxyWithMessageExchange(t *testing.T) {
}, },
inputDirectModeSupport: false, inputDirectModeSupport: false,
inputRemoteModeMessage: false, inputRemoteModeMessage: false,
expected: proxy.TypeWireguard, expected: proxy.TypeWireGuard,
}, },
{ {
name: "Should Result In Using Direct When Remote Direct Mode Support Is False And Local Eval Is No Use Proxy", name: "Should Result In Using Direct When Remote Direct Mode Support Is False And Local Eval Is No Use Proxy",
@@ -396,7 +396,7 @@ func TestGetProxyWithMessageExchange(t *testing.T) {
}, },
inputDirectModeSupport: false, inputDirectModeSupport: false,
inputRemoteModeMessage: false, inputRemoteModeMessage: false,
expected: proxy.TypeNoProxy, expected: proxy.TypeDirectNoProxy,
}, },
{ {
name: "Should Result In Using Direct When Local And Remote Eval Is No Proxy", name: "Should Result In Using Direct When Local And Remote Eval Is No Proxy",
@@ -406,7 +406,7 @@ func TestGetProxyWithMessageExchange(t *testing.T) {
}, },
inputDirectModeSupport: true, inputDirectModeSupport: true,
inputRemoteModeMessage: true, inputRemoteModeMessage: true,
expected: proxy.TypeNoProxy, expected: proxy.TypeDirectNoProxy,
}, },
} }
for _, testCase := range testCases { for _, testCase := range testCases {

View File

@@ -0,0 +1,55 @@
package proxy
import (
log "github.com/sirupsen/logrus"
"net"
)
// DirectNoProxy is used when there is no need for a proxy between ICE and WireGuard.
// This is possible in either of these cases:
// - peers are in the same local network
// - one of the peers has a public static IP (host)
// DirectNoProxy will just update remote peer with a remote host and fixed WireGuard port (r.g. 51820).
// In order DirectNoProxy to work, WireGuard port has to be fixed for the time being.
type DirectNoProxy struct {
config Config
// RemoteWgListenPort is a WireGuard port of a remote peer.
// It is used instead of the hardcoded 51820 port.
RemoteWgListenPort int
}
// NewDirectNoProxy creates a new DirectNoProxy with a provided config and remote peer's WireGuard listen port
func NewDirectNoProxy(config Config, remoteWgPort int) *DirectNoProxy {
return &DirectNoProxy{config: config, RemoteWgListenPort: remoteWgPort}
}
func (p *DirectNoProxy) Close() error {
err := p.config.WgInterface.RemovePeer(p.config.RemoteKey)
if err != nil {
return err
}
return nil
}
// Start just updates WireGuard peer with the remote IP and default WireGuard port
func (p *DirectNoProxy) Start(remoteConn net.Conn) error {
log.Debugf("using DirectNoProxy while connecting to peer %s", p.config.RemoteKey)
addr, err := net.ResolveUDPAddr("udp", remoteConn.RemoteAddr().String())
if err != nil {
return err
}
addr.Port = p.RemoteWgListenPort
err = p.config.WgInterface.UpdatePeer(p.config.RemoteKey, p.config.AllowedIps, DefaultWgKeepAlive,
addr, p.config.PreSharedKey)
if err != nil {
return err
}
return nil
}
func (p *DirectNoProxy) Type() Type {
return TypeDirectNoProxy
}

View File

@@ -5,24 +5,18 @@ import (
"net" "net"
) )
// NoProxy is used when there is no need for a proxy between ICE and WireGuard. // NoProxy is used just to configure WireGuard without any local proxy in between.
// This is possible in either of these cases: // Used when the WireGuard interface is userspace and uses bind.ICEBind
// - peers are in the same local network
// - one of the peers has a public static IP (host)
// NoProxy will just update remote peer with a remote host and fixed WireGuard port (r.g. 51820).
// In order NoProxy to work, WireGuard port has to be fixed for the time being.
type NoProxy struct { type NoProxy struct {
config Config config Config
// RemoteWgListenPort is a WireGuard port of a remote peer.
// It is used instead of the hardcoded 51820 port.
RemoteWgListenPort int
} }
// NewNoProxy creates a new NoProxy with a provided config and remote peer's WireGuard listen port // NewNoProxy creates a new NoProxy with a provided config
func NewNoProxy(config Config, remoteWgPort int) *NoProxy { func NewNoProxy(config Config) *NoProxy {
return &NoProxy{config: config, RemoteWgListenPort: remoteWgPort} return &NoProxy{config: config}
} }
// Close removes peer from the WireGuard interface
func (p *NoProxy) Close() error { func (p *NoProxy) Close() error {
err := p.config.WgInterface.RemovePeer(p.config.RemoteKey) err := p.config.WgInterface.RemovePeer(p.config.RemoteKey)
if err != nil { if err != nil {
@@ -31,23 +25,16 @@ func (p *NoProxy) Close() error {
return nil return nil
} }
// Start just updates WireGuard peer with the remote IP and default WireGuard port // Start just updates WireGuard peer with the remote address
func (p *NoProxy) Start(remoteConn net.Conn) error { func (p *NoProxy) Start(remoteConn net.Conn) error {
log.Debugf("using NoProxy while connecting to peer %s", p.config.RemoteKey) log.Debugf("using NoProxy to connect to peer %s at %s", p.config.RemoteKey, remoteConn.RemoteAddr().String())
addr, err := net.ResolveUDPAddr("udp", remoteConn.RemoteAddr().String()) addr, err := net.ResolveUDPAddr("udp", remoteConn.RemoteAddr().String())
if err != nil { if err != nil {
return err return err
} }
addr.Port = p.RemoteWgListenPort return p.config.WgInterface.UpdatePeer(p.config.RemoteKey, p.config.AllowedIps, DefaultWgKeepAlive,
err = p.config.WgInterface.UpdatePeer(p.config.RemoteKey, p.config.AllowedIps, DefaultWgKeepAlive,
addr, p.config.PreSharedKey) addr, p.config.PreSharedKey)
if err != nil {
return err
}
return nil
} }
func (p *NoProxy) Type() Type { func (p *NoProxy) Type() Type {

View File

@@ -13,9 +13,10 @@ const DefaultWgKeepAlive = 25 * time.Second
type Type string type Type string
const ( const (
TypeNoProxy Type = "NoProxy" TypeDirectNoProxy Type = "DirectNoProxy"
TypeWireguard Type = "Wireguard" TypeWireGuard Type = "WireGuard"
TypeDummy Type = "Dummy" TypeDummy Type = "Dummy"
TypeNoProxy Type = "NoProxy"
) )
type Config struct { type Config struct {

View File

@@ -124,5 +124,5 @@ func (p *WireGuardProxy) proxyToLocal() {
} }
func (p *WireGuardProxy) Type() Type { func (p *WireGuardProxy) Type() Type {
return TypeWireguard return TypeWireGuard
} }

View File

@@ -17,9 +17,15 @@ const (
// WGIface represents a interface instance // WGIface represents a interface instance
type WGIface struct { type WGIface struct {
tun *tunDevice tun *tunDevice
configurer wGConfigurer configurer wGConfigurer
mu sync.Mutex mu sync.Mutex
userspaceBind bool
}
// IsUserspaceBind indicates whether this interfaces is userspace with bind.ICEBind
func (w *WGIface) IsUserspaceBind() bool {
return w.userspaceBind
} }
// GetBind returns a userspace implementation of WireGuard Bind interface // GetBind returns a userspace implementation of WireGuard Bind interface
@@ -32,7 +38,7 @@ func (w *WGIface) GetBind() *bind.ICEBind {
func (w *WGIface) Create() error { func (w *WGIface) Create() error {
w.mu.Lock() w.mu.Lock()
defer w.mu.Unlock() defer w.mu.Unlock()
log.Debugf("create Wireguard interface %s", w.tun.DeviceName()) log.Debugf("create WireGuard interface %s", w.tun.DeviceName())
return w.tun.Create() return w.tun.Create()
} }

View File

@@ -5,21 +5,23 @@ import (
"sync" "sync"
) )
// NewWGIFace Creates a new Wireguard interface instance // NewWGIFace Creates a new WireGuard interface instance
func NewWGIFace(ifaceName string, address string, mtu int, tunAdapter TunAdapter, transportNet transport.Net) (*WGIface, error) { func NewWGIFace(iFaceName string, address string, mtu int, tunAdapter TunAdapter, transportNet transport.Net) (*WGIface, error) {
wgIface := &WGIface{ wgIFace := &WGIface{
mu: sync.Mutex{}, mu: sync.Mutex{},
} }
wgAddress, err := parseWGAddress(address) wgAddress, err := parseWGAddress(address)
if err != nil { if err != nil {
return wgIface, err return wgIFace, err
} }
tun := newTunDevice(wgAddress, mtu, tunAdapter, transportNet) tun := newTunDevice(wgAddress, mtu, tunAdapter, transportNet)
wgIface.tun = tun wgIFace.tun = tun
wgIface.configurer = newWGConfigurer(tun) wgIFace.configurer = newWGConfigurer(tun)
return wgIface, nil wgIFace.userspaceBind = !WireGuardModuleIsLoaded()
return wgIFace, nil
} }

View File

@@ -7,19 +7,20 @@ import (
"sync" "sync"
) )
// NewWGIFace Creates a new Wireguard interface instance // NewWGIFace Creates a new WireGuard interface instance
func NewWGIFace(ifaceName string, address string, mtu int, tunAdapter TunAdapter, transportNet transport.Net) (*WGIface, error) { func NewWGIFace(iFaceName string, address string, mtu int, tunAdapter TunAdapter, transportNet transport.Net) (*WGIface, error) {
wgIface := &WGIface{ wgIFace := &WGIface{
mu: sync.Mutex{}, mu: sync.Mutex{},
} }
wgAddress, err := parseWGAddress(address) wgAddress, err := parseWGAddress(address)
if err != nil { if err != nil {
return wgIface, err return wgIFace, err
} }
wgIface.tun = newTunDevice(ifaceName, wgAddress, mtu, transportNet) wgIFace.tun = newTunDevice(iFaceName, wgAddress, mtu, transportNet)
wgIface.configurer = newWGConfigurer(ifaceName) wgIFace.configurer = newWGConfigurer(iFaceName)
return wgIface, nil wgIFace.userspaceBind = !WireGuardModuleIsLoaded()
return wgIFace, nil
} }

View File

@@ -3,7 +3,7 @@
package iface package iface
// WireguardModuleIsLoaded check if we can load wireguard mod (linux only) // WireGuardModuleIsLoaded check if we can load WireGuard mod (linux only)
func WireguardModuleIsLoaded() bool { func WireGuardModuleIsLoaded() bool {
return false return false
} }

View File

@@ -81,9 +81,10 @@ func tunModuleIsLoaded() bool {
return tunLoaded return tunLoaded
} }
// WireguardModuleIsLoaded check if we can load wireguard mod (linux only) // WireGuardModuleIsLoaded check if we can load WireGuard mod (linux only)
func WireguardModuleIsLoaded() bool { func WireGuardModuleIsLoaded() bool {
if canCreateFakeWireguardInterface() { return false
if canCreateFakeWireGuardInterface() {
return true return true
} }
@@ -96,7 +97,7 @@ func WireguardModuleIsLoaded() bool {
return loaded return loaded
} }
func canCreateFakeWireguardInterface() bool { func canCreateFakeWireGuardInterface() bool {
link := newWGLink("mustnotexist") link := newWGLink("mustnotexist")
// We willingly try to create a device with an invalid // We willingly try to create a device with an invalid

View File

@@ -11,7 +11,7 @@ import (
) )
func (c *tunDevice) Create() error { func (c *tunDevice) Create() error {
if WireguardModuleIsLoaded() { if WireGuardModuleIsLoaded() {
log.Info("using kernel WireGuard") log.Info("using kernel WireGuard")
return c.createWithKernel() return c.createWithKernel()
} }