udpsrc: receive control messages only in multicast
authorPetr Kulhavy <brain@jikos.cz>
Sat, 12 Nov 2016 22:34:23 +0000 (23:34 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 14 Nov 2016 09:05:04 +0000 (11:05 +0200)
Control messages are used only in multicast mode - to detect if the destination
address is not ours and possibly drop the packet. However in non-multicast
modes the messages are still allocated and freed even if not used. Therefore
request control messages from g_socket_receive_message() only in multicast
mode.

https://bugzilla.gnome.org/show_bug.cgi?id=772841

gst/udp/gstudpsrc.c

index 0f22a76..36ff1d6 100644 (file)
@@ -847,6 +847,7 @@ gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf)
   gssize res;
   gsize offset;
   GSocketControlMessage **msgs = NULL;
+  GSocketControlMessage ***p_msgs;
   gint n_msgs = 0, i;
 
   udpsrc = GST_UDPSRC_CAST (psrc);
@@ -854,6 +855,11 @@ gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf)
   if (!gst_udpsrc_ensure_mem (udpsrc))
     goto memory_alloc_error;
 
+  /* optimization: use messages only in multicast mode */
+  p_msgs =
+      (g_inet_address_get_is_multicast (g_inet_socket_address_get_address
+          (udpsrc->addr))) ? &msgs : NULL;
+
   /* Retrieve sender address unless we've been configured not to do so */
   p_saddr = (udpsrc->retrieve_sender_address) ? &saddr : NULL;
 
@@ -898,7 +904,7 @@ retry:
 
   res =
       g_socket_receive_message (udpsrc->used_socket, p_saddr, udpsrc->vec, 2,
-      &msgs, &n_msgs, &flags, udpsrc->cancellable, &err);
+      p_msgs, &n_msgs, &flags, udpsrc->cancellable, &err);
 
   if (G_UNLIKELY (res < 0)) {
     /* G_IO_ERROR_HOST_UNREACHABLE for a UDP socket means that a packet sent
@@ -923,44 +929,40 @@ retry:
 
   /* Retry if multicast and the destination address is not ours. We don't want
    * to receive arbitrary packets */
-  {
+  if (p_msgs) {
     GInetAddress *iaddr = g_inet_socket_address_get_address (udpsrc->addr);
     gboolean skip_packet = FALSE;
     gsize iaddr_size = g_inet_address_get_native_size (iaddr);
     const guint8 *iaddr_bytes = g_inet_address_to_bytes (iaddr);
 
-    if (g_inet_address_get_is_multicast (iaddr)) {
-
-      for (i = 0; i < n_msgs && !skip_packet; i++) {
+    for (i = 0; i < n_msgs && !skip_packet; i++) {
 #ifdef IP_PKTINFO
-        if (GST_IS_IP_PKTINFO_MESSAGE (msgs[i])) {
-          GstIPPktinfoMessage *msg = GST_IP_PKTINFO_MESSAGE (msgs[i]);
+      if (GST_IS_IP_PKTINFO_MESSAGE (msgs[i])) {
+        GstIPPktinfoMessage *msg = GST_IP_PKTINFO_MESSAGE (msgs[i]);
 
-          if (sizeof (msg->addr) == iaddr_size
-              && memcmp (iaddr_bytes, &msg->addr, sizeof (msg->addr)))
-            skip_packet = TRUE;
-        }
+        if (sizeof (msg->addr) == iaddr_size
+            && memcmp (iaddr_bytes, &msg->addr, sizeof (msg->addr)))
+          skip_packet = TRUE;
+      }
 #endif
 #ifdef IPV6_PKTINFO
-        if (GST_IS_IPV6_PKTINFO_MESSAGE (msgs[i])) {
-          GstIPV6PktinfoMessage *msg = GST_IPV6_PKTINFO_MESSAGE (msgs[i]);
+      if (GST_IS_IPV6_PKTINFO_MESSAGE (msgs[i])) {
+        GstIPV6PktinfoMessage *msg = GST_IPV6_PKTINFO_MESSAGE (msgs[i]);
 
-          if (sizeof (msg->addr) == iaddr_size
-              && memcmp (iaddr_bytes, &msg->addr, sizeof (msg->addr)))
-            skip_packet = TRUE;
-        }
+        if (sizeof (msg->addr) == iaddr_size
+            && memcmp (iaddr_bytes, &msg->addr, sizeof (msg->addr)))
+          skip_packet = TRUE;
+      }
 #endif
 #ifdef IP_RECVDSTADDR
-        if (GST_IS_IP_RECVDSTADDR_MESSAGE (msgs[i])) {
-          GstIPRecvdstaddrMessage *msg = GST_IP_RECVDSTADDR_MESSAGE (msgs[i]);
+      if (GST_IS_IP_RECVDSTADDR_MESSAGE (msgs[i])) {
+        GstIPRecvdstaddrMessage *msg = GST_IP_RECVDSTADDR_MESSAGE (msgs[i]);
 
-          if (sizeof (msg->addr) == iaddr_size
-              && memcmp (iaddr_bytes, &msg->addr, sizeof (msg->addr)))
-            skip_packet = TRUE;
-        }
-#endif
+        if (sizeof (msg->addr) == iaddr_size
+            && memcmp (iaddr_bytes, &msg->addr, sizeof (msg->addr)))
+          skip_packet = TRUE;
       }
-
+#endif
     }
 
     for (i = 0; i < n_msgs; i++) {