mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 22:16:22 +00:00
rtsp-client: Avoid reuse of channel numbers for interleaved
If a (strange) client would reuse interleaved channel numbers in multiple SETUP requests, we should not accept them. The channel numbers are used for looking up stream transports in the priv->transports hash table, and transports disappear from the table if channel numbers are reused. RFC 7826 (RTSP 2.0), Section 18.54, clarifies that it is OK for the server to change the channel numbers suggested by the client. https://bugzilla.gnome.org/show_bug.cgi?id=796988
This commit is contained in:
parent
990d5dde86
commit
a2e182c3b4
2 changed files with 74 additions and 2 deletions
|
@ -2084,6 +2084,16 @@ default_configure_client_transport (GstRTSPClient * client,
|
|||
gst_rtsp_session_media_alloc_channels (ctx->sessmedia,
|
||||
&ct->interleaved);
|
||||
}
|
||||
/* alloc new channels if they are already taken */
|
||||
while (g_hash_table_contains (priv->transports,
|
||||
GINT_TO_POINTER (ct->interleaved.min))
|
||||
|| g_hash_table_contains (priv->transports,
|
||||
GINT_TO_POINTER (ct->interleaved.max))) {
|
||||
gst_rtsp_session_media_alloc_channels (ctx->sessmedia,
|
||||
&ct->interleaved);
|
||||
if (ct->interleaved.max > 255)
|
||||
goto error_allocating_channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -2115,6 +2125,11 @@ error_mcast_transport:
|
|||
GST_ERROR_OBJECT (client, "Failed to add multicast client transport");
|
||||
return FALSE;
|
||||
}
|
||||
error_allocating_channels:
|
||||
{
|
||||
GST_ERROR_OBJECT (client, "Failed to allocate interleaved channels");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GstRTSPTransport *
|
||||
|
|
|
@ -21,6 +21,13 @@
|
|||
|
||||
#include <rtsp-client.h>
|
||||
|
||||
#define VIDEO_PIPELINE "videotestsrc ! " \
|
||||
"video/x-raw,width=352,height=288 ! " \
|
||||
"rtpgstpay name=pay0 pt=96"
|
||||
#define AUDIO_PIPELINE "audiotestsrc ! " \
|
||||
"audio/x-raw,rate=8000 ! " \
|
||||
"rtpgstpay name=pay1 pt=97"
|
||||
|
||||
static gchar *session_id;
|
||||
static gint cseq;
|
||||
static guint expected_session_timeout = 60;
|
||||
|
@ -167,7 +174,7 @@ setup_client (const gchar * launch_line)
|
|||
factory = gst_rtsp_media_factory_new ();
|
||||
if (launch_line == NULL)
|
||||
gst_rtsp_media_factory_set_launch (factory,
|
||||
"videotestsrc ! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96");
|
||||
"( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
|
||||
else
|
||||
gst_rtsp_media_factory_set_launch (factory, launch_line);
|
||||
|
||||
|
@ -637,7 +644,7 @@ GST_START_TEST (test_setup_tcp)
|
|||
fail_unless (gst_rtsp_client_set_connection (client, conn));
|
||||
|
||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
||||
"rtsp://localhost/test") == GST_RTSP_OK);
|
||||
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
||||
str = g_strdup_printf ("%d", cseq);
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||
g_free (str);
|
||||
|
@ -658,6 +665,55 @@ GST_START_TEST (test_setup_tcp)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_setup_tcp_two_streams_same_channels)
|
||||
{
|
||||
GstRTSPClient *client;
|
||||
GstRTSPConnection *conn;
|
||||
GstRTSPMessage request = { 0, };
|
||||
gchar *str;
|
||||
|
||||
client = setup_client (NULL);
|
||||
create_connection (&conn);
|
||||
fail_unless (gst_rtsp_client_set_connection (client, conn));
|
||||
|
||||
/* test SETUP of a video stream with 0-1 as interleaved channels */
|
||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
||||
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
||||
str = g_strdup_printf ("%d", cseq);
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||
g_free (str);
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
|
||||
"RTP/AVP/TCP;unicast;interleaved=0-1");
|
||||
gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
|
||||
expected_transport =
|
||||
"RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=.*;mode=\"PLAY\"";
|
||||
fail_unless (gst_rtsp_client_handle_message (client,
|
||||
&request) == GST_RTSP_OK);
|
||||
gst_rtsp_message_unset (&request);
|
||||
|
||||
/* test SETUP of an audio stream with *the same* interleaved channels.
|
||||
* we expect the server to allocate new channel numbers */
|
||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
||||
"rtsp://localhost/test/stream=1") == GST_RTSP_OK);
|
||||
str = g_strdup_printf ("%d", cseq);
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||
g_free (str);
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
|
||||
"RTP/AVP/TCP;unicast;interleaved=0-1");
|
||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
|
||||
gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
|
||||
expected_transport =
|
||||
"RTP/AVP/TCP;unicast;interleaved=2-3;ssrc=.*;mode=\"PLAY\"";
|
||||
fail_unless (gst_rtsp_client_handle_message (client,
|
||||
&request) == GST_RTSP_OK);
|
||||
gst_rtsp_message_unset (&request);
|
||||
|
||||
send_teardown (client);
|
||||
teardown_client (client);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static GstRTSPClient *
|
||||
setup_multicast_client (guint max_ttl)
|
||||
{
|
||||
|
@ -1415,6 +1471,7 @@ rtspclient_suite (void)
|
|||
tcase_add_test (tc, test_options);
|
||||
tcase_add_test (tc, test_describe);
|
||||
tcase_add_test (tc, test_setup_tcp);
|
||||
tcase_add_test (tc, test_setup_tcp_two_streams_same_channels);
|
||||
tcase_add_test (tc, test_client_multicast_transport_404);
|
||||
tcase_add_test (tc, test_client_multicast_transport);
|
||||
tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
|
||||
|
|
Loading…
Reference in a new issue