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 { ...@@ -72,7 +72,8 @@ typedef enum {
#define MAX_UDP_MESSAGE_SIZE 65535 #define MAX_UDP_MESSAGE_SIZE 65535
#define MAGIC_COOKIE_OFFSET \ #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 void socket_close (NiceSocket *sock);
static gint socket_recv_messages (NiceSocket *sock, static gint socket_recv_messages (NiceSocket *sock,
...@@ -182,8 +183,11 @@ socket_recv_message (NiceSocket *sock, NiceInputMessage *recv_message) ...@@ -182,8 +183,11 @@ socket_recv_message (NiceSocket *sock, NiceInputMessage *recv_message)
/* Unexpected data, error in stream */ /* Unexpected data, error in stream */
return -1; 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, ...@@ -263,7 +267,6 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to,
struct { struct {
guint8 pt; guint8 pt;
guint8 zero; guint8 zero;
guint16 packet_len;
} msoc; } msoc;
} header_buf; } header_buf;
guint offset = 0; guint offset = 0;
...@@ -302,7 +305,6 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to, ...@@ -302,7 +305,6 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to,
guint8 u8[4]; guint8 u8[4];
} cookie; } cookie;
guint16 len = output_message_get_size (message); guint16 len = output_message_get_size (message);
guint16 header_len;
/* Copy the cookie from possibly split messages */ /* Copy the cookie from possibly split messages */
cookie.u32 = 0; cookie.u32 = 0;
...@@ -328,16 +330,14 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to, ...@@ -328,16 +330,14 @@ socket_send_message (NiceSocket *sock, const NiceAddress *to,
} }
cookie.u32 = ntohl(cookie.u32); cookie.u32 = ntohl(cookie.u32);
header_buf.msoc.packet_len = htons (len);
header_buf.msoc.zero = 0; header_buf.msoc.zero = 0;
header_len = sizeof(header_buf.msoc);
if (cookie.u32 == TURN_MAGIC_COOKIE) if (cookie.u32 == TURN_MAGIC_COOKIE)
header_buf.msoc.pt = MS_TURN_CONTROL_MESSAGE; header_buf.msoc.pt = MS_TURN_CONTROL_MESSAGE;
else else
header_buf.msoc.pt = MS_TURN_END_TO_END_DATA; header_buf.msoc.pt = MS_TURN_END_TO_END_DATA;
local_bufs[0].buffer = &header_buf; local_bufs[0].buffer = &header_buf;
local_bufs[0].size = header_len; local_bufs[0].size = sizeof(header_buf.msoc);
offset = 1; offset = 1;
} else { } else {
local_message.n_buffers = n_bufs; local_message.n_buffers = n_bufs;
......
...@@ -534,24 +534,93 @@ static gint ...@@ -534,24 +534,93 @@ static gint
_socket_send_messages_wrapped (NiceSocket *sock, const NiceAddress *to, _socket_send_messages_wrapped (NiceSocket *sock, const NiceAddress *to,
const NiceOutputMessage *messages, guint n_messages, gboolean reliable) const NiceOutputMessage *messages, guint n_messages, gboolean reliable)
{ {
if (!nice_socket_is_reliable (sock)) {
if (reliable) if (reliable)
return nice_socket_send_messages_reliable (sock, to, messages, n_messages); return nice_socket_send_messages_reliable (sock, to, messages, n_messages);
else else
return nice_socket_send_messages (sock, to, messages, n_messages); 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 static gssize
_socket_send_wrapped (NiceSocket *sock, const NiceAddress *to, _socket_send_wrapped (NiceSocket *sock, const NiceAddress *to,
guint len, const gchar *buf, gboolean reliable) guint len, const gchar *buf, gboolean reliable)
{ {
gint ret;
if (!nice_socket_is_reliable (sock)) {
GOutputVector local_buf = { buf, len }; GOutputVector local_buf = { buf, len };
NiceOutputMessage local_message = { &local_buf, 1}; NiceOutputMessage local_message = { &local_buf, 1};
gint ret;
ret = _socket_send_messages_wrapped (sock, to, &local_message, 1, reliable); ret = _socket_send_messages_wrapped (sock, to, &local_message, 1, reliable);
if (ret == 1) if (ret == 1)
return len; return len;
return ret; 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 static void
...@@ -1044,7 +1113,14 @@ nice_udp_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, ...@@ -1044,7 +1113,14 @@ nice_udp_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
guint16 *u16; guint16 *u16;
} recv_buf; } 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)) { if (nice_address_equal (&priv->server_addr, recv_from)) {
valid = stun_agent_validate (&priv->agent, &msg, 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