summaryrefslogtreecommitdiff
path: root/socket
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
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')
-rw-r--r--socket/udp-turn-over-tcp.c16
-rw-r--r--socket/udp-turn.c98
2 files changed, 95 insertions, 19 deletions
diff --git a/socket/udp-turn-over-tcp.c b/socket/udp-turn-over-tcp.c
index df74e78..225ea35 100644
--- a/socket/udp-turn-over-tcp.c
+++ b/socket/udp-turn-over-tcp.c
@@ -72,7 +72,8 @@ typedef enum {
#define MAX_UDP_MESSAGE_SIZE 65535
#define MAGIC_COOKIE_OFFSET \
- STUN_MESSAGE_HEADER_LENGTH + STUN_MESSAGE_TYPE_LEN + STUN_MESSAGE_LENGTH_LEN
+ STUN_MESSAGE_HEADER_LENGTH + STUN_MESSAGE_TYPE_LEN + \
+ STUN_MESSAGE_LENGTH_LEN + sizeof(guint16)
static void socket_close (NiceSocket *sock);
static gint socket_recv_messages (NiceSocket *sock,
@@ -182,8 +183,11 @@ socket_recv_message (NiceSocket *sock, NiceInputMessage *recv_message)
/* Unexpected data, error in stream */
return -1;
}
- priv->expecting_len = packetlen;
- priv->recv_buf_len = 0;
+
+ /* Keep the RFC4571 framing for the NiceAgent to unframe */
+ priv->expecting_len = packetlen + sizeof(guint16);
+ priv->recv_buf_len = sizeof(guint16);
+ priv->recv_buf.u16[0] = priv->recv_buf.u16[1];
}
}
@@ -263,7 +267,6 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to,
struct {
guint8 pt;
guint8 zero;
- guint16 packet_len;
} msoc;
} header_buf;
guint offset = 0;
@@ -302,7 +305,6 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to,
guint8 u8[4];
} cookie;
guint16 len = output_message_get_size (message);
- guint16 header_len;
/* Copy the cookie from possibly split messages */
cookie.u32 = 0;
@@ -328,16 +330,14 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to,
}
cookie.u32 = ntohl(cookie.u32);
- header_buf.msoc.packet_len = htons (len);
header_buf.msoc.zero = 0;
- header_len = sizeof(header_buf.msoc);
if (cookie.u32 == TURN_MAGIC_COOKIE)
header_buf.msoc.pt = MS_TURN_CONTROL_MESSAGE;
else
header_buf.msoc.pt = MS_TURN_END_TO_END_DATA;
local_bufs[0].buffer = &header_buf;
- local_bufs[0].size = header_len;
+ local_bufs[0].size = sizeof(header_buf.msoc);
offset = 1;
} else {
local_message.n_buffers = n_bufs;
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,