Commit a2e182c3 authored by David Svensson Fors's avatar David Svensson Fors Committed by Sebastian Dröge

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
parent 990d5dde
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment