static gboolean
alloc_ports_one_family (GstRTSPStream * stream, GSocketFamily family,
GSocket * socket_out[2], GstRTSPAddress ** server_addr_out,
- gboolean multicast, GstRTSPTransport * ct, gboolean use_transport_settings)
+ gboolean multicast, GstRTSPTransport * ct)
{
GstRTSPStreamPrivate *priv = stream->priv;
GSocket *rtp_socket = NULL;
- GSocket *rtcp_socket = NULL;
+ GSocket *rtcp_socket;
gint tmp_rtp, tmp_rtcp;
guint count;
GList *rejected_addresses = NULL;
GSocketAddress *rtp_sockaddr = NULL;
GSocketAddress *rtcp_sockaddr = NULL;
GstRTSPAddressPool *pool;
- gboolean transport_settings_defined = FALSE;
pool = priv->pool;
count = 0;
/* Start with random port */
tmp_rtp = 0;
- if (use_transport_settings) {
- if (!multicast)
- goto no_mcast;
-
- if (ct == NULL)
- goto no_transport;
-
- /* multicast and transport specific case */
- if (ct->destination != NULL) {
- tmp_rtp = ct->port.min;
- tmp_rtcp = ct->port.max;
- inetaddr = g_inet_address_new_from_string (ct->destination);
- if (inetaddr == NULL)
- goto destination_error;
- if (!g_inet_address_get_is_multicast (inetaddr))
- goto destination_no_mcast;
- g_object_unref (inetaddr);
- inetaddr = g_inet_address_new_any (family);
-
- GST_DEBUG_OBJECT (stream, "use transport settings");
- transport_settings_defined = TRUE;
- }
- }
-
rtcp_socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM,
G_SOCKET_PROTOCOL_UDP, NULL);
if (!rtcp_socket)
g_socket_set_multicast_loopback (rtp_socket, FALSE);
}
- if (!transport_settings_defined) {
- if ((pool && gst_rtsp_address_pool_has_unicast_addresses (pool))
- || multicast) {
- GstRTSPAddressFlags flags;
+ if ((pool && gst_rtsp_address_pool_has_unicast_addresses (pool)) || multicast) {
+ GstRTSPAddressFlags flags;
- if (addr)
- rejected_addresses = g_list_prepend (rejected_addresses, addr);
-
- if (!pool)
- goto no_pool;
+ if (addr)
+ rejected_addresses = g_list_prepend (rejected_addresses, addr);
- flags = GST_RTSP_ADDRESS_FLAG_EVEN_PORT;
- if (multicast)
- flags |= GST_RTSP_ADDRESS_FLAG_MULTICAST;
- else
- flags |= GST_RTSP_ADDRESS_FLAG_UNICAST;
+ if (!pool)
+ goto no_pool;
- if (family == G_SOCKET_FAMILY_IPV6)
- flags |= GST_RTSP_ADDRESS_FLAG_IPV6;
- else
- flags |= GST_RTSP_ADDRESS_FLAG_IPV4;
+ flags = GST_RTSP_ADDRESS_FLAG_EVEN_PORT;
+ if (multicast)
+ flags |= GST_RTSP_ADDRESS_FLAG_MULTICAST;
+ else
+ flags |= GST_RTSP_ADDRESS_FLAG_UNICAST;
- addr = gst_rtsp_address_pool_acquire_address (pool, flags, 2);
+ if (family == G_SOCKET_FAMILY_IPV6)
+ flags |= GST_RTSP_ADDRESS_FLAG_IPV6;
+ else
+ flags |= GST_RTSP_ADDRESS_FLAG_IPV4;
- if (addr == NULL)
- goto no_address;
+ addr = gst_rtsp_address_pool_acquire_address (pool, flags, 2);
- tmp_rtp = addr->port;
+ if (addr == NULL)
+ goto no_address;
- g_clear_object (&inetaddr);
- /* FIXME: Does it really work with the IP_MULTICAST_ALL socket option and
- * socket control message set in udpsrc? */
- if (multicast)
- inetaddr = g_inet_address_new_any (family);
- else
- inetaddr = g_inet_address_new_from_string (addr->address);
- } else {
- if (tmp_rtp != 0) {
- tmp_rtp += 2;
- if (++count > 20)
- goto no_ports;
- }
+ tmp_rtp = addr->port;
- if (inetaddr == NULL)
- inetaddr = g_inet_address_new_any (family);
+ g_clear_object (&inetaddr);
+ /* FIXME: Does it really work with the IP_MULTICAST_ALL socket option and
+ * socket control message set in udpsrc? */
+ if (multicast)
+ inetaddr = g_inet_address_new_any (family);
+ else
+ inetaddr = g_inet_address_new_from_string (addr->address);
+ } else {
+ if (tmp_rtp != 0) {
+ tmp_rtp += 2;
+ if (++count > 20)
+ goto no_ports;
}
+
+ if (inetaddr == NULL)
+ inetaddr = g_inet_address_new_any (family);
}
rtp_sockaddr = g_inet_socket_address_new (inetaddr, tmp_rtp);
if (!g_socket_bind (rtp_socket, rtp_sockaddr, FALSE, NULL)) {
GST_DEBUG_OBJECT (stream, "rtp bind() failed, will try again");
g_object_unref (rtp_sockaddr);
- if (transport_settings_defined)
- goto transport_settings_error;
goto again;
}
g_object_unref (rtp_sockaddr);
goto socket_error;
}
- if (!transport_settings_defined) {
- tmp_rtp =
- g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_sockaddr));
-
- /* check if port is even. RFC 3550 encorages the use of an even/odd port
- * pair, however it's not a strict requirement so this check is not done
- * for the client selected ports. */
- if ((tmp_rtp & 1) != 0) {
- /* port not even, close and allocate another */
- tmp_rtp++;
- g_object_unref (rtp_sockaddr);
- g_clear_object (&rtp_socket);
- goto again;
- }
- }
+ tmp_rtp =
+ g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_sockaddr));
g_object_unref (rtp_sockaddr);
+ /* check if port is even */
+ if ((tmp_rtp & 1) != 0) {
+ /* port not even, close and allocate another */
+ tmp_rtp++;
+ g_clear_object (&rtp_socket);
+ goto again;
+ }
+
/* set port */
tmp_rtcp = tmp_rtp + 1;
GST_DEBUG_OBJECT (stream, "rctp bind() failed, will try again");
g_object_unref (rtcp_sockaddr);
g_clear_object (&rtp_socket);
- if (transport_settings_defined)
- goto transport_settings_error;
goto again;
}
g_object_unref (rtcp_sockaddr);
if (!addr) {
addr = g_slice_new0 (GstRTSPAddress);
+ addr->address = g_inet_address_to_string (inetaddr);
addr->port = tmp_rtp;
addr->n_ports = 2;
- if (transport_settings_defined)
- addr->address = g_strdup (ct->destination);
- else
- addr->address = g_inet_address_to_string (inetaddr);
- addr->ttl = ct->ttl;
}
g_clear_object (&inetaddr);
return TRUE;
/* ERRORS */
-no_mcast:
- {
- GST_ERROR_OBJECT (stream, "failed to allocate UDP ports: wrong transport");
- goto cleanup;
- }
-no_transport:
- {
- GST_ERROR_OBJECT (stream, "failed to allocate UDP ports: no transport");
- goto cleanup;
- }
-destination_error:
- {
- GST_ERROR_OBJECT (stream,
- "failed to allocate UDP ports: destination error");
- goto cleanup;
- }
-destination_no_mcast:
- {
- GST_ERROR_OBJECT (stream,
- "failed to allocate UDP ports: destination not multicast address");
- goto cleanup;
- }
no_udp_protocol:
{
GST_WARNING_OBJECT (stream, "failed to allocate UDP ports: protocol error");
GST_WARNING_OBJECT (stream, "failed to allocate UDP ports: no ports");
goto cleanup;
}
-transport_settings_error:
- {
- GST_ERROR_OBJECT (stream,
- "failed to allocate UDP ports with requested transport settings");
- goto cleanup;
- }
socket_error:
{
GST_WARNING_OBJECT (stream, "failed to allocate UDP ports: socket error");
/* UDP unicast */
GST_DEBUG_OBJECT (stream, "GST_RTSP_LOWER_TRANS_UDP, ipv4");
ret = alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV4,
- priv->socket_v4, &priv->server_addr_v4, FALSE, ct, FALSE);
+ priv->socket_v4, &priv->server_addr_v4, FALSE, ct);
} else {
/* multicast */
GST_DEBUG_OBJECT (stream, "GST_RTSP_LOWER_TRANS_MCAST_UDP, ipv4");
ret = alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV4,
- priv->mcast_socket_v4, &priv->mcast_addr_v4, TRUE, ct,
- use_transport_settings);
+ priv->mcast_socket_v4, &priv->mcast_addr_v4, TRUE, ct);
}
} else {
/* IPv6 */
/* unicast */
GST_DEBUG_OBJECT (stream, "GST_RTSP_LOWER_TRANS_UDP, ipv6");
ret = alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV6,
- priv->socket_v6, &priv->server_addr_v6, FALSE, ct, FALSE);
+ priv->socket_v6, &priv->server_addr_v6, FALSE, ct);
} else {
/* multicast */
GST_DEBUG_OBJECT (stream, "GST_RTSP_LOWER_TRANS_MCAST_UDP, ipv6");
ret = alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV6,
- priv->mcast_socket_v6, &priv->mcast_addr_v6, TRUE, ct,
- use_transport_settings);
+ priv->mcast_socket_v6, &priv->mcast_addr_v6, TRUE, ct);
}
}
g_mutex_unlock (&priv->lock);
GST_END_TEST;
-static void
-multicast_transport_specific (void)
+GST_START_TEST (test_client_multicast_transport_specific)
{
GstRTSPClient *client;
GstRTSPMessage request = { 0, };
fail_unless (gst_rtsp_client_handle_message (client,
&request) == GST_RTSP_OK);
gst_rtsp_message_unset (&request);
+ expected_transport = NULL;
gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
NULL, NULL);
fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
g_object_unref (session_pool);
- /* 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);
-
send_teardown (client);
+
teardown_client (client);
g_object_unref (ctx.auth);
gst_rtsp_token_unref (ctx.token);
gst_rtsp_context_pop_current (&ctx);
}
-/* CASE: multicast address requested by the client exists in the address pool */
-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\"";
- multicast_transport_specific ();
- expected_transport = NULL;
-}
-
-GST_END_TEST;
-
-/* CASE: multicast address requested by the client does not exist in the address pool */
-GST_START_TEST (test_client_multicast_transport_specific_no_address_in_pool)
-{
- expected_transport = "RTP/AVP;multicast;destination=234.252.0.3;"
- "ttl=1;port=6000-6001;mode=\"PLAY\"";
- multicast_transport_specific ();
- expected_transport = NULL;
-}
-
GST_END_TEST;
static gboolean
g_object_unref (thread_pool);
}
-/* test if two multicast clients can choose different transport settings
- * CASE: media is shared */
+/* 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;
-/* test if two multicast clients can choose different transport settings
- * CASE: media is not shared */
-GST_START_TEST (test_client_multicast_transport_specific_two_clients)
-{
- mcast_transport_specific_two_clients (FALSE);
-}
-
-GST_END_TEST;
-
static Suite *
rtspclient_suite (void)
{
tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
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_no_address_in_pool);
return s;
}