package ice
import (
"fmt"
"net"
"github.com/pion/logging"
"github.com/pion/transport/v3"
"github.com/pion/transport/v3/stdnet"
)
type MultiUDPMuxDefault struct {
muxes []UDPMux
localAddrToMux map [string ]UDPMux
}
func NewMultiUDPMuxDefault (muxes ...UDPMux ) *MultiUDPMuxDefault {
addrToMux := make (map [string ]UDPMux )
for _ , mux := range muxes {
for _ , addr := range mux .GetListenAddresses () {
addrToMux [addr .String ()] = mux
}
}
return &MultiUDPMuxDefault {
muxes : muxes ,
localAddrToMux : addrToMux ,
}
}
func (m *MultiUDPMuxDefault ) GetConn (ufrag string , addr net .Addr ) (net .PacketConn , error ) {
mux , ok := m .localAddrToMux [addr .String ()]
if !ok {
return nil , errNoUDPMuxAvailable
}
return mux .GetConn (ufrag , addr )
}
func (m *MultiUDPMuxDefault ) RemoveConnByUfrag (ufrag string ) {
for _ , mux := range m .muxes {
mux .RemoveConnByUfrag (ufrag )
}
}
func (m *MultiUDPMuxDefault ) Close () error {
var err error
for _ , mux := range m .muxes {
if e := mux .Close (); e != nil {
err = e
}
}
return err
}
func (m *MultiUDPMuxDefault ) GetListenAddresses () []net .Addr {
addrs := make ([]net .Addr , 0 , len (m .localAddrToMux ))
for _ , mux := range m .muxes {
addrs = append (addrs , mux .GetListenAddresses ()...)
}
return addrs
}
func NewMultiUDPMuxFromPort (port int , opts ...UDPMuxFromPortOption ) (*MultiUDPMuxDefault , error ) {
params := multiUDPMuxFromPortParam {
networks : []NetworkType {NetworkTypeUDP4 , NetworkTypeUDP6 },
}
for _ , opt := range opts {
opt .apply (¶ms )
}
if params .net == nil {
var err error
if params .net , err = stdnet .NewNet (); err != nil {
return nil , fmt .Errorf ("failed to get create network: %w" , err )
}
}
_ , addrs , err := localInterfaces (params .net , params .ifFilter , params .ipFilter , params .networks , params .includeLoopback )
if err != nil {
return nil , err
}
conns := make ([]net .PacketConn , 0 , len (addrs ))
for _ , addr := range addrs {
conn , listenErr := params .net .ListenUDP ("udp" , &net .UDPAddr {
IP : addr .AsSlice (),
Port : port ,
Zone : addr .Zone (),
})
if listenErr != nil {
err = listenErr
break
}
if params .readBufferSize > 0 {
_ = conn .SetReadBuffer (params .readBufferSize )
}
if params .writeBufferSize > 0 {
_ = conn .SetWriteBuffer (params .writeBufferSize )
}
conns = append (conns , conn )
}
if err != nil {
for _ , conn := range conns {
_ = conn .Close ()
}
return nil , err
}
muxes := make ([]UDPMux , 0 , len (conns ))
for _ , conn := range conns {
mux := NewUDPMuxDefault (UDPMuxParams {
Logger : params .logger ,
UDPConn : conn ,
Net : params .net ,
})
muxes = append (muxes , mux )
}
return NewMultiUDPMuxDefault (muxes ...), nil
}
type UDPMuxFromPortOption interface {
apply(*multiUDPMuxFromPortParam )
}
type multiUDPMuxFromPortParam struct {
ifFilter func (string ) (keep bool )
ipFilter func (ip net .IP ) (keep bool )
networks []NetworkType
readBufferSize int
writeBufferSize int
logger logging .LeveledLogger
includeLoopback bool
net transport .Net
}
type udpMuxFromPortOption struct {
f func (*multiUDPMuxFromPortParam )
}
func (o *udpMuxFromPortOption ) apply (p *multiUDPMuxFromPortParam ) {
o .f (p )
}
func UDPMuxFromPortWithInterfaceFilter (f func (string ) (keep bool )) UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .ifFilter = f
},
}
}
func UDPMuxFromPortWithIPFilter (f func (ip net .IP ) (keep bool )) UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .ipFilter = f
},
}
}
func UDPMuxFromPortWithNetworks (networks ...NetworkType ) UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .networks = networks
},
}
}
func UDPMuxFromPortWithReadBufferSize (size int ) UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .readBufferSize = size
},
}
}
func UDPMuxFromPortWithWriteBufferSize (size int ) UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .writeBufferSize = size
},
}
}
func UDPMuxFromPortWithLogger (logger logging .LeveledLogger ) UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .logger = logger
},
}
}
func UDPMuxFromPortWithLoopback () UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .includeLoopback = true
},
}
}
func UDPMuxFromPortWithNet (n transport .Net ) UDPMuxFromPortOption {
return &udpMuxFromPortOption {
f : func (p *multiUDPMuxFromPortParam ) {
p .net = n
},
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .