summaryrefslogtreecommitdiff
path: root/socket/udp-turn.c
diff options
context:
space:
mode:
authorYouness Alaoui <youness.alaoui@collabora.co.uk>2014-04-19 00:52:18 -0400
committerOlivier CrĂȘte <olivier.crete@collabora.com>2014-05-17 00:22:36 -0400
commitc6ba5a24973cb2e8c79b6abe69af8c2fc3c10674 (patch)
treeabce4a2da9bfc999969d799047feb44ae4c9eec9 /socket/udp-turn.c
parent8e7cd06ad6fc4a4f63835c7608a871039245b025 (diff)
downloadlibnice-c6ba5a24973cb2e8c79b6abe69af8c2fc3c10674.tar.gz
Move the rfc4571 handling for OC2007 into udp-turn
In the case of OC2007, we must consider that the turn control messages are framed with rfc4571 and udp-turn-over-tcp only adds a single guint16 to represent turn-control or end-to-end indication. Otherwise, we will have issues with double-framing when we do the allocate directly on the udp-turn-over-tcp but we'd have no framing once we add the udp-turn socket layer on top of udp-turn-over-tcp
Diffstat (limited to 'socket/udp-turn.c')
-rw-r--r--socket/udp-turn.c98
1 files changed, 87 insertions, 11 deletions
diff --git a/socket/udp-turn.c b/socket/udp-turn.c
index 942007e..36ae94b 100644
--- a/socket/udp-turn.c
+++ b/socket/udp-turn.c
@@ -534,24 +534,93 @@ static gint
_socket_send_messages_wrapped (NiceSocket *sock, const NiceAddress *to,
const NiceOutputMessage *messages, guint n_messages, gboolean reliable)
{
- if (reliable)
- return nice_socket_send_messages_reliable (sock, to, messages, n_messages);
- else
- return nice_socket_send_messages (sock, to, messages, n_messages);
+ if (!nice_socket_is_reliable (sock)) {
+ if (reliable)
+ return nice_socket_send_messages_reliable (sock, to, messages, n_messages);
+ else
+ return nice_socket_send_messages (sock, to, messages, n_messages);
+ } else {
+ GOutputVector *local_bufs;
+ NiceOutputMessage local_message;
+ const NiceOutputMessage *message;
+ gsize message_len;
+ guint n_bufs = 0;
+ guint16 rfc4571_frame;
+ guint i;
+ gint ret;
+
+ g_assert (n_messages == 1);
+ message = &messages[0];
+ message_len = output_message_get_size (message);
+ g_assert (message_len <= G_MAXUINT16);
+
+ /* ICE-TCP requires that all packets be framed with RFC4571 */
+
+ /* Count the number of buffers. */
+ if (message->n_buffers == -1) {
+ for (i = 0; message->buffers[i].buffer != NULL; i++)
+ n_bufs++;
+ } else {
+ n_bufs = message->n_buffers;
+ }
+
+ local_bufs = g_malloc_n (n_bufs + 1, sizeof (GOutputVector));
+ local_message.buffers = local_bufs;
+ local_message.n_buffers = n_bufs + 1;
+
+ rfc4571_frame = htons (message_len);
+ local_bufs[0].buffer = &rfc4571_frame;
+ local_bufs[0].size = sizeof (guint16);
+
+ for (i = 0; i < n_bufs; i++) {
+ local_bufs[i + 1].buffer = message->buffers[i].buffer;
+ local_bufs[i + 1].size = message->buffers[i].size;
+ }
+
+
+ if (reliable)
+ ret = nice_socket_send_messages_reliable (sock, to,
+ &local_message, 1);
+ else
+ ret = nice_socket_send_messages (sock, to, &local_message, 1);
+
+ if (ret == 1)
+ ret = message_len;
+
+ g_free (local_bufs);
+
+ return ret;
+ }
}
static gssize
_socket_send_wrapped (NiceSocket *sock, const NiceAddress *to,
guint len, const gchar *buf, gboolean reliable)
{
- GOutputVector local_buf = { buf, len };
- NiceOutputMessage local_message = { &local_buf, 1};
gint ret;
- ret = _socket_send_messages_wrapped (sock, to, &local_message, 1, reliable);
- if (ret == 1)
- return len;
- return ret;
+ if (!nice_socket_is_reliable (sock)) {
+ GOutputVector local_buf = { buf, len };
+ NiceOutputMessage local_message = { &local_buf, 1};
+
+ ret = _socket_send_messages_wrapped (sock, to, &local_message, 1, reliable);
+ if (ret == 1)
+ return len;
+ return ret;
+ } else {
+ guint16 rfc4571_frame = htons (len);
+ GOutputVector local_buf[2] = {{&rfc4571_frame, 2}, { buf, len }};
+ NiceOutputMessage local_message = { local_buf, 2};
+
+ if (reliable)
+ ret = nice_socket_send_messages_reliable (sock, to, &local_message, 1);
+ else
+ ret = nice_socket_send_messages (sock, to, &local_message, 1);
+
+ if (ret == 1)
+ return len;
+ return ret;
+ }
}
static void
@@ -1044,7 +1113,14 @@ nice_udp_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
guint16 *u16;
} recv_buf;
- recv_buf.u8 = (guint8 *) _recv_buf;
+ /* In the case of a reliable UDP-TURN-OVER-TCP (which means MS-TURN)
+ * we must use RFC4571 framing */
+ if (nice_socket_is_reliable (sock)) {
+ recv_buf.u8 = _recv_buf + sizeof(guint16);
+ recv_len -= sizeof(guint16);
+ } else {
+ recv_buf.u8 = _recv_buf;
+ }
if (nice_address_equal (&priv->server_addr, recv_from)) {
valid = stun_agent_validate (&priv->agent, &msg,