[0.11] gst-plugins-good: udpsrc: drop dataless UDP packets

Sebastian Dröge slomo at kemper.freedesktop.org
Tue Jan 10 05:33:26 PST 2012


Module: gst-plugins-good
Branch: 0.11
Commit: 0c4b60f01044e097d30095ceb3b7c65e57126a8f
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=0c4b60f01044e097d30095ceb3b7c65e57126a8f

Author: John Ogness <john.ogness at linutronix.de>
Date:   Wed Dec 21 13:22:03 2011 +0100

udpsrc: drop dataless UDP packets

It is allowed to send/receive UDP packets with no data. When such
a packet is available, select() will return with success but
ioctl(FIONREAD) will return 0. But a read() must still occur in
order to clear off the UDP packet from the queue.

This patch will read the dataless packet from the socket. If
select() was woken for other reasons (and FIONREAD returns 0),
this may result in a UDP packet getting accidentally dropped.
But since UDP is not reliable, this is acceptable.

NOTE: This patch fixes a nasty bug where sending a dataless
      UDP packet to a udpsrc instance will cause an infinite
      loop.

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

Signed-off-by: John Ogness <john.ogness at linutronix.de>

---

 gst/udp/gstudpsrc.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c
index ec644af..dce2c99 100644
--- a/gst/udp/gstudpsrc.c
+++ b/gst/udp/gstudpsrc.c
@@ -483,12 +483,20 @@ retry:
               IOCTL_SOCKET (udpsrc->sock.fd, FIONREAD, &readsize)) < 0))
     goto ioctl_failed;
 
-  /* if we get here and there is nothing to read from the socket, the select got
-   * woken up by activity on the socket but it was not a read. We know someone
-   * will also do something with the socket so that we don't go into an infinite
-   * loop in the select(). */
+  /* If we get here and the readsize is zero, then either select was woken up
+   * by activity that is not a read, or a poll error occurred, or a UDP packet
+   * was received that has no data. Since we cannot identify which case it is,
+   * we handle all of them. This could possibly lead to a UDP packet getting
+   * lost, but since UDP is not reliable, we can accept this. */
   if (G_UNLIKELY (!readsize)) {
+    /* try to read a packet (and it will be ignored),
+     * in case a packet with no data arrived */
+    recvfrom (udpsrc->sock.fd, (char *)&slen, 0, 0, &sa.sa, &slen);
+
+    /* clear any error, in case a poll error occurred */
     clear_error (udpsrc);
+
+    /* poll again */
     goto retry;
   }
 



More information about the gstreamer-commits mailing list