diff options
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | socket/tcp-bsd.c | 25 | ||||
-rw-r--r-- | socket/tcp-turn.c | 25 |
3 files changed, 34 insertions, 17 deletions
@@ -2,7 +2,6 @@ check for the cookie and act accordingly for incoming messages. channel bind have a 10 minutes expiration :@ nice_socket_recv returns -1 means we must close the nice_socket and stop all connchecks/candidates and reelect if was eleected... Add HTTP Digest support -tcp turn must drop packets if the queue fills too fast make sure the timers don't race condition with frees, and have some kind of refcounting (like in turn send requests) for timers Add support for TURN-13 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; } |