diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index d4c5211985..8f39ccd6fb 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -1972,13 +1972,8 @@ default_configure_client_transport (GstRTSPClient * client, if ((ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) && gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS) && - (ct->destination != NULL)) { - - if (!gst_rtsp_stream_verify_mcast_ttl (ctx->stream, ct->ttl)) - goto error_ttl; - + (ct->destination != NULL)) use_client_settings = TRUE; - } /* We need to allocate the sockets for both families before starting * multiudpsink, otherwise multiudpsink won't accept new clients with @@ -1997,29 +1992,14 @@ default_configure_client_transport (GstRTSPClient * client, goto error_allocating_ports; if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) { - if (use_client_settings) { - /* 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. */ - GSocket *rtp_socket; - guint ttl; + /* 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. */ - rtp_socket = - gst_rtsp_stream_get_rtp_multicast_socket (ctx->stream, family); - if (rtp_socket == NULL) - goto no_socket; - ttl = g_socket_get_multicast_ttl (rtp_socket); - g_object_unref (rtp_socket); - if (ct->ttl < ttl) { - /* use the maximum ttl that is requested by multicast clients */ - GST_DEBUG ("requested ttl %u, but keeping ttl %u", ct->ttl, ttl); - ct->ttl = ttl; - } - - } else { + if (!use_client_settings) { GstRTSPAddress *addr = NULL; g_free (ct->destination); @@ -2032,11 +2012,6 @@ default_configure_client_transport (GstRTSPClient * client, ct->ttl = addr->ttl; gst_rtsp_address_free (addr); } - - if (!gst_rtsp_stream_add_multicast_client_address (ctx->stream, - ct->destination, ct->port.min, ct->port.max, family)) - goto error_mcast_transport; - } else { GstRTSPUrl *url; @@ -2089,12 +2064,6 @@ default_configure_client_transport (GstRTSPClient * client, return TRUE; /* ERRORS */ -error_ttl: - { - GST_ERROR_OBJECT (client, - "Failed to allocate UDP ports: invalid ttl value"); - return FALSE; - } error_allocating_ports: { GST_ERROR_OBJECT (client, "Failed to allocate UDP ports"); @@ -2105,16 +2074,6 @@ no_address: GST_ERROR_OBJECT (client, "Failed to acquire address for stream"); return FALSE; } -no_socket: - { - GST_ERROR_OBJECT (client, "Failed to get UDP socket"); - return FALSE; - } -error_mcast_transport: - { - GST_ERROR_OBJECT (client, "Failed to add multicast client transport"); - return FALSE; - } } static GstRTSPTransport * diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c index 65f0f5d2c6..0d17718d9d 100644 --- a/gst/rtsp-server/rtsp-stream.c +++ b/gst/rtsp-server/rtsp-stream.c @@ -110,7 +110,6 @@ struct _GstRTSPStreamPrivate GstElement *mcast_udpsink[2]; GSocket *mcast_socket_v4[2]; GSocket *mcast_socket_v6[2]; - GList *mcast_clients; /* for TCP transport */ GstElement *appsrc[2]; @@ -293,24 +292,6 @@ gst_rtsp_stream_init (GstRTSPStream * stream) (GDestroyNotify) gst_caps_unref); } -typedef struct _UdpClientAddrInfo UdpClientAddrInfo; - -struct _UdpClientAddrInfo -{ - gchar *address; - guint rtp_port; - guint add_count; /* how often this address has been added */ -}; - -static void -free_mcast_client (gpointer data) -{ - UdpClientAddrInfo *client = data; - - g_free (client->address); - g_free (client); -} - static void gst_rtsp_stream_finalize (GObject * obj) { @@ -357,7 +338,6 @@ gst_rtsp_stream_finalize (GObject * obj) } g_free (priv->multicast_iface); - g_list_free_full (priv->mcast_clients, (GDestroyNotify) free_mcast_client); gst_object_unref (priv->payloader); if (priv->srcpad) @@ -1517,12 +1497,6 @@ again: g_clear_object (&inetaddr); - if (multicast && (ct->ttl > 0) && (ct->ttl <= priv->max_mcast_ttl)) { - GST_DEBUG ("setting mcast ttl to %d", ct->ttl); - g_socket_set_multicast_ttl (rtp_socket, ct->ttl); - g_socket_set_multicast_ttl (rtcp_socket, ct->ttl); - } - socket_out[0] = rtp_socket; socket_out[1] = rtcp_socket; *server_addr_out = addr; @@ -1605,100 +1579,6 @@ cleanup: } } -/* must be called with lock */ -static gboolean -add_mcast_client_addr (GstRTSPStream * stream, const gchar * destination, - guint rtp_port, guint rtcp_port) -{ - GstRTSPStreamPrivate *priv; - GList *walk; - UdpClientAddrInfo *client; - GInetAddress *inet; - - priv = stream->priv; - - if (destination == NULL) - return FALSE; - - inet = g_inet_address_new_from_string (destination); - if (inet == NULL) - goto invalid_address; - - if (!g_inet_address_get_is_multicast (inet)) { - g_object_unref (inet); - goto invalid_address; - } - g_object_unref (inet); - - for (walk = priv->mcast_clients; walk; walk = g_list_next (walk)) { - UdpClientAddrInfo *cli = walk->data; - - if ((g_strcmp0 (cli->address, destination) == 0) && - (cli->rtp_port == rtp_port)) { - GST_DEBUG ("requested destination already exists: %s:%u-%u", - destination, rtp_port, rtcp_port); - cli->add_count++; - return TRUE; - } - } - - client = g_new0 (UdpClientAddrInfo, 1); - client->address = g_strdup (destination); - client->rtp_port = rtp_port; - client->add_count = 1; - priv->mcast_clients = g_list_prepend (priv->mcast_clients, client); - - GST_DEBUG ("added mcast client %s:%u-%u", destination, rtp_port, rtcp_port); - - return TRUE; - -invalid_address: - { - GST_WARNING_OBJECT (stream, "Multicast address is invalid: %s", - destination); - return FALSE; - } -} - -/* must be called with lock */ -static gboolean -remove_mcast_client_addr (GstRTSPStream * stream, const gchar * destination, - guint rtp_port, guint rtcp_port) -{ - GstRTSPStreamPrivate *priv; - GList *walk; - - priv = stream->priv; - - if (destination == NULL) - goto no_destination; - - for (walk = priv->mcast_clients; walk; walk = g_list_next (walk)) { - UdpClientAddrInfo *cli = walk->data; - - if ((g_strcmp0 (cli->address, destination) == 0) && - (cli->rtp_port == rtp_port)) { - cli->add_count--; - - if (!cli->add_count) { - priv->mcast_clients = g_list_remove (priv->mcast_clients, cli); - free_mcast_client (cli); - } - return TRUE; - } - } - - GST_WARNING_OBJECT (stream, "Address not found"); - return FALSE; - -no_destination: - { - GST_WARNING_OBJECT (stream, "No destination has been provided"); - return FALSE; - } -} - - /** * gst_rtsp_stream_allocate_udp_sockets: * @stream: a #GstRTSPStream @@ -2126,29 +2006,6 @@ gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream * stream) return ttl; } -/** - * gst_rtsp_stream_verify_mcast_ttl: - * @stream: a #GstRTSPStream - * @ttl: a requested multicast ttl - * - * Check if the requested multicast ttl value is allowed. - * - * Returns: TRUE if the requested ttl value is allowed. - * - */ -gboolean -gst_rtsp_stream_verify_mcast_ttl (GstRTSPStream * stream, guint ttl) -{ - gboolean res = FALSE; - - g_mutex_lock (&stream->priv->lock); - if ((ttl > 0) && (ttl <= stream->priv->max_mcast_ttl)) - res = TRUE; - g_mutex_unlock (&stream->priv->lock); - - return res; -} - /* executed from streaming thread */ static void caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPStream * stream) @@ -3482,29 +3339,38 @@ udpsrc_error: } static gboolean -check_mcast_client_addr (GstRTSPStream * stream, const GstRTSPTransport * tr) +check_mcast_part_for_transport (GstRTSPStream * stream, + const GstRTSPTransport * tr) { GstRTSPStreamPrivate *priv = stream->priv; - GList *walk; + GInetAddress *inetaddr; + GSocketFamily family; + GstRTSPAddress *mcast_addr; - if (priv->mcast_clients == NULL) - goto no_addr; + /* Check if it's a ipv4 or ipv6 transport */ + inetaddr = g_inet_address_new_from_string (tr->destination); + family = g_inet_address_get_family (inetaddr); + g_object_unref (inetaddr); - if (tr == NULL) - goto no_transport; - - if (tr->destination == NULL) - goto no_destination; - - for (walk = priv->mcast_clients; walk; walk = g_list_next (walk)) { - UdpClientAddrInfo *cli = walk->data; - - if ((g_strcmp0 (cli->address, tr->destination) == 0) && - (cli->rtp_port == tr->port.min)) - return TRUE; + /* Select fields corresponding to the family */ + if (family == G_SOCKET_FAMILY_IPV4) { + mcast_addr = priv->mcast_addr_v4; + } else { + mcast_addr = priv->mcast_addr_v6; } - return FALSE; + /* We support only one mcast group per family, make sure this transport + * matches it. */ + if (!mcast_addr) + goto no_addr; + + if (g_ascii_strcasecmp (tr->destination, mcast_addr->address) != 0 || + tr->port.min != mcast_addr->port || + tr->port.max != mcast_addr->port + mcast_addr->n_ports - 1 || + tr->ttl != mcast_addr->ttl) + goto wrong_addr; + + return TRUE; no_addr: { @@ -3512,13 +3378,7 @@ no_addr: "has been reserved"); return FALSE; } -no_transport: - { - GST_WARNING_OBJECT (stream, "Adding mcast transport, but no transport " - "has been provided"); - return FALSE; - } -no_destination: +wrong_addr: { GST_WARNING_OBJECT (stream, "Adding mcast transport, but it doesn't match " "the reserved address"); @@ -4195,11 +4055,10 @@ update_transport (GstRTSPStream * stream, GstRTSPStreamTransport * trans, if (add) { GST_INFO ("adding %s:%d-%d", dest, min, max); - if (!check_mcast_client_addr (stream, tr)) + if (!check_mcast_part_for_transport (stream, tr)) goto mcast_error; - add_client (priv->mcast_udpsink[0], priv->mcast_udpsink[1], dest, min, - max); + /* FIXME: Is it ok to set ttl-mc if media is shared? */ if (tr->ttl > 0) { GST_INFO ("setting ttl-mc %d", tr->ttl); if (priv->mcast_udpsink[0]) @@ -4209,12 +4068,11 @@ update_transport (GstRTSPStream * stream, GstRTSPStreamTransport * trans, g_object_set (G_OBJECT (priv->mcast_udpsink[1]), "ttl-mc", tr->ttl, NULL); } + add_client (priv->mcast_udpsink[0], priv->mcast_udpsink[1], dest, min, + max); priv->transports = g_list_prepend (priv->transports, trans); } else { GST_INFO ("removing %s:%d-%d", dest, min, max); - if (!remove_mcast_client_addr (stream, dest, min, max)) - GST_WARNING_OBJECT (stream, - "Failed to remove multicast address: %s:%d-%d", dest, min, max); remove_client (priv->mcast_udpsink[0], priv->mcast_udpsink[1], dest, min, max); priv->transports = g_list_remove (priv->transports, trans); @@ -4564,95 +4422,6 @@ gst_rtsp_stream_get_rtcp_multicast_socket (GstRTSPStream * stream, return socket; } -/** - * gst_rtsp_stream_add_multicast_client_address: - * @stream: a #GstRTSPStream - * @destination: (transfer none): a multicast address to add - * @rtp_port: RTP port - * @rtcp_port: RTCP port - * @family: socket family - * - * Add multicast client address to stream. At this point, the sockets that - * will stream RTP and RTCP data to @destination are supposed to be - * allocated. - * - * Returns: %TRUE if @destination can be addedd and handled by @stream. - */ -gboolean -gst_rtsp_stream_add_multicast_client_address (GstRTSPStream * stream, - const gchar * destination, guint rtp_port, guint rtcp_port, - GSocketFamily family) -{ - GstRTSPStreamPrivate *priv; - - g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE); - g_return_val_if_fail (destination != NULL, FALSE); - - priv = stream->priv; - g_mutex_lock (&priv->lock); - if ((family == G_SOCKET_FAMILY_IPV4) && (priv->mcast_socket_v4[0] == NULL)) - goto socket_error; - else if ((family == G_SOCKET_FAMILY_IPV6) && - (priv->mcast_socket_v6[0] == NULL)) - goto socket_error; - - if (!add_mcast_client_addr (stream, destination, rtp_port, rtcp_port)) - goto add_addr_error; - g_mutex_unlock (&priv->lock); - - return TRUE; - -socket_error: - { - GST_WARNING_OBJECT (stream, - "Failed to add multicast address: no udp socket"); - g_mutex_unlock (&priv->lock); - return FALSE; - } -add_addr_error: - { - GST_WARNING_OBJECT (stream, - "Failed to add multicast address: invalid address"); - g_mutex_unlock (&priv->lock); - return FALSE; - } -} - -/** - * gst_rtsp_stream_get_multicast_client_addresses - * @stream: a #GstRTSPStream - * - * Get all multicast client addresses that RTP data will be sent to - * - * Returns: A comma separated list of host:port pairs with destinations - */ -gchar * -gst_rtsp_stream_get_multicast_client_addresses (GstRTSPStream * stream) -{ - GstRTSPStreamPrivate *priv; - GString *str; - GList *clients; - - g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL); - - priv = stream->priv; - str = g_string_new (""); - - g_mutex_lock (&priv->lock); - clients = priv->mcast_clients; - while (clients != NULL) { - UdpClientAddrInfo *client; - - client = (UdpClientAddrInfo *) clients->data; - clients = g_list_next (clients); - g_string_append_printf (str, "%s:%d%s", client->address, client->rtp_port, - (clients != NULL ? "," : "")); - } - g_mutex_unlock (&priv->lock); - - return g_string_free (str, FALSE); -} - /** * gst_rtsp_stream_set_seqnum: * @stream: a #GstRTSPStream diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h index 0c6804d536..1ee146dda7 100644 --- a/gst/rtsp-server/rtsp-stream.h +++ b/gst/rtsp-server/rtsp-stream.h @@ -233,16 +233,6 @@ GST_RTSP_SERVER_API GSocket * gst_rtsp_stream_get_rtcp_multicast_socket (GstRTSPStream *stream, GSocketFamily family); -GST_RTSP_SERVER_API -gboolean gst_rtsp_stream_add_multicast_client_address (GstRTSPStream * stream, - const gchar * destination, - guint rtp_port, - guint rtcp_port, - GSocketFamily family); - -GST_RTSP_SERVER_API -gchar * gst_rtsp_stream_get_multicast_client_addresses (GstRTSPStream * stream); - GST_RTSP_SERVER_API gboolean gst_rtsp_stream_update_crypto (GstRTSPStream * stream, guint ssrc, GstCaps * crypto); @@ -308,9 +298,6 @@ gboolean gst_rtsp_stream_set_max_mcast_ttl (GstRTSPStream *strea GST_RTSP_SERVER_API guint gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream *stream); -GST_RTSP_SERVER_API -gboolean gst_rtsp_stream_verify_mcast_ttl (GstRTSPStream *stream, guint ttl); - GST_RTSP_SERVER_API gboolean gst_rtsp_stream_complete_stream (GstRTSPStream * stream, const GstRTSPTransport * transport); diff --git a/tests/check/gst/client.c b/tests/check/gst/client.c index d890b8218b..d4fdd9ec1f 100644 --- a/tests/check/gst/client.c +++ b/tests/check/gst/client.c @@ -541,35 +541,6 @@ test_setup_response_200_multicast (GstRTSPClient * client, return TRUE; } -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; -} - static gboolean test_teardown_response_200 (GstRTSPClient * client, GstRTSPMessage * response, gboolean close, gpointer user_data) @@ -613,7 +584,7 @@ send_teardown (GstRTSPClient * client) } static GstRTSPClient * -setup_multicast_client (guint max_ttl) +setup_multicast_client (void) { GstRTSPClient *client; GstRTSPSessionPool *session_pool; @@ -640,7 +611,6 @@ setup_multicast_client (guint max_ttl) "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL); gst_rtsp_mount_points_add_factory (mount_points, "/test", factory); gst_rtsp_client_set_mount_points (client, mount_points); - gst_rtsp_media_factory_set_max_mcast_ttl (factory, max_ttl); thread_pool = gst_rtsp_thread_pool_new (); gst_rtsp_client_set_thread_pool (client, thread_pool); @@ -659,7 +629,7 @@ GST_START_TEST (test_client_multicast_transport_404) GstRTSPMessage request = { 0, }; gchar *str; - client = setup_multicast_client (1); + client = setup_multicast_client (); /* simple SETUP for non-existing url */ fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP, @@ -692,7 +662,7 @@ GST_START_TEST (test_client_multicast_transport) GstRTSPMessage request = { 0, }; gchar *str; - client = setup_multicast_client (1); + client = setup_multicast_client (); expected_session_timeout = 20; g_signal_connect (G_OBJECT (client), "new-session", @@ -729,7 +699,7 @@ GST_START_TEST (test_client_multicast_ignore_transport_specific) GstRTSPMessage request = { 0, }; gchar *str; - client = setup_multicast_client (1); + client = setup_multicast_client (); /* simple SETUP with a valid URI and multicast and a specific dest, * but ignore it */ @@ -765,7 +735,7 @@ multicast_transport_specific (void) GstRTSPSessionPool *session_pool; GstRTSPContext ctx = { NULL }; - client = setup_multicast_client (1); + client = setup_multicast_client (); ctx.client = client; ctx.auth = gst_rtsp_auth_new (); @@ -980,12 +950,9 @@ GST_START_TEST (test_client_sdp_with_no_bitrate_tags) GST_END_TEST; static void -mcast_transport_two_clients (gboolean shared, const gchar * transport1, - const gchar * expected_transport1, const gchar * addr1, - const gchar * transport2, const gchar * expected_transport2, - const gchar * addr2) +mcast_transport_specific_two_clients (gboolean shared) { - GstRTSPClient *client1, *client2; + GstRTSPClient *client, *client2; GstRTSPMessage request = { 0, }; gchar *str; GstRTSPSessionPool *session_pool; @@ -996,7 +963,6 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1, GstRTSPAddressPool *address_pool; GstRTSPThreadPool *thread_pool; gchar *session_id1; - gchar *client_addr = NULL; mount_points = gst_rtsp_mount_points_new (); factory = gst_rtsp_media_factory_new (); @@ -1017,12 +983,12 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1, thread_pool = gst_rtsp_thread_pool_new (); /* first multicast client with transport specific request */ - client1 = gst_rtsp_client_new (); - gst_rtsp_client_set_session_pool (client1, session_pool); - gst_rtsp_client_set_mount_points (client1, mount_points); - gst_rtsp_client_set_thread_pool (client1, thread_pool); + 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 = client1; + ctx.client = client; ctx.auth = gst_rtsp_auth_new (); ctx.token = gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS, @@ -1030,18 +996,20 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1, "user", NULL); gst_rtsp_context_push_current (&ctx); - expected_transport = expected_transport1; + 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, transport1); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, + expected_transport); - gst_rtsp_client_set_send_func (client1, test_setup_response_200_multicast, + gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast, NULL, NULL); - fail_unless (gst_rtsp_client_handle_message (client1, + fail_unless (gst_rtsp_client_handle_message (client, &request) == GST_RTSP_OK); gst_rtsp_message_unset (&request); expected_transport = NULL; @@ -1052,17 +1020,10 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1, 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 (client1, test_response_200, NULL, NULL); - fail_unless (gst_rtsp_client_handle_message (client1, + 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); - - /* check address */ - client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx.stream); - fail_if (client_addr == NULL); - fail_unless (g_str_equal (client_addr, addr1)); - g_free (client_addr); - gst_rtsp_context_pop_current (&ctx); session_id1 = session_id; @@ -1081,14 +1042,16 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1, "user", NULL); gst_rtsp_context_push_current (&ctx2); - expected_transport = expected_transport2; + 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, transport2); + 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); @@ -1108,31 +1071,15 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1, &request) == GST_RTSP_OK); gst_rtsp_message_unset (&request); - /* check addresses */ - client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx2.stream); - fail_if (client_addr == NULL); - if (shared) { - if (g_str_equal (addr1, addr2)) { - fail_unless (g_str_equal (client_addr, addr1)); - } else { - gchar *addr_str = g_strdup_printf ("%s,%s", addr2, addr1); - fail_unless (g_str_equal (client_addr, addr_str)); - g_free (addr_str); - } - } else { - fail_unless (g_str_equal (client_addr, addr2)); - } - g_free (client_addr); - send_teardown (client2); gst_rtsp_context_pop_current (&ctx2); gst_rtsp_context_push_current (&ctx); session_id = session_id1; - send_teardown (client1); + send_teardown (client); gst_rtsp_context_pop_current (&ctx); - teardown_client (client1); + teardown_client (client); teardown_client (client2); g_object_unref (ctx.auth); g_object_unref (ctx2.auth); @@ -1148,19 +1095,7 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1, * CASE: media is shared */ GST_START_TEST (test_client_multicast_transport_specific_two_clients_shared_media) { - const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=1;port=5000-5001;mode=\"PLAY\""; - const gchar *expected_transport_1 = transport_client_1; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;" - "ttl=1;port=5002-5003;mode=\"PLAY\""; - const gchar *expected_transport_2 = transport_client_2; - const gchar *addr_client_2 = "233.252.0.2:5002"; - - mcast_transport_two_clients (TRUE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); + mcast_transport_specific_two_clients (TRUE); } GST_END_TEST; @@ -1169,195 +1104,7 @@ GST_END_TEST; * CASE: media is not shared */ GST_START_TEST (test_client_multicast_transport_specific_two_clients) { - const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=1;port=5000-5001;mode=\"PLAY\""; - const gchar *expected_transport_1 = transport_client_1; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;" - "ttl=1;port=5002-5003;mode=\"PLAY\""; - const gchar *expected_transport_2 = transport_client_2; - const gchar *addr_client_2 = "233.252.0.2:5002"; - - mcast_transport_two_clients (FALSE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); -} - -GST_END_TEST; - -/* test if two multicast clients can choose the same transport settings. - * CASE: media is shared */ -GST_START_TEST - (test_client_multicast_transport_specific_two_clients_shared_media_same_transport) -{ - - const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=1;port=5000-5001;mode=\"PLAY\""; - const gchar *expected_transport_1 = transport_client_1; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = transport_client_1; - const gchar *expected_transport_2 = expected_transport_1; - const gchar *addr_client_2 = addr_client_1; - - mcast_transport_two_clients (TRUE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); -} - -GST_END_TEST; - -/* test if two multicast clients get the same transport settings without - * requesting specific transport. - * CASE: media is shared */ -GST_START_TEST (test_client_multicast_two_clients_shared_media) -{ - const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\""; - const gchar *expected_transport_1 = - "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=1;port=5000-5001;mode=\"PLAY\""; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = transport_client_1; - const gchar *expected_transport_2 = expected_transport_1; - const gchar *addr_client_2 = addr_client_1; - - mcast_transport_two_clients (TRUE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); -} - -GST_END_TEST; - -/* test if two multicast clients get the different transport settings: the first client - * requests the specific transport configuration while the second client lets - * the server select the multicast address and the ports. - * CASE: media is shared */ -GST_START_TEST - (test_client_multicast_two_clients_first_specific_transport_shared_media) { - const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=1;port=5000-5001;mode=\"PLAY\""; - const gchar *expected_transport_1 = transport_client_1; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = "RTP/AVP;multicast;mode=\"PLAY\""; - const gchar *expected_transport_2 = expected_transport_1; - const gchar *addr_client_2 = addr_client_1; - - mcast_transport_two_clients (TRUE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); -} - -GST_END_TEST; -/* test if two multicast clients get the different transport settings: the first client lets - * the server select the multicast address and the ports while the second client requests - * the specific transport configuration. - * CASE: media is shared */ -GST_START_TEST - (test_client_multicast_two_clients_second_specific_transport_shared_media) { - const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\""; - const gchar *expected_transport_1 = - "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=1;port=5000-5001;mode=\"PLAY\""; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;" - "ttl=2;port=5004-5005;mode=\"PLAY\""; - const gchar *expected_transport_2 = transport_client_2; - const gchar *addr_client_2 = "233.252.0.2:5004"; - - mcast_transport_two_clients (TRUE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); -} - -GST_END_TEST; - -/* test if the maximum ttl multicast value is chosen by the server - * CASE: the first client provides the highest ttl value */ -GST_START_TEST (test_client_multicast_max_ttl_first_client) -{ - const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=3;port=5000-5001;mode=\"PLAY\""; - const gchar *expected_transport_1 = transport_client_1; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;" - "ttl=1;port=5002-5003;mode=\"PLAY\""; - const gchar *expected_transport_2 = - "RTP/AVP;multicast;destination=233.252.0.2;" - "ttl=3;port=5002-5003;mode=\"PLAY\""; - const gchar *addr_client_2 = "233.252.0.2:5002"; - - mcast_transport_two_clients (TRUE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); -} - -GST_END_TEST; - -/* test if the maximum ttl multicast value is chosen by the server - * CASE: the second client provides the highest ttl value */ -GST_START_TEST (test_client_multicast_max_ttl_second_client) -{ - const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;" - "ttl=2;port=5000-5001;mode=\"PLAY\""; - const gchar *expected_transport_1 = transport_client_1; - const gchar *addr_client_1 = "233.252.0.1:5000"; - - const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;" - "ttl=4;port=5002-5003;mode=\"PLAY\""; - const gchar *expected_transport_2 = transport_client_2; - const gchar *addr_client_2 = "233.252.0.2:5002"; - - mcast_transport_two_clients (TRUE, transport_client_1, - expected_transport_1, addr_client_1, transport_client_2, - expected_transport_2, addr_client_2); -} - -GST_END_TEST; -GST_START_TEST (test_client_multicast_invalid_ttl) -{ - GstRTSPClient *client; - GstRTSPMessage request = { 0, }; - gchar *str; - GstRTSPSessionPool *session_pool; - GstRTSPContext ctx = { NULL }; - - client = setup_multicast_client (3); - - 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 an invalid ttl=0 */ - 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=0;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); + mcast_transport_specific_two_clients (FALSE); } GST_END_TEST; @@ -1385,18 +1132,8 @@ rtspclient_suite (void) tcase_add_test (tc, test_client_multicast_transport_specific_two_clients_shared_media); tcase_add_test (tc, test_client_multicast_transport_specific_two_clients); - tcase_add_test (tc, - test_client_multicast_transport_specific_two_clients_shared_media_same_transport); - tcase_add_test (tc, test_client_multicast_two_clients_shared_media); - tcase_add_test (tc, - test_client_multicast_two_clients_first_specific_transport_shared_media); - tcase_add_test (tc, - test_client_multicast_two_clients_second_specific_transport_shared_media); tcase_add_test (tc, test_client_multicast_transport_specific_no_address_in_pool); - tcase_add_test (tc, test_client_multicast_max_ttl_first_client); - tcase_add_test (tc, test_client_multicast_max_ttl_second_client); - tcase_add_test (tc, test_client_multicast_invalid_ttl); return s; } diff --git a/tests/check/gst/stream.c b/tests/check/gst/stream.c index d71f1937f4..7b59c0abc9 100644 --- a/tests/check/gst/stream.c +++ b/tests/check/gst/stream.c @@ -486,95 +486,6 @@ GST_START_TEST (test_tcp_transport) GST_END_TEST; -static void -check_multicast_client_address (const gchar * destination, guint port, - const gchar * expected_addr_str, gboolean expected_res) -{ - GstPad *srcpad; - GstElement *pay; - GstRTSPStream *stream; - GstBin *bin; - GstElement *rtpbin; - GstRTSPTransport *transport; - GstRTSPRange ports = { 0 }; - gchar *addr_str = NULL; - - srcpad = gst_pad_new ("testsrcpad", GST_PAD_SRC); - fail_unless (srcpad != NULL); - gst_pad_set_active (srcpad, TRUE); - pay = gst_element_factory_make ("rtpgstpay", "testpayloader"); - fail_unless (pay != NULL); - stream = gst_rtsp_stream_new (0, pay, srcpad); - fail_unless (stream != NULL); - gst_object_unref (pay); - gst_object_unref (srcpad); - rtpbin = gst_element_factory_make ("rtpbin", "testrtpbin"); - fail_unless (rtpbin != NULL); - bin = GST_BIN (gst_bin_new ("testbin")); - fail_unless (bin != NULL); - fail_unless (gst_bin_add (bin, rtpbin)); - - fail_unless (gst_rtsp_stream_join_bin (stream, bin, rtpbin, GST_STATE_NULL)); - - fail_unless (gst_rtsp_transport_new (&transport) == GST_RTSP_OK); - transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP_MCAST; - transport->destination = g_strdup (destination); - transport->ttl = 1; - ports.min = port; - ports.max = port + 1; - transport->port = ports; - - /* allocate ports */ - fail_unless (gst_rtsp_stream_allocate_udp_sockets (stream, - G_SOCKET_FAMILY_IPV4, transport, TRUE) == expected_res); - - fail_unless (gst_rtsp_stream_add_multicast_client_address (stream, - destination, ports.min, ports.max, - G_SOCKET_FAMILY_IPV4) == expected_res); - - fail_unless (gst_rtsp_stream_complete_stream (stream, - transport) == expected_res); - - fail_unless (gst_rtsp_transport_free (transport) == GST_RTSP_OK); - addr_str = gst_rtsp_stream_get_multicast_client_addresses (stream); - - fail_unless (g_str_equal (addr_str, expected_addr_str)); - g_free (addr_str); - - fail_unless (gst_rtsp_stream_leave_bin (stream, bin, rtpbin)); - - gst_object_unref (bin); - gst_object_unref (stream); -} - -/* test if the provided transport destination is correct. - * CASE: valid multicast address */ -GST_START_TEST (test_multicast_client_address) -{ - const gchar *addr = "233.252.0.1"; - guint port = 50000; - const gchar *expected_addr_str = "233.252.0.1:50000"; - gboolean expected_res = TRUE; - - check_multicast_client_address (addr, port, expected_addr_str, expected_res); -} - -GST_END_TEST; - -/* test if the provided transport destination is correct. - * CASE: invalid multicast address */ -GST_START_TEST (test_multicast_client_address_invalid) -{ - const gchar *addr = "1.2.3.4"; - guint port = 50000; - const gchar *expected_addr_str = ""; - gboolean expected_res = FALSE; - - check_multicast_client_address (addr, port, expected_addr_str, expected_res); -} - -GST_END_TEST; - static Suite * rtspstream_suite (void) { @@ -590,8 +501,6 @@ rtspstream_suite (void) tcase_add_test (tc, test_allocate_udp_ports_multicast); tcase_add_test (tc, test_allocate_udp_ports_client_settings); tcase_add_test (tc, test_tcp_transport); - tcase_add_test (tc, test_multicast_client_address); - tcase_add_test (tc, test_multicast_client_address_invalid); return s; }