mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-21 07:46:38 +00:00
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@linutronix.de>
This commit is contained in:
parent
e72b55b6ac
commit
0c4b60f010
1 changed files with 12 additions and 4 deletions
|
@ -483,12 +483,20 @@ retry:
|
||||||
IOCTL_SOCKET (udpsrc->sock.fd, FIONREAD, &readsize)) < 0))
|
IOCTL_SOCKET (udpsrc->sock.fd, FIONREAD, &readsize)) < 0))
|
||||||
goto ioctl_failed;
|
goto ioctl_failed;
|
||||||
|
|
||||||
/* if we get here and there is nothing to read from the socket, the select got
|
/* If we get here and the readsize is zero, then either select was woken up
|
||||||
* woken up by activity on the socket but it was not a read. We know someone
|
* by activity that is not a read, or a poll error occurred, or a UDP packet
|
||||||
* will also do something with the socket so that we don't go into an infinite
|
* was received that has no data. Since we cannot identify which case it is,
|
||||||
* loop in the select(). */
|
* 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)) {
|
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);
|
clear_error (udpsrc);
|
||||||
|
|
||||||
|
/* poll again */
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue