mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-28 02:53:20 +01:00
2eeed55c18
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.
98 lines
2.8 KiB
Go
98 lines
2.8 KiB
Go
// Package stdnet is an extension of the pion's stdnet.
|
|
// With it the list of the interface can come from external source.
|
|
// More info: https://github.com/golang/go/issues/40569
|
|
package stdnet
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/pion/transport/v2"
|
|
"github.com/pion/transport/v2/stdnet"
|
|
)
|
|
|
|
// Net is an implementation of the net.Net interface
|
|
// based on functions of the standard net package.
|
|
type Net struct {
|
|
stdnet.Net
|
|
interfaces []*transport.Interface
|
|
iFaceDiscover iFaceDiscover
|
|
// interfaceFilter should return true if the given interfaceName is allowed
|
|
interfaceFilter func(interfaceName string) bool
|
|
}
|
|
|
|
// NewNetWithDiscover creates a new StdNet instance.
|
|
func NewNetWithDiscover(iFaceDiscover ExternalIFaceDiscover, disallowList []string) (*Net, error) {
|
|
n := &Net{
|
|
iFaceDiscover: newMobileIFaceDiscover(iFaceDiscover),
|
|
interfaceFilter: InterfaceFilter(disallowList),
|
|
}
|
|
return n, n.UpdateInterfaces()
|
|
}
|
|
|
|
// NewNet creates a new StdNet instance.
|
|
func NewNet(disallowList []string) (*Net, error) {
|
|
n := &Net{
|
|
iFaceDiscover: pionDiscover{},
|
|
interfaceFilter: InterfaceFilter(disallowList),
|
|
}
|
|
return n, n.UpdateInterfaces()
|
|
}
|
|
|
|
// UpdateInterfaces updates the internal list of network interfaces
|
|
// and associated addresses filtering them by name.
|
|
// The interfaces are discovered by an external iFaceDiscover function or by a default discoverer if the external one
|
|
// wasn't specified.
|
|
func (n *Net) UpdateInterfaces() (err error) {
|
|
allIfaces, err := n.iFaceDiscover.iFaces()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
n.interfaces = n.filterInterfaces(allIfaces)
|
|
return nil
|
|
}
|
|
|
|
// Interfaces returns a slice of interfaces which are available on the
|
|
// system
|
|
func (n *Net) Interfaces() ([]*transport.Interface, error) {
|
|
return n.interfaces, nil
|
|
}
|
|
|
|
// InterfaceByIndex returns the interface specified by index.
|
|
//
|
|
// On Solaris, it returns one of the logical network interfaces
|
|
// sharing the logical data link; for more precision use
|
|
// InterfaceByName.
|
|
func (n *Net) InterfaceByIndex(index int) (*transport.Interface, error) {
|
|
for _, ifc := range n.interfaces {
|
|
if ifc.Index == index {
|
|
return ifc, nil
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("%w: index=%d", transport.ErrInterfaceNotFound, index)
|
|
}
|
|
|
|
// InterfaceByName returns the interface specified by name.
|
|
func (n *Net) InterfaceByName(name string) (*transport.Interface, error) {
|
|
for _, ifc := range n.interfaces {
|
|
if ifc.Name == name {
|
|
return ifc, nil
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("%w: %s", transport.ErrInterfaceNotFound, name)
|
|
}
|
|
|
|
func (n *Net) filterInterfaces(interfaces []*transport.Interface) []*transport.Interface {
|
|
if n.interfaceFilter == nil {
|
|
return interfaces
|
|
}
|
|
result := []*transport.Interface{}
|
|
for _, iface := range interfaces {
|
|
if n.interfaceFilter(iface.Name) {
|
|
result = append(result, iface)
|
|
}
|
|
}
|
|
return result
|
|
}
|