1
0
Fork 0
forked from External/mediamtx

udp: fix reading two streams with same port and different multicast IP (#2133) (#2332)

Fixes #2133
This commit is contained in:
Alessandro Ros 2023-09-12 00:27:08 +02:00 committed by GitHub
parent 2a26962167
commit a005de1aa0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 46 deletions

View file

@ -8,8 +8,8 @@ import (
"github.com/bluenviron/gortsplib/v4/pkg/description"
"github.com/bluenviron/gortsplib/v4/pkg/format"
"github.com/bluenviron/gortsplib/v4/pkg/multicast"
"github.com/bluenviron/mediacommon/pkg/formats/mpegts"
"golang.org/x/net/ipv4"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger"
@ -18,34 +18,10 @@ import (
)
const (
multicastTTL = 16
udpMTU = 1472
// same size as GStreamer's rtspsrc
udpKernelReadBufferSize = 0x80000
)
func joinMulticastGroupOnAtLeastOneInterface(p *ipv4.PacketConn, listenIP net.IP) error {
intfs, err := net.Interfaces()
if err != nil {
return err
}
success := false
for _, intf := range intfs {
if (intf.Flags & net.FlagMulticast) != 0 {
err := p.JoinGroup(&intf, &net.UDPAddr{IP: listenIP})
if err == nil {
success = true
}
}
}
if !success {
return fmt.Errorf("unable to activate multicast on any network interface")
}
return nil
}
type packetConnReader struct {
net.PacketConn
}
@ -61,6 +37,11 @@ func (r *packetConnReader) Read(p []byte) (int, error) {
return n, err
}
type packetConn interface {
net.PacketConn
SetReadBuffer(int) error
}
type udpSourceParent interface {
logger.Writer
setReady(req pathSourceStaticSetReadyReq) pathSourceStaticSetReadyRes
@ -97,24 +78,26 @@ func (s *udpSource) run(ctx context.Context, cnf *conf.PathConf, _ chan *conf.Pa
return err
}
pc, err := net.ListenPacket(restrictNetwork("udp", addr.String()))
if err != nil {
return err
var pc packetConn
if ip4 := addr.IP.To4(); ip4 != nil && addr.IP.IsMulticast() {
pc, err = multicast.NewMultiConn(hostPort, net.ListenPacket)
if err != nil {
return err
}
} else {
tmp, err := net.ListenPacket(restrictNetwork("udp", addr.String()))
if err != nil {
return err
}
pc = tmp.(*net.UDPConn)
}
defer pc.Close()
if addr.IP.IsMulticast() {
p := ipv4.NewPacketConn(pc)
err = p.SetMulticastTTL(multicastTTL)
if err != nil {
return err
}
err = joinMulticastGroupOnAtLeastOneInterface(p, addr.IP)
if err != nil {
return err
}
err = pc.SetReadBuffer(udpKernelReadBufferSize)
if err != nil {
return err
}
readerErr := make(chan error)