summaryrefslogtreecommitdiffstats
path: root/gst/udp
diff options
context:
space:
mode:
authorBruno Santos <brunof@ua.pt>2008-05-21 09:56:02 +0000
committerWim Taymans <wim.taymans@gmail.com>2008-05-21 09:56:02 +0000
commit570718c2feb3093e2c3a682b48734f4cac20a164 (patch)
treed91a2aac4f2967d3fe9246c4cf0b95e45d06ad00 /gst/udp
parent94fb1d987043113b847131f86b3b096d7dbea8a1 (diff)
gst/udp/gstudpnetutils.*: Provide a bunch of helper methods to deal with IPv4 and IPv6 transparently.
Original commit message from CVS: Patch by: Bruno Santos <brunof at ua dot pt> * gst/udp/gstudpnetutils.c: (gst_udp_get_addr), (gst_udp_join_group), (gst_udp_leave_group), (gst_udp_is_multicast): * gst/udp/gstudpnetutils.h: Provide a bunch of helper methods to deal with IPv4 and IPv6 transparently. * gst/udp/gstmultiudpsink.c: (gst_multiudpsink_class_init), (gst_multiudpsink_init), (gst_multiudpsink_set_property), (gst_multiudpsink_get_property), (join_multicast), (gst_multiudpsink_init_send), (gst_multiudpsink_add_internal), (gst_multiudpsink_remove): * gst/udp/gstmultiudpsink.h: Add multicast TTL and loopback properties. Use the helper methods to implement ip4 and ip6. * gst/udp/gstudpsrc.c: (gst_udpsrc_create), (gst_udpsrc_start): * gst/udp/gstudpsrc.h: Use the helper methods to implement ip4 and ip6. Fixes #515962.
Diffstat (limited to 'gst/udp')
-rw-r--r--gst/udp/gstmultiudpsink.c110
-rw-r--r--gst/udp/gstmultiudpsink.h5
-rw-r--r--gst/udp/gstudpnetutils.c190
-rw-r--r--gst/udp/gstudpnetutils.h8
-rw-r--r--gst/udp/gstudpsrc.c65
-rw-r--r--gst/udp/gstudpsrc.h3
6 files changed, 276 insertions, 105 deletions
diff --git a/gst/udp/gstmultiudpsink.c b/gst/udp/gstmultiudpsink.c
index 6c23874a..0519ba32 100644
--- a/gst/udp/gstmultiudpsink.c
+++ b/gst/udp/gstmultiudpsink.c
@@ -81,6 +81,8 @@ enum
#define DEFAULT_SOCK -1
#define DEFAULT_CLIENTS NULL
#define DEFAULT_AUTO_MULTICAST TRUE
+#define DEFAULT_TTL 64
+#define DEFAULT_LOOP TRUE
enum
{
@@ -91,7 +93,9 @@ enum
PROP_CLOSEFD,
PROP_SOCK,
PROP_CLIENTS,
- PROP_AUTO_MULTICAST
+ PROP_AUTO_MULTICAST,
+ PROP_TTL,
+ PROP_LOOP
/* FILL ME */
};
@@ -292,6 +296,14 @@ gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass)
"Automatically join/leave multicast groups",
"Automatically join/leave the multicast groups, FALSE means user"
" has to do it himself", DEFAULT_AUTO_MULTICAST, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_TTL,
+ g_param_spec_int ("ttl", "Multicast TTL",
+ "Used for setting the multicast TTL parameter",
+ 0, 255, DEFAULT_TTL, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_LOOP,
+ g_param_spec_boolean ("loop", "Multicast Loopback",
+ "Used for setting the multicast loop parameter. TRUE = enable,"
+ " FALSE = disable", DEFAULT_LOOP, G_PARAM_READWRITE));
gstelement_class->change_state = gst_multiudpsink_change_state;
@@ -316,6 +328,8 @@ gst_multiudpsink_init (GstMultiUDPSink * sink)
sink->closefd = DEFAULT_CLOSEFD;
sink->externalfd = (sink->sockfd != -1);
sink->auto_multicast = DEFAULT_AUTO_MULTICAST;
+ sink->ttl = DEFAULT_TTL;
+ sink->loop = DEFAULT_LOOP;
}
static void
@@ -473,6 +487,12 @@ gst_multiudpsink_set_property (GObject * object, guint prop_id,
case PROP_AUTO_MULTICAST:
udpsink->auto_multicast = g_value_get_boolean (value);
break;
+ case PROP_TTL:
+ udpsink->ttl = g_value_get_int (value);
+ break;
+ case PROP_LOOP:
+ udpsink->loop = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -510,6 +530,12 @@ gst_multiudpsink_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_AUTO_MULTICAST:
g_value_set_boolean (value, udpsink->auto_multicast);
break;
+ case PROP_TTL:
+ g_value_set_int (value, udpsink->ttl);
+ break;
+ case PROP_LOOP:
+ g_value_set_boolean (value, udpsink->loop);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -517,33 +543,13 @@ gst_multiudpsink_get_property (GObject * object, guint prop_id, GValue * value,
}
static void
-join_multicast (GstUDPClient * client)
+join_multicast (GstUDPClient * client, gboolean loop, int ttl)
{
- unsigned char ttl = 64;
- unsigned char loop = 1;
-
/* Joining the multicast group */
/* FIXME, can we use multicast and unicast over the same
* socket? if not, search for socket of this multicast group or
* create a new one. */
- if (setsockopt (*(client->sock), IPPROTO_IP, IP_ADD_MEMBERSHIP,
- &(client->multi_addr), sizeof (client->multi_addr)) < 0)
- perror ("setsockopt IP_ADD_MEMBERSHIP\n");
- if (setsockopt (*(client->sock), IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
- sizeof (ttl)) < 0)
- perror ("setsockopt IP_MULTICAST_TTL\n");
- if (setsockopt (*(client->sock), IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
- sizeof (loop)) < 0)
- perror ("setsockopt IP_MULTICAST_LOOP\n");
-}
-
-static void
-leave_multicast (GstUDPClient * client)
-{
- if (setsockopt (*(client->sock), IPPROTO_IP, IP_DROP_MEMBERSHIP,
- &(client->multi_addr), sizeof (client->multi_addr)) < 0)
- GST_WARNING ("setsockopt IP_DROP_MEMBERSHIP failed '%s'",
- g_strerror (errno));
+ gst_udp_join_group (*(client->sock), loop, ttl, &client->theiraddr);
}
/* create a socket for sending to remote machine */
@@ -557,8 +563,9 @@ gst_multiudpsink_init_send (GstMultiUDPSink * sink)
if (sink->sockfd == -1) {
/* create sender socket */
- if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
- goto no_socket;
+ if ((sink->sock = socket (AF_INET6, SOCK_DGRAM, 0)) == -1)
+ if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+ goto no_socket;
sink->externalfd = FALSE;
} else {
@@ -580,8 +587,8 @@ gst_multiudpsink_init_send (GstMultiUDPSink * sink)
for (clients = sink->clients; clients; clients = g_list_next (clients)) {
client = (GstUDPClient *) clients->data;
- if (client->multi_addr.imr_multiaddr.s_addr && sink->auto_multicast)
- join_multicast (client);
+ if (gst_udp_is_multicast (&client->theiraddr) && sink->auto_multicast)
+ join_multicast (client, sink->loop, sink->ttl);
}
return TRUE;
@@ -612,8 +619,6 @@ static void
gst_multiudpsink_add_internal (GstMultiUDPSink * sink, const gchar * host,
gint port, gboolean lock)
{
- struct hostent *he;
- struct in_addr addr;
GstUDPClient *client;
GTimeVal now;
@@ -623,42 +628,19 @@ gst_multiudpsink_add_internal (GstMultiUDPSink * sink, const gchar * host,
client->port = port;
client->sock = &sink->sock;
- memset (&client->theiraddr, 0, sizeof (client->theiraddr));
- memset (&client->multi_addr, 0, sizeof (client->multi_addr));
- client->theiraddr.sin_family = AF_INET; /* host byte order */
- client->theiraddr.sin_port = g_htons (port); /* short, network byte order */
+ if (gst_udp_get_addr (host, port, &client->theiraddr) < 0)
+ goto getaddrinfo_error;
g_get_current_time (&now);
client->connect_time = GST_TIMEVAL_TO_TIME (now);
- /* if its an IP address */
- if (inet_aton (host, &addr)) {
- /* check if its a multicast address */
- if ((g_ntohl (addr.s_addr) & 0xf0000000) == 0xe0000000) {
- GST_DEBUG_OBJECT (sink, "multicast address detected");
- client->multi_addr.imr_multiaddr.s_addr = addr.s_addr;
- client->multi_addr.imr_interface.s_addr = INADDR_ANY;
-
- client->theiraddr.sin_addr = client->multi_addr.imr_multiaddr;
-
- } else {
- GST_DEBUG_OBJECT (sink, "normal address detected");
- client->theiraddr.sin_addr = *((struct in_addr *) &addr);
- }
- /* if init_send has already been called, set sockopts for multicast */
- if (*client->sock > 0 && client->multi_addr.imr_multiaddr.s_addr &&
- sink->auto_multicast)
- join_multicast (client);
- }
- /* we dont need to lookup for localhost */
- else if (strcmp (host, "localhost") == 0 && inet_aton ("127.0.0.1", &addr)) {
- client->theiraddr.sin_addr = *((struct in_addr *) &addr);
- }
- /* if its a hostname */
- else if ((he = gethostbyname (host))) {
- client->theiraddr.sin_addr = *((struct in_addr *) he->h_addr);
+ /* check if its a multicast address */
+ if (*client->sock > 0 && gst_udp_is_multicast (&client->theiraddr) &&
+ sink->auto_multicast) {
+ GST_DEBUG_OBJECT (sink, "multicast address detected");
+ join_multicast (client, sink->loop, sink->ttl);
} else {
- goto host_error;
+ GST_DEBUG_OBJECT (sink, "normal address detected");
}
if (lock)
@@ -673,9 +655,9 @@ gst_multiudpsink_add_internal (GstMultiUDPSink * sink, const gchar * host,
return;
/* ERRORS */
-host_error:
+getaddrinfo_error:
{
- GST_WARNING_OBJECT (sink, "hostname lookup error?");
+ GST_WARNING_OBJECT (sink, "getaddrinfo lookup error?");
g_free (client->host);
g_free (client);
return;
@@ -728,9 +710,9 @@ gst_multiudpsink_remove (GstMultiUDPSink * sink, const gchar * host, gint port)
g_get_current_time (&now);
client->disconnect_time = GST_TIMEVAL_TO_TIME (now);
- if (*(client->sock) != -1 && client->multi_addr.imr_multiaddr.s_addr
+ if (*(client->sock) != -1 && gst_udp_is_multicast (&client->theiraddr)
&& sink->auto_multicast)
- leave_multicast (client);
+ gst_udp_leave_group (*(client->sock), &client->theiraddr);
/* Unlock to emit signal before we delete the actual client */
g_mutex_unlock (sink->client_lock);
diff --git a/gst/udp/gstmultiudpsink.h b/gst/udp/gstmultiudpsink.h
index 6170aa17..21c2a96c 100644
--- a/gst/udp/gstmultiudpsink.h
+++ b/gst/udp/gstmultiudpsink.h
@@ -40,8 +40,7 @@ typedef struct _GstMultiUDPSinkClass GstMultiUDPSinkClass;
typedef struct {
int *sock;
- struct sockaddr_in theiraddr;
- struct ip_mreq multi_addr;
+ struct sockaddr_storage theiraddr;
gchar *host;
gint port;
@@ -72,6 +71,8 @@ struct _GstMultiUDPSink {
gboolean externalfd;
gboolean auto_multicast;
+ gint ttl;
+ gboolean loop;
};
struct _GstMultiUDPSinkClass {
diff --git a/gst/udp/gstudpnetutils.c b/gst/udp/gstudpnetutils.c
index 585916d8..b50336f5 100644
--- a/gst/udp/gstudpnetutils.c
+++ b/gst/udp/gstudpnetutils.c
@@ -22,21 +22,14 @@
#include "config.h"
#endif
+#include <errno.h>
+#include <stdio.h>
+#include <memory.h>
+
#include "gstudpnetutils.h"
#ifdef G_OS_WIN32
-int
-gst_udp_net_utils_win32_inet_aton (const char *c, struct in_addr *paddr)
-{
- paddr->s_addr = inet_addr (c);
-
- if (paddr->s_addr == INADDR_NONE)
- return 0;
-
- return 1;
-}
-
gboolean
gst_udp_net_utils_win32_wsa_startup (GstObject * obj)
{
@@ -60,3 +53,178 @@ gst_udp_net_utils_win32_wsa_startup (GstObject * obj)
}
#endif
+
+int
+gst_udp_get_addr (const char *hostname, int port, struct sockaddr_storage *addr)
+{
+ struct addrinfo hints, *res, *nres;
+ char service[NI_MAXSERV];
+ int ret;
+
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf (service, sizeof (service) - 1, "%d", port);
+ service[sizeof (service) - 1] = '\0';
+
+ if ((ret = getaddrinfo (hostname, (port == -1) ? NULL : service, &hints,
+ &res)) < 0) {
+ return ret;
+ }
+
+ nres = res;
+ while (nres) {
+ if (nres->ai_family == AF_INET || nres->ai_family == AF_INET6)
+ break;
+ nres = nres->ai_next;
+ }
+
+ if (nres) {
+ memcpy (addr, nres->ai_addr, nres->ai_addrlen);
+ } else {
+ errno = EAI_ADDRFAMILY;
+ ret = -1;
+ }
+ freeaddrinfo (res);
+
+ return ret;
+}
+
+int
+gst_udp_join_group (int sockfd, gboolean loop, int ttl,
+ struct sockaddr_storage *addr)
+{
+ int ret = -1;
+ int l = (loop == FALSE) ? 0 : 1;
+
+ switch (addr->ss_family) {
+ case AF_INET:
+ {
+ struct ip_mreq mreq4;
+
+ mreq4.imr_multiaddr.s_addr =
+ ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+ mreq4.imr_interface.s_addr = INADDR_ANY;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &l,
+ sizeof (l))) < 0)
+ return ret;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
+ sizeof (ttl))) < 0)
+ return ret;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (const void *) &mreq4, sizeof (mreq4))) < 0)
+ return ret;
+ }
+ break;
+
+ case AF_INET6:
+ {
+ struct ipv6_mreq mreq6;
+
+ memcpy (&mreq6.ipv6mr_multiaddr,
+ &(((struct sockaddr_in6 *) addr)->sin6_addr),
+ sizeof (struct in6_addr));
+ mreq6.ipv6mr_interface = 0;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &l,
+ sizeof (l))) < 0)
+ return ret;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl,
+ sizeof (ttl))) < 0)
+ return ret;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
+ (const void *) &mreq6, sizeof (mreq6))) < 0)
+ return ret;
+ }
+ break;
+
+ default:
+ errno = EAFNOSUPPORT;
+ }
+
+ return ret;
+}
+
+int
+gst_udp_leave_group (int sockfd, struct sockaddr_storage *addr)
+{
+ int ret = -1;
+
+ switch (addr->ss_family) {
+ case AF_INET:
+ {
+ struct ip_mreq mreq4;
+
+ mreq4.imr_multiaddr.s_addr =
+ ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+ mreq4.imr_interface.s_addr = INADDR_ANY;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (const void *) &mreq4, sizeof (mreq4))) < 0)
+ return ret;
+ }
+ break;
+
+ case AF_INET6:
+ {
+ struct ipv6_mreq mreq6;
+
+ memcpy (&mreq6.ipv6mr_multiaddr,
+ &(((struct sockaddr_in6 *) addr)->sin6_addr),
+ sizeof (struct in6_addr));
+ mreq6.ipv6mr_interface = 0;
+
+ if ((ret =
+ setsockopt (sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
+ (const void *) &mreq6, sizeof (mreq6))) < 0)
+ return ret;
+ }
+ break;
+
+ default:
+ errno = EAFNOSUPPORT;
+ }
+
+ return ret;
+}
+
+int
+gst_udp_is_multicast (struct sockaddr_storage *addr)
+{
+ int ret = -1;
+
+ switch (addr->ss_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
+
+ ret = IN_MULTICAST (ntohl (addr4->sin_addr.s_addr));
+ }
+ break;
+
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
+
+ ret = IN6_IS_ADDR_MULTICAST (&addr6->sin6_addr);
+ }
+ break;
+
+ default:
+ errno = EAFNOSUPPORT;
+ }
+
+ return ret;
+}
diff --git a/gst/udp/gstudpnetutils.h b/gst/udp/gstudpnetutils.h
index 86c90151..d098664c 100644
--- a/gst/udp/gstudpnetutils.h
+++ b/gst/udp/gstudpnetutils.h
@@ -52,7 +52,6 @@
#define IOCTL_SOCKET ioctlsocket
#define CLOSE_SOCKET(sock) closesocket(sock)
#define setsockopt(sock,l,opt,val,len) setsockopt(sock,l,opt,(char *)(val),len)
-#define inet_aton(c,addr) gst_udp_net_utils_win32_inet_aton ((c),(addr))
#define WSA_STARTUP(obj) gst_udp_net_utils_win32_wsa_startup(GST_OBJECT(obj))
#define WSA_CLEANUP(obj) WSACleanup ()
@@ -68,10 +67,15 @@
#ifdef G_OS_WIN32
-int gst_udp_net_utils_win32_inet_aton (const char *c, struct in_addr * addr);
gboolean gst_udp_net_utils_win32_wsa_startup (GstObject * obj);
#endif
+int gst_udp_get_addr (const char *hostname, int port, struct sockaddr_storage *addr);
+int gst_udp_is_multicast (struct sockaddr_storage *addr);
+
+int gst_udp_join_group (int sockfd, gboolean loop, int ttl, struct sockaddr_storage *addr);
+int gst_udp_leave_group (int sockfd, struct sockaddr_storage *addr);
+
#endif /* __GST_UDP_NET_UTILS_H__*/
diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c
index be150f3e..2927cdf6 100644
--- a/gst/udp/gstudpsrc.c
+++ b/gst/udp/gstudpsrc.c
@@ -349,7 +349,7 @@ gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf)
{
GstUDPSrc *udpsrc;
GstNetBuffer *outbuf;
- struct sockaddr_in tmpaddr;
+ struct sockaddr_storage tmpaddr;
socklen_t len;
guint8 *pktdata;
gint pktsize;
@@ -468,8 +468,28 @@ no_select:
GST_BUFFER_DATA (outbuf) = pktdata;
GST_BUFFER_SIZE (outbuf) = ret;
- gst_netaddress_set_ip4_address (&outbuf->from, tmpaddr.sin_addr.s_addr,
- tmpaddr.sin_port);
+ switch (tmpaddr.ss_family) {
+ case AF_INET:
+ {
+ gst_netaddress_set_ip4_address (&outbuf->from,
+ ((struct sockaddr_in *) &tmpaddr)->sin_addr.s_addr,
+ ((struct sockaddr_in *) &tmpaddr)->sin_port);
+ }
+ break;
+ case AF_INET6:
+ {
+ guint8 ip6[16];
+
+ memcpy (ip6, &((struct sockaddr_in6 *) &tmpaddr)->sin6_addr,
+ sizeof (ip6));
+ gst_netaddress_set_ip6_address (&outbuf->from, ip6,
+ ((struct sockaddr_in *) &tmpaddr)->sin_port);
+ }
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ goto receive_error;
+ }
gst_buffer_set_caps (GST_BUFFER_CAST (outbuf), udpsrc->caps);
@@ -681,7 +701,7 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
{
guint bc_val;
gint reuse;
- struct sockaddr_in my_addr;
+ struct sockaddr_storage my_addr;
guint len;
int port;
GstUDPSrc *src;
@@ -690,12 +710,12 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
src = GST_UDPSRC (bsrc);
- if (!inet_aton (src->multi_group, &(src->multi_addr.imr_multiaddr)))
- src->multi_addr.imr_multiaddr.s_addr = 0;
-
if (src->sockfd == -1) {
/* need to allocate a socket */
- if ((ret = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ if ((ret =
+ gst_udp_get_addr (src->multi_group, src->port, &src->myaddr)) < 0)
+ goto getaddrinfo_error;
+ if ((ret = socket (src->myaddr.ss_family, SOCK_DGRAM, IPPROTO_UDP)) < 0)
goto no_socket;
src->sock.fd = ret;
@@ -707,15 +727,6 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
sizeof (reuse))) < 0)
goto setsockopt_error;
- memset (&src->myaddr, 0, sizeof (src->myaddr));
- src->myaddr.sin_family = AF_INET; /* host byte order */
- src->myaddr.sin_port = g_htons (src->port); /* short, network byte order */
-
- if (src->multi_addr.imr_multiaddr.s_addr)
- src->myaddr.sin_addr.s_addr = src->multi_addr.imr_multiaddr.s_addr;
- else
- src->myaddr.sin_addr.s_addr = INADDR_ANY;
-
GST_DEBUG_OBJECT (src, "binding on port %d", src->port);
if ((ret = bind (src->sock.fd, (struct sockaddr *) &src->myaddr,
sizeof (src->myaddr))) < 0)
@@ -726,11 +737,9 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
src->externalfd = TRUE;
}
- if (src->multi_addr.imr_multiaddr.s_addr) {
- src->multi_addr.imr_interface.s_addr = INADDR_ANY;
- if ((ret =
- setsockopt (src->sock.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- &src->multi_addr, sizeof (src->multi_addr))) < 0)
+ if (gst_udp_is_multicast (&src->myaddr)) {
+ ret = gst_udp_join_group (src->sock.fd, TRUE, src->ttl, &src->myaddr);
+ if (ret < 0)
goto membership;
}
@@ -769,7 +778,9 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
sizeof (bc_val))) < 0)
goto no_broadcast;
- port = g_ntohs (my_addr.sin_port);
+ /* NOTE: sockaddr_in.sin_port works for ipv4 and ipv6 because sin_port
+ * follows ss_family on both */
+ port = ntohs (((struct sockaddr_in *) &my_addr)->sin_port);
GST_DEBUG_OBJECT (src, "bound, on port %d", port);
if (port != src->port) {
src->port = port;
@@ -777,7 +788,7 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
g_object_notify (G_OBJECT (src), "port");
}
- src->myaddr.sin_port = g_htons (src->port + 1);
+ ((struct sockaddr_in *) &src->myaddr)->sin_port = htons (src->port + 1);
if ((src->fdset = gst_poll_new (TRUE)) == NULL)
goto no_fdset;
@@ -788,6 +799,12 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
return TRUE;
/* ERRORS */
+getaddrinfo_error:
+ {
+ GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
+ ("getaddrinfo failed %d: %s (%d)", ret, g_strerror (errno), errno));
+ return FALSE;
+ }
no_socket:
{
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
diff --git a/gst/udp/gstudpsrc.h b/gst/udp/gstudpsrc.h
index e736a592..597a6a70 100644
--- a/gst/udp/gstudpsrc.h
+++ b/gst/udp/gstudpsrc.h
@@ -68,8 +68,7 @@ struct _GstUDPSrc {
GstPoll *fdset;
gboolean externalfd;
- struct sockaddr_in myaddr;
- struct ip_mreq multi_addr;
+ struct sockaddr_storage myaddr;
};
struct _GstUDPSrcClass {