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 739799 - rtspconnection: watch flushing doesn't flush output stream
rtspconnection: watch flushing doesn't flush output stream
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-11-07 23:51 UTC by Aleix Conchillo Flaqué
Modified: 2018-11-03 11:32 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
flush output stream (1.88 KB, patch)
2014-11-08 01:59 UTC, Aleix Conchillo Flaqué
none Details | Review
flush output stream clean (1.91 KB, patch)
2014-11-11 21:47 UTC, Aleix Conchillo Flaqué
none Details | Review

Description Aleix Conchillo Flaqué 2014-11-07 23:51:54 UTC
This is a tricky one. I'm not sure if this can be fixed in gstreamer or glib-networking.

I have an RTSP server sending interleaved data in the RTSP TCP port.

The problem is when TEARDOWN request is handled. The situation is like this:

(1) rtsp connection sends (gst_rtsp_watch_write_data), let's day 1000 bytes.

(2) this travels down to gnutls.

(3) gnutls returns EAGAIN or EINTR.

(4) rtsp connections records this data to be sent afterwards.

(5) teardown request is handled.

(6) watch flushing is TRUE (data saved in (4) is discarded).

(7) watch flushing is FALSE.

(8) TEARDOWN reply message is sent around 154 bytes.

gnutls internally has buffered data from (1). it buffers it because the user is supposed to send exactly the same data again and gnutls has already encrypted the data, so it avoid re-encrypting it.

However, this makes gnutls return the number of bytes from (1) instead of (8) which make rtsp connection go crazy and finally crashing.

I think the right solution is to call g_output_stream_flush and implement the flush method in glib-networking. The flush would call:

   gnutls_record_send (gnutls->priv->session, NULL, 0);

Which will flush the internal data.

Another option is to check if the returned size from gnutls_record_send is greater than the one being sent. If so, call it again.

Ot may be something in rtsp connection?

This is the stack trace.

  • #0 __memcpy_ssse3_back
    at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S line 1579
  • #1 g_memdup
    at /usr/include/x86_64-linux-gnu/bits/string3.h line 52
  • #2 gst_rtsp_watch_write_data
    at gstrtspconnection.c line 3675
  • #3 do_send_message
    at rtsp-client.c line 3105
  • #4 send_message
    at rtsp-client.c line 510
  • #5 handle_teardown_request
    at rtsp-client.c line 917
  • #6 handle_request
    at rtsp-client.c line 2466
  • #7 gst_rtsp_client_handle_message
    at rtsp-client.c line 3034
  • #8 gst_rtsp_source_dispatch_read
    at gstrtspconnection.c line 3228
  • #9 gnutls_source_dispatch
    at gtlsconnection-gnutls.c line 917
  • #10 g_main_dispatch
    at gmain.c line 3111
  • #11 g_main_context_dispatch
    at gmain.c line 3710
  • #12 g_main_context_iterate
    at gmain.c line 3781
  • #13 g_main_context_iterate
    at gmain.c line 3748
  • #14 g_main_loop_run
    at gmain.c line 3975
  • #15 do_loop
    at rtsp-thread-pool.c line 329
  • #16 g_thread_pool_thread_proxy
    at gthreadpool.c line 307
  • #17 g_thread_proxy
    at gthread.c line 764
  • #18 start_thread
    at pthread_create.c line 308
  • #19 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 112
  • #20 ??

Comment 1 Aleix Conchillo Flaqué 2014-11-08 01:59:37 UTC
Created attachment 290206 [details] [review]
flush output stream

I'm still verifying that this is the write fix.

It bothers me a bit because gnutls will be sending buffered data that the application thought was never going to be sent. The counter argument of this is that the application is flushing so it doesn't really care wht was pending to be sent or not.

How else could we avoid this?
Comment 2 Aleix Conchillo Flaqué 2014-11-08 07:01:34 UTC
Review of attachment 290206 [details] [review]:

::: gst-libs/gst/rtsp/gstrtspconnection.c
@@ +3882,3 @@
+      res = g_output_stream_flush (watch->conn->output_stream,
+          watch->conn->cancellable, &err);
+

Not really sure if we want the cancellable here as we really want it to block until done.

WDYT?
Comment 3 Nicolas Dufresne (ndufresne) 2014-11-08 14:22:51 UTC
For what it's worth, g_output_stream_flush() is a blocking call. The cancellable is most likely needed to avoid deadlock when doing to NULL state.
Comment 4 Aleix Conchillo Flaqué 2014-11-08 15:46:53 UTC
(In reply to comment #3)
> For what it's worth, g_output_stream_flush() is a blocking call. The
> cancellable is most likely needed to avoid deadlock when doing to NULL state.

Oh,  I see.  I was wondering why it gets a cancellable if flush was blocking.  That makes sense.

The test seems to solve my crash.  I added flush to glib-networking gnutls but I still need to test it a bit more. 

In any case,  if this patch makes sense for GStreamer may be we can merge it? I'd like to clean it up a bit though first. 

WDYT?
Comment 5 Aleix Conchillo Flaqué 2014-11-11 16:18:11 UTC
I was thinking that flushing the output stream is not enough or correct.

Shouldn't we send all the messages in rtspconnection queue instead of just emptying it? Otherwise we get an unpredictable behavior. The user has no idea which messages have been really sent but is probably assuming that all of them were sent.

The solution from my patch in comment 1 only solve the specific gnutls problem where gnutls is buffering data. But still, the user will have no idea which messages have been sent.

So, my feeling is that we should really send all remaining messages when flushing.

WDYT?
Comment 6 Aleix Conchillo Flaqué 2014-11-11 18:19:47 UTC
(In reply to comment #5)
> 
> So, my feeling is that we should really send all remaining messages when
> flushing.
> 

What I'm suggesting here is just the opposite of what gst_rtsp_watch_set_flushing documentation says.
Comment 7 Aleix Conchillo Flaqué 2014-11-11 20:54:27 UTC
Just filed bug 739983 with a patch implementing flush in glib-networking (gnutls).
Comment 8 Aleix Conchillo Flaqué 2014-11-11 21:47:53 UTC
Created attachment 290436 [details] [review]
flush output stream clean

Just added a debug message. This should be it.
Comment 9 Aleix Conchillo Flaqué 2014-11-13 01:52:47 UTC
As a side note. Patch for this bug and bug 739983 have been tested over ~300k connection/disconnection successfully.
Comment 10 GStreamer system administrator 2018-11-03 11:32:22 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/141.