Commit c6ba5a24 authored by Youness Alaoui's avatar Youness Alaoui Committed by Olivier Crête

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
parent 8e7cd06a
......@@ -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;
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment