From 308480e7624fba1e1b28685907c0b0d1556950fc Mon Sep 17 00:00:00 2001 From: Patricia Muscalu Date: Tue, 24 Jul 2018 14:02:40 +0200 Subject: [PATCH] client: Don't reserve multicast address in the client setting case When two multicast clients request specific transport configurations, and "transport.client-settings" parameter is set to true, it's wrong to actually require that these two clients request the same multicast group. Removed test_client_multicast_invalid_transport_specific test cases as they wrongly require that the requested destination address is supposed to be present in the address pool, also in the case when "transport.client-settings" parameter is set to true. Change-Id: I4580182ef35996caf644686d6139f72ec599c9fa https://bugzilla.gnome.org/show_bug.cgi?id=793441 --- gst/rtsp-server/rtsp-client.c | 20 ++-- tests/check/gst/client.c | 267 ++++++++++++++++++++++++------------------ 2 files changed, 162 insertions(+), 125 deletions(-) diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index 92135f2..01e63bf 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -1990,17 +1990,16 @@ default_configure_client_transport (GstRTSPClient * client, goto error_allocating_ports; if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) { - GstRTSPAddress *addr = NULL; + /* FIXME: the address has been successfully allocated, however, in + * the use_client_settings case we need to verify that the allocated + * address is the one requested by the client and if this address is + * an allowed destination. Verifying this via the address pool in not + * the proper way as the address pool should only be used for choosing + * the server-selected address/port pairs. */ - if (use_client_settings) { - /* the address has been successfully allocated, let's check if it's - * the one requested by the client */ - addr = gst_rtsp_stream_reserve_address (ctx->stream, ct->destination, - ct->port.min, ct->port.max - ct->port.min + 1, ct->ttl); + if (!use_client_settings) { + GstRTSPAddress *addr = NULL; - if (addr == NULL) - goto no_address; - } else { g_free (ct->destination); addr = gst_rtsp_stream_get_multicast_address (ctx->stream, family); if (addr == NULL) @@ -2009,9 +2008,8 @@ default_configure_client_transport (GstRTSPClient * client, ct->port.min = addr->port; ct->port.max = addr->port + addr->n_ports - 1; ct->ttl = addr->ttl; + gst_rtsp_address_free (addr); } - - gst_rtsp_address_free (addr); } else { GstRTSPUrl *url; diff --git a/tests/check/gst/client.c b/tests/check/gst/client.c index 4adf3d1..ab95509 100644 --- a/tests/check/gst/client.c +++ b/tests/check/gst/client.c @@ -525,7 +525,6 @@ test_setup_response_200_multicast (GstRTSPClient * client, session_pool = gst_rtsp_client_get_session_pool (client); fail_unless (session_pool != NULL); - fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1); session = gst_rtsp_session_pool_find (session_pool, session_hdr_params[0]); g_strfreev (session_hdr_params); @@ -727,117 +726,6 @@ GST_START_TEST (test_client_multicast_ignore_transport_specific) GST_END_TEST; -static gboolean -test_setup_response_461 (GstRTSPClient * client, - GstRTSPMessage * response, gboolean close, gpointer user_data) -{ - GstRTSPStatusCode code; - const gchar *reason; - GstRTSPVersion version; - gchar *str; - - fail_unless (expected_transport == NULL); - - fail_unless (gst_rtsp_message_get_type (response) == - GST_RTSP_MESSAGE_RESPONSE); - - fail_unless (gst_rtsp_message_parse_response (response, &code, &reason, - &version) - == GST_RTSP_OK); - fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT); - fail_unless (g_str_equal (reason, "Unsupported transport")); - fail_unless (version == GST_RTSP_VERSION_1_0); - - fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str, - 0) == GST_RTSP_OK); - fail_unless (atoi (str) == cseq++); - - - return TRUE; -} - -GST_START_TEST (test_client_multicast_invalid_transport_specific) -{ - GstRTSPClient *client; - GstRTSPMessage request = { 0, }; - gchar *str; - GstRTSPSessionPool *session_pool; - GstRTSPContext ctx = { NULL }; - - client = setup_multicast_client (); - - ctx.client = client; - ctx.auth = gst_rtsp_auth_new (); - ctx.token = - gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS, - G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING, - "user", NULL); - gst_rtsp_context_push_current (&ctx); - - /* simple SETUP with a valid URI and multicast, but an invalid ip */ - 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_take_header (&request, GST_RTSP_HDR_CSEQ, str); - gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, - "RTP/AVP;multicast;destination=233.252.0.2;ttl=1;port=5000-5001;"); - - gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL); - fail_unless (gst_rtsp_client_handle_message (client, - &request) == GST_RTSP_OK); - gst_rtsp_message_unset (&request); - - session_pool = gst_rtsp_client_get_session_pool (client); - fail_unless (session_pool != NULL); - fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); - g_object_unref (session_pool); - - - /* simple SETUP with a valid URI and multicast, but an invalid prt */ - 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_take_header (&request, GST_RTSP_HDR_CSEQ, str); - gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, - "RTP/AVP;multicast;destination=233.252.0.1;ttl=1;port=6000-6001;"); - - gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL); - fail_unless (gst_rtsp_client_handle_message (client, - &request) == GST_RTSP_OK); - gst_rtsp_message_unset (&request); - - session_pool = gst_rtsp_client_get_session_pool (client); - fail_unless (session_pool != NULL); - fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); - g_object_unref (session_pool); - - - /* simple SETUP with a valid URI and multicast, but an invalid ttl */ - 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_take_header (&request, GST_RTSP_HDR_CSEQ, str); - gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, - "RTP/AVP;multicast;destination=233.252.0.1;ttl=2;port=5000-5001;"); - - gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL); - fail_unless (gst_rtsp_client_handle_message (client, - &request) == GST_RTSP_OK); - gst_rtsp_message_unset (&request); - - session_pool = gst_rtsp_client_get_session_pool (client); - fail_unless (session_pool != NULL); - fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); - g_object_unref (session_pool); - - teardown_client (client); - g_object_unref (ctx.auth); - gst_rtsp_token_unref (ctx.token); - gst_rtsp_context_pop_current (&ctx); -} - -GST_END_TEST; - GST_START_TEST (test_client_multicast_transport_specific) { GstRTSPClient *client; @@ -859,7 +747,7 @@ GST_START_TEST (test_client_multicast_transport_specific) expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;" "ttl=1;port=5000-5001;mode=\"PLAY\""; - /* simple SETUP with a valid URI and multicast, but an invalid ip */ + /* simple SETUP with a valid URI */ 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); @@ -1031,6 +919,156 @@ GST_START_TEST (test_client_sdp_with_no_bitrate_tags) GST_END_TEST; +static void +mcast_transport_specific_two_clients (gboolean shared) +{ + GstRTSPClient *client, *client2; + GstRTSPMessage request = { 0, }; + gchar *str; + GstRTSPSessionPool *session_pool; + GstRTSPContext ctx = { NULL }; + GstRTSPContext ctx2 = { NULL }; + GstRTSPMountPoints *mount_points; + GstRTSPMediaFactory *factory; + GstRTSPAddressPool *address_pool; + GstRTSPThreadPool *thread_pool; + gchar *session_id1; + + mount_points = gst_rtsp_mount_points_new (); + factory = gst_rtsp_media_factory_new (); + if (shared) + gst_rtsp_media_factory_set_shared (factory, TRUE); + gst_rtsp_media_factory_set_max_mcast_ttl (factory, 5); + gst_rtsp_media_factory_set_launch (factory, + "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0"); + address_pool = gst_rtsp_address_pool_new (); + fail_unless (gst_rtsp_address_pool_add_range (address_pool, + "233.252.0.1", "233.252.0.1", 5000, 5001, 1)); + gst_rtsp_media_factory_set_address_pool (factory, address_pool); + gst_rtsp_media_factory_add_role (factory, "user", + "media.factory.access", G_TYPE_BOOLEAN, TRUE, + "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL); + gst_rtsp_mount_points_add_factory (mount_points, "/test", factory); + session_pool = gst_rtsp_session_pool_new (); + thread_pool = gst_rtsp_thread_pool_new (); + + /* first multicast client with transport specific request */ + client = gst_rtsp_client_new (); + gst_rtsp_client_set_session_pool (client, session_pool); + gst_rtsp_client_set_mount_points (client, mount_points); + gst_rtsp_client_set_thread_pool (client, thread_pool); + + ctx.client = client; + ctx.auth = gst_rtsp_auth_new (); + ctx.token = + gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS, + G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING, + "user", NULL); + gst_rtsp_context_push_current (&ctx); + + expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;" + "ttl=1;port=5000-5001;mode=\"PLAY\""; + + /* send SETUP request */ + 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_take_header (&request, GST_RTSP_HDR_CSEQ, str); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, + expected_transport); + + gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast, + NULL, NULL); + fail_unless (gst_rtsp_client_handle_message (client, + &request) == GST_RTSP_OK); + gst_rtsp_message_unset (&request); + expected_transport = NULL; + + /* send PLAY request */ + fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY, + "rtsp://localhost/test") == GST_RTSP_OK); + str = g_strdup_printf ("%d", cseq); + gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id); + gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL); + fail_unless (gst_rtsp_client_handle_message (client, + &request) == GST_RTSP_OK); + gst_rtsp_message_unset (&request); + gst_rtsp_context_pop_current (&ctx); + session_id1 = session_id; + + /* second multicast client with transport specific request */ + cseq = 0; + client2 = gst_rtsp_client_new (); + gst_rtsp_client_set_session_pool (client2, session_pool); + gst_rtsp_client_set_mount_points (client2, mount_points); + gst_rtsp_client_set_thread_pool (client2, thread_pool); + + ctx2.client = client2; + ctx2.auth = gst_rtsp_auth_new (); + ctx2.token = + gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS, + G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING, + "user", NULL); + gst_rtsp_context_push_current (&ctx2); + + expected_transport = "RTP/AVP;multicast;destination=233.252.0.2;" + "ttl=1;port=5002-5003;mode=\"PLAY\""; + + /* send SETUP request */ + 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_take_header (&request, GST_RTSP_HDR_CSEQ, str); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, + expected_transport); + + gst_rtsp_client_set_send_func (client2, test_setup_response_200_multicast, + NULL, NULL); + fail_unless (gst_rtsp_client_handle_message (client2, + &request) == GST_RTSP_OK); + gst_rtsp_message_unset (&request); + expected_transport = NULL; + + /* send PLAY request */ + fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY, + "rtsp://localhost/test") == GST_RTSP_OK); + str = g_strdup_printf ("%d", cseq); + gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id); + gst_rtsp_client_set_send_func (client2, test_response_200, NULL, NULL); + fail_unless (gst_rtsp_client_handle_message (client2, + &request) == GST_RTSP_OK); + gst_rtsp_message_unset (&request); + + send_teardown (client2); + gst_rtsp_context_pop_current (&ctx2); + + gst_rtsp_context_push_current (&ctx); + session_id = session_id1; + send_teardown (client); + gst_rtsp_context_pop_current (&ctx); + + teardown_client (client); + teardown_client (client2); + g_object_unref (ctx.auth); + g_object_unref (ctx2.auth); + gst_rtsp_token_unref (ctx.token); + gst_rtsp_token_unref (ctx2.token); + g_object_unref (mount_points); + g_object_unref (session_pool); + g_object_unref (address_pool); + g_object_unref (thread_pool); +} + +/* test if two multicast clients can choose different transport settings */ +GST_START_TEST + (test_client_multicast_transport_specific_two_clients_shared_media) { + mcast_transport_specific_two_clients (TRUE); +} + +GST_END_TEST; + static Suite * rtspclient_suite (void) { @@ -1046,12 +1084,13 @@ rtspclient_suite (void) 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); - tcase_add_test (tc, test_client_multicast_invalid_transport_specific); tcase_add_test (tc, test_client_multicast_transport_specific); tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag); tcase_add_test (tc, test_client_sdp_with_bitrate_tag); tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags); tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags); + tcase_add_test (tc, + test_client_multicast_transport_specific_two_clients_shared_media); return s; } -- 2.7.4