summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--socket/tcp-bsd.c25
-rw-r--r--socket/tcp-turn.c25
3 files changed, 34 insertions, 17 deletions
diff --git a/TODO b/TODO
index c3c30ed..eaab911 100644
--- a/TODO
+++ b/TODO
@@ -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;
}