[farsight2/master] multicast: Implement ToS field
Olivier Crête
olivier.crete at collabora.co.uk
Wed Jul 22 13:57:49 PDT 2009
---
transmitters/multicast/fs-multicast-transmitter.c | 78 ++++++++++++++++++---
1 files changed, 69 insertions(+), 9 deletions(-)
diff --git a/transmitters/multicast/fs-multicast-transmitter.c b/transmitters/multicast/fs-multicast-transmitter.c
index 00475cd..a643931 100644
--- a/transmitters/multicast/fs-multicast-transmitter.c
+++ b/transmitters/multicast/fs-multicast-transmitter.c
@@ -72,7 +72,8 @@ enum
PROP_0,
PROP_GST_SINK,
PROP_GST_SRC,
- PROP_COMPONENTS
+ PROP_COMPONENTS,
+ PROP_TYPE_OF_SERVICE
};
struct _FsMulticastTransmitterPrivate
@@ -90,6 +91,8 @@ struct _FsMulticastTransmitterPrivate
GMutex *mutex;
GList **udpsocks;
+ gint type_of_service;
+
gboolean disposed;
};
@@ -119,6 +122,11 @@ static FsStreamTransmitter *fs_multicast_transmitter_new_stream_transmitter (
static GType fs_multicast_transmitter_get_stream_transmitter_type (
FsTransmitter *transmitter);
+static void fs_multicast_transmitter_set_type_of_service (
+ FsMulticastTransmitter *self,
+ gint tos);
+
+
static GObjectClass *parent_class = NULL;
//static guint signals[LAST_SIGNAL] = { 0 };
@@ -182,6 +190,8 @@ fs_multicast_transmitter_class_init (FsMulticastTransmitterClass *klass)
g_object_class_override_property (gobject_class, PROP_GST_SINK, "gst-sink");
g_object_class_override_property (gobject_class, PROP_COMPONENTS,
"components");
+ g_object_class_override_property (gobject_class, PROP_TYPE_OF_SERVICE,
+ "tos");
transmitter_class->new_stream_transmitter =
fs_multicast_transmitter_new_stream_transmitter;
@@ -423,6 +433,11 @@ fs_multicast_transmitter_get_property (GObject *object,
case PROP_COMPONENTS:
g_value_set_uint (value, self->components);
break;
+ case PROP_TYPE_OF_SERVICE:
+ g_mutex_lock (self->priv->mutex);
+ g_value_set_uint (value, self->priv->type_of_service);
+ g_mutex_unlock (self->priv->mutex);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -441,6 +456,10 @@ fs_multicast_transmitter_set_property (GObject *object,
case PROP_COMPONENTS:
self->components = g_value_get_uint (value);
break;
+ case PROP_TYPE_OF_SERVICE:
+ fs_multicast_transmitter_set_type_of_service (self,
+ g_value_get_uint (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -538,6 +557,7 @@ _bind_port (
const gchar *multicast_ip,
guint16 port,
guchar ttl,
+ int type_of_service,
GError **error)
{
int sock = -1;
@@ -550,7 +570,6 @@ _bind_port (
#else
struct ip_mreq mreq;
#endif
- int tos, prio;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
@@ -639,13 +658,15 @@ _bind_port (
goto error;
}
- tos = IPTOS_LOWDELAY;
- if (setsockopt (sock, IPPROTO_IP, IP_TOS, &tos, sizeof (tos)) < 0)
- GST_WARNING ("could not set TOS: %s", g_strerror (errno));
+ if (setsockopt (sock, IPPROTO_IP, IP_TOS,
+ &type_of_service, sizeof (type_of_service)) < 0)
+ GST_WARNING ("could not set socket ToS: %s", g_strerror (errno));
- prio = 6;
- if (setsockopt (sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof (tos)) < 0)
- GST_WARNING ( "could not set socket priority: %s", g_strerror (errno));
+#ifdef IPV6_TCLASS
+ if (setsockopt (sock, IPPROTO_IPV6, IPV6_TCLASS,
+ &type_of_service, sizeof (type_of_service)) < 0)
+ GST_WARNING ("could not set TCLASS: %s", g_strerror (errno));
+#endif
address.sin_port = htons (port);
retval = bind (sock, (struct sockaddr *) &address, sizeof (address));
@@ -871,6 +892,7 @@ fs_multicast_transmitter_get_udpsock (FsMulticastTransmitter *trans,
UdpSock *udpsock;
UdpSock *tmpudpsock;
GError *local_error = NULL;
+ int tos;
/* First lets check if we already have one */
if (component_id > trans->components)
@@ -883,6 +905,7 @@ fs_multicast_transmitter_get_udpsock (FsMulticastTransmitter *trans,
g_mutex_lock (trans->priv->mutex);
udpsock = fs_multicast_transmitter_get_udpsock_locked (trans, component_id,
local_ip, multicast_ip, port, ttl, sending, &local_error);
+ tos = trans->priv->type_of_service;
g_mutex_unlock (trans->priv->mutex);
if (local_error)
@@ -911,7 +934,7 @@ fs_multicast_transmitter_get_udpsock (FsMulticastTransmitter *trans,
/* Now lets bind both ports */
- udpsock->fd = _bind_port (local_ip, multicast_ip, port, ttl, error);
+ udpsock->fd = _bind_port (local_ip, multicast_ip, port, ttl, tos, error);
if (udpsock->fd < 0)
goto error;
@@ -1143,3 +1166,40 @@ fs_multicast_transmitter_udpsock_ref (FsMulticastTransmitter *trans,
g_byte_array_append (udpsock->ttls, &ttl, 1);
g_mutex_unlock (trans->priv->mutex);
}
+
+
+static void
+fs_multicast_transmitter_set_type_of_service (FsMulticastTransmitter *self,
+ gint tos)
+{
+ gint i;
+
+ g_mutex_lock (self->priv->mutex);
+ if (self->priv->type_of_service == tos)
+ goto out;
+
+ self->priv->type_of_service = tos;
+
+ for (i = 0; i < self->components; i++)
+ {
+ GList *item;
+
+ for (item = self->priv->udpsocks[i]; item; item = item->next)
+ {
+ UdpSock *udpsock = item->data;
+
+ if (setsockopt (udpsock->fd, IPPROTO_IP, IP_TOS,
+ &tos, sizeof (tos)) < 0)
+ GST_WARNING ( "could not set socket tos: %s", g_strerror (errno));
+
+#ifdef IPV6_TCLASS
+ if (setsockopt (udpsock->fd, IPPROTO_IPV6, IPV6_TCLASS,
+ &tos, sizeof (tos)) < 0)
+ GST_WARNING ("could not set TCLASS: %s", g_strerror (errno));
+#endif
+ }
+ }
+
+ out:
+ g_mutex_unlock (self->priv->mutex);
+}
--
1.5.6.5
More information about the farsight-commits
mailing list