mirror of
https://github.com/aler9/gortsplib
synced 2025-09-28 03:52:12 +08:00
this fixes most errors "found no interface that is multicast-capable and can communicate with IP".
This commit is contained in:
51
client.go
51
client.go
@@ -252,6 +252,48 @@ func supportsGetParameter(header base.Header) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func interfaceOfConn(c net.Conn) (*net.Interface, error) {
|
||||||
|
var localIP net.IP
|
||||||
|
|
||||||
|
switch addr := c.LocalAddr().(type) {
|
||||||
|
case *net.TCPAddr:
|
||||||
|
localIP = addr.IP
|
||||||
|
case *net.UDPAddr:
|
||||||
|
localIP = addr.IP
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown connection type: %T", c.LocalAddr())
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, iface := range interfaces {
|
||||||
|
var addrs []net.Addr
|
||||||
|
addrs, err = iface.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip != nil && ip.Equal(localIP) {
|
||||||
|
return &iface, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("no interface found for IP %s", localIP)
|
||||||
|
}
|
||||||
|
|
||||||
type clientState int
|
type clientState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -1796,9 +1838,16 @@ func (c *Client) doSetup(
|
|||||||
remoteIP = c.nconn.RemoteAddr().(*net.TCPAddr).IP
|
remoteIP = c.nconn.RemoteAddr().(*net.TCPAddr).IP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var intf *net.Interface
|
||||||
|
intf, err = interfaceOfConn(c.nconn)
|
||||||
|
if err != nil {
|
||||||
|
cm.close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
err = cm.createUDPListeners(
|
err = cm.createUDPListeners(
|
||||||
true,
|
true,
|
||||||
remoteIP,
|
intf,
|
||||||
net.JoinHostPort(thRes.Destination.String(), strconv.FormatInt(int64(thRes.Ports[0]), 10)),
|
net.JoinHostPort(thRes.Destination.String(), strconv.FormatInt(int64(thRes.Ports[0]), 10)),
|
||||||
net.JoinHostPort(thRes.Destination.String(), strconv.FormatInt(int64(thRes.Ports[1]), 10)),
|
net.JoinHostPort(thRes.Destination.String(), strconv.FormatInt(int64(thRes.Ports[1]), 10)),
|
||||||
)
|
)
|
||||||
|
@@ -101,17 +101,17 @@ func (cm *clientMedia) close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cm *clientMedia) createUDPListeners(
|
func (cm *clientMedia) createUDPListeners(
|
||||||
multicastEnable bool,
|
multicast bool,
|
||||||
multicastSourceIP net.IP,
|
multicastInterface *net.Interface,
|
||||||
rtpAddress string,
|
rtpAddress string,
|
||||||
rtcpAddress string,
|
rtcpAddress string,
|
||||||
) error {
|
) error {
|
||||||
if rtpAddress != ":0" {
|
if rtpAddress != ":0" {
|
||||||
l1 := &clientUDPListener{
|
l1 := &clientUDPListener{
|
||||||
c: cm.c,
|
c: cm.c,
|
||||||
multicastEnable: multicastEnable,
|
multicast: multicast,
|
||||||
multicastSourceIP: multicastSourceIP,
|
multicastInterface: multicastInterface,
|
||||||
address: rtpAddress,
|
address: rtpAddress,
|
||||||
}
|
}
|
||||||
err := l1.initialize()
|
err := l1.initialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -119,10 +119,10 @@ func (cm *clientMedia) createUDPListeners(
|
|||||||
}
|
}
|
||||||
|
|
||||||
l2 := &clientUDPListener{
|
l2 := &clientUDPListener{
|
||||||
c: cm.c,
|
c: cm.c,
|
||||||
multicastEnable: multicastEnable,
|
multicast: multicast,
|
||||||
multicastSourceIP: multicastSourceIP,
|
multicastInterface: multicastInterface,
|
||||||
address: rtcpAddress,
|
address: rtcpAddress,
|
||||||
}
|
}
|
||||||
err = l2.initialize()
|
err = l2.initialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -146,10 +146,8 @@ func (cm *clientMedia) createUDPListeners(
|
|||||||
rtcpPort := rtpPort + 1
|
rtcpPort := rtpPort + 1
|
||||||
|
|
||||||
cm.udpRTPListener = &clientUDPListener{
|
cm.udpRTPListener = &clientUDPListener{
|
||||||
c: cm.c,
|
c: cm.c,
|
||||||
multicastEnable: false,
|
address: net.JoinHostPort("", strconv.FormatInt(int64(rtpPort), 10)),
|
||||||
multicastSourceIP: nil,
|
|
||||||
address: net.JoinHostPort("", strconv.FormatInt(int64(rtpPort), 10)),
|
|
||||||
}
|
}
|
||||||
err = cm.udpRTPListener.initialize()
|
err = cm.udpRTPListener.initialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -158,10 +156,8 @@ func (cm *clientMedia) createUDPListeners(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cm.udpRTCPListener = &clientUDPListener{
|
cm.udpRTCPListener = &clientUDPListener{
|
||||||
c: cm.c,
|
c: cm.c,
|
||||||
multicastEnable: false,
|
address: net.JoinHostPort("", strconv.FormatInt(int64(rtcpPort), 10)),
|
||||||
multicastSourceIP: nil,
|
|
||||||
address: net.JoinHostPort("", strconv.FormatInt(int64(rtcpPort), 10)),
|
|
||||||
}
|
}
|
||||||
err = cm.udpRTCPListener.initialize()
|
err = cm.udpRTCPListener.initialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -29,10 +29,10 @@ type packetConn interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type clientUDPListener struct {
|
type clientUDPListener struct {
|
||||||
c *Client
|
c *Client
|
||||||
multicastEnable bool
|
multicast bool
|
||||||
multicastSourceIP net.IP
|
multicastInterface *net.Interface
|
||||||
address string
|
address string
|
||||||
|
|
||||||
pc packetConn
|
pc packetConn
|
||||||
readFunc readFunc
|
readFunc readFunc
|
||||||
@@ -47,13 +47,9 @@ type clientUDPListener struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *clientUDPListener) initialize() error {
|
func (u *clientUDPListener) initialize() error {
|
||||||
if u.multicastEnable {
|
if u.multicast {
|
||||||
intf, err := multicast.InterfaceForSource(u.multicastSourceIP)
|
var err error
|
||||||
if err != nil {
|
u.pc, err = multicast.NewSingleConn(u.multicastInterface, u.address, u.c.ListenPacket)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
u.pc, err = multicast.NewSingleConn(intf, u.address, u.c.ListenPacket)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,8 @@ type Conn interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceForSource returns a multicast-capable interface that can communicate with given IP.
|
// InterfaceForSource returns a multicast-capable interface that can communicate with given IP.
|
||||||
|
//
|
||||||
|
// Deprecated: not used anymore.
|
||||||
func InterfaceForSource(ip net.IP) (*net.Interface, error) {
|
func InterfaceForSource(ip net.IP) (*net.Interface, error) {
|
||||||
if ip.Equal(net.ParseIP("127.0.0.1")) {
|
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")
|
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")
|
||||||
|
Reference in New Issue
Block a user