if ((ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) &&
gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS) &&
- (ct->destination != NULL))
+ (ct->destination != NULL)) {
+
+ if (!gst_rtsp_stream_verify_mcast_ttl (ctx->stream, ct->ttl))
+ goto error_ttl;
+
use_client_settings = TRUE;
+ }
/* We need to allocate the sockets for both families before starting
* multiudpsink, otherwise multiudpsink won't accept new clients with
*/
/* FIXME: could be more adequately solved by making it possible
* to set a socket on multiudpsink after it has already been started */
- if (!gst_rtsp_stream_allocate_udp_sockets (ctx->stream, G_SOCKET_FAMILY_IPV4, ct,
- use_client_settings) && family == G_SOCKET_FAMILY_IPV4)
+ if (!gst_rtsp_stream_allocate_udp_sockets (ctx->stream,
+ G_SOCKET_FAMILY_IPV4, ct, use_client_settings)
+ && family == G_SOCKET_FAMILY_IPV4)
goto error_allocating_ports;
- if (!gst_rtsp_stream_allocate_udp_sockets (ctx->stream, G_SOCKET_FAMILY_IPV6, ct,
- use_client_settings) && family == G_SOCKET_FAMILY_IPV6)
+ if (!gst_rtsp_stream_allocate_udp_sockets (ctx->stream,
+ G_SOCKET_FAMILY_IPV6, ct, use_client_settings)
+ && family == G_SOCKET_FAMILY_IPV6)
goto error_allocating_ports;
if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
- GstRTSPAddress *addr = NULL;
-
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);
+ /* 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;
+
+ 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;
+ }
- if (addr == NULL)
- goto no_address;
} else {
+ GstRTSPAddress *addr = NULL;
+
g_free (ct->destination);
addr = gst_rtsp_stream_get_multicast_address (ctx->stream, family);
if (addr == NULL)
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);
+ 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;
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;
/* 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");
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;
+ }
+error_allocating_channels:
+ {
+ GST_ERROR_OBJECT (client, "Failed to allocate interleaved channels");
+ return FALSE;
+ }
}
static GstRTSPTransport *