diff options
author | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2009-06-11 14:07:54 -0400 |
---|---|---|
committer | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2009-06-11 14:07:54 -0400 |
commit | 9497d78fb13d1d2648dea0211b06c8fd79435e03 (patch) | |
tree | 1eda7b0cfcc6a9e9796967c488bd08337e11295d /socket | |
parent | fa38c1ad3533b3e6f1096bdf7e833ba2e9160531 (diff) | |
download | libnice-9497d78fb13d1d2648dea0211b06c8fd79435e03.tar.gz |
Add support for droping packets when using TCP and the bandwidth is too slow for the data output. The queue now has a limit of 20 packets and the tcp-turn now has to call send in a single shot to avoid dropping parts of the packet (dropping the length but send the data, or dropping only the padding at the end, etc..)
Diffstat (limited to 'socket')
-rw-r--r-- | socket/tcp-bsd.c | 25 | ||||
-rw-r--r-- | socket/tcp-turn.c | 25 |
2 files changed, 34 insertions, 16 deletions
diff --git a/socket/tcp-bsd.c b/socket/tcp-bsd.c index 2c41d75..2b829ba 100644 --- a/socket/tcp-bsd.c +++ b/socket/tcp-bsd.c @@ -70,8 +70,10 @@ typedef struct { struct to_be_sent { guint length; gchar *buf; + gboolean can_drop; }; +#define MAX_QUEUE_LENGTH 20 static void socket_close (NiceSocket *sock); static gint socket_recv (NiceSocket *sock, NiceAddress *from, @@ -222,7 +224,9 @@ socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf) return ret; } - +/* Data sent to this function must be a single entity because buffers can be + * dropped if the bandwidth isn't fast enough. So do not send a message in + * multiple chunks. */ static gboolean socket_send (NiceSocket *sock, const NiceAddress *to, guint len, const gchar *buf) @@ -247,10 +251,24 @@ socket_send (NiceSocket *sock, const NiceAddress *to, return FALSE; } } else if ((guint)ret < len) { - add_to_be_sent (sock, buf + ret, len - ret, FALSE); + add_to_be_sent (sock, buf + ret, len - ret, TRUE); return TRUE; } } else { + if (g_queue_get_length(&priv->send_queue) >= MAX_QUEUE_LENGTH) { + int peek_idx = 0; + struct to_be_sent *tbs = NULL; + while ((tbs = g_queue_peek_nth (&priv->send_queue, peek_idx)) != NULL) { + if (tbs->can_drop) { + tbs = g_queue_pop_nth (&priv->send_queue, peek_idx); + g_free (tbs->buf); + g_slice_free (struct to_be_sent, tbs); + break; + } else { + peek_idx++; + } + } + } add_to_be_sent (sock, buf, len, FALSE); } @@ -283,7 +301,7 @@ socket_send_more ( g_static_rec_mutex_lock (&priv->agent->mutex); - while ((tbs = g_queue_pop_head (&priv->send_queue))) { + while ((tbs = g_queue_pop_head (&priv->send_queue)) != NULL) { int ret; ret = send (sock->fileno, tbs->buf, tbs->length, 0); @@ -338,6 +356,7 @@ add_to_be_sent (NiceSocket *sock, const gchar *buf, guint len, gboolean head) tbs = g_slice_new0 (struct to_be_sent); tbs->buf = g_memdup (buf, len); tbs->length = len; + tbs->can_drop = !head; if (head) g_queue_push_head (&priv->send_queue, tbs); else diff --git a/socket/tcp-turn.c b/socket/tcp-turn.c index b0306da..0d0dc53 100644 --- a/socket/tcp-turn.c +++ b/socket/tcp-turn.c @@ -65,6 +65,7 @@ typedef struct { NiceSocket *base_socket; } TurnTcpPriv; +#define MAX_UDP_MESSAGE_SIZE 65535 static void socket_close (NiceSocket *sock); static gint socket_recv (NiceSocket *sock, NiceAddress *from, @@ -183,32 +184,30 @@ static gboolean socket_send (NiceSocket *sock, const NiceAddress *to, guint len, const gchar *buf) { - gboolean ret = TRUE; TurnTcpPriv *priv = sock->priv; gchar padbuf[3] = {0, 0, 0}; int padlen = (len%4) ? 4 - (len%4) : 0; + gchar buffer[MAX_UDP_MESSAGE_SIZE + sizeof(guint16) + sizeof(padbuf)]; + guint buffer_len = 0; if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) padlen = 0; if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { guint16 tmpbuf = htons (len); - ret = nice_socket_send (priv->base_socket, to, - sizeof(guint16), (gchar *)&tmpbuf); - - if (!ret) - return ret; + memcpy (buffer + buffer_len, (gchar *)&tmpbuf, sizeof(guint16)); + buffer_len += sizeof(guint16); } - ret = nice_socket_send (priv->base_socket, to, len, buf); - - if (!ret) - return ret; + memcpy (buffer + buffer_len, buf, len); + buffer_len += len; - if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) - ret = nice_socket_send (priv->base_socket, to, padlen, padbuf); + if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) { + memcpy (buffer + buffer_len, padbuf, padlen); + buffer_len += padlen; + } + return nice_socket_send (priv->base_socket, to, buffer_len, buffer); - return ret; } |