mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
udpsrc: Add network interface selection
Add network interface selection when joining multicast groups. Useful when using the udpsrc on multihomed hosts. Fixes #575234. API: GstUDPSrc::multicast-iface
This commit is contained in:
parent
a32581abee
commit
469aced581
5 changed files with 43 additions and 5 deletions
|
@ -635,7 +635,7 @@ gst_multiudpsink_init_send (GstMultiUDPSink * sink)
|
|||
for (clients = sink->clients; clients; clients = g_list_next (clients)) {
|
||||
client = (GstUDPClient *) clients->data;
|
||||
if (sink->auto_multicast && gst_udp_is_multicast (&client->theiraddr))
|
||||
gst_udp_join_group (*(client->sock), &client->theiraddr);
|
||||
gst_udp_join_group (*(client->sock), &client->theiraddr, NULL);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
|
@ -687,7 +687,7 @@ gst_multiudpsink_add_internal (GstMultiUDPSink * sink, const gchar * host,
|
|||
GST_DEBUG_OBJECT (sink, "multicast address detected");
|
||||
if (sink->auto_multicast) {
|
||||
GST_DEBUG_OBJECT (sink, "joining multicast group");
|
||||
gst_udp_join_group (*(client->sock), &client->theiraddr);
|
||||
gst_udp_join_group (*(client->sock), &client->theiraddr, NULL);
|
||||
}
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (sink, "normal address detected");
|
||||
|
|
|
@ -163,19 +163,31 @@ gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* FIXME: Add interface selection for windows hosts. */
|
||||
int
|
||||
gst_udp_join_group (int sockfd, struct sockaddr_storage *addr)
|
||||
gst_udp_join_group (int sockfd, struct sockaddr_storage *addr, gchar * iface)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
switch (addr->ss_family) {
|
||||
case AF_INET:
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
struct ip_mreq mreq4;
|
||||
#else
|
||||
struct ip_mreqn mreq4;
|
||||
#endif
|
||||
|
||||
mreq4.imr_multiaddr.s_addr =
|
||||
((struct sockaddr_in *) addr)->sin_addr.s_addr;
|
||||
#ifdef G_OS_WIN32
|
||||
mreq4.imr_interface.s_addr = INADDR_ANY;
|
||||
#else
|
||||
if (iface)
|
||||
mreq4.imr_ifindex = if_nametoindex (iface);
|
||||
else
|
||||
mreq4.imr_ifindex = 0; /* Pick any. */
|
||||
#endif
|
||||
|
||||
if ((ret =
|
||||
setsockopt (sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
|
@ -192,6 +204,10 @@ gst_udp_join_group (int sockfd, struct sockaddr_storage *addr)
|
|||
&(((struct sockaddr_in6 *) addr)->sin6_addr),
|
||||
sizeof (struct in6_addr));
|
||||
mreq6.ipv6mr_interface = 0;
|
||||
#if !defined(G_OS_WIN32)
|
||||
if (iface)
|
||||
mreq6.ipv6mr_interface = if_nametoindex (iface);
|
||||
#endif
|
||||
|
||||
if ((ret =
|
||||
setsockopt (sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#else
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
@ -81,7 +82,8 @@ int gst_udp_is_multicast (struct sockaddr_storage *addr);
|
|||
|
||||
int gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl);
|
||||
|
||||
int gst_udp_join_group (int sockfd, struct sockaddr_storage *addr);
|
||||
int gst_udp_join_group (int sockfd, struct sockaddr_storage *addr,
|
||||
gchar *iface);
|
||||
int gst_udp_leave_group (int sockfd, struct sockaddr_storage *addr);
|
||||
|
||||
#endif /* __GST_UDP_NET_UTILS_H__*/
|
||||
|
|
|
@ -142,6 +142,7 @@ GST_ELEMENT_DETAILS ("UDP packet receiver",
|
|||
|
||||
#define UDP_DEFAULT_PORT 4951
|
||||
#define UDP_DEFAULT_MULTICAST_GROUP "0.0.0.0"
|
||||
#define UDP_DEFAULT_MULTICAST_IFACE NULL
|
||||
#define UDP_DEFAULT_URI "udp://"UDP_DEFAULT_MULTICAST_GROUP":"G_STRINGIFY(UDP_DEFAULT_PORT)
|
||||
#define UDP_DEFAULT_CAPS NULL
|
||||
#define UDP_DEFAULT_SOCKFD -1
|
||||
|
@ -158,6 +159,7 @@ enum
|
|||
|
||||
PROP_PORT,
|
||||
PROP_MULTICAST_GROUP,
|
||||
PROP_MULTICAST_IFACE,
|
||||
PROP_URI,
|
||||
PROP_CAPS,
|
||||
PROP_SOCKFD,
|
||||
|
@ -253,6 +255,10 @@ gst_udpsrc_class_init (GstUDPSrcClass * klass)
|
|||
g_param_spec_string ("multicast_group", "Multicast Group",
|
||||
"The Address of multicast group to join", UDP_DEFAULT_MULTICAST_GROUP,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class, PROP_MULTICAST_IFACE,
|
||||
g_param_spec_string ("multicast_iface", "Multicast Interface",
|
||||
"The network interface on which to join the multicast group",
|
||||
UDP_DEFAULT_MULTICAST_IFACE, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class, PROP_URI,
|
||||
g_param_spec_string ("uri", "URI",
|
||||
"URI in the form of udp://multicast_group:port", UDP_DEFAULT_URI,
|
||||
|
@ -306,6 +312,7 @@ gst_udpsrc_init (GstUDPSrc * udpsrc, GstUDPSrcClass * g_class)
|
|||
udpsrc->port = UDP_DEFAULT_PORT;
|
||||
udpsrc->sockfd = UDP_DEFAULT_SOCKFD;
|
||||
udpsrc->multi_group = g_strdup (UDP_DEFAULT_MULTICAST_GROUP);
|
||||
udpsrc->multi_iface = g_strdup (UDP_DEFAULT_MULTICAST_IFACE);
|
||||
udpsrc->uri = g_strdup (UDP_DEFAULT_URI);
|
||||
udpsrc->buffer_size = UDP_DEFAULT_BUFFER_SIZE;
|
||||
udpsrc->timeout = UDP_DEFAULT_TIMEOUT;
|
||||
|
@ -334,6 +341,7 @@ gst_udpsrc_finalize (GObject * object)
|
|||
if (udpsrc->caps)
|
||||
gst_caps_unref (udpsrc->caps);
|
||||
g_free (udpsrc->multi_group);
|
||||
g_free (udpsrc->multi_iface);
|
||||
g_free (udpsrc->uri);
|
||||
|
||||
if (udpsrc->sockfd >= 0 && udpsrc->closefd)
|
||||
|
@ -667,6 +675,14 @@ gst_udpsrc_set_property (GObject * object, guint prop_id, const GValue * value,
|
|||
udpsrc->multi_group = g_value_dup_string (value);
|
||||
gst_udpsrc_update_uri (udpsrc);
|
||||
break;
|
||||
case PROP_MULTICAST_IFACE:
|
||||
g_free (udpsrc->multi_iface);
|
||||
|
||||
if (g_value_get_string (value) == NULL)
|
||||
udpsrc->multi_iface = g_strdup (UDP_DEFAULT_MULTICAST_IFACE);
|
||||
else
|
||||
udpsrc->multi_iface = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_URI:
|
||||
gst_udpsrc_set_uri (udpsrc, g_value_get_string (value));
|
||||
break;
|
||||
|
@ -731,6 +747,9 @@ gst_udpsrc_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_MULTICAST_GROUP:
|
||||
g_value_set_string (value, udpsrc->multi_group);
|
||||
break;
|
||||
case PROP_MULTICAST_IFACE:
|
||||
g_value_set_string (value, udpsrc->multi_iface);
|
||||
break;
|
||||
case PROP_URI:
|
||||
g_value_set_string (value, udpsrc->uri);
|
||||
break;
|
||||
|
@ -871,7 +890,7 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
|
|||
|
||||
if (src->auto_multicast && gst_udp_is_multicast (&src->myaddr)) {
|
||||
GST_DEBUG_OBJECT (src, "joining multicast group %s", src->multi_group);
|
||||
ret = gst_udp_join_group (src->sock.fd, &src->myaddr);
|
||||
ret = gst_udp_join_group (src->sock.fd, &src->myaddr, src->multi_iface);
|
||||
if (ret < 0)
|
||||
goto membership;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ struct _GstUDPSrc {
|
|||
gchar *uri;
|
||||
int port;
|
||||
gchar *multi_group;
|
||||
gchar *multi_iface;
|
||||
gint ttl;
|
||||
GstCaps *caps;
|
||||
gint buffer_size;
|
||||
|
|
Loading…
Reference in a new issue