client: Check client provided addresses against the address pool
authorOlivier CrĂȘte <olivier.crete@collabora.com>
Wed, 13 Feb 2013 23:32:20 +0000 (18:32 -0500)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 11 Mar 2013 10:07:19 +0000 (11:07 +0100)
gst/rtsp-server/rtsp-client.c
gst/rtsp-server/rtsp-stream.c
gst/rtsp-server/rtsp-stream.h

index 9da27ad..4b4602c 100644 (file)
@@ -1072,7 +1072,17 @@ configure_client_transport (GstRTSPClient * client, GstRTSPClientState * state,
 
   /* we have a valid transport now, set the destination of the client. */
   if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
-    if (ct->destination == NULL || !priv->use_client_settings) {
+    if (ct->destination && priv->use_client_settings) {
+      GstRTSPAddress *addr;
+
+      addr = gst_rtsp_stream_reserve_address (state->stream, ct->destination,
+          ct->port.min, ct->port.max - ct->port.min + 1, ct->ttl);
+
+      if (addr == NULL)
+        goto no_address;
+
+      gst_rtsp_address_free (addr);
+    } else {
       GstRTSPAddress *addr;
 
       addr = gst_rtsp_stream_get_address (state->stream);
@@ -1084,6 +1094,8 @@ configure_client_transport (GstRTSPClient * client, GstRTSPClientState * state,
       ct->port.min = addr->port;
       ct->port.max = addr->port + addr->n_ports - 1;
       ct->ttl = addr->ttl;
+
+      gst_rtsp_address_free (addr);
     }
   } else {
     GstRTSPUrl *url;
index d1776e8..c0634bf 100644 (file)
@@ -342,6 +342,73 @@ no_address:
   }
 }
 
+/**
+ * gst_rtsp_stream_reserve_address:
+ * @stream: a #GstRTSPStream
+ *
+ * Get a specific multicast address of @stream.
+ *
+ * Returns: the #GstRTSPAddress of @stream or %NULL when no address could be
+ * allocated. gst_rtsp_address_free() after usage.
+ */
+GstRTSPAddress *
+gst_rtsp_stream_reserve_address (GstRTSPStream * stream,
+    const gchar * address, guint port, guint n_ports, guint ttl)
+{
+  GstRTSPStreamPrivate *priv;
+  GstRTSPAddress *result;
+
+  g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
+  g_return_val_if_fail (address != NULL, NULL);
+  g_return_val_if_fail (port > 0, NULL);
+  g_return_val_if_fail (n_ports > 0, NULL);
+  g_return_val_if_fail (ttl > 0, NULL);
+
+  priv = stream->priv;
+
+  g_mutex_lock (&priv->lock);
+  if (priv->addr == NULL) {
+    if (priv->pool == NULL)
+      goto no_pool;
+
+    priv->addr = gst_rtsp_address_pool_reserve_address (priv->pool, address,
+        port, n_ports, ttl);
+    if (priv->addr == NULL)
+      goto no_address;
+  } else {
+    if (strcmp (priv->addr->address, address) ||
+        priv->addr->port != port || priv->addr->n_ports != n_ports ||
+        priv->addr->ttl != ttl)
+      goto different_address;
+  }
+  result = gst_rtsp_address_copy (priv->addr);
+  g_mutex_unlock (&priv->lock);
+
+  return result;
+
+  /* ERRORS */
+no_pool:
+  {
+    GST_ERROR_OBJECT (stream, "no address pool specified");
+    g_mutex_unlock (&priv->lock);
+    return NULL;
+  }
+no_address:
+  {
+    GST_ERROR_OBJECT (stream, "failed to acquire address %s from pool",
+        address);
+    g_mutex_unlock (&priv->lock);
+    return NULL;
+  }
+different_address:
+  {
+    GST_ERROR_OBJECT (stream, "address %s is not the same that was already"
+        " reserved", address);
+    g_mutex_unlock (&priv->lock);
+    return NULL;
+  }
+}
+
 /* must be called with lock */
 static gboolean
 alloc_ports (GstRTSPStream * stream)
index 3367fe2..ba3bf40 100644 (file)
@@ -74,6 +74,12 @@ GstRTSPAddressPool *
 
 GstRTSPAddress *  gst_rtsp_stream_get_address      (GstRTSPStream *stream);
 
+GstRTSPAddress *  gst_rtsp_stream_reserve_address  (GstRTSPStream *stream,
+                                                    const gchar * address,
+                                                    guint port,
+                                                    guint n_ports,
+                                                    guint ttl);
+
 gboolean          gst_rtsp_stream_join_bin         (GstRTSPStream *stream,
                                                     GstBin *bin, GstElement *rtpbin,
                                                     GstState state);