diff options
author | Bruno Santos <brunof@ua.pt> | 2008-05-21 09:56:02 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2008-05-21 09:56:02 +0000 |
commit | 570718c2feb3093e2c3a682b48734f4cac20a164 (patch) | |
tree | d91a2aac4f2967d3fe9246c4cf0b95e45d06ad00 /gst/udp/gstudpsrc.c | |
parent | 94fb1d987043113b847131f86b3b096d7dbea8a1 (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/gstudpsrc.c')
-rw-r--r-- | gst/udp/gstudpsrc.c | 65 |
1 files changed, 41 insertions, 24 deletions
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), |