After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 533619 - udpsink dies when Linux fails (for no reason) sendto() with non-posix errno
udpsink dies when Linux fails (for no reason) sendto() with non-posix errno
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
0.10.x
Other All
: Normal normal
: 0.10.9
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2008-05-17 19:44 UTC by Gustaf Räntilä
Modified: 2008-05-21 11:38 UTC
See Also:
GNOME target: ---
GNOME version: 2.21/2.22


Attachments
The patch (629 bytes, patch)
2008-05-17 19:45 UTC, Gustaf Räntilä
committed Details | Review
The patch (printing a warning) (1.11 KB, patch)
2008-05-17 19:46 UTC, Gustaf Räntilä
none Details | Review

Description Gustaf Räntilä 2008-05-17 19:44:47 UTC
Please describe the problem:
I don't know why, perhaps it is when my firewall-scripts (using iptables/netfilter) are restarting, Linux fails udp sendto() and sets errno to EPERM, which is NOT conforming to POSIX. This errno shouldn't be used for sendto().
I've tried to see why this happens, but found nothing wrong in the udp implementation in Linux, but the IO syscalls are filtered in a rather messy way in Linux, to "secure" syscalls, for instance with SELinux (which I am NOT using btw).
Well, EPERM is set anyway, and I'm using a plain vanilla kernel.

The problem is, when this happens, the stream dies. I'm streaming over network to a set-top-box connected to my TV. When sendto() fails, this is not visible/noticeable, so to just ignore the few hundred (at most) failing sendto()'s is fine, whenever it happens.

The attached patches fixes this issue, by ignoring sendo() failures where errno is non-POSIX EPERM.
The 'talking' patch prints a warning the first time this happens.
The 'silent' patch just fixes the problem.

Please use any of the patches (preferably the silent one).

Steps to reproduce:
1. Run Linux and make sure it sets errno to EPERM (don't ask me how)
2. Use udpsink


Actual results:
Stream dies

Expected results:
I don't really know what to expect when Linux doesn't conform to POSIX, but reasonably "try as good as you can". This patch makes sure udpsink really tries.

Does this happen every time?
Yes

Other information:
Comment 1 Gustaf Räntilä 2008-05-17 19:45:33 UTC
Created attachment 111070 [details] [review]
The patch
Comment 2 Gustaf Räntilä 2008-05-17 19:46:41 UTC
Created attachment 111071 [details] [review]
The patch (printing a warning)
Comment 3 Sebastian Dröge (slomo) 2008-05-20 07:57:19 UTC
If you block some outgoing ports with iptables and try to send from them you'll get EPERM but IMHO udpsink should simply fail then. Is there any reason why it should continue to send data although it is blocked by the kernel?
Comment 4 Gustaf Räntilä 2008-05-20 10:43:31 UTC
Yes there is.

When my computer gets a new IP from my ISP, or when my DHCP lease expires although I might regain the same IP (this happens frequently), my firewall scripts restarts.
This affects *no* applications that I have experienced over the last 10 years.

However, during these microseconds, if udpsink dies, an entire stream will end. This means, I cannot watch movies through gstreamer, simply because during a few microseconds of FW reconfiguring, udpsink will die.

I have streamed movies from a variety of RTSP servers (which use RTP over UDP for the payload) from the same machine, and I have never experienced that a stream ends/fails. It simply never happens. I've also tried simple udp streamers, with the same result.
With gstreamer's udpsink however, the stream dies after 10-20 minutes every single time.

I don't understand why gstreamer needs to be so extremely afraid of EPERM as to kill the entire stream (which obviously no other software does). What is the purpose of killing the stream? Is it really up to udpsink to kill a stream on (what I would) loose grounds like these?
From what I have understood, software usually don't care about results from sendto() for UDP payloads, only TCP.

Perhaps a patch which tests the first sendto() and fails if the first packet got EPERM, but ignores EPERM after a successful sendto() would be better.
Please tell me, and I can write that.
Comment 5 Wim Taymans 2008-05-20 11:01:45 UTC
Or simply emit a warning instead of an error? Failing on the first EPERM does not seem to be reliable if you're unlucky. You could maybe also fail after N consecutive EPERM errors? or if it lasts longer than N seconds?
I agree that the current behaviour is over sensitive to these little glitches.
Comment 6 Gustaf Räntilä 2008-05-20 18:38:44 UTC
I was thinking about that - counting consecutive EPERM's and failing after a "decent" number of them.
But then it stroke me; Why fail at all?

If someone streams, but wants to halt (long or perhaps continous, think webcam) a stream from being streamed for a few minutes by temporarily telling its OS (through iptables for instance) to not allow the packets, but then change back to accept them, shouldn't gstreamer allow that? Should gstreamer really be "afraid" of EPERM's at all?
Most UDP applications are hard to find the error for when there's a firewall issue, simply because they don't "fail", the packets gets lost in the FW, but again; They don't fail.

Even worse, udpsink is basically (from what I could see of the source code) an alias for multiudpsink with only 1 destination. But what if you have several destinations, but then want to disallow one of them for a while. All other streams end!

I think my patch is the only reasonable solution; basically ignoring EPERM, just like most other software seems to be doing.
Comment 7 Wim Taymans 2008-05-21 09:32:45 UTC
Yes, I'll apply the patch to ignore the errors.
Comment 8 Wim Taymans 2008-05-21 11:38:38 UTC
        Patch by: Gustaf Räntilä <g dot rantila at gmail dot com>

        * gst/udp/gstmultiudpsink.c: (gst_multiudpsink_render):
        Ignore EPERM errors from sendto. Fixes #533619.