rtspconnection: watch flushing doesn't flush output stream
Submitted by Aleix Conchillo Flaqué
Link to original bug (#739799)
Description
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:1579
#1 0x00007f89e3c6b999 in g_memdup (mem=0x7f88a8aaa386, byte_size=4294966036) at /usr/include/x86_64-linux-gnu/bits/string3.h:52
#2 0x00007f89e48386fd in gst_rtsp_watch_write_data (watch=0x7f89d8063800,
data=0x7f88a8aa9e00 "RTSP/1.0 200 OK\r\nCSeq: 5\r\nServer: GStreamer RTSP server\r\nSession: jVzlgEvvxCFWEMVt; timeout=10\r\nConnection: close\r\nDate: Thu, 06 Nov 2014 00:43:37 GMT\r\n\r\n", size=154, id=0x7f89d806ab10)
at gstrtspconnection.c:3675
#3 0x00007f89e4a6d0ef in do_send_message (client=0x7f89d806ab90, message=0x7f891a7fba00, close=<optimized out>, user_data=<optimized out>) at rtsp-client.c:3105
#4 0x00007f89e4a6d406 in send_message (client=0x7f89d806ab90, ctx=<optimized out>, message=0x7f891a7fba00, close=1) at rtsp-client.c:510
#5 0x00007f89e4a70eda in handle_teardown_request (ctx=0x7f891a7fb970, client=0x7f89d806ab90) at rtsp-client.c:917
#6 handle_request (client=0x7f89d806ab90, request=<optimized out>) at rtsp-client.c:2466
#7 0x00007f89e4a730bb in gst_rtsp_client_handle_message (client=0x7f89d806ab90, message=0x7f89d8064888) at rtsp-client.c:3034
#8 0x00007f89e4838a91 in gst_rtsp_source_dispatch_read (stream=<optimized out>, watch=0x7f89d8063800) at gstrtspconnection.c:3228
#9 0x00007f89dcd6b1e4 in gnutls_source_dispatch (source=0x7f89d807fb30, callback=<optimized out>, user_data=<optimized out>) at gtlsconnection-gnutls.c:917
#10 0x00007f89e3c4cf29 in g_main_dispatch (context=0x7f89d804d920) at gmain.c:3111
#11 g_main_context_dispatch (context=0x7f89d804d920) at gmain.c:3710
#12 0x00007f89e3c4d238 in g_main_context_iterate (context=0x7f89d804d920, block=<optimized out>, dispatch=1, self=<optimized out>) at gmain.c:3781
#13 0x00007f89e3c4d5ea in g_main_context_iterate (dispatch=1, block=1, context=0x7f89d804d920, self=<optimized out>) at gmain.c:3748
#14 g_main_loop_run (loop=0x7f89d804fd90) at gmain.c:3975
#15 0x00007f89e4a57188 in do_loop (thread=0x7f88a9950b40) at rtsp-thread-pool.c:329
#16 0x00007f89e3c750c6 in g_thread_pool_thread_proxy (data=<optimized out>) at gthreadpool.c:307
#17 0x00007f89e3c745b5 in g_thread_proxy (data=0x7f88a851bd90) at gthread.c:764
#18 0x00007f89e5ac2e9a in start_thread (arg=0x7f891a7fc700) at pthread_create.c:308
#19 0x00007f89e52da31d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#20 0x0000000000000000 in ?? ()