address-pool: Add unicast addresses

This commit is contained in:
Olivier Crête 2013-02-19 16:34:16 -05:00 committed by Wim Taymans
parent 4c61c6d308
commit d06e68abd1
5 changed files with 110 additions and 12 deletions

View file

@ -411,10 +411,14 @@ GstRTSPStreamTransportPrivate
GstRTSPAddressPool
gst_rtsp_address_pool_new
gst_rtsp_address_pool_add_range
GST_RTSP_ADDRESS_POOL_ANY_IPV4
GST_RTSP_ADDRESS_POOL_ANY_IPV6
gst_rtsp_address_pool_add_range_unicast
gst_rtsp_address_pool_clear
gst_rtsp_address_pool_dump
gst_rtsp_address_pool_acquire_address
gst_rtsp_address_pool_reserve_address
gst_rtsp_address_pool_has_unicast_addresses
<SUBSECTION Standard>
GstRTSPAddressPoolClass
GstRTSPAddressPoolPrivate

View file

@ -70,6 +70,8 @@ struct _GstRTSPAddressPoolPrivate
GMutex lock; /* protects everything in this struct */
GList *addresses;
GList *allocated;
gboolean has_unicast_addresses;
};
#define ADDR_IS_IPV4(a) ((a)->size == 4)
@ -258,6 +260,9 @@ gst_rtsp_address_pool_add_range (GstRTSPAddressPool * pool,
g_mutex_lock (&priv->lock);
priv->addresses = g_list_prepend (priv->addresses, range);
if (ttl == 0)
priv->has_unicast_addresses = TRUE;
g_mutex_unlock (&priv->lock);
return TRUE;
@ -272,6 +277,33 @@ invalid:
}
}
/**
* gst_rtsp_address_pool_add_range_unicast:
* @pool: a #GstRTSPAddressPool
* @min_address: a minimum address to add
* @max_address: a maximum address to add
* @min_port: the minimum port
* @max_port: the maximum port
*
* Adds the unicast addresses from @min_addess to @max_address (inclusive)
* to @pool. The valid port range for the addresses will be from @min_port to
* @max_port inclusive.
*
* @min_address and @max_address can be set to
* #GST_RTSP_ADDRESS_POOL_ANY_IPV4 or #GST_RTSP_ADDRESS_POOL_ANY_IPV6 to bind
* to all available IPv4 or IPv6 addresses.
*
* Returns: %TRUE if the addresses could be added.
*/
gboolean
gst_rtsp_address_pool_add_range_unicast (GstRTSPAddressPool * pool,
const gchar * min_address, const gchar * max_address,
guint16 min_port, guint16 max_port)
{
return gst_rtsp_address_pool_add_range (pool, min_address, max_address,
min_port, max_port, 0);
}
/* increments the address by count */
static void
@ -407,6 +439,10 @@ gst_rtsp_address_pool_acquire_address (GstRTSPAddressPool * pool,
continue;
if (flags & GST_RTSP_ADDRESS_FLAG_IPV6 && !ADDR_IS_IPV6 (&range->min))
continue;
if (flags & GST_RTSP_ADDRESS_FLAG_MULTICAST && range->ttl == 0)
continue;
if (flags & GST_RTSP_ADDRESS_FLAG_UNICAST && range->ttl != 0)
continue;
/* check for enough ports */
ports = range->max.port - range->min.port + 1;
@ -624,3 +660,29 @@ gst_rtsp_address_pool_reserve_address (GstRTSPAddressPool * pool,
return addr;
}
/**
* gst_rtsp_address_pool_has_unicast_addresses:
* @pool: a #GstRTSPAddressPool
*
* Used to know if the pool includes any unicast addresses.
*
* Returns: %TRUE if the pool includes any unicast addresses, %FALSE otherwise
*/
gboolean
gst_rtsp_address_pool_has_unicast_addresses (GstRTSPAddressPool * pool)
{
GstRTSPAddressPoolPrivate *priv;
gboolean has_unicast_addresses;
g_return_val_if_fail (GST_IS_RTSP_ADDRESS_POOL (pool), FALSE);
priv = pool->priv;
g_mutex_lock (&priv->lock);
has_unicast_addresses = priv->has_unicast_addresses;
g_mutex_unlock (&priv->lock);
return has_unicast_addresses;
}

View file

@ -60,9 +60,28 @@ typedef enum {
GST_RTSP_ADDRESS_FLAG_NONE = 0,
GST_RTSP_ADDRESS_FLAG_IPV4 = (1 << 0),
GST_RTSP_ADDRESS_FLAG_IPV6 = (1 << 1),
GST_RTSP_ADDRESS_FLAG_EVEN_PORT = (1 << 2)
GST_RTSP_ADDRESS_FLAG_EVEN_PORT = (1 << 2),
GST_RTSP_ADDRESS_FLAG_MULTICAST = (1 << 3),
GST_RTSP_ADDRESS_FLAG_UNICAST = (1 << 4),
} GstRTSPAddressFlags;
/**
* GST_RTSP_ADDRESS_POOL_ANY_IPV4:
*
* Used with gst_rtsp_address_pool_add_range_unicast() to bind to all
* IPv4 addresses
*/
/**
* GST_RTSP_ADDRESS_POOL_ANY_IPV6:
*
* Used with gst_rtsp_address_pool_add_range_unicast() to bind to all
* IPv6 addresses
*/
#define GST_RTSP_ADDRESS_POOL_ANY_IPV4 "0.0.0.0"
#define GST_RTSP_ADDRESS_POOL_ANY_IPV6 "::"
/**
* GstRTSPAddressPool:
* @parent: the parent GObject
@ -94,6 +113,12 @@ gboolean gst_rtsp_address_pool_add_range (GstRTSPAddressPool
guint16 max_port,
guint8 ttl);
gboolean gst_rtsp_address_pool_add_range_unicast (GstRTSPAddressPool * pool,
const gchar *min_address,
const gchar *max_address,
guint16 min_port,
guint16 max_port);
GstRTSPAddress * gst_rtsp_address_pool_acquire_address (GstRTSPAddressPool * pool,
GstRTSPAddressFlags flags,
gint n_ports);
@ -104,6 +129,7 @@ GstRTSPAddress * gst_rtsp_address_pool_reserve_address (GstRTSPAddressPool
guint n_ports,
guint ttl);
gboolean gst_rtsp_address_pool_has_unicast_addresses (GstRTSPAddressPool * pool);
G_END_DECLS

View file

@ -318,7 +318,7 @@ gst_rtsp_stream_get_address (GstRTSPStream * stream)
goto no_pool;
priv->addr = gst_rtsp_address_pool_acquire_address (priv->pool,
GST_RTSP_ADDRESS_FLAG_EVEN_PORT, 2);
GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_MULTICAST, 2);
if (priv->addr == NULL)
goto no_address;
}

View file

@ -47,10 +47,12 @@ GST_START_TEST (test_pool)
"233.255.0.0", "233.255.0.0", 5020, 5020, 1));
/* should fail, we can't allocate a block of 256 ports */
addr = gst_rtsp_address_pool_acquire_address (pool, 0, 256);
addr = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_MULTICAST, 256);
fail_unless (addr == NULL);
addr = gst_rtsp_address_pool_acquire_address (pool, 0, 2);
addr = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_MULTICAST, 2);
fail_unless (addr != NULL);
addr2 = gst_rtsp_address_copy (addr);
@ -58,7 +60,8 @@ GST_START_TEST (test_pool)
gst_rtsp_address_free (addr2);
gst_rtsp_address_free (addr);
addr = gst_rtsp_address_pool_acquire_address (pool, 0, 4);
addr = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_MULTICAST, 4);
fail_unless (addr != NULL);
/* Will fail because pool is NULL */
@ -78,19 +81,21 @@ GST_START_TEST (test_pool)
"2001:DB8::1", "2001:DB8::1", 5001, 5003, 1));
addr = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_IPV6 | GST_RTSP_ADDRESS_FLAG_EVEN_PORT, 2);
GST_RTSP_ADDRESS_FLAG_IPV6 | GST_RTSP_ADDRESS_FLAG_EVEN_PORT |
GST_RTSP_ADDRESS_FLAG_MULTICAST, 2);
fail_unless (addr != NULL);
fail_unless (addr->port == 5002);
fail_unless (!g_ascii_strcasecmp (addr->address, "2001:DB8::1"));
/* Will fail becuse there is only one IPv6 address left */
addr2 = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_IPV6, 2);
GST_RTSP_ADDRESS_FLAG_IPV6 | GST_RTSP_ADDRESS_FLAG_MULTICAST, 2);
fail_unless (addr2 == NULL);
/* Will fail because the only IPv6 address left has an odd port */
addr2 = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_IPV6 | GST_RTSP_ADDRESS_FLAG_EVEN_PORT, 1);
GST_RTSP_ADDRESS_FLAG_IPV6 | GST_RTSP_ADDRESS_FLAG_EVEN_PORT |
GST_RTSP_ADDRESS_FLAG_MULTICAST, 1);
fail_unless (addr2 == NULL);
gst_rtsp_address_free (addr);
@ -101,13 +106,13 @@ GST_START_TEST (test_pool)
"233.252.0.0", "233.252.0.255", 5000, 5002, 1));
addr = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_EVEN_PORT, 2);
GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_MULTICAST, 2);
fail_unless (addr != NULL);
fail_unless (addr->port == 5000);
fail_unless (!strcmp (addr->address, "233.252.0.0"));
addr2 = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_EVEN_PORT, 2);
GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_MULTICAST, 2);
fail_unless (addr2 != NULL);
fail_unless (addr2->port == 5000);
fail_unless (!strcmp (addr2->address, "233.252.0.1"));
@ -167,13 +172,14 @@ GST_START_TEST (test_pool)
fail_unless (!strcmp (addr2->address, "233.252.1.3"));
addr3 = gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_EVEN_PORT, 2);
GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_MULTICAST, 2);
fail_unless (addr3 != NULL);
fail_unless (addr3->port == 5000);
fail_unless (!strcmp (addr3->address, "233.252.1.2"));
fail_unless (gst_rtsp_address_pool_acquire_address (pool,
GST_RTSP_ADDRESS_FLAG_EVEN_PORT, 2) == NULL);
GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_MULTICAST, 2)
== NULL);
gst_rtsp_address_free (addr);
gst_rtsp_address_free (addr2);