From 6711060cdb38d0fac6313b0e8daf4a849903541d Mon Sep 17 00:00:00 2001 From: cnderrauber Date: Wed, 23 Nov 2022 16:01:36 +0800 Subject: [PATCH] Add enable loopback candidate option (#1185) --- config-sample.yaml | 2 ++ go.mod | 2 +- go.sum | 7 ++---- pkg/config/config.go | 25 ++++++++++---------- pkg/config/ip.go | 8 +++++-- pkg/rtc/config.go | 15 ++++++++---- pkg/service/wire_gen.go | 52 ++--------------------------------------- 7 files changed, 37 insertions(+), 74 deletions(-) diff --git a/config-sample.yaml b/config-sample.yaml index 0db26cd40..f6866d6d3 100644 --- a/config-sample.yaml +++ b/config-sample.yaml @@ -80,6 +80,8 @@ rtc: # low_quality: 500ms # mid_quality: 1s # high_quality: 1s + # # when set, Livekit will collect loopback candidates, it is useful for some VM have public address mapped to its loopback interface. + # enable_loopback_candidate: true # # network interface filter. If the machine has more than one network interface and you'd like it to use or skip specific interfaces # # both inclusion and exclusion filters can be used together. If neither is defined (default), all interfaces on the machine will be used. # # If both of them are set, then only include takes effect. diff --git a/go.mod b/go.mod index 40a418c03..78eb86a57 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/pion/stun v0.3.5 github.com/pion/transport v0.13.1 github.com/pion/turn/v2 v2.0.8 - github.com/pion/webrtc/v3 v3.1.48 + github.com/pion/webrtc/v3 v3.1.49 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 github.com/rs/cors v1.8.2 diff --git a/go.sum b/go.sum index 4af610162..3187956b3 100644 --- a/go.sum +++ b/go.sum @@ -308,7 +308,6 @@ github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQ github.com/pion/dtls/v2 v2.1.5 h1:jlh2vtIyUBShchoTDqpCCqiYCyRFJ/lvf/gQ8TALs+c= github.com/pion/dtls/v2 v2.1.5/go.mod h1:BqCE7xPZbPSubGasRoDFJeTsyJtdD1FanJYL0JGheqY= github.com/pion/ice/v2 v2.2.6/go.mod h1:SWuHiOGP17lGromHTFadUe1EuPgFh/oCU6FCMZHooVE= -github.com/pion/ice/v2 v2.2.11/go.mod h1:NqUDUao6SjSs1+4jrqpexDmFlptlVhGxQjcymXLaVvE= github.com/pion/ice/v2 v2.2.12 h1:n3M3lUMKQM5IoofhJo73D3qVla+mJN2nVvbSPq32Nig= github.com/pion/ice/v2 v2.2.12/go.mod h1:z2KXVFyRkmjetRlaVRgjO9U3ShKwzhlUylvxKfHfd5A= github.com/pion/interceptor v0.1.11/go.mod h1:tbtKjZY14awXd7Bq0mmWvgtHB5MDaRN7HV3OZ/uy7s8= @@ -346,8 +345,8 @@ github.com/pion/turn/v2 v2.0.8/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkp github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o= github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M= github.com/pion/webrtc/v3 v3.1.44/go.mod h1:G/J8k0+grVsjC/rjCZ24AKoCCxcFFODgh7zThNZGs0M= -github.com/pion/webrtc/v3 v3.1.48 h1:lRAdRAewrcQTlj2n7pDUbJcuiQpHwwMq61edwhTkVq4= -github.com/pion/webrtc/v3 v3.1.48/go.mod h1:JOk9h4pOtogTAWM1SCoEG2opDQmEOR0QZcbEo9vy0Xc= +github.com/pion/webrtc/v3 v3.1.49 h1:rbsNGxK9jMYts+xE6zYAJMUQHnGwmk/JYze8yttW+to= +github.com/pion/webrtc/v3 v3.1.49/go.mod h1:kHf/o47QW4No1rgpsFux/h7lUhtUnwFnSFDZOXeLapw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -547,7 +546,6 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= @@ -642,7 +640,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/config/config.go b/pkg/config/config.go index 17ed0546f..080c075a6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -58,18 +58,19 @@ type Config struct { } type RTCConfig struct { - UDPPort uint32 `yaml:"udp_port,omitempty"` - TCPPort uint32 `yaml:"tcp_port,omitempty"` - ICEPortRangeStart uint32 `yaml:"port_range_start,omitempty"` - ICEPortRangeEnd uint32 `yaml:"port_range_end,omitempty"` - NodeIP string `yaml:"node_ip,omitempty"` - NodeIPAutoGenerated bool `yaml:"-"` - STUNServers []string `yaml:"stun_servers,omitempty"` - TURNServers []TURNServer `yaml:"turn_servers,omitempty"` - UseExternalIP bool `yaml:"use_external_ip"` - UseICELite bool `yaml:"use_ice_lite,omitempty"` - Interfaces InterfacesConfig `yaml:"interfaces"` - IPs IPsConfig `yaml:"ips"` + UDPPort uint32 `yaml:"udp_port,omitempty"` + TCPPort uint32 `yaml:"tcp_port,omitempty"` + ICEPortRangeStart uint32 `yaml:"port_range_start,omitempty"` + ICEPortRangeEnd uint32 `yaml:"port_range_end,omitempty"` + NodeIP string `yaml:"node_ip,omitempty"` + NodeIPAutoGenerated bool `yaml:"-"` + STUNServers []string `yaml:"stun_servers,omitempty"` + TURNServers []TURNServer `yaml:"turn_servers,omitempty"` + UseExternalIP bool `yaml:"use_external_ip"` + UseICELite bool `yaml:"use_ice_lite,omitempty"` + Interfaces InterfacesConfig `yaml:"interfaces"` + IPs IPsConfig `yaml:"ips"` + EnableLoopbackCandidate bool `yaml:"enable_loopback_candidate"` // Number of packets to buffer for NACK PacketBufferSize int `yaml:"packet_buffer_size,omitempty"` diff --git a/pkg/config/ip.go b/pkg/config/ip.go index cbf22637e..ac583eaa6 100644 --- a/pkg/config/ip.go +++ b/pkg/config/ip.go @@ -30,14 +30,14 @@ func (conf *Config) determineIP() (string, error) { } // use local ip instead - addresses, err := GetLocalIPAddresses() + addresses, err := GetLocalIPAddresses(false) if len(addresses) > 0 { return addresses[0], err } return "", err } -func GetLocalIPAddresses() ([]string, error) { +func GetLocalIPAddresses(includeLoopback bool) ([]string, error) { ifaces, err := net.Interfaces() if err != nil { return nil, err @@ -70,6 +70,10 @@ func GetLocalIPAddresses() ([]string, error) { } } + if includeLoopback { + addresses = append(addresses, loopBacks...) + } + if len(addresses) > 0 { return addresses, nil } diff --git a/pkg/rtc/config.go b/pkg/rtc/config.go index 96e81643a..48a6be22b 100644 --- a/pkg/rtc/config.go +++ b/pkg/rtc/config.go @@ -114,12 +114,15 @@ func NewWebRTCConfig(conf *config.Config, externalIP string) (*WebRTCConfig, err return nil, err } } else if rtcConf.UDPPort != 0 { - udpMux, err := ice.NewMultiUDPMuxFromPort( - int(rtcConf.UDPPort), + opts := []ice.UDPMuxFromPortOption{ ice.UDPMuxFromPortWithReadBufferSize(defaultUDPBufferSize), ice.UDPMuxFromPortWithWriteBufferSize(defaultUDPBufferSize), ice.UDPMuxFromPortWithLogger(s.LoggerFactory.NewLogger("udp_mux")), - ) + } + if rtcConf.EnableLoopbackCandidate { + opts = append(opts, ice.UDPMuxFromPortWithLoopback()) + } + udpMux, err := ice.NewMultiUDPMuxFromPort(int(rtcConf.UDPPort), opts...) if err != nil { return nil, err } @@ -159,6 +162,10 @@ func NewWebRTCConfig(conf *config.Config, externalIP string) (*WebRTCConfig, err } s.SetNetworkTypes(networkTypes) + if rtcConf.EnableLoopbackCandidate { + s.SetIncludeLoopbackCandidate(true) + } + // publisher configuration publisherConfig := DirectionConfig{ RTPHeaderExtension: RTPHeaderExtensionConfig{ @@ -251,7 +258,7 @@ func getNAT1to1IPsForConf(conf *config.Config, ipFilter func(net.IP) bool) ([]st if len(stunServers) == 0 { stunServers = config.DefaultStunServers } - localIPs, err := config.GetLocalIPAddresses() + localIPs, err := config.GetLocalIPAddresses(conf.RTC.EnableLoopbackCandidate) if err != nil { return nil, err } diff --git a/pkg/service/wire_gen.go b/pkg/service/wire_gen.go index 7f356d329..dd00814b6 100644 --- a/pkg/service/wire_gen.go +++ b/pkg/service/wire_gen.go @@ -7,8 +7,6 @@ package service import ( - "context" - "crypto/tls" "fmt" "github.com/go-redis/redis/v8" "github.com/livekit/livekit-server/pkg/clientconfiguration" @@ -19,7 +17,7 @@ import ( "github.com/livekit/protocol/egress" "github.com/livekit/protocol/ingress" "github.com/livekit/protocol/livekit" - "github.com/livekit/protocol/logger" + redis2 "github.com/livekit/protocol/redis" "github.com/livekit/protocol/webhook" "github.com/pion/turn/v2" "github.com/pkg/errors" @@ -144,53 +142,7 @@ func createWebhookNotifier(conf *config.Config, provider auth.KeyProvider) (webh } func createRedisClient(conf *config.Config) (redis.UniversalClient, error) { - if !conf.HasRedis() { - return nil, nil - } - - var rc redis.UniversalClient - var tlsConfig *tls.Config - - if conf.Redis.UseTLS { - tlsConfig = &tls.Config{ - MinVersion: tls.VersionTLS12, - } - } - - values := make([]interface{}, 0) - values = append(values, "sentinel", conf.UseSentinel()) - if conf.UseSentinel() { - values = append(values, "addr", conf.Redis.SentinelAddresses, "masterName", conf.Redis.MasterName) - rcOptions := &redis.FailoverOptions{ - SentinelAddrs: conf.Redis.SentinelAddresses, - SentinelUsername: conf.Redis.SentinelUsername, - SentinelPassword: conf.Redis.SentinelPassword, - MasterName: conf.Redis.MasterName, - Username: conf.Redis.Username, - Password: conf.Redis.Password, - DB: conf.Redis.DB, - TLSConfig: tlsConfig, - } - rc = redis.NewFailoverClient(rcOptions) - } else { - values = append(values, "addr", conf.Redis.Address) - rcOptions := &redis.Options{ - Addr: conf.Redis.Address, - Username: conf.Redis.Username, - Password: conf.Redis.Password, - DB: conf.Redis.DB, - TLSConfig: tlsConfig, - } - rc = redis.NewClient(rcOptions) - } - logger.Infow("using multi-node routing via redis", values...) - - if err := rc.Ping(context.Background()).Err(); err != nil { - err = errors.Wrap(err, "unable to connect to redis") - return nil, err - } - - return rc, nil + return redis2.GetRedisClient(&conf.Redis) } func createStore(rc redis.UniversalClient) ObjectStore {