Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / socket / udp-turn.c
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2008 Collabora Ltd.
5  *  Contact: Youness Alaoui
6  * (C) 2008 Nokia Corporation
7  *
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/
12  *
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
16  * License.
17  *
18  * The Original Code is the Nice GLib ICE library.
19  *
20  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21  * Corporation. All Rights Reserved.
22  *
23  * Contributors:
24  *   Youness Alaoui, Collabora Ltd.
25  *
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.
35  */
36
37 /*
38  * Implementation of TURN
39  */
40 #ifdef HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include <string.h>
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <stdlib.h>
48
49 #include "udp-turn.h"
50 #include "stun/stunagent.h"
51 #include "stun/usages/timer.h"
52 #include "agent-priv.h"
53
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 */
59
60 static GMutex mutex;
61
62 typedef struct {
63   StunMessage message;
64   uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
65   StunTimer timer;
66 } TURNMessage;
67
68 typedef struct {
69   NiceAddress peer;
70   uint16_t channel;
71   gboolean renew;
72   GSource *timeout_source;
73 } ChannelBinding;
74
75 typedef struct {
76   GMainContext *ctx;
77   StunAgent agent;
78   GList *channels;
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;
87   uint8_t *username;
88   gsize username_len;
89   uint8_t *password;
90   gsize password_len;
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
102                                            permissions */
103
104   guint8 *cached_realm;
105   uint16_t cached_realm_len;
106   guint8 *cached_nonce;
107   uint16_t cached_nonce_len;
108
109   GByteArray *fragment_buffer;
110   NiceAddress from;
111 } UdpTurnPriv;
112
113
114 typedef struct {
115   StunTransactionId id;
116   GSource *source;
117   UdpTurnPriv *priv;
118 } SendRequest;
119
120 /* used to store data sent while obtaining a permission */
121 typedef struct {
122   gchar *data;
123   guint data_len;
124   gboolean reliable;
125 } SendData;
126
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);
139
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,
148     uint16_t channel,
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);
154
155 static void
156 send_request_free (SendRequest *r)
157 {
158     g_source_destroy (r->source);
159     g_source_unref (r->source);
160
161     stun_agent_forget_transaction (&r->priv->agent, r->id);
162
163     g_slice_free (SendRequest, r);
164 }
165
166 static guint
167 priv_nice_address_hash (gconstpointer data)
168 {
169   gchar address[NICE_ADDRESS_STRING_LEN];
170
171   nice_address_to_string ((NiceAddress *) data, address);
172
173   return g_str_hash(address);
174 }
175
176 static void
177 priv_send_data_queue_destroy (gpointer user_data)
178 {
179   GQueue *send_queue = (GQueue *) user_data;
180   GList *i;
181
182   for (i = g_queue_peek_head_link (send_queue); i; i = i->next) {
183     SendData *data = (SendData *) i->data;
184
185     g_free (data->data);
186     g_slice_free (SendData, data);
187   }
188   g_queue_free (send_queue);
189 }
190
191 NiceSocket *
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)
196 {
197   UdpTurnPriv *priv;
198   NiceSocket *sock = g_slice_new0 (NiceSocket);
199
200   if (!sock) {
201     return NULL;
202   }
203
204   priv = g_new0 (UdpTurnPriv, 1);
205
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);
226   }
227
228   priv->channels = NULL;
229   priv->current_binding = NULL;
230   priv->base_socket = base_socket;
231   if (ctx)
232     priv->ctx = g_main_context_ref (ctx);
233
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);
238   } else {
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;
244     } else {
245       priv->password = (uint8_t *)g_strdup (password);
246       priv->password_len = (gsize) strlen (password);
247     }
248   }
249   priv->server_addr = *server_addr;
250   priv->compatibility = compatibility;
251   priv->send_requests = g_queue_new ();
252
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);
258
259   sock->type = NICE_SOCKET_TYPE_UDP_TURN;
260   sock->fileno = NULL;
261   sock->addr = *addr;
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;
271
272   return sock;
273 }
274
275
276
277 static void
278 socket_close (NiceSocket *sock)
279 {
280   UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
281   GList *i = NULL;
282
283   g_mutex_lock (&mutex);
284
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);
290     }
291     g_free (b);
292   }
293   g_list_free (priv->channels);
294
295   g_list_free_full (priv->pending_bindings, (GDestroyNotify) nice_address_free);
296
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;
301   }
302
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;
307   }
308
309   g_queue_free_full (priv->send_requests, (GDestroyNotify) send_request_free);
310
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);
314
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;
319   }
320
321   if (priv->ctx)
322     g_main_context_unref (priv->ctx);
323
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);
331
332   if (priv->fragment_buffer) {
333     g_byte_array_free(priv->fragment_buffer, TRUE);
334   }
335
336   g_free (priv);
337
338   sock->priv = NULL;
339
340   g_mutex_unlock (&mutex);
341 }
342
343 static gint
344 socket_recv_messages (NiceSocket *sock,
345     NiceInputMessage *recv_messages, guint n_recv_messages)
346 {
347   UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
348   gint n_messages;
349   gint n_output_messages = 0;
350   guint i;
351   gboolean error = FALSE;
352
353   /* Make sure socket has not been freed: */
354   g_assert (sock->priv != NULL);
355
356   nice_debug_verbose ("received message on TURN socket");
357
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;
363
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);
366
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. */
370         break;
371       }
372
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;
377
378       f_buffer += msg_len;
379       f_buffer_len -= msg_len;
380       ++n_output_messages;
381     }
382
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;
386
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;
393     }
394   }
395
396   n_messages = nice_socket_recv_messages (priv->base_socket,
397       recv_messages, n_recv_messages);
398
399   if (n_messages < 0)
400     return n_messages;
401
402   /* Process all the messages. Those which fail parsing are re-used for the next
403    * message.
404    *
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];
411     NiceSocket *dummy;
412     NiceAddress from;
413     guint8 *buffer;
414     gsize buffer_length;
415     gint parsed_buffer_length;
416     gboolean allocated_buffer = FALSE;
417
418     if (message->length == 0)
419       continue;
420
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;
429     } else {
430       nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC);
431
432       buffer = compact_input_message (message, &buffer_length);
433       allocated_buffer = TRUE;
434     }
435
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);
441
442     if (parsed_buffer_length < 0) {
443       error = TRUE;
444     } else if (parsed_buffer_length > 0) {
445       *message->from = from;
446     }
447     /* parsed_buffer_length == 0 means this is a TURN control message which
448      * needs ignoring. */
449
450     if (nice_socket_is_reliable (sock) && parsed_buffer_length > 0) {
451       /* Determine the portion of the current NiceInputMessage we can already
452        * return. */
453       gint32 msg_len = 0;
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. */
459           msg_len = 0;
460         }
461       }
462
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. */
466         gint j;
467         guint buffer_len = 0;
468
469         for (j = i; j < n_messages; ++j) {
470           buffer_len += recv_messages[j].length;
471         }
472         priv->fragment_buffer = g_byte_array_sized_new (buffer_len);
473       }
474
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);
480
481         parsed_buffer_length = msg_len;
482         message->length = msg_len;
483         priv->from = from;
484       }
485     }
486
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);
491     }
492
493     if (allocated_buffer)
494       g_free (buffer);
495
496     if (error)
497       break;
498
499     ++n_output_messages;
500   }
501
502   /* Was there an error processing the first message? */
503   if (error && i == 0)
504     return -1;
505
506   return n_output_messages;
507 }
508
509 /* interval is given in milliseconds */
510 static GSource *
511 priv_timeout_add_with_context (UdpTurnPriv *priv, guint interval,
512     GSourceFunc function, gpointer data)
513 {
514   GSource *source = NULL;
515
516   g_return_val_if_fail (function != NULL, NULL);
517
518   source = g_timeout_source_new (interval);
519
520   g_source_set_callback (source, function, data, NULL);
521   g_source_attach (source, priv->ctx);
522
523   return source;
524 }
525
526 /* interval is given in seconds */
527 static GSource *
528 priv_timeout_add_seconds_with_context (UdpTurnPriv *priv, guint interval,
529     GSourceFunc function, gpointer data)
530 {
531   GSource *source = NULL;
532
533   g_return_val_if_fail (function != NULL, NULL);
534
535   source = g_timeout_source_new_seconds (interval);
536
537   g_source_set_callback (source, function, data, NULL);
538   g_source_attach (source, priv->ctx);
539
540   return source;
541 }
542
543 static StunMessageReturn
544 stun_message_append_ms_connection_id(StunMessage *msg,
545     uint8_t *ms_connection_id, uint32_t ms_sequence_num)
546 {
547   union {
548     uint8_t buf8[24];
549     uint32_t buf32[24/4];
550   } buf;
551
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,
555       buf.buf8, 24);
556 }
557
558 static void
559 stun_message_ensure_ms_realm(StunMessage *msg, uint8_t *realm)
560 {
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));
570   }
571 }
572
573 static gboolean
574 priv_is_peer_in_list (const GList *list, const NiceAddress *peer)
575 {
576   const GList *iter;
577
578   for (iter = list ; iter ; iter = g_list_next (iter)) {
579     NiceAddress *address = (NiceAddress *) iter->data;
580
581     if (nice_address_equal (address, peer))
582       return TRUE;
583   }
584
585   return FALSE;
586 }
587
588 static gboolean
589 priv_has_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
590 {
591   return priv_is_peer_in_list (priv->permissions, peer);
592 }
593
594 static gboolean
595 priv_has_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
596 {
597   return priv_is_peer_in_list (priv->sent_permissions, peer);
598 }
599
600 static void
601 priv_add_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
602 {
603   priv->permissions =
604       g_list_append (priv->permissions, nice_address_dup (peer));
605 }
606
607 static void
608 priv_add_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
609 {
610   priv->sent_permissions =
611       g_list_append (priv->sent_permissions, nice_address_dup (peer));
612 }
613
614 static GList *
615 priv_remove_peer_from_list (GList *list, const NiceAddress *peer)
616 {
617   GList *iter;
618
619   for (iter = list ; iter ; iter = g_list_next (iter)) {
620     NiceAddress *address = (NiceAddress *) iter->data;
621
622     if (nice_address_equal (address, peer)) {
623       GList *prev = iter->prev;
624
625       nice_address_free (address);
626       list = g_list_delete_link (list, iter);
627       iter = prev;
628       if (iter)
629         iter = list;
630     }
631   }
632
633   return list;
634 }
635
636 static void
637 priv_remove_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer)
638 {
639   priv->sent_permissions =
640       priv_remove_peer_from_list (priv->sent_permissions, peer);
641 }
642
643 static void
644 priv_clear_permissions (UdpTurnPriv *priv)
645 {
646   g_list_free_full (priv->permissions, (GDestroyNotify) nice_address_free);
647   priv->permissions = NULL;
648 }
649
650 static gint
651 _socket_send_messages_wrapped (NiceSocket *sock, const NiceAddress *to,
652     const NiceOutputMessage *messages, guint n_messages, gboolean reliable)
653 {
654   if (!nice_socket_is_reliable (sock)) {
655     if (reliable)
656       return nice_socket_send_messages_reliable (sock, to, messages, n_messages);
657     else
658       return nice_socket_send_messages (sock, to, messages, n_messages);
659   } else {
660     GOutputVector *local_bufs;
661     NiceOutputMessage local_message;
662     const NiceOutputMessage *message;
663     gsize message_len;
664     guint n_bufs = 0;
665     guint16 rfc4571_frame;
666     guint i;
667     gint ret;
668
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);
673
674     /* ICE-TCP requires that all packets be framed with RFC4571 */
675
676     /* Count the number of buffers. */
677     if (message->n_buffers == -1) {
678       for (i = 0; message->buffers[i].buffer != NULL; i++)
679         n_bufs++;
680     } else {
681       n_bufs = message->n_buffers;
682     }
683
684     local_bufs = g_alloca ((n_bufs + 1) * sizeof (GOutputVector));
685     local_message.buffers = local_bufs;
686     local_message.n_buffers = n_bufs + 1;
687
688     rfc4571_frame = htons (message_len);
689     local_bufs[0].buffer = &rfc4571_frame;
690     local_bufs[0].size = sizeof (guint16);
691
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;
695     }
696
697
698     if (reliable)
699       ret = nice_socket_send_messages_reliable (sock, to,
700           &local_message, 1);
701     else
702       ret = nice_socket_send_messages (sock, to, &local_message, 1);
703
704     if (ret == 1)
705       ret = message_len;
706
707     return ret;
708   }
709 }
710
711 static gssize
712 _socket_send_wrapped (NiceSocket *sock, const NiceAddress *to,
713     guint len, const gchar *buf, gboolean reliable)
714 {
715   gint ret;
716
717   if (!nice_socket_is_reliable (sock)) {
718     GOutputVector local_buf = { buf, len };
719     NiceOutputMessage local_message = { &local_buf, 1};
720
721     ret = _socket_send_messages_wrapped (sock, to, &local_message, 1, reliable);
722     if (ret == 1)
723       return len;
724     return ret;
725   } else {
726     guint16 rfc4571_frame = htons (len);
727     GOutputVector local_buf[2] = {{&rfc4571_frame, 2}, { buf, len }};
728     NiceOutputMessage local_message = { local_buf, 2};
729
730     if (reliable)
731       ret = nice_socket_send_messages_reliable (sock, to, &local_message, 1);
732     else
733       ret = nice_socket_send_messages (sock, to, &local_message, 1);
734
735     if (ret == 1)
736       return len;
737     return ret;
738   }
739 }
740
741 static void
742 socket_enqueue_data(UdpTurnPriv *priv, const NiceAddress *to,
743     guint len, const gchar *buf, gboolean reliable)
744 {
745   SendData *data = g_slice_new0 (SendData);
746   GQueue *queue = g_hash_table_lookup (priv->send_data_queues, to);
747
748   if (queue == NULL) {
749     queue = g_queue_new ();
750     g_hash_table_insert (priv->send_data_queues, nice_address_dup (to),
751         queue);
752   }
753
754   data->data = g_memdup(buf, len);
755   data->data_len = len;
756   data->reliable = reliable;
757   g_queue_push_tail (queue, data);
758 }
759
760 static void
761 socket_dequeue_all_data (UdpTurnPriv *priv, const NiceAddress *to)
762 {
763   GQueue *send_queue = g_hash_table_lookup (priv->send_data_queues, to);
764
765   if (send_queue) {
766     while (!g_queue_is_empty (send_queue)) {
767       SendData *data =
768           (SendData *) g_queue_pop_head(send_queue);
769
770       nice_debug_verbose ("dequeuing data");
771       _socket_send_wrapped (priv->base_socket, &priv->server_addr,
772           data->data_len, data->data, data->reliable);
773
774       g_free (data->data);
775       g_slice_free (SendData, data);
776     }
777
778     /* remove queue from table */
779     g_hash_table_remove (priv->send_data_queues, to);
780   }
781 }
782
783
784 static gssize
785 socket_send_message (NiceSocket *sock, const NiceAddress *to,
786     const NiceOutputMessage *message, gboolean reliable)
787 {
788   UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
789   StunMessage msg;
790   uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
791   size_t msg_len;
792   union {
793     struct sockaddr_storage storage;
794     struct sockaddr addr;
795   } sa;
796   GList *i;
797   ChannelBinding *binding = NULL;
798   gint ret;
799
800   /* Make sure socket has not been freed: */
801   g_assert (sock->priv != NULL);
802
803   for (i = priv->channels; i; i = i->next) {
804     ChannelBinding *b = i->data;
805     if (nice_address_equal (&b->peer, to)) {
806       binding = b;
807       break;
808     }
809   }
810
811   nice_address_copy_to_sockaddr (to, &sa.addr);
812
813   if (binding) {
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);
817
818       if (message_len + sizeof(uint32_t) <= sizeof(buffer)) {
819         guint j;
820         uint16_t len16, channel16;
821         gsize message_offset = 0;
822
823         len16 = htons ((uint16_t) message_len);
824         channel16 = htons (binding->channel);
825
826         memcpy (buffer, &channel16, sizeof(uint16_t));
827         memcpy (buffer + sizeof(uint16_t), &len16, sizeof(uint16_t));
828
829         /* FIXME: Slow path! This should be replaced by code which manipulates
830          * the GOutputVector array, rather than the buffer contents
831          * themselves. */
832         for (j = 0;
833              (message->n_buffers >= 0 && j < (guint) message->n_buffers) ||
834              (message->n_buffers < 0 && message->buffers[j].buffer != NULL);
835              j++) {
836           const GOutputVector *out_buf = &message->buffers[j];
837           gsize out_len;
838
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;
843         }
844
845         msg_len = message_len + sizeof(uint32_t);
846       } else {
847         goto error;
848       }
849     } else {
850       ret = _socket_send_messages_wrapped (priv->base_socket,
851           &priv->server_addr, message, 1, reliable);
852
853       if (ret == 1)
854         return output_message_get_size (message);
855       return ret;
856     }
857   } else {
858     guint8 *compacted_buf;
859     gsize compacted_buf_len;
860
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))
865         goto error;
866       if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS,
867               &sa.storage, sizeof(sa)) !=
868           STUN_MESSAGE_RETURN_SUCCESS)
869         goto error;
870     } else {
871       if (!stun_agent_init_request (&priv->agent, &msg,
872               buffer, sizeof(buffer), STUN_SEND))
873         goto error;
874
875       if (stun_message_append32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
876               TURN_MAGIC_COOKIE) != STUN_MESSAGE_RETURN_SUCCESS)
877         goto error;
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)
882           goto error;
883       }
884       if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_DESTINATION_ADDRESS,
885               &sa.addr, sizeof(sa)) !=
886           STUN_MESSAGE_RETURN_SUCCESS)
887         goto error;
888
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)
894           goto error;
895       }
896     }
897
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)
901           goto error;
902
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)
907           goto error;
908
909       stun_message_ensure_ms_realm(&msg, priv->ms_realm);
910     }
911
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);
916
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);
920       goto error;
921     }
922
923     g_free (compacted_buf);
924
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);
931
932       req->priv = priv;
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);
937     }
938   }
939
940   if (msg_len > 0) {
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);
945       }
946
947       /* enque data */
948       nice_debug_verbose ("enqueuing data");
949       socket_enqueue_data(priv, to, msg_len, (gchar *)buffer, reliable);
950
951       return msg_len;
952     } else {
953       GOutputVector local_buf = { buffer, msg_len };
954       NiceOutputMessage local_message = {&local_buf, 1};
955
956       ret = _socket_send_messages_wrapped (priv->base_socket,
957           &priv->server_addr, &local_message, 1, reliable);
958
959       if (ret == 1)
960         return msg_len;
961       return ret;
962     }
963   }
964
965   /* Error condition pass through to the base socket. */
966   ret = _socket_send_messages_wrapped (priv->base_socket, to, message, 1,
967       reliable);
968   if (ret == 1)
969     return output_message_get_size (message);
970   return ret;
971 error:
972   return -1;
973 }
974
975 static gint
976 socket_send_messages (NiceSocket *sock, const NiceAddress *to,
977     const NiceOutputMessage *messages, guint n_messages)
978 {
979   guint i;
980
981   g_mutex_lock (&mutex);
982
983   /* Make sure socket has not been freed: */
984   g_assert (sock->priv != NULL);
985
986   for (i = 0; i < n_messages; i++) {
987     const NiceOutputMessage *message = &messages[i];
988     gssize len;
989
990     len = socket_send_message (sock, to, message, FALSE);
991
992     if (len < 0) {
993       /* Error. */
994       if (i > 0)
995         break;
996       g_mutex_unlock (&mutex);
997       return len;
998     } else if (len == 0) {
999       /* EWOULDBLOCK. */
1000       break;
1001     }
1002   }
1003
1004   g_mutex_unlock (&mutex);
1005
1006   return i;
1007 }
1008
1009 static gint
1010 socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to,
1011     const NiceOutputMessage *messages, guint n_messages)
1012 {
1013   UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
1014   guint i;
1015
1016   g_mutex_lock (&mutex);
1017
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.
1022    */
1023   if (priv->base_socket->type == NICE_SOCKET_TYPE_UDP_BSD) {
1024     g_mutex_unlock (&mutex);
1025     return -1;
1026   }
1027
1028   for (i = 0; i < n_messages; i++) {
1029     const NiceOutputMessage *message = &messages[i];
1030     gssize len;
1031
1032     len = socket_send_message (sock, to, message, TRUE);
1033
1034     if (len < 0) {
1035       /* Error. */
1036       g_mutex_unlock (&mutex);
1037       return len;
1038     } else if (len == 0) {
1039       /* EWOULDBLOCK. */
1040       break;
1041     }
1042   }
1043
1044   g_mutex_unlock (&mutex);
1045   return i;
1046 }
1047
1048 static gboolean
1049 socket_is_reliable (NiceSocket *sock)
1050 {
1051   UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
1052
1053   return nice_socket_is_reliable (priv->base_socket);
1054 }
1055
1056 static gboolean
1057 socket_can_send (NiceSocket *sock, NiceAddress *addr)
1058 {
1059   UdpTurnPriv *priv = sock->priv;
1060
1061   return nice_socket_can_send (priv->base_socket, addr);
1062 }
1063
1064 static void
1065 socket_set_writable_callback (NiceSocket *sock,
1066     NiceSocketWritableCb callback, gpointer user_data)
1067 {
1068   UdpTurnPriv *priv = sock->priv;
1069
1070   nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
1071 }
1072
1073 static gboolean
1074 socket_is_based_on (NiceSocket *sock, NiceSocket *other)
1075 {
1076   UdpTurnPriv *priv = sock->priv;
1077
1078   return (sock == other) ||
1079       (priv && nice_socket_is_based_on (priv->base_socket, other));
1080 }
1081
1082 static gboolean
1083 priv_forget_send_request_timeout (gpointer pointer)
1084 {
1085   SendRequest *req = pointer;
1086
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;
1093   }
1094
1095   send_request_free (req);
1096   g_queue_remove (req->priv->send_requests, req);
1097
1098   g_mutex_unlock (&mutex);
1099
1100   return G_SOURCE_REMOVE;
1101 }
1102
1103 static gboolean
1104 priv_permission_timeout (gpointer data)
1105 {
1106   UdpTurnPriv *priv = (UdpTurnPriv *) data;
1107
1108   nice_debug ("Permission is about to timeout, schedule renewal");
1109
1110   g_mutex_lock (&mutex);
1111
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");
1115
1116     g_mutex_unlock (&mutex);
1117     return G_SOURCE_REMOVE;
1118   }
1119
1120
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);
1125
1126   return TRUE;
1127 }
1128
1129 static gboolean
1130 priv_binding_expired_timeout (gpointer data)
1131 {
1132   UdpTurnPriv *priv = (UdpTurnPriv *) data;
1133   GList *i;
1134   GSource *source = NULL;
1135
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");
1140
1141     g_mutex_unlock (&mutex);
1142     return G_SOURCE_REMOVE;
1143   }
1144
1145   nice_debug ("Permission expired, refresh failed");
1146
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) {
1154         union {
1155           struct sockaddr_storage storage;
1156           struct sockaddr addr;
1157         } sa;
1158         socklen_t sa_len = sizeof(sa);
1159         NiceAddress to;
1160
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);
1166
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;
1172           break;
1173         }
1174       }
1175       /* In case the binding timed out before it could be processed, add it to
1176          the pending list */
1177       priv_add_channel_binding (priv, &b->peer);
1178       g_free (b);
1179       break;
1180     }
1181   }
1182
1183   g_mutex_unlock (&mutex);
1184   return G_SOURCE_REMOVE;
1185 }
1186
1187 static gboolean
1188 priv_binding_timeout (gpointer data)
1189 {
1190   UdpTurnPriv *priv = (UdpTurnPriv *) data;
1191   GList *i;
1192   GSource *source = NULL;
1193
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");
1198
1199     g_mutex_unlock (&mutex);
1200     return G_SOURCE_REMOVE;
1201   }
1202
1203   nice_debug ("Permission is about to timeout, sending binding renewal");
1204   source = g_main_current_source ();
1205
1206   /* find current binding and mark it for renewal */
1207   for (i = priv->channels ; i; i = i->next) {
1208     ChannelBinding *b = i->data;
1209
1210     if (b->timeout_source == source) {
1211       b->renew = TRUE;
1212
1213       /* Remove any existing timer */
1214       if (b->timeout_source) {
1215         g_source_destroy (b->timeout_source);
1216         g_source_unref (b->timeout_source);
1217       }
1218
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);
1222
1223       /* Send renewal */
1224       if (!priv->current_binding_msg)
1225         priv_send_channel_bind (priv, b->channel, &b->peer);
1226       break;
1227     }
1228   }
1229
1230   g_mutex_unlock (&mutex);
1231
1232   return G_SOURCE_REMOVE;
1233 }
1234
1235 static void
1236 nice_udp_turn_socket_cache_realm_nonce_locked (NiceSocket *sock,
1237     StunMessage *msg)
1238 {
1239   UdpTurnPriv *priv = sock->priv;
1240   gconstpointer tmp;
1241
1242   g_assert_cmpint (sock->type, ==, NICE_SOCKET_TYPE_UDP_TURN);
1243
1244   g_free (priv->cached_realm);
1245   priv->cached_realm = NULL;
1246   priv->cached_realm_len = 0;
1247
1248   g_free (priv->cached_nonce);
1249   priv->cached_nonce = NULL;
1250   priv->cached_nonce_len = 0;
1251
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);
1255
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);
1259
1260 }
1261
1262 void
1263 nice_udp_turn_socket_cache_realm_nonce (NiceSocket *sock,
1264     StunMessage *msg)
1265 {
1266   g_mutex_lock (&mutex);
1267   nice_udp_turn_socket_cache_realm_nonce_locked (sock, msg);
1268   g_mutex_unlock (&mutex);
1269 }
1270
1271 guint
1272 nice_udp_turn_socket_parse_recv_message (NiceSocket *sock, NiceSocket **from_sock,
1273     NiceInputMessage *message)
1274 {
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. */
1277   guint8 *buf;
1278   gsize buf_len, len;
1279
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);
1288
1289     g_assert_cmpuint (len, <=, message->length);
1290
1291     message->length = len;
1292
1293     return (len > 0) ? 1 : 0;
1294   }
1295
1296   /* Slow path. */
1297   nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC);
1298
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);
1304   g_free (buf);
1305
1306   return (len > 0) ? 1 : 0;
1307 }
1308
1309 gsize
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)
1313 {
1314
1315   UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv;
1316   StunValidationStatus valid;
1317   StunMessage msg;
1318   GList *l;
1319   ChannelBinding *binding = NULL;
1320
1321   union {
1322     const guint8 *u8;
1323     const guint16 *u16;
1324   } recv_buf;
1325
1326   g_mutex_lock (&mutex);
1327
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);
1333   } else {
1334     recv_buf.u8 = _recv_buf;
1335   }
1336
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);
1340
1341     if (valid == STUN_VALIDATION_SUCCESS) {
1342       if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 &&
1343           priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
1344         uint32_t cookie;
1345         if (stun_message_find32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
1346                 &cookie) != STUN_MESSAGE_RETURN_SUCCESS)
1347           goto recv;
1348         if (cookie != TURN_MAGIC_COOKIE)
1349           goto recv;
1350       }
1351
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;
1357
1358           stun_message_id (&msg, msg_id);
1359
1360           for (; i; i = i->next) {
1361             SendRequest *r = i->data;
1362             if (memcmp (&r->id, msg_id, sizeof(StunTransactionId)) == 0) {
1363               req = r;
1364               break;
1365             }
1366           }
1367
1368           if (req) {
1369             g_queue_remove (priv->send_requests, req);
1370             send_request_free (req);
1371           }
1372
1373           if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
1374             uint32_t opts = 0;
1375             if (stun_message_find32 (&msg, STUN_ATTRIBUTE_OPTIONS, &opts) ==
1376                 STUN_MESSAGE_RETURN_SUCCESS && opts & 0x1)
1377               goto msn_google_lock;
1378           }
1379         }
1380
1381         goto done;
1382       } else if (stun_message_get_method (&msg) == STUN_OLD_SET_ACTIVE_DST) {
1383         StunTransactionId request_id;
1384         StunTransactionId response_id;
1385
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;
1393
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;
1398             } else {
1399               g_free (priv->current_binding);
1400               priv->current_binding = NULL;
1401             }
1402           }
1403         }
1404
1405         goto done;
1406       } else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) {
1407         StunTransactionId request_id;
1408         StunTransactionId response_id;
1409
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) {
1415
1416             if (priv->current_binding) {
1417               /* New channel binding */
1418               binding = priv->current_binding;
1419             } else {
1420               /* Existing binding refresh */
1421               GList *i;
1422               union {
1423                 struct sockaddr_storage storage;
1424                 struct sockaddr addr;
1425               } sa;
1426               socklen_t sa_len = sizeof(sa);
1427               NiceAddress to;
1428
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);
1434
1435               for (i = priv->channels; i; i = i->next) {
1436                 ChannelBinding *b = i->data;
1437                 if (nice_address_equal (&b->peer, &to)) {
1438                   binding = b;
1439                   break;
1440                 }
1441               }
1442             }
1443
1444             if (stun_message_get_class (&msg) == STUN_ERROR) {
1445               int code = -1;
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;
1450
1451               sent_realm =
1452                   (uint8_t *) stun_message_find (
1453                       &priv->current_binding_msg->message,
1454                       STUN_ATTRIBUTE_REALM, &sent_realm_len);
1455               recv_realm =
1456                   (uint8_t *) stun_message_find (&msg,
1457                       STUN_ATTRIBUTE_REALM, &recv_realm_len);
1458
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)))) {
1470
1471                 g_free (priv->current_binding_msg);
1472                 priv->current_binding_msg = NULL;
1473                 nice_udp_turn_socket_cache_realm_nonce_locked (sock, &msg);
1474                 if (binding)
1475                   priv_send_channel_bind (priv, binding->channel,
1476                       &binding->peer);
1477               } else {
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);
1483               }
1484             } else if (stun_message_get_class (&msg) == STUN_RESPONSE) {
1485               g_free (priv->current_binding_msg);
1486               priv->current_binding_msg = NULL;
1487
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;
1493
1494               if (binding) {
1495                 binding->renew = FALSE;
1496
1497                 /* Remove any existing timer */
1498                 if (binding->timeout_source) {
1499                   g_source_destroy (binding->timeout_source);
1500                   g_source_unref (binding->timeout_source);
1501                 }
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);
1506               }
1507               priv_process_pending_bindings (priv);
1508             }
1509           }
1510         }
1511         goto done;
1512       } else if (stun_message_get_method (&msg) == STUN_CREATEPERMISSION) {
1513         StunTransactionId request_id;
1514         StunTransactionId response_id;
1515         GList *i, *next;
1516         TURNMessage *current_create_permission_msg;
1517
1518         for (i = priv->pending_permissions; i; i = next) {
1519           current_create_permission_msg = (TURNMessage *) i->data;
1520           next = i->next;
1521
1522           stun_message_id (&msg, response_id);
1523           stun_message_id (&current_create_permission_msg->message, request_id);
1524
1525           if (memcmp (request_id, response_id,
1526                   sizeof(StunTransactionId)) == 0) {
1527             union {
1528               struct sockaddr_storage storage;
1529               struct sockaddr addr;
1530             } peer;
1531             socklen_t peer_len = sizeof(peer);
1532             NiceAddress to;
1533             gchar tmpbuf[INET6_ADDRSTRLEN];
1534
1535             stun_message_find_xor_addr (
1536                 &current_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");
1544
1545             /* unathorized => resend with realm and nonce */
1546             if (stun_message_get_class (&msg) == STUN_ERROR) {
1547               int code = -1;
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;
1552
1553               sent_realm =
1554                   (uint8_t *) stun_message_find (
1555                       &current_create_permission_msg->message,
1556                       STUN_ATTRIBUTE_REALM, &sent_realm_len);
1557               recv_realm =
1558                   (uint8_t *) stun_message_find (&msg,
1559                       STUN_ATTRIBUTE_REALM, &recv_realm_len);
1560
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)))) {
1572
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;
1577
1578                 nice_udp_turn_socket_cache_realm_nonce_locked (sock, &msg);
1579                 /* resend CreatePermission */
1580                 priv_send_create_permission (priv, &to);
1581                 goto done;
1582               }
1583             }
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);
1590
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,
1598                       priv);
1599             }
1600
1601             /* send enqued data */
1602             socket_dequeue_all_data (priv, &to);
1603
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;
1608
1609             break;
1610           }
1611         }
1612
1613         goto done;
1614       } else if (stun_message_get_class (&msg) == STUN_INDICATION &&
1615           stun_message_get_method (&msg) == STUN_IND_DATA) {
1616         uint16_t data_len;
1617         uint8_t *data;
1618         union {
1619           struct sockaddr_storage storage;
1620           struct sockaddr addr;
1621         } sa;
1622         socklen_t from_len = sizeof (sa);
1623
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)
1629             goto recv;
1630         } else {
1631           if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
1632                   &sa.storage, &from_len) !=
1633               STUN_MESSAGE_RETURN_SUCCESS)
1634             goto recv;
1635         }
1636
1637         data = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_DATA,
1638             &data_len);
1639
1640         if (data == NULL)
1641           goto recv;
1642
1643         nice_address_set_from_sockaddr (from, &sa.addr);
1644
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);
1649           }
1650         }
1651
1652         *from_sock = sock;
1653         memmove (buf, data, len > data_len ? data_len : len);
1654         g_mutex_unlock (&mutex);
1655         return len > data_len ? data_len : len;
1656       } else {
1657         goto recv;
1658       }
1659     }
1660   }
1661
1662  recv:
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);
1670         binding = b;
1671         break;
1672       }
1673     } else {
1674       binding = b;
1675       break;
1676     }
1677   }
1678
1679   if (binding) {
1680     *from = binding->peer;
1681     *from_sock = sock;
1682   } else {
1683     *from = *recv_from;
1684   }
1685
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;
1689
1690  msn_google_lock:
1691
1692   if (priv->current_binding) {
1693     GList *i = priv->channels;
1694     for (; i; i = i->next) {
1695       ChannelBinding *b = i->data;
1696       g_free (b);
1697     }
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);
1702   }
1703
1704  done:
1705   g_mutex_unlock (&mutex);
1706   return 0;
1707 }
1708
1709 gboolean
1710 nice_udp_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer)
1711 {
1712   UdpTurnPriv *priv;
1713   gboolean ret;
1714
1715   g_mutex_lock (&mutex);
1716
1717   priv = (UdpTurnPriv *) sock->priv;
1718
1719   ret = priv_add_channel_binding (priv, peer);
1720
1721   g_mutex_unlock (&mutex);
1722
1723   return ret;
1724 }
1725
1726 static void
1727 priv_process_pending_bindings (UdpTurnPriv *priv)
1728 {
1729   gboolean ret = FALSE;
1730
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);
1736   }
1737
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) {
1741     GList *i = NULL;
1742
1743     /* find binding to renew */
1744     for (i = priv->channels ; i; i = i->next) {
1745       ChannelBinding *b = i->data;
1746       if (b->renew) {
1747         priv_send_channel_bind (priv, b->channel, &b->peer);
1748         break;
1749       }
1750     }
1751   }
1752 }
1753
1754
1755 static gboolean
1756 priv_retransmissions_tick_unlocked (UdpTurnPriv *priv)
1757 {
1758   gboolean ret = FALSE;
1759
1760   if (priv->current_binding_msg) {
1761     switch (stun_timer_refresh (&priv->current_binding_msg->timer)) {
1762       case STUN_USAGE_TIMER_RETURN_TIMEOUT:
1763         {
1764           /* Time out */
1765           StunTransactionId id;
1766
1767           stun_message_id (&priv->current_binding_msg->message, id);
1768           stun_agent_forget_transaction (&priv->agent, id);
1769
1770           g_free (priv->current_binding);
1771           priv->current_binding = NULL;
1772           g_free (priv->current_binding_msg);
1773           priv->current_binding_msg = NULL;
1774
1775
1776           priv_process_pending_bindings (priv);
1777           break;
1778         }
1779       case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
1780         /* 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);
1784         ret = TRUE;
1785         break;
1786       case STUN_USAGE_TIMER_RETURN_SUCCESS:
1787         ret = TRUE;
1788         break;
1789       default:
1790         /* Nothing to do. */
1791         break;
1792     }
1793   }
1794
1795   if (ret)
1796     priv_schedule_tick (priv);
1797   return ret;
1798 }
1799
1800 static gboolean
1801 priv_retransmissions_create_permission_tick_unlocked (UdpTurnPriv *priv, GList *list_element)
1802 {
1803   gboolean ret = FALSE;
1804   TURNMessage *current_create_permission_msg;
1805
1806   current_create_permission_msg = (TURNMessage *)list_element->data;
1807
1808   if (current_create_permission_msg) {
1809     switch (stun_timer_refresh (&current_create_permission_msg->timer)) {
1810       case STUN_USAGE_TIMER_RETURN_TIMEOUT:
1811         {
1812           /* Time out */
1813           StunTransactionId id;
1814           NiceAddress to;
1815           union {
1816             struct sockaddr_storage storage;
1817             struct sockaddr addr;
1818           } addr;
1819           socklen_t addr_len = sizeof(addr);
1820
1821           stun_message_id (&current_create_permission_msg->message, id);
1822           stun_agent_forget_transaction (&priv->agent, id);
1823           stun_message_find_xor_addr (
1824               &current_create_permission_msg->message,
1825               STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &addr.storage, &addr_len);
1826           nice_address_set_from_sockaddr (&to, &addr.addr);
1827
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;
1833
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);
1839
1840           socket_dequeue_all_data (priv, &to);
1841
1842           break;
1843         }
1844       case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
1845         /* Retransmit */
1846         _socket_send_wrapped (priv->base_socket, &priv->server_addr,
1847             stun_message_length (&current_create_permission_msg->message),
1848             (gchar *)current_create_permission_msg->buffer, FALSE);
1849         ret = TRUE;
1850         break;
1851       case STUN_USAGE_TIMER_RETURN_SUCCESS:
1852         ret = TRUE;
1853         break;
1854       default:
1855         /* Nothing to do. */
1856         break;
1857     }
1858   }
1859
1860   return ret;
1861 }
1862
1863 static gboolean
1864 priv_retransmissions_tick (gpointer pointer)
1865 {
1866   UdpTurnPriv *priv = pointer;
1867
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");
1872
1873     g_mutex_unlock (&mutex);
1874     return G_SOURCE_REMOVE;
1875   }
1876
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;
1882     }
1883   }
1884
1885   g_mutex_unlock (&mutex);
1886
1887   return G_SOURCE_REMOVE;
1888 }
1889
1890 static gboolean
1891 priv_retransmissions_create_permission_tick (gpointer pointer)
1892 {
1893   UdpTurnPriv *priv = pointer;
1894
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");
1899
1900     g_mutex_unlock (&mutex);
1901     return G_SOURCE_REMOVE;
1902   }
1903
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);
1908
1909   g_mutex_unlock (&mutex);
1910
1911   return G_SOURCE_REMOVE;
1912 }
1913
1914 static void
1915 priv_schedule_tick (UdpTurnPriv *priv)
1916 {
1917   GList *i, *next, *prev;
1918   TURNMessage *current_create_permission_msg;
1919   guint min_timeout = G_MAXUINT;
1920
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;
1925   }
1926
1927   if (priv->current_binding_msg) {
1928     guint timeout = stun_timer_remainder (&priv->current_binding_msg->timer);
1929     if (timeout > 0) {
1930       priv->tick_source_channel_bind =
1931           priv_timeout_add_with_context (priv, timeout,
1932               priv_retransmissions_tick, priv);
1933     } else {
1934       priv_retransmissions_tick_unlocked (priv);
1935     }
1936   }
1937
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;
1942   }
1943
1944   for (i = priv->pending_permissions, prev = NULL; i; i = next) {
1945     guint timeout;
1946
1947     current_create_permission_msg = (TURNMessage *)i->data;
1948     next = i->next;
1949
1950     timeout = stun_timer_remainder (&current_create_permission_msg->timer);
1951
1952     if (timeout > 0) {
1953       min_timeout = MIN (min_timeout, timeout);
1954       prev = i;
1955     } else {
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);
1959       if (prev == NULL)
1960         next = priv->pending_permissions;
1961       else
1962         next = prev->next;
1963     }
1964   }
1965
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,
1971             priv);
1972   }
1973 }
1974
1975 static void
1976 priv_send_turn_message (UdpTurnPriv *priv, TURNMessage *msg)
1977 {
1978   size_t stun_len = stun_message_length (&msg->message);
1979
1980   if (priv->current_binding_msg) {
1981     g_free (priv->current_binding_msg);
1982     priv->current_binding_msg = NULL;
1983   }
1984
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);
1990   } else {
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);
1997   }
1998
1999   priv->current_binding_msg = msg;
2000   priv_schedule_tick (priv);
2001 }
2002
2003 static gboolean
2004 priv_send_create_permission(UdpTurnPriv *priv,
2005     const NiceAddress *peer)
2006 {
2007   guint msg_buf_len;
2008   gboolean res = FALSE;
2009   TURNMessage *msg = g_new0 (TURNMessage, 1);
2010   union {
2011     struct sockaddr_storage storage;
2012     struct sockaddr addr;
2013   } addr;
2014
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);
2018   }
2019
2020   nice_address_copy_to_sockaddr (peer, &addr.addr);
2021
2022   /* send CreatePermission */
2023   msg_buf_len = stun_usage_turn_create_permission(&priv->agent, &msg->message,
2024       msg->buffer,
2025       sizeof(msg->buffer),
2026       priv->username,
2027       priv->username_len,
2028       priv->password,
2029       priv->password_len,
2030       priv->cached_realm, priv->cached_realm_len,
2031       priv->cached_nonce, priv->cached_nonce_len,
2032       &addr.storage,
2033       STUN_USAGE_TURN_COMPATIBILITY_RFC5766);
2034
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);
2039     } else {
2040       res = _socket_send_wrapped (priv->base_socket, &priv->server_addr,
2041           msg_buf_len, (gchar *) msg->buffer, TRUE);
2042       if (res < 0)
2043         res = _socket_send_wrapped (priv->base_socket, &priv->server_addr,
2044             msg_buf_len, (gchar *) msg->buffer, FALSE);
2045     }
2046
2047     if (nice_socket_is_reliable (priv->base_socket)) {
2048       stun_timer_start_reliable (&msg->timer,
2049         STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT);
2050     } else {
2051       stun_timer_start (&msg->timer, STUN_TIMER_DEFAULT_TIMEOUT,
2052         STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);
2053     }
2054
2055     priv->pending_permissions = g_list_append (priv->pending_permissions, msg);
2056     priv_schedule_tick (priv);
2057   } else {
2058     g_free(msg);
2059   }
2060
2061   return res;
2062 }
2063
2064 static gboolean
2065 priv_send_channel_bind (UdpTurnPriv *priv, uint16_t channel,
2066     const NiceAddress *peer)
2067 {
2068   uint32_t channel_attr = channel << 16;
2069   size_t stun_len;
2070   union {
2071     struct sockaddr_storage storage;
2072     struct sockaddr addr;
2073   } sa;
2074   TURNMessage *msg = g_new0 (TURNMessage, 1);
2075
2076   nice_address_copy_to_sockaddr (peer, &sa.addr);
2077
2078   if (!stun_agent_init_request (&priv->agent, &msg->message,
2079           msg->buffer, sizeof(msg->buffer),
2080           STUN_CHANNELBIND)) {
2081     g_free (msg);
2082     return FALSE;
2083   }
2084
2085   if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_CHANNEL_NUMBER,
2086           channel_attr) != STUN_MESSAGE_RETURN_SUCCESS) {
2087     g_free (msg);
2088     return FALSE;
2089   }
2090
2091   if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS,
2092           &sa.storage,
2093           sizeof(sa))
2094       != STUN_MESSAGE_RETURN_SUCCESS) {
2095     g_free (msg);
2096     return FALSE;
2097   }
2098
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) {
2102
2103     if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
2104             priv->username, priv->username_len)
2105         != STUN_MESSAGE_RETURN_SUCCESS) {
2106       g_free (msg);
2107       return FALSE;
2108     }
2109
2110     if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_REALM,
2111             priv->cached_realm,  priv->cached_realm_len)
2112         != STUN_MESSAGE_RETURN_SUCCESS) {
2113       g_free (msg);
2114       return 0;
2115     }
2116
2117     if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_NONCE,
2118             priv->cached_nonce, priv->cached_nonce_len)
2119         != STUN_MESSAGE_RETURN_SUCCESS) {
2120       g_free (msg);
2121       return 0;
2122     }
2123   }
2124
2125   stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
2126       priv->password, priv->password_len);
2127
2128   if (stun_len > 0) {
2129     priv_send_turn_message (priv, msg);
2130     return TRUE;
2131   }
2132
2133   g_free (msg);
2134   return FALSE;
2135 }
2136
2137 static gboolean
2138 priv_add_channel_binding (UdpTurnPriv *priv, const NiceAddress *peer)
2139 {
2140   size_t stun_len;
2141   union {
2142     struct sockaddr_storage storage;
2143     struct sockaddr addr;
2144   } sa;
2145
2146   nice_address_copy_to_sockaddr (peer, &sa.addr);
2147
2148   if (priv->current_binding) {
2149     NiceAddress * pending= nice_address_new ();
2150     *pending = *peer;
2151     priv->pending_bindings = g_list_append (priv->pending_bindings, pending);
2152     return FALSE;
2153   }
2154
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) {
2162         i = priv->channels;
2163         channel++;
2164         continue;
2165       }
2166     }
2167
2168     if (channel >= 0x4000 && channel < 0xffff) {
2169       gboolean ret = priv_send_channel_bind (priv, channel, peer);
2170       if (ret) {
2171         priv->current_binding = g_new0 (ChannelBinding, 1);
2172         priv->current_binding->channel = channel;
2173         priv->current_binding->peer = *peer;
2174       }
2175       return ret;
2176     }
2177     return FALSE;
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)) {
2184       g_free (msg);
2185       return FALSE;
2186     }
2187
2188     if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_MAGIC_COOKIE,
2189             TURN_MAGIC_COOKIE)
2190         != STUN_MESSAGE_RETURN_SUCCESS) {
2191       g_free (msg);
2192       return FALSE;
2193     }
2194
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) {
2199         g_free (msg);
2200         return FALSE;
2201       }
2202     }
2203
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);
2208
2209       stun_message_ensure_ms_realm(&msg->message, priv->ms_realm);
2210     }
2211
2212     if (stun_message_append_addr (&msg->message,
2213             STUN_ATTRIBUTE_DESTINATION_ADDRESS,
2214             &sa.addr, sizeof(sa))
2215         != STUN_MESSAGE_RETURN_SUCCESS) {
2216       g_free (msg);
2217       return FALSE;
2218     }
2219
2220     stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
2221         priv->password, priv->password_len);
2222
2223     if (stun_len > 0) {
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);
2228       return TRUE;
2229     }
2230     g_free (msg);
2231     return FALSE;
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;
2236     return TRUE;
2237   } else {
2238     return FALSE;
2239   }
2240
2241   return FALSE;
2242 }
2243
2244 void
2245 nice_udp_turn_socket_set_ms_realm(NiceSocket *sock, StunMessage *msg)
2246 {
2247   UdpTurnPriv *priv = (UdpTurnPriv *)sock->priv;
2248   uint16_t alen;
2249   const uint8_t *realm = stun_message_find(msg, STUN_ATTRIBUTE_REALM, &alen);
2250
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);
2256   }
2257 }
2258
2259 void
2260 nice_udp_turn_socket_set_ms_connection_id (NiceSocket *sock, StunMessage *msg)
2261 {
2262   UdpTurnPriv *priv = (UdpTurnPriv *)sock->priv;
2263   uint16_t alen;
2264   const uint8_t *ms_seq_num = stun_message_find(msg,
2265       STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER, &alen);
2266
2267
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);
2274   }
2275 }