summaryrefslogtreecommitdiff
path: root/socket
diff options
context:
space:
mode:
authorYouness Alaoui <youness.alaoui@collabora.co.uk>2009-06-11 14:07:54 -0400
committerYouness Alaoui <youness.alaoui@collabora.co.uk>2009-06-11 14:07:54 -0400
commit9497d78fb13d1d2648dea0211b06c8fd79435e03 (patch)
tree1eda7b0cfcc6a9e9796967c488bd08337e11295d /socket
parentfa38c1ad3533b3e6f1096bdf7e833ba2e9160531 (diff)
downloadlibnice-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.c25
-rw-r--r--socket/tcp-turn.c25
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;
}