Update WebRTC server operation in closed docker containers
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/internal/api/ws"
|
"github.com/AlexxIT/go2rtc/internal/api/ws"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/webrtc"
|
"github.com/AlexxIT/go2rtc/pkg/webrtc"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/xnet"
|
||||||
pion "github.com/pion/webrtc/v3"
|
pion "github.com/pion/webrtc/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -73,6 +74,11 @@ func FilterCandidate(candidate *pion.ICECandidate) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove any Docker-like IP from candidates
|
||||||
|
if ip := net.ParseIP(candidate.Address); ip != nil && xnet.Docker.Contains(ip) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// host candidate should be in the hosts list
|
// host candidate should be in the hosts list
|
||||||
if candidate.Typ == pion.ICECandidateTypeHost && filters.Candidates != nil {
|
if candidate.Typ == pion.ICECandidateTypeHost && filters.Candidates != nil {
|
||||||
if !core.Contains(filters.Candidates, candidate.Address) {
|
if !core.Contains(filters.Candidates, candidate.Address) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func Init() {
|
|||||||
} `yaml:"webrtc"`
|
} `yaml:"webrtc"`
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.Mod.Listen = ":8555/tcp"
|
cfg.Mod.Listen = ":8555"
|
||||||
cfg.Mod.IceServers = []pion.ICEServer{
|
cfg.Mod.IceServers = []pion.ICEServer{
|
||||||
{URLs: []string{"stun:stun.l.google.com:19302"}},
|
{URLs: []string{"stun:stun.l.google.com:19302"}},
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-29
@@ -10,7 +10,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/net2"
|
"github.com/AlexxIT/go2rtc/pkg/xnet"
|
||||||
"github.com/miekg/dns" // awesome library for parsing mDNS records
|
"github.com/miekg/dns" // awesome library for parsing mDNS records
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -170,7 +170,9 @@ type Browser struct {
|
|||||||
// Receiver will get multicast responses on senders requests.
|
// Receiver will get multicast responses on senders requests.
|
||||||
func (b *Browser) ListenMulticastUDP() error {
|
func (b *Browser) ListenMulticastUDP() error {
|
||||||
// 1. Collect IPv4 interfaces
|
// 1. Collect IPv4 interfaces
|
||||||
nets, err := IPNets()
|
nets, err := xnet.IPNets(func(ip net.IP) bool {
|
||||||
|
return !xnet.Docker.Contains(ip)
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -370,30 +372,3 @@ func NewServiceEntries(msg *dns.Msg, ip net.IP) (entries []*ServiceEntry) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func IPNets() ([]*net.IPNet, error) {
|
|
||||||
intfs, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var nets []*net.IPNet
|
|
||||||
|
|
||||||
for _, intf := range intfs {
|
|
||||||
if intf.Flags&net.FlagUp == 0 || intf.Flags&net.FlagLoopback != 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
addrs, _ := intf.Addrs()
|
|
||||||
for _, addr := range addrs {
|
|
||||||
switch v := addr.(type) {
|
|
||||||
case *net.IPNet:
|
|
||||||
if ip := v.IP.To4(); ip != nil && !net2.Docker.Contains(ip) {
|
|
||||||
nets = append(nets, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nets, nil
|
|
||||||
}
|
|
||||||
|
|||||||
+14
-4
@@ -4,7 +4,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/net2"
|
"github.com/AlexxIT/go2rtc/pkg/xnet"
|
||||||
"github.com/pion/ice/v2"
|
"github.com/pion/ice/v2"
|
||||||
"github.com/pion/interceptor"
|
"github.com/pion/interceptor"
|
||||||
"github.com/pion/webrtc/v3"
|
"github.com/pion/webrtc/v3"
|
||||||
@@ -20,6 +20,7 @@ func NewAPI() (*webrtc.API, error) {
|
|||||||
|
|
||||||
type Filters struct {
|
type Filters struct {
|
||||||
Candidates []string `yaml:"candidates"`
|
Candidates []string `yaml:"candidates"`
|
||||||
|
Loopback bool `yaml:"loopback"`
|
||||||
Interfaces []string `yaml:"interfaces"`
|
Interfaces []string `yaml:"interfaces"`
|
||||||
IPs []string `yaml:"ips"`
|
IPs []string `yaml:"ips"`
|
||||||
Networks []string `yaml:"networks"`
|
Networks []string `yaml:"networks"`
|
||||||
@@ -46,6 +47,10 @@ func NewServerAPI(network, address string, filters *Filters) (*webrtc.API, error
|
|||||||
// fix https://github.com/pion/webrtc/pull/2407
|
// fix https://github.com/pion/webrtc/pull/2407
|
||||||
s.SetDTLSInsecureSkipHelloVerify(true)
|
s.SetDTLSInsecureSkipHelloVerify(true)
|
||||||
|
|
||||||
|
if filters != nil && filters.Loopback {
|
||||||
|
s.SetIncludeLoopbackCandidate(true)
|
||||||
|
}
|
||||||
|
|
||||||
var interfaceFilter func(name string) bool
|
var interfaceFilter func(name string) bool
|
||||||
if filters != nil && filters.Interfaces != nil {
|
if filters != nil && filters.Interfaces != nil {
|
||||||
interfaceFilter = func(name string) bool {
|
interfaceFilter = func(name string) bool {
|
||||||
@@ -62,9 +67,14 @@ func NewServerAPI(network, address string, filters *Filters) (*webrtc.API, error
|
|||||||
return core.Contains(filters.IPs, ip.String())
|
return core.Contains(filters.IPs, ip.String())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// default ips - all, except loopback and docker
|
// try filter all Docker-like interfaces
|
||||||
ipFilter = func(ip net.IP) bool {
|
ipFilter = func(ip net.IP) bool {
|
||||||
return !net2.Docker.Contains(ip)
|
return !xnet.Docker.Contains(ip)
|
||||||
|
}
|
||||||
|
// if there are no such interfaces - disable the filter
|
||||||
|
// the user will need to enable port forwarding
|
||||||
|
if nets, _ := xnet.IPNets(ipFilter); len(nets) == 0 {
|
||||||
|
ipFilter = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.SetIPFilter(ipFilter)
|
s.SetIPFilter(ipFilter)
|
||||||
@@ -109,7 +119,7 @@ func NewServerAPI(network, address string, filters *Filters) (*webrtc.API, error
|
|||||||
if network == "" || network == "udp" {
|
if network == "" || network == "udp" {
|
||||||
// UDPMuxDefault should not listening on unspecified address, use NewMultiUDPMuxFromPort instead
|
// UDPMuxDefault should not listening on unspecified address, use NewMultiUDPMuxFromPort instead
|
||||||
var udpMux ice.UDPMux
|
var udpMux ice.UDPMux
|
||||||
if port := net2.ParseUnspecifiedPort(address); port != 0 {
|
if port := xnet.ParseUnspecifiedPort(address); port != 0 {
|
||||||
var networks []ice.NetworkType
|
var networks []ice.NetworkType
|
||||||
for _, ntype := range networkTypes {
|
for _, ntype := range networkTypes {
|
||||||
networks = append(networks, ice.NetworkType(ntype))
|
networks = append(networks, ice.NetworkType(ntype))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package net2
|
package xnet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
@@ -30,3 +30,35 @@ func ParseUnspecifiedPort(address string) int {
|
|||||||
i, _ := strconv.Atoi(port)
|
i, _ := strconv.Atoi(port)
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IPNets(ipFilter func(ip net.IP) bool) ([]*net.IPNet, error) {
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var nets []*net.IPNet
|
||||||
|
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
addrs, _ := iface.Addrs() // range on nil slice is OK
|
||||||
|
for _, addr := range addrs {
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip := v.IP.To4()
|
||||||
|
if ip == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ipFilter != nil && !ipFilter(ip) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nets = append(nets, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nets, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user