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 727067 - udpsrc: set udp buffer size forcibly
udpsrc: set udp buffer size forcibly
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
unspecified
Other Linux
: Normal enhancement
: 1.15.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-03-26 01:50 UTC by KYUNGNAM BAE
Modified: 2018-08-17 18:27 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
udpsrc: add force-buffer-size property (3.99 KB, patch)
2014-03-26 01:52 UTC, KYUNGNAM BAE
none Details | Review
Add 'force-buffer-size' for udpsrc element (3.99 KB, patch)
2014-03-26 02:09 UTC, KYUNGNAM BAE
needs-work Details | Review
Modify 1st patchset for applying Julien Isorce's comment (4.34 KB, patch)
2014-11-02 01:26 UTC, KYUNGNAM BAE
none Details | Review
Modify patchset for applying Sebastian Dröge (slomo)'s comment (3.49 KB, patch)
2015-08-25 12:10 UTC, KYUNGNAM BAE
none Details | Review
Modify patchset for applying Sebastian Dröge (slomo)'s comment (3.38 KB, text/plain)
2015-08-26 11:38 UTC, KYUNGNAM BAE
  Details
Modify patchset for applying Sebastian Dröge (slomo)'s comment (3.38 KB, patch)
2015-08-26 11:38 UTC, KYUNGNAM BAE
none Details | Review
udpsrc: factor out gst_udpsrc_get_rcvbuf() (2.06 KB, patch)
2018-08-17 12:38 UTC, Guillaume Desmottes
committed Details | Review
updsrc: set udp buffer size forcibly (2.24 KB, patch)
2018-08-17 12:38 UTC, Guillaume Desmottes
none Details | Review
updsrc: set udp buffer size forcibly (2.75 KB, patch)
2018-08-17 13:44 UTC, Guillaume Desmottes
committed Details | Review
udpsrc: Balance Linux value of get/set_rcvbuf (1.07 KB, patch)
2018-08-17 18:24 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review

Description KYUNGNAM BAE 2014-03-26 01:50:58 UTC
I hope to add "force-buffer-size" property to the udpsrc element.

When playing the live streaming by using udpsrc, the buffer size too small to receive the streaming data.

The buffer size should be set the value what user want forcibly, since the buffer size is set to default size by linux kernel.

Please concern this patch.
Comment 1 KYUNGNAM BAE 2014-03-26 01:52:49 UTC
Created attachment 272942 [details] [review]
udpsrc: add force-buffer-size property

add patch file.
Comment 2 KYUNGNAM BAE 2014-03-26 02:09:02 UTC
Comment on attachment 272942 [details] [review]
udpsrc: add force-buffer-size property

modify the patch file because of the author.
Comment 3 KYUNGNAM BAE 2014-03-26 02:09:44 UTC
Created attachment 272944 [details] [review]
Add 'force-buffer-size' for udpsrc element
Comment 4 Julien Isorce 2014-11-01 09:27:36 UTC
I think it would cleaner to just have the "force-buffer-size" as a boolean, and re-use "buffer-size" in both cases.
Comment 5 KYUNGNAM BAE 2014-11-02 01:26:25 UTC
Created attachment 289819 [details] [review]
Modify 1st patchset for applying Julien Isorce's comment

I think user can select one between the 'buffer-size' and 'force-buffer-size' property in https://bug727067.bugzilla-attachments.gnome.org/attachment.cgi?id=272944 patchset.

In your opinion, user should use two properties together.
Actually I'm not sure which one is more better solution.

I've just add the patch set for following your opinion.
Please choose one patch set and apply it for adding the 'force-buffer-size' property.
Comment 6 Julien Isorce 2014-11-03 07:50:42 UTC
Review of attachment 289819 [details] [review]:

::: gst/udp/gstudpsrc.c
@@ +1007,1 @@
   }

You should also use udpsrc->force_buffer_size in the first block "#if GLIB_CHECK_VERSION (2, 35, 7)", or any reason you did not ?

@@ +1007,2 @@
   }
 #elif defined (SO_RCVBUF)

Is SO_RCVBUFFORCE always available if SO_RCVBUF is ?
Comment 7 Sebastian Dröge (slomo) 2014-11-03 08:09:24 UTC
This should probably indeed be in an #ifdef SO_RCVBUFFORCE block.

Also what's the argument against *always* forcing the buffer size? That's what the user expected probably.
Comment 8 Tim-Philipp Müller 2014-11-03 09:15:21 UTC
Yes, was going to ask the same thing, why have a property for this, instead of just trying to force it if the normal way didn't succeed? After all, if a buffer size got set, it's already a "I really want this".
Comment 9 Julien Isorce 2014-11-03 09:43:19 UTC
According to http://linux.die.net/man/7/socket it seems it requires some privileges to use SO_RCVBUFFORCE: "... a privileged (CAP_NET_ADMIN) process can perform ..."
Comment 10 Tim-Philipp Müller 2014-11-03 09:50:25 UTC
Right, but you can try setting it, and if the resulting size is too small you can try forcing it, and if that didn't work you post a warning message on the bus and move on. If we don't have the special caps, we can error out or try with whatever size we got.
Comment 11 Sebastian Dröge (slomo) 2015-02-16 14:45:04 UTC
Anybody going to update the patch accordingly? I think it would be good to do that :)

I.e., no new property. First try the current way, if that fails try the FORCE one, if that fails post a warning message.
Comment 12 KYUNGNAM BAE 2015-08-25 12:10:06 UTC
Created attachment 309951 [details] [review]
Modify patchset for applying Sebastian Dröge (slomo)'s comment

I'm following Sebastian Dröge (slomo)'s advice and attach new patchset.
1. Delete new property. 
2. First try the current way, if that fails try the FORCE one, if that fails post a warning message.
Comment 13 Sebastian Dröge (slomo) 2015-08-26 09:21:14 UTC
Review of attachment 309951 [details] [review]:

::: gst/udp/gstudpsrc.c
@@ +1019,3 @@
+              src->buffer_size, &opt_err)) {
+        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
+            ("Could not create forcibly a buffer of requested %d bytes: %s",

"Could not force receive buffer size to %d bytes: %s" seems more descriptive

@@ +1022,3 @@
+                src->buffer_size, opt_err->message));
+        g_error_free (opt_err);
+        opt_err = NULL;

This is equivalent to g_clear_error(&opt_err). Just use that :)

@@ +1070,3 @@
+     * Try to set the buffer_size by using SO_RCVBUFFORCE */
+    if (rcvsize < src->buffer_size) {
+      rcvsize = src->buffer_size;

Instead of having this code here copied twice, please move it into a function :)
Comment 14 KYUNGNAM BAE 2015-08-26 09:52:57 UTC
Review of attachment 309951 [details] [review]:

Could you give me some advice?

::: gst/udp/gstudpsrc.c
@@ +1019,3 @@
+              src->buffer_size, &opt_err)) {
+        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
+      GST_INFO_OBJECT (src, "forcibly setting udp buffer of %d bytes",

I will do that.

@@ +1022,3 @@
+                src->buffer_size, opt_err->message));
+        g_error_free (opt_err);
+          src->buffer_size);

I will change the 1023~1024 line to the g_clear_error function.

@@ +1070,3 @@
+     * Try to set the buffer_size by using SO_RCVBUFFORCE */
+    if (rcvsize < src->buffer_size) {
+      rcvsize = src->buffer_size;

Could you explain it more?

Do you mean that a function is needed for the line 1072 and line 1042?
i.e) Is the "rcvsize = src->buffer_size;" line moved into a function?

Or Does I need to make a function for Line 1012~1033 and Line 1068~1096?
Although I make the function for this, the #if and #elif (line 981 and line 1035) is needed.
So I didn't split the function.
Comment 15 Sebastian Dröge (slomo) 2015-08-26 10:01:19 UTC
I saw that you have almost the same code in 1012-1033 and 1068-1096. Try to make those one function that is called from both places :)
Comment 16 KYUNGNAM BAE 2015-08-26 11:38:02 UTC
Created attachment 310023 [details]
Modify patchset for applying Sebastian Dröge (slomo)'s comment
Comment 17 KYUNGNAM BAE 2015-08-26 11:38:29 UTC
Created attachment 310025 [details] [review]
Modify patchset for applying Sebastian Dröge (slomo)'s comment
Comment 18 Guillaume Desmottes 2018-08-17 12:38:08 UTC
I tried rebasing this patch on top of master but ended up re-implementing it. We don't care about supporting older glib now.
Comment 19 Guillaume Desmottes 2018-08-17 12:38:22 UTC
Created attachment 373377 [details] [review]
udpsrc: factor out gst_udpsrc_get_rcvbuf()

No semantic change.
Comment 20 Guillaume Desmottes 2018-08-17 12:38:28 UTC
Created attachment 373378 [details] [review]
updsrc: set udp buffer size forcibly

The udp buffer size is limited to a maximum of around 100K.
Some apps need to set the force bufsize for their own operation.
Use the SO_RCVBUFFORCE option in order to override the rmem_max limit
of linux kernel.

Original patch from Kyungnam Bae <kyungnam.bae@lge.com>
Comment 21 Nicolas Dufresne (ndufresne) 2018-08-17 12:44:58 UTC
Review of attachment 373378 [details] [review]:

I think it does not address the review comment. The suggestion was to set the recv buffer size the normal way, and if this didn't work, simply try the second method, or warn if that failed (you need privileged user, so it should fail for most use case). And then we don't need yet another property. We do the same for multi-cast groups, but can't remember if it's sex or sink.
Comment 22 Guillaume Desmottes 2018-08-17 12:46:24 UTC
Yeah that's the logic I implemented. Or did I miss something?
Comment 23 Tim-Philipp Müller 2018-08-17 13:07:19 UTC
Forgive me for asking, but does this actually work for you?

Because for me the kernel seems to just cap the actual configured setting at the configured max size and not return FALSE from g_socket_set_option().
Comment 24 Guillaume Desmottes 2018-08-17 13:12:57 UTC
Yes it does. Actually it fixes a performance issue when streaming.

The first call (not force) is indeed capped but after the force one it is the to the double of the value as expected.

Tested on 4.14.0 as root.
Comment 25 Nicolas Dufresne (ndufresne) 2018-08-17 13:20:56 UTC
(In reply to Tim-Philipp Müller from comment #23)
> Forgive me for asking, but does this actually work for you?
> 
> Because for me the kernel seems to just cap the actual configured setting at
> the configured max size and not return FALSE from g_socket_set_option().

I'm guessing the point here is that instead of getting EPERM, you get success with smaller size. So you neither get a warning or an error, all you get is the maximum allowed by the kernel.
Comment 26 Guillaume Desmottes 2018-08-17 13:22:42 UTC
Yes indeed, see https://elixir.bootlin.com/linux/v3.4/source/net/core/sock.c#L613
That's why I check the actual value after setting before try to force.
Comment 27 Nicolas Dufresne (ndufresne) 2018-08-17 13:28:54 UTC
Review of attachment 373378 [details] [review]:

Outch, my review is wrong.
Comment 28 Nicolas Dufresne (ndufresne) 2018-08-17 13:30:02 UTC
Review of attachment 373377 [details] [review]:

.
Comment 29 Nicolas Dufresne (ndufresne) 2018-08-17 13:32:15 UTC
Review of attachment 373378 [details] [review]:

The comment should maybe state that this will only work if you have the net.admin privilege.

::: gst/udp/gstudpsrc.c
@@ +1441,1 @@
       }

So, I think we should add the if (val < src->buffer_size), and warn, just to help users a little.
Comment 30 Guillaume Desmottes 2018-08-17 13:44:29 UTC
Created attachment 373394 [details] [review]
updsrc: set udp buffer size forcibly

The udp buffer size is limited to a maximum of around 100K.
Some apps need to set the force bufsize for their own operation.
Use the SO_RCVBUFFORCE option in order to override the rmem_max limit
of linux kernel. Require user to have the CAP_NET_ADMIN privilege to
work.

Original patch from Kyungnam Bae <kyungnam.bae@lge.com>
Comment 31 Tim-Philipp Müller 2018-08-17 13:56:55 UTC
Right, sorry, I missed the other check, thought you relied on the if (!set_options) failing :)
Comment 32 Tim-Philipp Müller 2018-08-17 16:57:51 UTC
> So, I think we should add the if (val < src->buffer_size), and warn,
> just to help users a little.

Not superimportant, but here the kernel returns 200,000 when reading the value after 100,000 was set (apparently for extra overhead for the internal structs etc.), so maybe on Linux this needs to be if (val / 2 < src->buffer_size) then? Bit ugly, but might be confusing if setting values around the limit if not taken into consideration?
Comment 33 Nicolas Dufresne (ndufresne) 2018-08-17 18:24:30 UTC
Created attachment 373407 [details] [review]
udpsrc: Balance Linux value of get/set_rcvbuf

On Linux, the kernel returns twice the size as it will allocate extra
space for accouting. We devides this value by two in order to ensure
that get/set value now match. This fixes the set buffer size validation
and allow having a nice warning when the size if surpassed and the
process does not have CAP_NET_ADMIN capabilities.
Comment 34 Nicolas Dufresne (ndufresne) 2018-08-17 18:24:46 UTC
Attachment 373377 [details] pushed as 58a5f59 - udpsrc: factor out gst_udpsrc_get_rcvbuf()
Attachment 373394 [details] pushed as 9b4a022 - updsrc: set udp buffer size forcibly
Attachment 373407 [details] pushed as c61bcb1 - udpsrc: Balance Linux value of get/set_rcvbuf