Skip to content

Commit

Permalink
add multicast.InterfaceForSource (#414)
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 authored Sep 11, 2023
1 parent 78198a5 commit 4ede58c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 31 deletions.
32 changes: 1 addition & 31 deletions client_udp_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package gortsplib

import (
"crypto/rand"
"fmt"
"math/big"
"net"
"strconv"
Expand All @@ -25,35 +24,6 @@ func randInRange(max int) (int, error) {
return int(n.Int64()), nil
}

func findMulticastInterfaceForSource(ip net.IP) (*net.Interface, error) {
if ip.Equal(net.ParseIP("127.0.0.1")) {
return nil, fmt.Errorf("IP 127.0.0.1 can't be used as source of a multicast stream. Use the LAN IP of your PC")
}

intfs, err := net.Interfaces()
if err != nil {
return nil, err
}

for _, intf := range intfs {
if (intf.Flags & net.FlagMulticast) == 0 {
continue
}

addrs, err := intf.Addrs()
if err == nil {
for _, addr := range addrs {
_, ipnet, err := net.ParseCIDR(addr.String())
if err == nil && ipnet.Contains(ip) {
return &intf, nil
}
}
}
}

return nil, fmt.Errorf("found no interface that is multicast-capable and can communicate with IP %v", ip)
}

type clientUDPListener struct {
c *Client
pc net.PacketConn
Expand Down Expand Up @@ -118,7 +88,7 @@ func newClientUDPListener(
) (*clientUDPListener, error) {
var pc packetConn
if multicastEnable {
intf, err := findMulticastInterfaceForSource(multicastSourceIP)
intf, err := multicast.InterfaceForSource(multicastSourceIP)
if err != nil {
return nil, err
}
Expand Down
31 changes: 31 additions & 0 deletions pkg/multicast/multicast.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package multicast

import (
"fmt"
"net"
)

Expand All @@ -10,3 +11,33 @@ type Conn interface {
net.PacketConn
SetReadBuffer(int) error
}

// InterfaceForSource returns a multicast-capable interface that can communicate with given IP.
func InterfaceForSource(ip net.IP) (*net.Interface, error) {
if ip.Equal(net.ParseIP("127.0.0.1")) {
return nil, fmt.Errorf("IP 127.0.0.1 can't be used as source of a multicast stream. Use the LAN IP of your PC")
}

intfs, err := net.Interfaces()
if err != nil {
return nil, err
}

for _, intf := range intfs {
if (intf.Flags & net.FlagMulticast) == 0 {
continue
}

addrs, err := intf.Addrs()
if err == nil {
for _, addr := range addrs {
_, ipnet, err := net.ParseCIDR(addr.String())
if err == nil && ipnet.Contains(ip) {
return &intf, nil
}
}
}
}

return nil, fmt.Errorf("found no interface that is multicast-capable and can communicate with IP %v", ip)
}

0 comments on commit 4ede58c

Please sign in to comment.