diff --git a/internal/webrtc/candidates.go b/internal/webrtc/candidates.go index adbfb4a7..a15c4e7d 100644 --- a/internal/webrtc/candidates.go +++ b/internal/webrtc/candidates.go @@ -7,6 +7,7 @@ import ( "github.com/AlexxIT/go2rtc/internal/api/ws" "github.com/AlexxIT/go2rtc/pkg/core" "github.com/AlexxIT/go2rtc/pkg/webrtc" + "github.com/AlexxIT/go2rtc/pkg/xnet" pion "github.com/pion/webrtc/v3" ) @@ -73,6 +74,11 @@ func FilterCandidate(candidate *pion.ICECandidate) bool { 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 if candidate.Typ == pion.ICECandidateTypeHost && filters.Candidates != nil { if !core.Contains(filters.Candidates, candidate.Address) { diff --git a/internal/webrtc/webrtc.go b/internal/webrtc/webrtc.go index fe25c919..989600f9 100644 --- a/internal/webrtc/webrtc.go +++ b/internal/webrtc/webrtc.go @@ -24,7 +24,7 @@ func Init() { } `yaml:"webrtc"` } - cfg.Mod.Listen = ":8555/tcp" + cfg.Mod.Listen = ":8555" cfg.Mod.IceServers = []pion.ICEServer{ {URLs: []string{"stun:stun.l.google.com:19302"}}, } diff --git a/pkg/mdns/client.go b/pkg/mdns/client.go index 0e74952f..e7abb50d 100644 --- a/pkg/mdns/client.go +++ b/pkg/mdns/client.go @@ -10,7 +10,7 @@ import ( "syscall" "time" - "github.com/AlexxIT/go2rtc/pkg/net2" + "github.com/AlexxIT/go2rtc/pkg/xnet" "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. func (b *Browser) ListenMulticastUDP() error { // 1. Collect IPv4 interfaces - nets, err := IPNets() + nets, err := xnet.IPNets(func(ip net.IP) bool { + return !xnet.Docker.Contains(ip) + }) if err != nil { return err } @@ -370,30 +372,3 @@ func NewServiceEntries(msg *dns.Msg, ip net.IP) (entries []*ServiceEntry) { 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 -} diff --git a/pkg/webrtc/api.go b/pkg/webrtc/api.go index 7fb68af7..013a2f25 100644 --- a/pkg/webrtc/api.go +++ b/pkg/webrtc/api.go @@ -4,7 +4,7 @@ import ( "net" "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/interceptor" "github.com/pion/webrtc/v3" @@ -20,6 +20,7 @@ func NewAPI() (*webrtc.API, error) { type Filters struct { Candidates []string `yaml:"candidates"` + Loopback bool `yaml:"loopback"` Interfaces []string `yaml:"interfaces"` IPs []string `yaml:"ips"` 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 s.SetDTLSInsecureSkipHelloVerify(true) + if filters != nil && filters.Loopback { + s.SetIncludeLoopbackCandidate(true) + } + var interfaceFilter func(name string) bool if filters != nil && filters.Interfaces != nil { 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()) } } else { - // default ips - all, except loopback and docker + // try filter all Docker-like interfaces 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) @@ -109,7 +119,7 @@ func NewServerAPI(network, address string, filters *Filters) (*webrtc.API, error if network == "" || network == "udp" { // UDPMuxDefault should not listening on unspecified address, use NewMultiUDPMuxFromPort instead var udpMux ice.UDPMux - if port := net2.ParseUnspecifiedPort(address); port != 0 { + if port := xnet.ParseUnspecifiedPort(address); port != 0 { var networks []ice.NetworkType for _, ntype := range networkTypes { networks = append(networks, ice.NetworkType(ntype)) diff --git a/pkg/net2/net.go b/pkg/xnet/net.go similarity index 50% rename from pkg/net2/net.go rename to pkg/xnet/net.go index 6d02ad89..16361503 100644 --- a/pkg/net2/net.go +++ b/pkg/xnet/net.go @@ -1,4 +1,4 @@ -package net2 +package xnet import ( "net" @@ -30,3 +30,35 @@ func ParseUnspecifiedPort(address string) int { i, _ := strconv.Atoi(port) 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 +}