diff options
author | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2014-04-19 00:52:18 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2014-05-17 00:22:36 -0400 |
commit | c6ba5a24973cb2e8c79b6abe69af8c2fc3c10674 (patch) | |
tree | abce4a2da9bfc999969d799047feb44ae4c9eec9 /socket | |
parent | 8e7cd06ad6fc4a4f63835c7608a871039245b025 (diff) | |
download | libnice-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.c | 16 | ||||
-rw-r--r-- | socket/udp-turn.c | 98 |
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, |