[farsight2/master] rawudp: Implement setting of the ToS
Olivier Crête
olivier.crete at collabora.co.uk
Wed Jul 22 13:51:23 PDT 2009
---
transmitters/rawudp/fs-rawudp-transmitter.c | 71 ++++++++++++++++++++++++---
1 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/transmitters/rawudp/fs-rawudp-transmitter.c b/transmitters/rawudp/fs-rawudp-transmitter.c
index 6de1fb0..7e915f4 100644
--- a/transmitters/rawudp/fs-rawudp-transmitter.c
+++ b/transmitters/rawudp/fs-rawudp-transmitter.c
@@ -72,7 +72,8 @@ enum
PROP_0,
PROP_GST_SINK,
PROP_GST_SRC,
- PROP_COMPONENTS
+ PROP_COMPONENTS,
+ PROP_TYPE_OF_SERVICE
};
struct _FsRawUdpTransmitterPrivate
@@ -91,6 +92,8 @@ struct _FsRawUdpTransmitterPrivate
/* Protected by the mutex */
GList **udpports;
+ gint type_of_service;
+
gboolean disposed;
};
@@ -122,6 +125,10 @@ static FsStreamTransmitter *fs_rawudp_transmitter_new_stream_transmitter (
static GType fs_rawudp_transmitter_get_stream_transmitter_type (
FsTransmitter *transmitter);
+static void fs_rawudp_transmitter_set_type_of_service (
+ FsRawUdpTransmitter *self,
+ gint tos);
+
static GObjectClass *parent_class = NULL;
//static guint signals[LAST_SIGNAL] = { 0 };
@@ -187,6 +194,8 @@ fs_rawudp_transmitter_class_init (FsRawUdpTransmitterClass *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_rawudp_transmitter_new_stream_transmitter;
@@ -442,6 +451,11 @@ fs_rawudp_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;
@@ -461,6 +475,10 @@ fs_rawudp_transmitter_set_property (GObject *object,
case PROP_COMPONENTS:
self->components = g_value_get_uint (value);
break;
+ case PROP_TYPE_OF_SERVICE:
+ fs_rawudp_transmitter_set_type_of_service (self,
+ g_value_get_uint (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -543,12 +561,12 @@ _bind_port (
const gchar *ip,
guint port,
guint *used_port,
+ int tos,
GError **error)
{
int sock;
struct sockaddr_in address;
int retval;
- int tos, prio;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
@@ -598,13 +616,13 @@ _bind_port (
*used_port = port;
- tos = IPTOS_LOWDELAY;
if (setsockopt (sock, IPPROTO_IP, IP_TOS, &tos, sizeof (tos)) < 0)
- GST_WARNING ( "could not set TOS: %s", g_strerror (errno));
+ 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, &tos, sizeof (tos)) < 0)
+ GST_WARNING ("could not set TCLASS: %s", g_strerror (errno));
+#endif
return sock;
}
@@ -808,6 +826,7 @@ fs_rawudp_transmitter_get_udpport (FsRawUdpTransmitter *trans,
{
UdpPort *udpport;
UdpPort *tmpudpport;
+ int tos;
/* First lets check if we already have one */
if (component_id > trans->components)
@@ -820,6 +839,7 @@ fs_rawudp_transmitter_get_udpport (FsRawUdpTransmitter *trans,
g_mutex_lock (trans->priv->mutex);
udpport = fs_rawudp_transmitter_get_udpport_locked (trans, component_id,
requested_ip, requested_port);
+ tos = trans->priv->type_of_service;
g_mutex_unlock (trans->priv->mutex);
if (udpport)
@@ -841,7 +861,7 @@ fs_rawudp_transmitter_get_udpport (FsRawUdpTransmitter *trans,
/* Now lets bind both ports */
- udpport->fd = _bind_port (requested_ip, requested_port, &udpport->port,
+ udpport->fd = _bind_port (requested_ip, requested_port, &udpport->port, tos,
error);
if (udpport->fd < 0)
goto error;
@@ -1241,3 +1261,38 @@ fs_rawudp_transmitter_udpport_remove_recvonly_dest (UdpPort *udpport,
if (udpport->recvonly_udpsink)
g_signal_emit_by_name (udpport->recvonly_udpsink, "remove", ip, port);
}
+
+static void
+fs_rawudp_transmitter_set_type_of_service (FsRawUdpTransmitter *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->udpports[i]; item; item = item->next)
+ {
+ UdpPort *udpport = item->data;
+
+ if (setsockopt (udpport->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 (udpport->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