Commit 9abd47fe authored by Tudor.Suciu's avatar Tudor.Suciu Committed by Michael Niedermayer

udp: add multicast input interface selection

Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 3c9a86df
...@@ -35,6 +35,16 @@ ...@@ -35,6 +35,16 @@
#include <unistd.h> #include <unistd.h>
#include "internal.h" #include "internal.h"
#include "network.h" #include "network.h"
#ifdef WIN32
# define if_nametoindex( str ) atoi( str )
#else
# include <unistd.h>
# include <net/if.h>
#endif
#include "os_support.h" #include "os_support.h"
#include "url.h" #include "url.h"
...@@ -100,11 +110,12 @@ static int udp_set_multicast_ttl(int sockfd, int mcastTTL, ...@@ -100,11 +110,12 @@ static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
return 0; return 0;
} }
static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, int miface_nr)
{ {
#ifdef IP_ADD_MEMBERSHIP #ifdef IP_ADD_MEMBERSHIP
if (addr->sa_family == AF_INET) { if (addr->sa_family == AF_INET) {
struct ip_mreq mreq; struct ip_mreq mreq;
struct group_req gr;
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr= INADDR_ANY; mreq.imr_interface.s_addr= INADDR_ANY;
...@@ -112,6 +123,16 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) ...@@ -112,6 +123,16 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno)); av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno));
return -1; return -1;
} }
#ifdef MCAST_JOIN_GROUP
memset(&gr, 0, sizeof(struct group_req));
gr.gr_interface = miface_nr;
memcpy(&gr.gr_group, addr, sizeof(struct sockaddr_in));
if (setsockopt(sockfd, SOL_IP, MCAST_JOIN_GROUP, &gr, sizeof(struct group_req)) < 0) {
av_log(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_GROUP): %s\n", strerror(errno));
return -1;
}
#endif
} }
#endif #endif
#if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6) #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
...@@ -259,6 +280,7 @@ static int udp_port(struct sockaddr_storage *addr, int addr_len) ...@@ -259,6 +280,7 @@ static int udp_port(struct sockaddr_storage *addr, int addr_len)
* option: 'ttl=n' : set the ttl value (for multicast only) * option: 'ttl=n' : set the ttl value (for multicast only)
* 'localport=n' : set the local port * 'localport=n' : set the local port
* 'pkt_size=n' : set max packet size * 'pkt_size=n' : set max packet size
* 'miface=if' : set multicast input interface
* 'reuse=1' : enable reusing the socket * 'reuse=1' : enable reusing the socket
* *
* @param h media file context * @param h media file context
...@@ -401,6 +423,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -401,6 +423,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
struct sockaddr_storage my_addr; struct sockaddr_storage my_addr;
int len; int len;
int reuse_specified = 0; int reuse_specified = 0;
int miface_nr = 0;
h->is_streamed = 1; h->is_streamed = 1;
h->max_packet_size = 1472; h->max_packet_size = 1472;
...@@ -443,6 +466,9 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -443,6 +466,9 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) { if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
av_strlcpy(localaddr, buf, sizeof(localaddr)); av_strlcpy(localaddr, buf, sizeof(localaddr));
} }
if (av_find_info_tag(buf, sizeof(buf), "miface", p)) {
miface_nr = if_nametoindex (buf);
}
} }
/* fill the dest addr */ /* fill the dest addr */
...@@ -500,7 +526,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -500,7 +526,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
} }
if (h->flags & AVIO_FLAG_READ) { if (h->flags & AVIO_FLAG_READ) {
/* input */ /* input */
if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr, miface_nr) < 0)
goto fail; goto fail;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment