[client] Update local interface addresses when gathering candidates (#3324)

This commit is contained in:
Viktor Liu
2025-02-21 19:44:50 +01:00
committed by GitHub
parent 73101c8977
commit 9a0354b681
4 changed files with 98 additions and 48 deletions

View File

@ -5,11 +5,16 @@ package stdnet
import (
"fmt"
"slices"
"sync"
"time"
"github.com/pion/transport/v3"
"github.com/pion/transport/v3/stdnet"
)
const updateInterval = 30 * time.Second
// Net is an implementation of the net.Net interface
// based on functions of the standard net package.
type Net struct {
@ -18,6 +23,10 @@ type Net struct {
iFaceDiscover iFaceDiscover
// interfaceFilter should return true if the given interfaceName is allowed
interfaceFilter func(interfaceName string) bool
lastUpdate time.Time
// mu is shared between interfaces and lastUpdate
mu sync.Mutex
}
// NewNetWithDiscover creates a new StdNet instance.
@ -43,18 +52,40 @@ func NewNet(disallowList []string) (*Net, error) {
// 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) {
n.mu.Lock()
defer n.mu.Unlock()
return n.updateInterfaces()
}
func (n *Net) updateInterfaces() (err error) {
allIfaces, err := n.iFaceDiscover.iFaces()
if err != nil {
return err
}
n.interfaces = n.filterInterfaces(allIfaces)
n.lastUpdate = time.Now()
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
n.mu.Lock()
defer n.mu.Unlock()
if time.Since(n.lastUpdate) < updateInterval {
return slices.Clone(n.interfaces), nil
}
if err := n.updateInterfaces(); err != nil {
return nil, fmt.Errorf("update interfaces: %w", err)
}
return slices.Clone(n.interfaces), nil
}
// InterfaceByIndex returns the interface specified by index.
@ -63,6 +94,8 @@ func (n *Net) Interfaces() ([]*transport.Interface, error) {
// sharing the logical data link; for more precision use
// InterfaceByName.
func (n *Net) InterfaceByIndex(index int) (*transport.Interface, error) {
n.mu.Lock()
defer n.mu.Unlock()
for _, ifc := range n.interfaces {
if ifc.Index == index {
return ifc, nil
@ -74,6 +107,8 @@ func (n *Net) InterfaceByIndex(index int) (*transport.Interface, error) {
// InterfaceByName returns the interface specified by name.
func (n *Net) InterfaceByName(name string) (*transport.Interface, error) {
n.mu.Lock()
defer n.mu.Unlock()
for _, ifc := range n.interfaces {
if ifc.Name == name {
return ifc, nil
@ -87,7 +122,7 @@ func (n *Net) filterInterfaces(interfaces []*transport.Interface) []*transport.I
if n.interfaceFilter == nil {
return interfaces
}
result := []*transport.Interface{}
var result []*transport.Interface
for _, iface := range interfaces {
if n.interfaceFilter(iface.Name) {
result = append(result, iface)