diff --git a/apidocs/openapi.yaml b/apidocs/openapi.yaml index 391c57a5..0ebfb148 100644 --- a/apidocs/openapi.yaml +++ b/apidocs/openapi.yaml @@ -162,6 +162,10 @@ components: type: string password: type: string + webrtcICEInterfaces: + type: array + items: + type: string webrtcICEHostNAT1To1IPs: type: array items: diff --git a/internal/conf/conf.go b/internal/conf/conf.go index 6691df62..33c58667 100644 --- a/internal/conf/conf.go +++ b/internal/conf/conf.go @@ -164,6 +164,7 @@ type Conf struct { WebRTCTrustedProxies IPsOrCIDRs `json:"webrtcTrustedProxies"` WebRTCICEServers []string `json:"webrtcICEServers"` // deprecated WebRTCICEServers2 []WebRTCICEServer `json:"webrtcICEServers2"` + WebRTCICEInterfaces []string `json:"webrtcICEInterfaces"` WebRTCICEHostNAT1To1IPs []string `json:"webrtcICEHostNAT1To1IPs"` WebRTCICEUDPMuxAddress string `json:"webrtcICEUDPMuxAddress"` WebRTCICETCPMuxAddress string `json:"webrtcICETCPMuxAddress"` @@ -395,6 +396,7 @@ func (conf *Conf) UnmarshalJSON(b []byte) error { conf.WebRTCServerCert = "server.crt" conf.WebRTCAllowOrigin = "*" conf.WebRTCICEServers2 = []WebRTCICEServer{{URL: "stun:stun.l.google.com:19302"}} + conf.WebRTCICEInterfaces = []string{} conf.WebRTCICEHostNAT1To1IPs = []string{} // SRT diff --git a/internal/core/core.go b/internal/core/core.go index 4182b835..9ba56c50 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -454,6 +454,7 @@ func (p *Core) createResources(initial bool) error { p.conf.WebRTCICEServers2, p.conf.ReadTimeout, p.conf.WriteQueueSize, + p.conf.WebRTCICEInterfaces, p.conf.WebRTCICEHostNAT1To1IPs, p.conf.WebRTCICEUDPMuxAddress, p.conf.WebRTCICETCPMuxAddress, @@ -667,6 +668,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) { !reflect.DeepEqual(newConf.WebRTCICEServers2, p.conf.WebRTCICEServers2) || newConf.ReadTimeout != p.conf.ReadTimeout || newConf.WriteQueueSize != p.conf.WriteQueueSize || + !reflect.DeepEqual(newConf.WebRTCICEInterfaces, p.conf.WebRTCICEInterfaces) || !reflect.DeepEqual(newConf.WebRTCICEHostNAT1To1IPs, p.conf.WebRTCICEHostNAT1To1IPs) || newConf.WebRTCICEUDPMuxAddress != p.conf.WebRTCICEUDPMuxAddress || newConf.WebRTCICETCPMuxAddress != p.conf.WebRTCICETCPMuxAddress || diff --git a/internal/core/webrtc_manager.go b/internal/core/webrtc_manager.go index f2a64a74..fc0606d8 100644 --- a/internal/core/webrtc_manager.go +++ b/internal/core/webrtc_manager.go @@ -168,13 +168,29 @@ func randomTurnUser() (string, error) { return string(b), nil } +func stringInSlice(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +} + func webrtcNewAPI( + iceInterfaces []string, iceHostNAT1To1IPs []string, iceUDPMux ice.UDPMux, iceTCPMux ice.TCPMux, ) (*webrtc.API, error) { settingsEngine := webrtc.SettingEngine{} + if len(iceInterfaces) != 0 { + settingsEngine.SetInterfaceFilter(func(iface string) bool { + return stringInSlice(iface, iceInterfaces) + }) + } + if len(iceHostNAT1To1IPs) != 0 { settingsEngine.SetNAT1To1IPs(iceHostNAT1To1IPs, webrtc.ICECandidateTypeHost) } @@ -317,6 +333,7 @@ func newWebRTCManager( iceServers []conf.WebRTCICEServer, readTimeout conf.StringDuration, writeQueueSize int, + iceInterfaces []string, iceHostNAT1To1IPs []string, iceUDPMuxAddress string, iceTCPMuxAddress string, @@ -391,7 +408,7 @@ func newWebRTCManager( iceTCPMux = webrtc.NewICETCPMux(nil, m.tcpMuxLn, 8) } - m.api, err = webrtcNewAPI(iceHostNAT1To1IPs, iceUDPMux, iceTCPMux) + m.api, err = webrtcNewAPI(iceInterfaces, iceHostNAT1To1IPs, iceUDPMux, iceTCPMux) if err != nil { m.udpMuxLn.Close() m.tcpMuxLn.Close() diff --git a/internal/core/webrtc_manager_test.go b/internal/core/webrtc_manager_test.go index ab2c69a5..467d8002 100644 --- a/internal/core/webrtc_manager_test.go +++ b/internal/core/webrtc_manager_test.go @@ -43,7 +43,7 @@ func newWebRTCTestClient( c := &webRTCTestClient{} - api, err := webrtcNewAPI(nil, nil, nil) + api, err := webrtcNewAPI(nil, nil, nil, nil) require.NoError(t, err) pc, err := webrtcpc.New(iceServers, api, nilLogger{}) diff --git a/internal/core/webrtc_source.go b/internal/core/webrtc_source.go index e888c12f..5f81900b 100644 --- a/internal/core/webrtc_source.go +++ b/internal/core/webrtc_source.go @@ -67,7 +67,7 @@ func (s *webRTCSource) run(ctx context.Context, cnf *conf.PathConf, _ chan *conf return err } - api, err := webrtcNewAPI(nil, nil, nil) + api, err := webrtcNewAPI(nil, nil, nil, nil) if err != nil { return err } diff --git a/internal/core/webrtc_source_test.go b/internal/core/webrtc_source_test.go index 23d63575..52e00b04 100644 --- a/internal/core/webrtc_source_test.go +++ b/internal/core/webrtc_source_test.go @@ -20,7 +20,7 @@ import ( func TestWebRTCSource(t *testing.T) { state := 0 - api, err := webrtcNewAPI(nil, nil, nil) + api, err := webrtcNewAPI(nil, nil, nil, nil) require.NoError(t, err) pc, err := webrtcpc.New(nil, api, nilLogger{}) diff --git a/mediamtx.yml b/mediamtx.yml index d59a24ee..e74ecfa3 100644 --- a/mediamtx.yml +++ b/mediamtx.yml @@ -215,6 +215,9 @@ webrtcICEServers2: # the secret must be inserted into the password field. username: '' password: '' +# List of interfaces that will be used to gather IPs to send +# to the counterpart to establish a connection. +webrtcICEInterfaces: [] # List of public IP addresses that are to be used as a host. # This is used typically for servers that are behind 1:1 D-NAT. webrtcICEHostNAT1To1IPs: []