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
send_request_free(SendRequest * r)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
priv_nice_address_hash(gconstpointer data)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
priv_send_data_queue_destroy(gpointer user_data)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 *
nice_udp_turn_socket_new(GMainContext * ctx,NiceAddress * addr,NiceSocket * base_socket,const NiceAddress * server_addr,const gchar * username,const gchar * password,NiceTurnSocketCompatibility compatibility)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
socket_close(NiceSocket * sock)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
socket_recv_messages(NiceSocket * sock,NiceInputMessage * recv_messages,guint n_recv_messages)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 *
priv_timeout_add_with_context(UdpTurnPriv * priv,guint interval,GSourceFunc function,gpointer data)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 *
priv_timeout_add_seconds_with_context(UdpTurnPriv * priv,guint interval,GSourceFunc function,gpointer data)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
stun_message_append_ms_connection_id(StunMessage * msg,uint8_t * ms_connection_id,uint32_t ms_sequence_num)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
stun_message_ensure_ms_realm(StunMessage * msg,uint8_t * realm)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
priv_is_peer_in_list(const GList * list,const NiceAddress * peer)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
priv_has_permission_for_peer(UdpTurnPriv * priv,const NiceAddress * peer)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
priv_has_sent_permission_for_peer(UdpTurnPriv * priv,const NiceAddress * peer)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
priv_add_permission_for_peer(UdpTurnPriv * priv,const NiceAddress * peer)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
priv_add_sent_permission_for_peer(UdpTurnPriv * priv,const NiceAddress * peer)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 *
priv_remove_peer_from_list(GList * list,const NiceAddress * peer)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
priv_remove_sent_permission_for_peer(UdpTurnPriv * priv,const NiceAddress * peer)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
priv_clear_permissions(UdpTurnPriv * priv)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
_socket_send_messages_wrapped(NiceSocket * sock,const NiceAddress * to,const NiceOutputMessage * messages,guint n_messages,gboolean reliable)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
_socket_send_wrapped(NiceSocket * sock,const NiceAddress * to,guint len,const gchar * buf,gboolean reliable)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
socket_enqueue_data(UdpTurnPriv * priv,const NiceAddress * to,guint len,const gchar * buf,gboolean reliable)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
socket_dequeue_all_data(UdpTurnPriv * priv,const NiceAddress * to)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
socket_send_message(NiceSocket * sock,const NiceAddress * to,const NiceOutputMessage * message,gboolean reliable)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
socket_send_messages(NiceSocket * sock,const NiceAddress * to,const NiceOutputMessage * messages,guint n_messages)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
socket_send_messages_reliable(NiceSocket * sock,const NiceAddress * to,const NiceOutputMessage * messages,guint n_messages)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
socket_is_reliable(NiceSocket * sock)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
socket_can_send(NiceSocket * sock,NiceAddress * addr)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
socket_set_writable_callback(NiceSocket * sock,NiceSocketWritableCb callback,gpointer user_data)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
socket_is_based_on(NiceSocket * sock,NiceSocket * other)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
priv_forget_send_request_timeout(gpointer pointer)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
priv_permission_timeout(gpointer data)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
priv_binding_expired_timeout(gpointer data)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
priv_binding_timeout(gpointer data)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
nice_udp_turn_socket_cache_realm_nonce_locked(NiceSocket * sock,StunMessage * msg)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
nice_udp_turn_socket_cache_realm_nonce(NiceSocket * sock,StunMessage * msg)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
nice_udp_turn_socket_parse_recv_message(NiceSocket * sock,NiceSocket ** from_sock,NiceInputMessage * message)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
nice_udp_turn_socket_parse_recv(NiceSocket * sock,NiceSocket ** from_sock,NiceAddress * from,gsize len,guint8 * buf,const NiceAddress * recv_from,const guint8 * _recv_buf,gsize recv_len)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 (¤t_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 ¤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");
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 ¤t_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
nice_udp_turn_socket_set_peer(NiceSocket * sock,NiceAddress * peer)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
priv_process_pending_bindings(UdpTurnPriv * priv)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
priv_retransmissions_tick_unlocked(UdpTurnPriv * priv)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
priv_retransmissions_create_permission_tick_unlocked(UdpTurnPriv * priv,GList * list_element)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 (¤t_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 (¤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);
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 (¤t_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
priv_retransmissions_tick(gpointer pointer)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
priv_retransmissions_create_permission_tick(gpointer pointer)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
priv_schedule_tick(UdpTurnPriv * priv)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 (¤t_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
priv_send_turn_message(UdpTurnPriv * priv,TURNMessage * msg)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
priv_send_create_permission(UdpTurnPriv * priv,const NiceAddress * peer)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
priv_send_channel_bind(UdpTurnPriv * priv,uint16_t channel,const NiceAddress * peer)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
priv_add_channel_binding(UdpTurnPriv * priv,const NiceAddress * peer)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
nice_udp_turn_socket_set_ms_realm(NiceSocket * sock,StunMessage * msg)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
nice_udp_turn_socket_set_ms_connection_id(NiceSocket * sock,StunMessage * msg)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 }
2276