2 * This file is part of the Nice GLib ICE library.
4 * (C) 2008 Collabora Ltd.
5 * Contact: Youness Alaoui
6 * (C) 2008 Nokia Corporation
8 * The contents of this file are subject to the Mozilla Public License Version
9 * 1.1 (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS IS" basis,
14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15 * for the specific language governing rights and limitations under the
18 * The Original Code is the Nice GLib ICE library.
20 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21 * Corporation. All Rights Reserved.
24 * Youness Alaoui, Collabora Ltd.
26 * Alternatively, the contents of this file may be used under the terms of the
27 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28 * case the provisions of LGPL are applicable instead of those above. If you
29 * wish to allow use of your version of this file only under the terms of the
30 * LGPL and not to allow others to use your version of this file under the
31 * MPL, indicate your decision by deleting the provisions above and replace
32 * them with the notice and other provisions required by the LGPL. If you do
33 * not delete the provisions above, a recipient may use your version of this
34 * file under either the MPL or the LGPL.
38 * Implementation of TURN
50 #include "stun/stunagent.h"
51 #include "stun/usages/timer.h"
52 #include "agent-priv.h"
54 #define STUN_END_TIMEOUT 8000
55 #define STUN_MAX_MS_REALM_LEN 128 // as defined in [MS-TURN]
56 #define STUN_EXPIRE_TIMEOUT 60 /* Time we refresh before expiration */
57 #define STUN_PERMISSION_TIMEOUT (300 - STUN_EXPIRE_TIMEOUT) /* 240 s */
58 #define STUN_BINDING_TIMEOUT (600 - STUN_EXPIRE_TIMEOUT) /* 540 s */
64 uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
72 GSource *timeout_source;
79 GList *pending_bindings;
80 ChannelBinding *current_binding;
81 TURNMessage *current_binding_msg;
82 GList *pending_permissions;
83 GSource *tick_source_channel_bind;
84 GSource *tick_source_create_permission;
85 NiceSocket *base_socket;
86 NiceAddress server_addr;
91 NiceTurnSocketCompatibility compatibility;
92 GQueue *send_requests;
93 uint8_t ms_realm[STUN_MAX_MS_REALM_LEN + 1];
94 uint8_t ms_connection_id[20];
95 uint32_t ms_sequence_num;
96 bool ms_connection_id_valid;
97 GList *permissions; /* the peers (NiceAddress) for which
98 there is an installed permission */
99 GList *sent_permissions; /* ongoing permission installed */
100 GHashTable *send_data_queues; /* stores a send data queue for per peer */
101 GSource *permission_timeout_source; /* timer used to invalidate
104 guint8 *cached_realm;
105 uint16_t cached_realm_len;
106 guint8 *cached_nonce;
107 uint16_t cached_nonce_len;
109 GByteArray *fragment_buffer;
115 StunTransactionId id;
120 /* used to store data sent while obtaining a permission */
127 static void socket_close (NiceSocket *sock);
128 static gint socket_recv_messages (NiceSocket *sock,
129 NiceInputMessage *recv_messages, guint n_recv_messages);
130 static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
131 const NiceOutputMessage *messages, guint n_messages);
132 static gint socket_send_messages_reliable (NiceSocket *sock,
133 const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
134 static gboolean socket_is_reliable (NiceSocket *sock);
135 static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
136 static void socket_set_writable_callback (NiceSocket *sock,
137 NiceSocketWritableCb callback, gpointer user_data);
138 static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other);
140 static void priv_process_pending_bindings (UdpTurnPriv *priv);
141 static gboolean priv_retransmissions_tick_unlocked (UdpTurnPriv *priv);
142 static gboolean priv_retransmissions_tick (gpointer pointer);
143 static void priv_schedule_tick (UdpTurnPriv *priv);
144 static void priv_send_turn_message (UdpTurnPriv *priv, TURNMessage *msg);
145 static gboolean priv_send_create_permission (UdpTurnPriv *priv,
146 const NiceAddress *peer);
147 static gboolean priv_send_channel_bind (UdpTurnPriv *priv,
149 const NiceAddress *peer);
150 static gboolean priv_add_channel_binding (UdpTurnPriv *priv,
151 const NiceAddress *peer);
152 static gboolean priv_forget_send_request_timeout (gpointer pointer);
153 static void priv_clear_permissions (UdpTurnPriv *priv);
156 send_request_free (SendRequest *r)
158 g_source_destroy (r->source);
159 g_source_unref (r->source);
161 stun_agent_forget_transaction (&r->priv->agent, r->id);
163 g_slice_free (SendRequest, r);
167 priv_nice_address_hash (gconstpointer data)
169 gchar address[NICE_ADDRESS_STRING_LEN];
171 nice_address_to_string ((NiceAddress *) data, address);
173 return g_str_hash(address);
177 priv_send_data_queue_destroy (gpointer user_data)
179 GQueue *send_queue = (GQueue *) user_data;
182 for (i = g_queue_peek_head_link (send_queue); i; i = i->next) {
183 SendData *data = (SendData *) i->data;
186 g_slice_free (SendData, data);
188 g_queue_free (send_queue);
192 nice_udp_turn_socket_new (GMainContext *ctx, NiceAddress *addr,
193 NiceSocket *base_socket, const NiceAddress *server_addr,
194 const gchar *username, const gchar *password,
195 NiceTurnSocketCompatibility compatibility)
198 NiceSocket *sock = g_slice_new0 (NiceSocket);
204 priv = g_new0 (UdpTurnPriv, 1);
206 if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
207 compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
208 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
209 STUN_COMPATIBILITY_RFC5389,
210 STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS);
211 } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) {
212 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
213 STUN_COMPATIBILITY_RFC3489,
214 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
215 STUN_AGENT_USAGE_NO_INDICATION_AUTH);
216 } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
217 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
218 STUN_COMPATIBILITY_RFC3489,
219 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
220 STUN_AGENT_USAGE_IGNORE_CREDENTIALS);
221 } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
222 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
223 STUN_COMPATIBILITY_OC2007,
224 STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS |
225 STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES);
228 priv->channels = NULL;
229 priv->current_binding = NULL;
230 priv->base_socket = base_socket;
232 priv->ctx = g_main_context_ref (ctx);
234 if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN ||
235 compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
236 priv->username = g_base64_decode (username, &priv->username_len);
237 priv->password = g_base64_decode (password, &priv->password_len);
239 priv->username = (uint8_t *)g_strdup (username);
240 priv->username_len = (gsize) strlen (username);
241 if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
242 priv->password = NULL;
243 priv->password_len = 0;
245 priv->password = (uint8_t *)g_strdup (password);
246 priv->password_len = (gsize) strlen (password);
249 priv->server_addr = *server_addr;
250 priv->compatibility = compatibility;
251 priv->send_requests = g_queue_new ();
253 priv->send_data_queues =
254 g_hash_table_new_full (priv_nice_address_hash,
255 (GEqualFunc) nice_address_equal,
256 (GDestroyNotify) nice_address_free,
257 priv_send_data_queue_destroy);
259 sock->type = NICE_SOCKET_TYPE_UDP_TURN;
262 sock->send_messages = socket_send_messages;
263 sock->send_messages_reliable = socket_send_messages_reliable;
264 sock->recv_messages = socket_recv_messages;
265 sock->is_reliable = socket_is_reliable;
266 sock->can_send = socket_can_send;
267 sock->set_writable_callback = socket_set_writable_callback;
268 sock->is_based_on = socket_is_based_on;
269 sock->close = socket_close;
270 sock->priv = (void *) priv;
278 socket_close (NiceSocket *sock)
280 UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
283 g_mutex_lock (&mutex);
285 for (i = priv->channels; i; i = i->next) {
286 ChannelBinding *b = i->data;
287 if (b->timeout_source) {
288 g_source_destroy (b->timeout_source);
289 g_source_unref (b->timeout_source);
293 g_list_free (priv->channels);
295 g_list_free_full (priv->pending_bindings, (GDestroyNotify) nice_address_free);
297 if (priv->tick_source_channel_bind != NULL) {
298 g_source_destroy (priv->tick_source_channel_bind);
299 g_source_unref (priv->tick_source_channel_bind);
300 priv->tick_source_channel_bind = NULL;
303 if (priv->tick_source_create_permission != NULL) {
304 g_source_destroy (priv->tick_source_create_permission);
305 g_source_unref (priv->tick_source_create_permission);
306 priv->tick_source_create_permission = NULL;
309 g_queue_free_full (priv->send_requests, (GDestroyNotify) send_request_free);
311 priv_clear_permissions (priv);
312 g_list_free_full (priv->sent_permissions, (GDestroyNotify) nice_address_free);
313 g_hash_table_destroy (priv->send_data_queues);
315 if (priv->permission_timeout_source) {
316 g_source_destroy (priv->permission_timeout_source);
317 g_source_unref (priv->permission_timeout_source);
318 priv->permission_timeout_source = NULL;
322 g_main_context_unref (priv->ctx);
324 g_free (priv->current_binding);
325 g_free (priv->current_binding_msg);
326 g_list_free_full (priv->pending_permissions, g_free);
327 g_free (priv->username);
328 g_free (priv->password);
329 g_free (priv->cached_realm);
330 g_free (priv->cached_nonce);
332 if (priv->fragment_buffer) {
333 g_byte_array_free(priv->fragment_buffer, TRUE);
340 g_mutex_unlock (&mutex);
344 socket_recv_messages (NiceSocket *sock,
345 NiceInputMessage *recv_messages, guint n_recv_messages)
347 UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
349 gint n_output_messages = 0;
351 gboolean error = FALSE;
353 /* Make sure socket has not been freed: */
354 g_assert (sock->priv != NULL);
356 nice_debug_verbose ("received message on TURN socket");
358 if (priv->fragment_buffer) {
359 /* Fill as many recv_messages as possible with RFC4571-framed data we
360 * already hold in our buffer before reading more from the base socket. */
361 guint8 *f_buffer = priv->fragment_buffer->data;
362 guint f_buffer_len = priv->fragment_buffer->len;
364 for (i = 0; i < n_recv_messages && f_buffer_len >= sizeof (guint16); ++i) {
365 guint32 msg_len = ((f_buffer[0] << 8) | f_buffer[1]) + sizeof (guint16);
367 if (msg_len > f_buffer_len) {
368 /* The next message in the buffer isn't complete yet. Wait for more
369 * data from the base socket. */
373 /* We have a full message in the buffer. Copy it into the user-provided
374 * NiceInputMessage. */
375 memcpy_buffer_to_input_message (&recv_messages[i], f_buffer, msg_len);
376 *recv_messages[i].from = priv->from;
379 f_buffer_len -= msg_len;
383 /* Adjust recv_messages with the number of messages we've just filled. */
384 recv_messages += n_output_messages;
385 n_recv_messages -= n_output_messages;
387 /* Shrink the fragment buffer, deallocate it if empty. */
388 g_byte_array_remove_range (priv->fragment_buffer, 0,
389 priv->fragment_buffer->len - f_buffer_len);
390 if (priv->fragment_buffer->len == 0) {
391 g_byte_array_free (priv->fragment_buffer, TRUE);
392 priv->fragment_buffer = NULL;
396 n_messages = nice_socket_recv_messages (priv->base_socket,
397 recv_messages, n_recv_messages);
402 /* Process all the messages. Those which fail parsing are re-used for the next
405 * FIXME: This needs a fast path which avoids allocations or memcpy()s.
406 * Implementing such a path means rewriting the TURN parser (and hence the
407 * STUN message code) to operate on vectors of buffers, rather than a
408 * monolithic buffer. */
409 for (i = 0; i < (guint) n_messages; ++i) {
410 NiceInputMessage *message = &recv_messages[i];
415 gint parsed_buffer_length;
416 gboolean allocated_buffer = FALSE;
418 if (message->length == 0)
421 /* Compact the message’s buffers into a single one for parsing. Avoid this
422 * in the (hopefully) common case of a single-element buffer vector. */
423 if (message->n_buffers == 1 ||
424 (message->n_buffers == -1 &&
425 message->buffers[0].buffer != NULL &&
426 message->buffers[1].buffer == NULL)) {
427 buffer = message->buffers[0].buffer;
428 buffer_length = message->length;
430 nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC);
432 buffer = compact_input_message (message, &buffer_length);
433 allocated_buffer = TRUE;
436 /* Parse in-place. */
437 parsed_buffer_length = nice_udp_turn_socket_parse_recv (sock, &dummy,
438 &from, buffer_length, buffer,
439 message->from, buffer, buffer_length);
440 message->length = MAX (parsed_buffer_length, 0);
442 if (parsed_buffer_length < 0) {
444 } else if (parsed_buffer_length > 0) {
445 *message->from = from;
447 /* parsed_buffer_length == 0 means this is a TURN control message which
450 if (nice_socket_is_reliable (sock) && parsed_buffer_length > 0) {
451 /* Determine the portion of the current NiceInputMessage we can already
454 if (!priv->fragment_buffer) {
455 msg_len = ((buffer[0] << 8) | buffer[1]) + sizeof (guint16);
456 if (msg_len > parsed_buffer_length) {
457 /* The RFC4571 frame is larger than the current TURN message, need to
458 * buffer it and wait for more data. */
463 if (msg_len != parsed_buffer_length && !priv->fragment_buffer) {
464 /* Start of message fragmenting detected. Allocate fragment buffer
465 * large enough for the recv_message's we haven't parsed yet. */
467 guint buffer_len = 0;
469 for (j = i; j < n_messages; ++j) {
470 buffer_len += recv_messages[j].length;
472 priv->fragment_buffer = g_byte_array_sized_new (buffer_len);
475 if (priv->fragment_buffer) {
476 /* The messages are fragmented. Store the excess data (after msg_len
477 * bytes) into fragment buffer for reassembly. */
478 g_byte_array_append (priv->fragment_buffer, buffer + msg_len,
479 parsed_buffer_length - msg_len);
481 parsed_buffer_length = msg_len;
482 message->length = msg_len;
487 /* Split up the monolithic buffer again into the caller-provided buffers. */
488 if (parsed_buffer_length > 0 && allocated_buffer) {
489 memcpy_buffer_to_input_message (message, buffer,
490 parsed_buffer_length);
493 if (allocated_buffer)
502 /* Was there an error processing the first message? */
506 return n_output_messages;
509 /* interval is given in milliseconds */
511 priv_timeout_add_with_context (UdpTurnPriv *priv, guint interval,
512 GSourceFunc function, gpointer data)
514 GSource *source = NULL;
516 g_return_val_if_fail (function != NULL, NULL);
518 source = g_timeout_source_new (interval);
520 g_source_set_callback (source, function, data, NULL);
521 g_source_attach (source, priv->ctx);
526 /* interval is given in seconds */
528 priv_timeout_add_seconds_with_context (UdpTurnPriv *priv, guint interval,
529 GSourceFunc function, gpointer data)
531 GSource *source = NULL;
533 g_return_val_if_fail (function != NULL, NULL);
535 source = g_timeout_source_new_seconds (interval);
537 g_source_set_callback (source, function, data, NULL);
538 g_source_attach (source, priv->ctx);
543 static StunMessageReturn
544 stun_message_append_ms_connection_id(StunMessage *msg,
545 uint8_t *ms_connection_id, uint32_t ms_sequence_num)
549 uint32_t buf32[24/4];
552 memcpy(buf.buf8, ms_connection_id, 20);
553 buf.buf32[5] = htonl(ms_sequence_num);
554 return stun_message_append_bytes (msg, STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER,
559 stun_message_ensure_ms_realm(StunMessage *msg, uint8_t *realm)
561 /* With MS-TURN, original clients do not send REALM attribute in Send and Set
562 * Active Destination requests, but use it to compute MESSAGE-INTEGRITY. We
563 * simply append cached realm value to the message and use it in subsequent
564 * stun_agent_finish_message() call. Messages with this additional attribute
565 * are handled correctly on OCS Access Edge working as TURN server. */
566 if (stun_message_get_method(msg) == STUN_SEND ||
567 stun_message_get_method(msg) == STUN_OLD_SET_ACTIVE_DST) {
568 stun_message_append_bytes (msg, STUN_ATTRIBUTE_REALM, realm,
569 strlen((char *)realm));
574 priv_is_peer_in_list (const GList *list, const NiceAddress *peer)
578 for (iter = list ; iter ; iter = g_list_next (iter)) {
579 NiceAddress *address = (NiceAddress *) iter->data;
581 if (nice_address_equal (address, peer))
589 priv_has_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
591 return priv_is_peer_in_list (priv->permissions, peer);
595 priv_has_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
597 return priv_is_peer_in_list (priv->sent_permissions, peer);
601 priv_add_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
604 g_list_append (priv->permissions, nice_address_dup (peer));
608 priv_add_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
610 priv->sent_permissions =
611 g_list_append (priv->sent_permissions, nice_address_dup (peer));
615 priv_remove_peer_from_list (GList *list, const NiceAddress *peer)
619 for (iter = list ; iter ; iter = g_list_next (iter)) {
620 NiceAddress *address = (NiceAddress *) iter->data;
622 if (nice_address_equal (address, peer)) {
623 GList *prev = iter->prev;
625 nice_address_free (address);
626 list = g_list_delete_link (list, iter);
637 priv_remove_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
639 priv->sent_permissions =
640 priv_remove_peer_from_list (priv->sent_permissions, peer);
644 priv_clear_permissions (UdpTurnPriv *priv)
646 g_list_free_full (priv->permissions, (GDestroyNotify) nice_address_free);
647 priv->permissions = NULL;
651 _socket_send_messages_wrapped (NiceSocket *sock, const NiceAddress *to,
652 const NiceOutputMessage *messages, guint n_messages, gboolean reliable)
654 if (!nice_socket_is_reliable (sock)) {
656 return nice_socket_send_messages_reliable (sock, to, messages, n_messages);
658 return nice_socket_send_messages (sock, to, messages, n_messages);
660 GOutputVector *local_bufs;
661 NiceOutputMessage local_message;
662 const NiceOutputMessage *message;
665 guint16 rfc4571_frame;
669 g_assert_cmpuint (n_messages, ==, 1);
670 message = &messages[0];
671 message_len = output_message_get_size (message);
672 g_assert_cmpint (message_len, <=, G_MAXUINT16);
674 /* ICE-TCP requires that all packets be framed with RFC4571 */
676 /* Count the number of buffers. */
677 if (message->n_buffers == -1) {
678 for (i = 0; message->buffers[i].buffer != NULL; i++)
681 n_bufs = message->n_buffers;
684 local_bufs = g_alloca ((n_bufs + 1) * sizeof (GOutputVector));
685 local_message.buffers = local_bufs;
686 local_message.n_buffers = n_bufs + 1;
688 rfc4571_frame = htons (message_len);
689 local_bufs[0].buffer = &rfc4571_frame;
690 local_bufs[0].size = sizeof (guint16);
692 for (i = 0; i < n_bufs; i++) {
693 local_bufs[i + 1].buffer = message->buffers[i].buffer;
694 local_bufs[i + 1].size = message->buffers[i].size;
699 ret = nice_socket_send_messages_reliable (sock, to,
702 ret = nice_socket_send_messages (sock, to, &local_message, 1);
712 _socket_send_wrapped (NiceSocket *sock, const NiceAddress *to,
713 guint len, const gchar *buf, gboolean reliable)
717 if (!nice_socket_is_reliable (sock)) {
718 GOutputVector local_buf = { buf, len };
719 NiceOutputMessage local_message = { &local_buf, 1};
721 ret = _socket_send_messages_wrapped (sock, to, &local_message, 1, reliable);
726 guint16 rfc4571_frame = htons (len);
727 GOutputVector local_buf[2] = {{&rfc4571_frame, 2}, { buf, len }};
728 NiceOutputMessage local_message = { local_buf, 2};
731 ret = nice_socket_send_messages_reliable (sock, to, &local_message, 1);
733 ret = nice_socket_send_messages (sock, to, &local_message, 1);
742 socket_enqueue_data(UdpTurnPriv *priv, const NiceAddress *to,
743 guint len, const gchar *buf, gboolean reliable)
745 SendData *data = g_slice_new0 (SendData);
746 GQueue *queue = g_hash_table_lookup (priv->send_data_queues, to);
749 queue = g_queue_new ();
750 g_hash_table_insert (priv->send_data_queues, nice_address_dup (to),
754 data->data = g_memdup(buf, len);
755 data->data_len = len;
756 data->reliable = reliable;
757 g_queue_push_tail (queue, data);
761 socket_dequeue_all_data (UdpTurnPriv *priv, const NiceAddress *to)
763 GQueue *send_queue = g_hash_table_lookup (priv->send_data_queues, to);
766 while (!g_queue_is_empty (send_queue)) {
768 (SendData *) g_queue_pop_head(send_queue);
770 nice_debug_verbose ("dequeuing data");
771 _socket_send_wrapped (priv->base_socket, &priv->server_addr,
772 data->data_len, data->data, data->reliable);
775 g_slice_free (SendData, data);
778 /* remove queue from table */
779 g_hash_table_remove (priv->send_data_queues, to);
785 socket_send_message (NiceSocket *sock, const NiceAddress *to,
786 const NiceOutputMessage *message, gboolean reliable)
788 UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
790 uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
793 struct sockaddr_storage storage;
794 struct sockaddr addr;
797 ChannelBinding *binding = NULL;
800 /* Make sure socket has not been freed: */
801 g_assert (sock->priv != NULL);
803 for (i = priv->channels; i; i = i->next) {
804 ChannelBinding *b = i->data;
805 if (nice_address_equal (&b->peer, to)) {
811 nice_address_copy_to_sockaddr (to, &sa.addr);
814 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
815 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
816 gsize message_len = output_message_get_size (message);
818 if (message_len + sizeof(uint32_t) <= sizeof(buffer)) {
820 uint16_t len16, channel16;
821 gsize message_offset = 0;
823 len16 = htons ((uint16_t) message_len);
824 channel16 = htons (binding->channel);
826 memcpy (buffer, &channel16, sizeof(uint16_t));
827 memcpy (buffer + sizeof(uint16_t), &len16, sizeof(uint16_t));
829 /* FIXME: Slow path! This should be replaced by code which manipulates
830 * the GOutputVector array, rather than the buffer contents
833 (message->n_buffers >= 0 && j < (guint) message->n_buffers) ||
834 (message->n_buffers < 0 && message->buffers[j].buffer != NULL);
836 const GOutputVector *out_buf = &message->buffers[j];
839 out_len = MIN (message_len - message_offset, out_buf->size);
840 memcpy (buffer + sizeof (uint32_t) + message_offset,
841 out_buf->buffer, out_len);
842 message_offset += out_len;
845 msg_len = message_len + sizeof(uint32_t);
850 ret = _socket_send_messages_wrapped (priv->base_socket,
851 &priv->server_addr, message, 1, reliable);
854 return output_message_get_size (message);
858 guint8 *compacted_buf;
859 gsize compacted_buf_len;
861 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
862 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
863 if (!stun_agent_init_indication (&priv->agent, &msg,
864 buffer, sizeof(buffer), STUN_IND_SEND))
866 if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS,
867 &sa.storage, sizeof(sa)) !=
868 STUN_MESSAGE_RETURN_SUCCESS)
871 if (!stun_agent_init_request (&priv->agent, &msg,
872 buffer, sizeof(buffer), STUN_SEND))
875 if (stun_message_append32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
876 TURN_MAGIC_COOKIE) != STUN_MESSAGE_RETURN_SUCCESS)
878 if (priv->username != NULL && priv->username_len > 0) {
879 if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_USERNAME,
880 priv->username, priv->username_len) !=
881 STUN_MESSAGE_RETURN_SUCCESS)
884 if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_DESTINATION_ADDRESS,
885 &sa.addr, sizeof(sa)) !=
886 STUN_MESSAGE_RETURN_SUCCESS)
889 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE &&
890 priv->current_binding &&
891 nice_address_equal (&priv->current_binding->peer, to)) {
892 if (stun_message_append32 (&msg, STUN_ATTRIBUTE_OPTIONS, 1) !=
893 STUN_MESSAGE_RETURN_SUCCESS)
898 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
899 if(stun_message_append32(&msg, STUN_ATTRIBUTE_MS_VERSION, 1) !=
900 STUN_MESSAGE_RETURN_SUCCESS)
903 if (priv->ms_connection_id_valid)
904 if (stun_message_append_ms_connection_id(&msg, priv->ms_connection_id,
905 ++priv->ms_sequence_num) !=
906 STUN_MESSAGE_RETURN_SUCCESS)
909 stun_message_ensure_ms_realm(&msg, priv->ms_realm);
912 /* Slow path! We have to compact the buffers to append them to the message.
913 * FIXME: This could be improved by adding vectored I/O support to
914 * stun_message_append_bytes(). */
915 compacted_buf = compact_output_message (message, &compacted_buf_len);
917 if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_DATA,
918 compacted_buf, compacted_buf_len) != STUN_MESSAGE_RETURN_SUCCESS) {
919 g_free (compacted_buf);
923 g_free (compacted_buf);
925 /* Finish the message. */
926 msg_len = stun_agent_finish_message (&priv->agent, &msg,
927 priv->password, priv->password_len);
928 if (msg_len > 0 && stun_message_get_class (&msg) == STUN_REQUEST &&
929 priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
930 SendRequest *req = g_slice_new0 (SendRequest);
933 stun_message_id (&msg, req->id);
934 req->source = priv_timeout_add_with_context (priv,
935 STUN_END_TIMEOUT, priv_forget_send_request_timeout, req);
936 g_queue_push_tail (priv->send_requests, req);
941 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766 &&
942 !priv_has_permission_for_peer (priv, to)) {
943 if (!priv_has_sent_permission_for_peer (priv, to)) {
944 priv_send_create_permission (priv, to);
948 nice_debug_verbose ("enqueuing data");
949 socket_enqueue_data(priv, to, msg_len, (gchar *)buffer, reliable);
953 GOutputVector local_buf = { buffer, msg_len };
954 NiceOutputMessage local_message = {&local_buf, 1};
956 ret = _socket_send_messages_wrapped (priv->base_socket,
957 &priv->server_addr, &local_message, 1, reliable);
965 /* Error condition pass through to the base socket. */
966 ret = _socket_send_messages_wrapped (priv->base_socket, to, message, 1,
969 return output_message_get_size (message);
976 socket_send_messages (NiceSocket *sock, const NiceAddress *to,
977 const NiceOutputMessage *messages, guint n_messages)
981 g_mutex_lock (&mutex);
983 /* Make sure socket has not been freed: */
984 g_assert (sock->priv != NULL);
986 for (i = 0; i < n_messages; i++) {
987 const NiceOutputMessage *message = &messages[i];
990 len = socket_send_message (sock, to, message, FALSE);
996 g_mutex_unlock (&mutex);
998 } else if (len == 0) {
1004 g_mutex_unlock (&mutex);
1010 socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to,
1011 const NiceOutputMessage *messages, guint n_messages)
1013 UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
1016 g_mutex_lock (&mutex);
1018 /* TURN can depend either on tcp-turn or udp-bsd as a base socket
1019 * if we allow reliable send and need to create permissions and we queue the
1020 * data, then we must be sure that the reliable send will succeed later, so
1021 * we check for udp-bsd here as the base socket and don't allow it.
1023 if (priv->base_socket->type == NICE_SOCKET_TYPE_UDP_BSD) {
1024 g_mutex_unlock (&mutex);
1028 for (i = 0; i < n_messages; i++) {
1029 const NiceOutputMessage *message = &messages[i];
1032 len = socket_send_message (sock, to, message, TRUE);
1036 g_mutex_unlock (&mutex);
1038 } else if (len == 0) {
1044 g_mutex_unlock (&mutex);
1049 socket_is_reliable (NiceSocket *sock)
1051 UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
1053 return nice_socket_is_reliable (priv->base_socket);
1057 socket_can_send (NiceSocket *sock, NiceAddress *addr)
1059 UdpTurnPriv *priv = sock->priv;
1061 return nice_socket_can_send (priv->base_socket, addr);
1065 socket_set_writable_callback (NiceSocket *sock,
1066 NiceSocketWritableCb callback, gpointer user_data)
1068 UdpTurnPriv *priv = sock->priv;
1070 nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
1074 socket_is_based_on (NiceSocket *sock, NiceSocket *other)
1076 UdpTurnPriv *priv = sock->priv;
1078 return (sock == other) ||
1079 (priv && nice_socket_is_based_on (priv->base_socket, other));
1083 priv_forget_send_request_timeout (gpointer pointer)
1085 SendRequest *req = pointer;
1087 g_mutex_lock (&mutex);
1088 if (g_source_is_destroyed (g_main_current_source ())) {
1089 nice_debug ("Source was destroyed. "
1090 "Avoided race condition in turn.c:priv_forget_send_request");
1091 g_mutex_unlock (&mutex);
1092 return G_SOURCE_REMOVE;
1095 send_request_free (req);
1096 g_queue_remove (req->priv->send_requests, req);
1098 g_mutex_unlock (&mutex);
1100 return G_SOURCE_REMOVE;
1104 priv_permission_timeout (gpointer data)
1106 UdpTurnPriv *priv = (UdpTurnPriv *) data;
1108 nice_debug ("Permission is about to timeout, schedule renewal");
1110 g_mutex_lock (&mutex);
1112 if (g_source_is_destroyed (g_main_current_source ())) {
1113 nice_debug ("Source was destroyed. Avoided race condition in "
1114 "udp-turn.c:priv_permission_timeout");
1116 g_mutex_unlock (&mutex);
1117 return G_SOURCE_REMOVE;
1121 /* remove all permissions for this agent (the permission for the peer
1122 we are sending to will be renewed) */
1123 priv_clear_permissions (priv);
1124 g_mutex_unlock (&mutex);
1130 priv_binding_expired_timeout (gpointer data)
1132 UdpTurnPriv *priv = (UdpTurnPriv *) data;
1134 GSource *source = NULL;
1136 g_mutex_lock (&mutex);
1137 if (g_source_is_destroyed (g_main_current_source ())) {
1138 nice_debug ("Source was destroyed. Avoided race condition in "
1139 "udp-turn.c:priv_permission_timeout");
1141 g_mutex_unlock (&mutex);
1142 return G_SOURCE_REMOVE;
1145 nice_debug ("Permission expired, refresh failed");
1147 /* find current binding and destroy it */
1148 for (i = priv->channels ; i; i = i->next) {
1149 ChannelBinding *b = i->data;
1150 if (b->timeout_source == source) {
1151 priv->channels = g_list_remove (priv->channels, b);
1152 /* Make sure we don't free a currently being-refreshed binding */
1153 if (priv->current_binding_msg && !priv->current_binding) {
1155 struct sockaddr_storage storage;
1156 struct sockaddr addr;
1158 socklen_t sa_len = sizeof(sa);
1161 /* look up binding associated with peer */
1162 stun_message_find_xor_addr (
1163 &priv->current_binding_msg->message,
1164 STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.storage, &sa_len);
1165 nice_address_set_from_sockaddr (&to, &sa.addr);
1167 /* If the binding is being refreshed, then move it to
1168 priv->current_binding so it counts as a 'new' binding and
1169 will get readded to the list if it succeeds */
1170 if (nice_address_equal (&b->peer, &to)) {
1171 priv->current_binding = b;
1175 /* In case the binding timed out before it could be processed, add it to
1177 priv_add_channel_binding (priv, &b->peer);
1183 g_mutex_unlock (&mutex);
1184 return G_SOURCE_REMOVE;
1188 priv_binding_timeout (gpointer data)
1190 UdpTurnPriv *priv = (UdpTurnPriv *) data;
1192 GSource *source = NULL;
1194 g_mutex_lock (&mutex);
1195 if (g_source_is_destroyed (g_main_current_source ())) {
1196 nice_debug ("Source was destroyed. Avoided race condition in "
1197 "udp-turn.c:priv_permission_timeout");
1199 g_mutex_unlock (&mutex);
1200 return G_SOURCE_REMOVE;
1203 nice_debug ("Permission is about to timeout, sending binding renewal");
1204 source = g_main_current_source ();
1206 /* find current binding and mark it for renewal */
1207 for (i = priv->channels ; i; i = i->next) {
1208 ChannelBinding *b = i->data;
1210 if (b->timeout_source == source) {
1213 /* Remove any existing timer */
1214 if (b->timeout_source) {
1215 g_source_destroy (b->timeout_source);
1216 g_source_unref (b->timeout_source);
1219 /* Install timer to expire the permission */
1220 b->timeout_source = priv_timeout_add_seconds_with_context (priv,
1221 STUN_EXPIRE_TIMEOUT, priv_binding_expired_timeout, priv);
1224 if (!priv->current_binding_msg)
1225 priv_send_channel_bind (priv, b->channel, &b->peer);
1230 g_mutex_unlock (&mutex);
1232 return G_SOURCE_REMOVE;
1236 nice_udp_turn_socket_cache_realm_nonce_locked (NiceSocket *sock,
1239 UdpTurnPriv *priv = sock->priv;
1242 g_assert_cmpint (sock->type, ==, NICE_SOCKET_TYPE_UDP_TURN);
1244 g_free (priv->cached_realm);
1245 priv->cached_realm = NULL;
1246 priv->cached_realm_len = 0;
1248 g_free (priv->cached_nonce);
1249 priv->cached_nonce = NULL;
1250 priv->cached_nonce_len = 0;
1252 tmp = stun_message_find (msg, STUN_ATTRIBUTE_REALM, &priv->cached_realm_len);
1253 if (tmp && priv->cached_realm_len < 764)
1254 priv->cached_realm = g_memdup (tmp, priv->cached_realm_len);
1256 tmp = stun_message_find (msg, STUN_ATTRIBUTE_NONCE, &priv->cached_nonce_len);
1257 if (tmp && priv->cached_nonce_len < 764)
1258 priv->cached_nonce = g_memdup (tmp, priv->cached_nonce_len);
1263 nice_udp_turn_socket_cache_realm_nonce (NiceSocket *sock,
1266 g_mutex_lock (&mutex);
1267 nice_udp_turn_socket_cache_realm_nonce_locked (sock, msg);
1268 g_mutex_unlock (&mutex);
1272 nice_udp_turn_socket_parse_recv_message (NiceSocket *sock, NiceSocket **from_sock,
1273 NiceInputMessage *message)
1275 /* TODO: Speed this up in the common reliable case of having a 24-byte header
1276 * buffer to begin with, followed by one or more massive buffers. */
1280 if (message->n_buffers == 1 ||
1281 (message->n_buffers == -1 &&
1282 message->buffers[0].buffer != NULL &&
1283 message->buffers[1].buffer == NULL)) {
1284 /* Fast path. Single massive buffer. */
1285 len = nice_udp_turn_socket_parse_recv (sock, from_sock,
1286 message->from, message->length, message->buffers[0].buffer,
1287 message->from, message->buffers[0].buffer, message->length);
1289 g_assert_cmpuint (len, <=, message->length);
1291 message->length = len;
1293 return (len > 0) ? 1 : 0;
1297 nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC);
1299 buf = compact_input_message (message, &buf_len);
1300 len = nice_udp_turn_socket_parse_recv (sock, from_sock,
1301 message->from, buf_len, buf,
1302 message->from, buf, buf_len);
1303 len = memcpy_buffer_to_input_message (message, buf, len);
1306 return (len > 0) ? 1 : 0;
1310 nice_udp_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
1311 NiceAddress *from, gsize len, guint8 *buf,
1312 const NiceAddress *recv_from, const guint8 *_recv_buf, gsize recv_len)
1315 UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
1316 StunValidationStatus valid;
1319 ChannelBinding *binding = NULL;
1326 g_mutex_lock (&mutex);
1328 /* In the case of a reliable UDP-TURN-OVER-TCP (which means MS-TURN)
1329 * we must use RFC4571 framing */
1330 if (nice_socket_is_reliable (sock)) {
1331 recv_buf.u8 = _recv_buf + sizeof(guint16);
1332 recv_len -= sizeof(guint16);
1334 recv_buf.u8 = _recv_buf;
1337 if (nice_address_equal (&priv->server_addr, recv_from)) {
1338 valid = stun_agent_validate (&priv->agent, &msg,
1339 recv_buf.u8, recv_len, NULL, NULL);
1341 if (valid == STUN_VALIDATION_SUCCESS) {
1342 if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 &&
1343 priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
1345 if (stun_message_find32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
1346 &cookie) != STUN_MESSAGE_RETURN_SUCCESS)
1348 if (cookie != TURN_MAGIC_COOKIE)
1352 if (stun_message_get_method (&msg) == STUN_SEND) {
1353 if (stun_message_get_class (&msg) == STUN_RESPONSE) {
1354 SendRequest *req = NULL;
1355 GList *i = g_queue_peek_head_link (priv->send_requests);
1356 StunTransactionId msg_id;
1358 stun_message_id (&msg, msg_id);
1360 for (; i; i = i->next) {
1361 SendRequest *r = i->data;
1362 if (memcmp (&r->id, msg_id, sizeof(StunTransactionId)) == 0) {
1369 g_queue_remove (priv->send_requests, req);
1370 send_request_free (req);
1373 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
1375 if (stun_message_find32 (&msg, STUN_ATTRIBUTE_OPTIONS, &opts) ==
1376 STUN_MESSAGE_RETURN_SUCCESS && opts & 0x1)
1377 goto msn_google_lock;
1382 } else if (stun_message_get_method (&msg) == STUN_OLD_SET_ACTIVE_DST) {
1383 StunTransactionId request_id;
1384 StunTransactionId response_id;
1386 if (priv->current_binding && priv->current_binding_msg) {
1387 stun_message_id (&msg, response_id);
1388 stun_message_id (&priv->current_binding_msg->message, request_id);
1389 if (memcmp (request_id, response_id,
1390 sizeof(StunTransactionId)) == 0) {
1391 g_free (priv->current_binding_msg);
1392 priv->current_binding_msg = NULL;
1394 if (stun_message_get_class (&msg) == STUN_RESPONSE &&
1395 (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007 ||
1396 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN)) {
1397 goto msn_google_lock;
1399 g_free (priv->current_binding);
1400 priv->current_binding = NULL;
1406 } else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) {
1407 StunTransactionId request_id;
1408 StunTransactionId response_id;
1410 if (priv->current_binding_msg) {
1411 stun_message_id (&msg, response_id);
1412 stun_message_id (&priv->current_binding_msg->message, request_id);
1413 if (memcmp (request_id, response_id,
1414 sizeof(StunTransactionId)) == 0) {
1416 if (priv->current_binding) {
1417 /* New channel binding */
1418 binding = priv->current_binding;
1420 /* Existing binding refresh */
1423 struct sockaddr_storage storage;
1424 struct sockaddr addr;
1426 socklen_t sa_len = sizeof(sa);
1429 /* look up binding associated with peer */
1430 stun_message_find_xor_addr (
1431 &priv->current_binding_msg->message,
1432 STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.storage, &sa_len);
1433 nice_address_set_from_sockaddr (&to, &sa.addr);
1435 for (i = priv->channels; i; i = i->next) {
1436 ChannelBinding *b = i->data;
1437 if (nice_address_equal (&b->peer, &to)) {
1444 if (stun_message_get_class (&msg) == STUN_ERROR) {
1446 uint8_t *sent_realm = NULL;
1447 uint8_t *recv_realm = NULL;
1448 uint16_t sent_realm_len = 0;
1449 uint16_t recv_realm_len = 0;
1452 (uint8_t *) stun_message_find (
1453 &priv->current_binding_msg->message,
1454 STUN_ATTRIBUTE_REALM, &sent_realm_len);
1456 (uint8_t *) stun_message_find (&msg,
1457 STUN_ATTRIBUTE_REALM, &recv_realm_len);
1459 /* check for unauthorized error response */
1460 if (stun_message_find_error (&msg, &code) ==
1461 STUN_MESSAGE_RETURN_SUCCESS &&
1462 (code == STUN_ERROR_STALE_NONCE ||
1463 (code == STUN_ERROR_UNAUTHORIZED &&
1464 !(recv_realm != NULL &&
1465 recv_realm_len > 0 &&
1466 recv_realm_len == sent_realm_len &&
1467 sent_realm != NULL &&
1468 memcmp (sent_realm, recv_realm,
1469 sent_realm_len) == 0)))) {
1471 g_free (priv->current_binding_msg);
1472 priv->current_binding_msg = NULL;
1473 nice_udp_turn_socket_cache_realm_nonce_locked (sock, &msg);
1475 priv_send_channel_bind (priv, binding->channel,
1478 g_free (priv->current_binding);
1479 priv->current_binding = NULL;
1480 g_free (priv->current_binding_msg);
1481 priv->current_binding_msg = NULL;
1482 priv_process_pending_bindings (priv);
1484 } else if (stun_message_get_class (&msg) == STUN_RESPONSE) {
1485 g_free (priv->current_binding_msg);
1486 priv->current_binding_msg = NULL;
1488 /* If it's a new channel binding, then add it to the list */
1489 if (priv->current_binding)
1490 priv->channels = g_list_append (priv->channels,
1491 priv->current_binding);
1492 priv->current_binding = NULL;
1495 binding->renew = FALSE;
1497 /* Remove any existing timer */
1498 if (binding->timeout_source) {
1499 g_source_destroy (binding->timeout_source);
1500 g_source_unref (binding->timeout_source);
1502 /* Install timer to schedule refresh of the permission */
1503 binding->timeout_source =
1504 priv_timeout_add_seconds_with_context (priv,
1505 STUN_BINDING_TIMEOUT, priv_binding_timeout, priv);
1507 priv_process_pending_bindings (priv);
1512 } else if (stun_message_get_method (&msg) == STUN_CREATEPERMISSION) {
1513 StunTransactionId request_id;
1514 StunTransactionId response_id;
1516 TURNMessage *current_create_permission_msg;
1518 for (i = priv->pending_permissions; i; i = next) {
1519 current_create_permission_msg = (TURNMessage *) i->data;
1522 stun_message_id (&msg, response_id);
1523 stun_message_id (¤t_create_permission_msg->message, request_id);
1525 if (memcmp (request_id, response_id,
1526 sizeof(StunTransactionId)) == 0) {
1528 struct sockaddr_storage storage;
1529 struct sockaddr addr;
1531 socklen_t peer_len = sizeof(peer);
1533 gchar tmpbuf[INET6_ADDRSTRLEN];
1535 stun_message_find_xor_addr (
1536 ¤t_create_permission_msg->message,
1537 STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &peer.storage, &peer_len);
1538 nice_address_set_from_sockaddr (&to, &peer.addr);
1539 nice_address_to_string (&to, tmpbuf);
1540 nice_debug ("TURN: got response for CreatePermission "
1541 "with XOR_PEER_ADDRESS=[%s]:%u : %s",
1542 tmpbuf, nice_address_get_port (&to),
1543 stun_message_get_class (&msg) == STUN_ERROR ? "unauthorized" : "ok");
1545 /* unathorized => resend with realm and nonce */
1546 if (stun_message_get_class (&msg) == STUN_ERROR) {
1548 uint8_t *sent_realm = NULL;
1549 uint8_t *recv_realm = NULL;
1550 uint16_t sent_realm_len = 0;
1551 uint16_t recv_realm_len = 0;
1554 (uint8_t *) stun_message_find (
1555 ¤t_create_permission_msg->message,
1556 STUN_ATTRIBUTE_REALM, &sent_realm_len);
1558 (uint8_t *) stun_message_find (&msg,
1559 STUN_ATTRIBUTE_REALM, &recv_realm_len);
1561 /* check for unauthorized error response */
1562 if (stun_message_find_error (&msg, &code) ==
1563 STUN_MESSAGE_RETURN_SUCCESS &&
1564 (code == STUN_ERROR_STALE_NONCE ||
1565 (code == STUN_ERROR_UNAUTHORIZED &&
1566 !(recv_realm != NULL &&
1567 recv_realm_len > 0 &&
1568 recv_realm_len == sent_realm_len &&
1569 sent_realm != NULL &&
1570 memcmp (sent_realm, recv_realm,
1571 sent_realm_len) == 0)))) {
1573 priv->pending_permissions = g_list_delete_link (
1574 priv->pending_permissions, i);
1575 g_free (current_create_permission_msg);
1576 current_create_permission_msg = NULL;
1578 nice_udp_turn_socket_cache_realm_nonce_locked (sock, &msg);
1579 /* resend CreatePermission */
1580 priv_send_create_permission (priv, &to);
1584 /* If we get an error, we just assume the server somehow
1585 doesn't support permissions and we ignore the error and
1586 fake a successful completion. If the server needs a permission
1587 but it failed to create it, then the connchecks will fail. */
1588 priv_remove_sent_permission_for_peer (priv, &to);
1589 priv_add_permission_for_peer (priv, &to);
1591 /* install timer to schedule refresh of the permission */
1592 /* (will not schedule refresh if we got an error) */
1593 if (stun_message_get_class (&msg) == STUN_RESPONSE &&
1594 !priv->permission_timeout_source) {
1595 priv->permission_timeout_source =
1596 priv_timeout_add_seconds_with_context (priv,
1597 STUN_PERMISSION_TIMEOUT, priv_permission_timeout,
1601 /* send enqued data */
1602 socket_dequeue_all_data (priv, &to);
1604 priv->pending_permissions = g_list_delete_link (
1605 priv->pending_permissions, i);
1606 g_free (current_create_permission_msg);
1607 current_create_permission_msg = NULL;
1614 } else if (stun_message_get_class (&msg) == STUN_INDICATION &&
1615 stun_message_get_method (&msg) == STUN_IND_DATA) {
1619 struct sockaddr_storage storage;
1620 struct sockaddr addr;
1622 socklen_t from_len = sizeof (sa);
1624 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
1625 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
1626 if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
1627 &sa.storage, &from_len) !=
1628 STUN_MESSAGE_RETURN_SUCCESS)
1631 if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
1632 &sa.storage, &from_len) !=
1633 STUN_MESSAGE_RETURN_SUCCESS)
1637 data = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_DATA,
1643 nice_address_set_from_sockaddr (from, &sa.addr);
1645 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766 &&
1646 !priv_has_permission_for_peer (priv, from)) {
1647 if (!priv_has_sent_permission_for_peer (priv, from)) {
1648 priv_send_create_permission (priv, from);
1653 memmove (buf, data, len > data_len ? data_len : len);
1654 g_mutex_unlock (&mutex);
1655 return len > data_len ? data_len : len;
1663 for (l = priv->channels; l; l = l->next) {
1664 ChannelBinding *b = l->data;
1665 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
1666 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
1667 if (b->channel == ntohs(recv_buf.u16[0])) {
1668 recv_len = ntohs (recv_buf.u16[1]);
1669 recv_buf.u8 += sizeof(uint32_t);
1680 *from = binding->peer;
1686 memmove (buf, recv_buf.u8, len > recv_len ? recv_len : len);
1687 g_mutex_unlock (&mutex);
1688 return len > recv_len ? recv_len : len;
1692 if (priv->current_binding) {
1693 GList *i = priv->channels;
1694 for (; i; i = i->next) {
1695 ChannelBinding *b = i->data;
1698 g_list_free (priv->channels);
1699 priv->channels = g_list_append (NULL, priv->current_binding);
1700 priv->current_binding = NULL;
1701 priv_process_pending_bindings (priv);
1705 g_mutex_unlock (&mutex);
1710 nice_udp_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer)
1715 g_mutex_lock (&mutex);
1717 priv = (UdpTurnPriv *) sock->priv;
1719 ret = priv_add_channel_binding (priv, peer);
1721 g_mutex_unlock (&mutex);
1727 priv_process_pending_bindings (UdpTurnPriv *priv)
1729 gboolean ret = FALSE;
1731 while (priv->pending_bindings != NULL && ret == FALSE) {
1732 NiceAddress *peer = priv->pending_bindings->data;
1733 ret = priv_add_channel_binding (priv, peer);
1734 priv->pending_bindings = g_list_remove (priv->pending_bindings, peer);
1735 nice_address_free (peer);
1738 /* If no new channel bindings are in progress and there are no
1739 pending bindings, then renew the soon to be expired bindings */
1740 if (priv->pending_bindings == NULL && priv->current_binding_msg == NULL) {
1743 /* find binding to renew */
1744 for (i = priv->channels ; i; i = i->next) {
1745 ChannelBinding *b = i->data;
1747 priv_send_channel_bind (priv, b->channel, &b->peer);
1756 priv_retransmissions_tick_unlocked (UdpTurnPriv *priv)
1758 gboolean ret = FALSE;
1760 if (priv->current_binding_msg) {
1761 switch (stun_timer_refresh (&priv->current_binding_msg->timer)) {
1762 case STUN_USAGE_TIMER_RETURN_TIMEOUT:
1765 StunTransactionId id;
1767 stun_message_id (&priv->current_binding_msg->message, id);
1768 stun_agent_forget_transaction (&priv->agent, id);
1770 g_free (priv->current_binding);
1771 priv->current_binding = NULL;
1772 g_free (priv->current_binding_msg);
1773 priv->current_binding_msg = NULL;
1776 priv_process_pending_bindings (priv);
1779 case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
1781 _socket_send_wrapped (priv->base_socket, &priv->server_addr,
1782 stun_message_length (&priv->current_binding_msg->message),
1783 (gchar *)priv->current_binding_msg->buffer, FALSE);
1786 case STUN_USAGE_TIMER_RETURN_SUCCESS:
1790 /* Nothing to do. */
1796 priv_schedule_tick (priv);
1801 priv_retransmissions_create_permission_tick_unlocked (UdpTurnPriv *priv, GList *list_element)
1803 gboolean ret = FALSE;
1804 TURNMessage *current_create_permission_msg;
1806 current_create_permission_msg = (TURNMessage *)list_element->data;
1808 if (current_create_permission_msg) {
1809 switch (stun_timer_refresh (¤t_create_permission_msg->timer)) {
1810 case STUN_USAGE_TIMER_RETURN_TIMEOUT:
1813 StunTransactionId id;
1816 struct sockaddr_storage storage;
1817 struct sockaddr addr;
1819 socklen_t addr_len = sizeof(addr);
1821 stun_message_id (¤t_create_permission_msg->message, id);
1822 stun_agent_forget_transaction (&priv->agent, id);
1823 stun_message_find_xor_addr (
1824 ¤t_create_permission_msg->message,
1825 STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &addr.storage, &addr_len);
1826 nice_address_set_from_sockaddr (&to, &addr.addr);
1828 priv_remove_sent_permission_for_peer (priv, &to);
1829 priv->pending_permissions = g_list_delete_link (
1830 priv->pending_permissions, list_element);
1831 g_free (current_create_permission_msg);
1832 current_create_permission_msg = NULL;
1834 /* we got a timeout when retransmitting a CreatePermission
1835 message, assume we can just send the data, the server
1836 might not support RFC TURN, or connectivity check will
1837 fail eventually anyway */
1838 priv_add_permission_for_peer (priv, &to);
1840 socket_dequeue_all_data (priv, &to);
1844 case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
1846 _socket_send_wrapped (priv->base_socket, &priv->server_addr,
1847 stun_message_length (¤t_create_permission_msg->message),
1848 (gchar *)current_create_permission_msg->buffer, FALSE);
1851 case STUN_USAGE_TIMER_RETURN_SUCCESS:
1855 /* Nothing to do. */
1864 priv_retransmissions_tick (gpointer pointer)
1866 UdpTurnPriv *priv = pointer;
1868 g_mutex_lock (&mutex);
1869 if (g_source_is_destroyed (g_main_current_source ())) {
1870 nice_debug ("Source was destroyed. Avoided race condition in "
1871 "udp-turn.c:priv_permission_timeout");
1873 g_mutex_unlock (&mutex);
1874 return G_SOURCE_REMOVE;
1877 if (priv_retransmissions_tick_unlocked (priv) == FALSE) {
1878 if (priv->tick_source_channel_bind != NULL) {
1879 g_source_destroy (priv->tick_source_channel_bind);
1880 g_source_unref (priv->tick_source_channel_bind);
1881 priv->tick_source_channel_bind = NULL;
1885 g_mutex_unlock (&mutex);
1887 return G_SOURCE_REMOVE;
1891 priv_retransmissions_create_permission_tick (gpointer pointer)
1893 UdpTurnPriv *priv = pointer;
1895 g_mutex_lock (&mutex);
1896 if (g_source_is_destroyed (g_main_current_source ())) {
1897 nice_debug ("Source was destroyed. Avoided race condition in "
1898 "udp-turn.c:priv_permission_timeout");
1900 g_mutex_unlock (&mutex);
1901 return G_SOURCE_REMOVE;
1904 /* This will call priv_retransmissions_create_permission_tick_unlocked() for
1905 * every pending permission with an expired timer and will create a new timer
1906 * if there are pending permissions that require it */
1907 priv_schedule_tick (priv);
1909 g_mutex_unlock (&mutex);
1911 return G_SOURCE_REMOVE;
1915 priv_schedule_tick (UdpTurnPriv *priv)
1917 GList *i, *next, *prev;
1918 TURNMessage *current_create_permission_msg;
1919 guint min_timeout = G_MAXUINT;
1921 if (priv->tick_source_channel_bind != NULL) {
1922 g_source_destroy (priv->tick_source_channel_bind);
1923 g_source_unref (priv->tick_source_channel_bind);
1924 priv->tick_source_channel_bind = NULL;
1927 if (priv->current_binding_msg) {
1928 guint timeout = stun_timer_remainder (&priv->current_binding_msg->timer);
1930 priv->tick_source_channel_bind =
1931 priv_timeout_add_with_context (priv, timeout,
1932 priv_retransmissions_tick, priv);
1934 priv_retransmissions_tick_unlocked (priv);
1938 if (priv->tick_source_create_permission != NULL) {
1939 g_source_destroy (priv->tick_source_create_permission);
1940 g_source_unref (priv->tick_source_create_permission);
1941 priv->tick_source_create_permission = NULL;
1944 for (i = priv->pending_permissions, prev = NULL; i; i = next) {
1947 current_create_permission_msg = (TURNMessage *)i->data;
1950 timeout = stun_timer_remainder (¤t_create_permission_msg->timer);
1953 min_timeout = MIN (min_timeout, timeout);
1956 /* This could either delete the permission from the list, or it could
1957 * refresh it, changing its timeout value */
1958 priv_retransmissions_create_permission_tick_unlocked (priv, i);
1960 next = priv->pending_permissions;
1966 /* We create one timer for the minimal timeout we need */
1967 if (min_timeout != G_MAXUINT) {
1968 priv->tick_source_create_permission =
1969 priv_timeout_add_with_context (priv, min_timeout,
1970 priv_retransmissions_create_permission_tick,
1976 priv_send_turn_message (UdpTurnPriv *priv, TURNMessage *msg)
1978 size_t stun_len = stun_message_length (&msg->message);
1980 if (priv->current_binding_msg) {
1981 g_free (priv->current_binding_msg);
1982 priv->current_binding_msg = NULL;
1985 if (nice_socket_is_reliable (priv->base_socket)) {
1986 _socket_send_wrapped (priv->base_socket, &priv->server_addr,
1987 stun_len, (gchar *)msg->buffer, TRUE);
1988 stun_timer_start_reliable (&msg->timer,
1989 STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT);
1991 if (_socket_send_wrapped (priv->base_socket, &priv->server_addr,
1992 stun_len, (gchar *)msg->buffer, TRUE) < 0)
1993 _socket_send_wrapped (priv->base_socket, &priv->server_addr,
1994 stun_len, (gchar *)msg->buffer, FALSE);
1995 stun_timer_start (&msg->timer, STUN_TIMER_DEFAULT_TIMEOUT,
1996 STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);
1999 priv->current_binding_msg = msg;
2000 priv_schedule_tick (priv);
2004 priv_send_create_permission(UdpTurnPriv *priv,
2005 const NiceAddress *peer)
2008 gboolean res = FALSE;
2009 TURNMessage *msg = g_new0 (TURNMessage, 1);
2011 struct sockaddr_storage storage;
2012 struct sockaddr addr;
2015 /* register this peer as being pening a permission (if not already pending) */
2016 if (!priv_has_sent_permission_for_peer (priv, peer)) {
2017 priv_add_sent_permission_for_peer (priv, peer);
2020 nice_address_copy_to_sockaddr (peer, &addr.addr);
2022 /* send CreatePermission */
2023 msg_buf_len = stun_usage_turn_create_permission(&priv->agent, &msg->message,
2025 sizeof(msg->buffer),
2030 priv->cached_realm, priv->cached_realm_len,
2031 priv->cached_nonce, priv->cached_nonce_len,
2033 STUN_USAGE_TURN_COMPATIBILITY_RFC5766);
2035 if (msg_buf_len > 0) {
2036 if (nice_socket_is_reliable (priv->base_socket)) {
2037 res = _socket_send_wrapped (priv->base_socket, &priv->server_addr,
2038 msg_buf_len, (gchar *) msg->buffer, TRUE);
2040 res = _socket_send_wrapped (priv->base_socket, &priv->server_addr,
2041 msg_buf_len, (gchar *) msg->buffer, TRUE);
2043 res = _socket_send_wrapped (priv->base_socket, &priv->server_addr,
2044 msg_buf_len, (gchar *) msg->buffer, FALSE);
2047 if (nice_socket_is_reliable (priv->base_socket)) {
2048 stun_timer_start_reliable (&msg->timer,
2049 STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT);
2051 stun_timer_start (&msg->timer, STUN_TIMER_DEFAULT_TIMEOUT,
2052 STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);
2055 priv->pending_permissions = g_list_append (priv->pending_permissions, msg);
2056 priv_schedule_tick (priv);
2065 priv_send_channel_bind (UdpTurnPriv *priv, uint16_t channel,
2066 const NiceAddress *peer)
2068 uint32_t channel_attr = channel << 16;
2071 struct sockaddr_storage storage;
2072 struct sockaddr addr;
2074 TURNMessage *msg = g_new0 (TURNMessage, 1);
2076 nice_address_copy_to_sockaddr (peer, &sa.addr);
2078 if (!stun_agent_init_request (&priv->agent, &msg->message,
2079 msg->buffer, sizeof(msg->buffer),
2080 STUN_CHANNELBIND)) {
2085 if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_CHANNEL_NUMBER,
2086 channel_attr) != STUN_MESSAGE_RETURN_SUCCESS) {
2091 if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS,
2094 != STUN_MESSAGE_RETURN_SUCCESS) {
2099 if (priv->username != NULL && priv->username_len > 0 &&
2100 priv->cached_realm != NULL && priv->cached_realm_len > 0 &&
2101 priv->cached_nonce != NULL && priv->cached_nonce_len > 0) {
2103 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
2104 priv->username, priv->username_len)
2105 != STUN_MESSAGE_RETURN_SUCCESS) {
2110 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_REALM,
2111 priv->cached_realm, priv->cached_realm_len)
2112 != STUN_MESSAGE_RETURN_SUCCESS) {
2117 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_NONCE,
2118 priv->cached_nonce, priv->cached_nonce_len)
2119 != STUN_MESSAGE_RETURN_SUCCESS) {
2125 stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
2126 priv->password, priv->password_len);
2129 priv_send_turn_message (priv, msg);
2138 priv_add_channel_binding (UdpTurnPriv *priv, const NiceAddress *peer)
2142 struct sockaddr_storage storage;
2143 struct sockaddr addr;
2146 nice_address_copy_to_sockaddr (peer, &sa.addr);
2148 if (priv->current_binding) {
2149 NiceAddress * pending= nice_address_new ();
2151 priv->pending_bindings = g_list_append (priv->pending_bindings, pending);
2155 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
2156 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
2157 uint16_t channel = 0x4000;
2158 GList *i = priv->channels;
2159 for (; i; i = i->next) {
2160 ChannelBinding *b = i->data;
2161 if (channel == b->channel) {
2168 if (channel >= 0x4000 && channel < 0xffff) {
2169 gboolean ret = priv_send_channel_bind (priv, channel, peer);
2171 priv->current_binding = g_new0 (ChannelBinding, 1);
2172 priv->current_binding->channel = channel;
2173 priv->current_binding->peer = *peer;
2178 } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN ||
2179 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
2180 TURNMessage *msg = g_new0 (TURNMessage, 1);
2181 if (!stun_agent_init_request (&priv->agent, &msg->message,
2182 msg->buffer, sizeof(msg->buffer),
2183 STUN_OLD_SET_ACTIVE_DST)) {
2188 if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_MAGIC_COOKIE,
2190 != STUN_MESSAGE_RETURN_SUCCESS) {
2195 if (priv->username != NULL && priv->username_len > 0) {
2196 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
2197 priv->username, priv->username_len)
2198 != STUN_MESSAGE_RETURN_SUCCESS) {
2204 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
2205 if (priv->ms_connection_id_valid)
2206 stun_message_append_ms_connection_id(&msg->message,
2207 priv->ms_connection_id, ++priv->ms_sequence_num);
2209 stun_message_ensure_ms_realm(&msg->message, priv->ms_realm);
2212 if (stun_message_append_addr (&msg->message,
2213 STUN_ATTRIBUTE_DESTINATION_ADDRESS,
2214 &sa.addr, sizeof(sa))
2215 != STUN_MESSAGE_RETURN_SUCCESS) {
2220 stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
2221 priv->password, priv->password_len);
2224 priv->current_binding = g_new0 (ChannelBinding, 1);
2225 priv->current_binding->channel = 0;
2226 priv->current_binding->peer = *peer;
2227 priv_send_turn_message (priv, msg);
2232 } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
2233 priv->current_binding = g_new0 (ChannelBinding, 1);
2234 priv->current_binding->channel = 0;
2235 priv->current_binding->peer = *peer;
2245 nice_udp_turn_socket_set_ms_realm(NiceSocket *sock, StunMessage *msg)
2247 UdpTurnPriv *priv = (UdpTurnPriv *)sock->priv;
2249 const uint8_t *realm = stun_message_find(msg, STUN_ATTRIBUTE_REALM, &alen);
2251 if (realm && alen <= STUN_MAX_MS_REALM_LEN) {
2252 g_mutex_lock (&mutex);
2253 memcpy(priv->ms_realm, realm, alen);
2254 priv->ms_realm[alen] = '\0';
2255 g_mutex_unlock (&mutex);
2260 nice_udp_turn_socket_set_ms_connection_id (NiceSocket *sock, StunMessage *msg)
2262 UdpTurnPriv *priv = (UdpTurnPriv *)sock->priv;
2264 const uint8_t *ms_seq_num = stun_message_find(msg,
2265 STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER, &alen);
2268 if (ms_seq_num && alen == 24) {
2269 g_mutex_lock (&mutex);
2270 memcpy (priv->ms_connection_id, ms_seq_num, 20);
2271 priv->ms_sequence_num = ntohl((uint32_t)*(ms_seq_num + 20));
2272 priv->ms_connection_id_valid = TRUE;
2273 g_mutex_unlock (&mutex);