Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / agent / component.c
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2006-2009 Collabora Ltd.
5  *  Contact: Youness Alaoui
6  * (C) 2006-2009 Nokia Corporation. All rights reserved.
7  *  Contact: Kai Vehmanen
8  *
9  * The contents of this file are subject to the Mozilla Public License Version
10  * 1.1 (the "License"); you may not use this file except in compliance with
11  * the License. You may obtain a copy of the License at
12  * http://www.mozilla.org/MPL/
13  *
14  * Software distributed under the License is distributed on an "AS IS" basis,
15  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16  * for the specific language governing rights and limitations under the
17  * License.
18  *
19  * The Original Code is the Nice GLib ICE library.
20  *
21  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22  * Corporation. All Rights Reserved.
23  *
24  * Contributors:
25  *   Dafydd Harries, Collabora Ltd.
26  *   Youness Alaoui, Collabora Ltd.
27  *   Kai Vehmanen, Nokia
28  *
29  * Alternatively, the contents of this file may be used under the terms of the
30  * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
31  * case the provisions of LGPL are applicable instead of those above. If you
32  * wish to allow use of your version of this file only under the terms of the
33  * LGPL and not to allow others to use your version of this file under the
34  * MPL, indicate your decision by deleting the provisions above and replace
35  * them with the notice and other provisions required by the LGPL. If you do
36  * not delete the provisions above, a recipient may use your version of this
37  * file under either the MPL or the LGPL.
38  */
39
40 /*
41  * @file component.c
42  * @brief ICE component functions
43  */
44
45 /* Simple tracking for the number of alive components. These must be accessed
46  * atomically. */
47 static volatile unsigned int n_components_created = 0;
48 static volatile unsigned int n_components_destroyed = 0;
49
50 #ifdef HAVE_CONFIG_H
51 # include <config.h>
52 #endif
53
54 #include <string.h>
55
56 #include "debug.h"
57
58 #include "component.h"
59 #include "discovery.h"
60 #include "agent-priv.h"
61
62 G_DEFINE_TYPE (NiceComponent, nice_component, G_TYPE_OBJECT);
63
64 typedef enum {
65   PROP_ID = 1,
66   PROP_AGENT,
67   PROP_STREAM,
68 } NiceComponentProperty;
69
70 static void
71 nice_component_constructed (GObject *obj);
72 static void
73 nice_component_get_property (GObject *obj,
74     guint property_id, GValue *value, GParamSpec *pspec);
75 static void
76 nice_component_set_property (GObject *obj,
77     guint property_id, const GValue *value, GParamSpec *pspec);
78 static void
79 nice_component_finalize (GObject *obj);
80
81 static void
82 nice_component_schedule_io_callback (NiceComponent *component);
83 static void
84 nice_component_deschedule_io_callback (NiceComponent *component);
85 static void
86 nice_component_detach_socket (NiceComponent *component, NiceSocket *nicesock);
87 static void
88 nice_component_clear_selected_pair (NiceComponent *component);
89
90
91 void
92 incoming_check_free (IncomingCheck *icheck)
93 {
94   g_free (icheck->username);
95   g_slice_free (IncomingCheck, icheck);
96 }
97
98 /* Must *not* take the agent lock, since it’s called from within
99  * nice_component_set_io_context(), which holds the Component’s I/O lock. */
100 static void
101 socket_source_attach (SocketSource *socket_source, GMainContext *context)
102 {
103   GSource *source;
104
105   if (socket_source->socket->fileno == NULL)
106     return;
107
108   /* Do not create a GSource for UDP turn socket, because it
109    * would duplicate the packets already received on the base
110    * UDP socket.
111    */
112   if (socket_source->socket->type == NICE_SOCKET_TYPE_UDP_TURN)
113     return;
114
115   /* Create a source. */
116   source = g_socket_create_source (socket_source->socket->fileno,
117       G_IO_IN, NULL);
118   g_source_set_callback (source, (GSourceFunc) G_CALLBACK (component_io_cb),
119       socket_source, NULL);
120
121   /* Add the source. */
122   nice_debug ("Attaching source %p (socket %p, FD %d) to context %p", source,
123       socket_source->socket, g_socket_get_fd (socket_source->socket->fileno),
124       context);
125
126   g_assert (socket_source->source == NULL);
127   socket_source->source = source;
128   g_source_attach (source, context);
129 }
130
131 static void
132 socket_source_detach (SocketSource *source)
133 {
134   nice_debug ("Detaching source %p (socket %p, FD %d) from context %p",
135       source->source, source->socket,
136       (source->socket->fileno != NULL) ?
137           g_socket_get_fd (source->socket->fileno) : 0,
138       (source->source != NULL) ? g_source_get_context (source->source) : 0);
139
140   if (source->source != NULL) {
141     g_source_destroy (source->source);
142     g_source_unref (source->source);
143   }
144   source->source = NULL;
145 }
146
147 static void
148 socket_source_free (SocketSource *source)
149 {
150   socket_source_detach (source);
151   nice_socket_free (source->socket);
152
153   g_slice_free (SocketSource, source);
154 }
155
156 NiceComponent *
157 nice_component_new (guint id, NiceAgent *agent, NiceStream *stream)
158 {
159   return g_object_new (NICE_TYPE_COMPONENT,
160                        "id", id,
161                        "agent", agent,
162                        "stream", stream,
163                        NULL);
164 }
165
166 void
167 nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp,
168     NiceSocket *nsocket)
169 {
170   GSList *i;
171   NiceStream *stream;
172
173   stream = agent_find_stream (agent, cmp->stream_id);
174
175   discovery_prune_socket (agent, nsocket);
176   if (stream)
177     conn_check_prune_socket (agent, stream, cmp, nsocket);
178
179   for (i = cmp->local_candidates; i;) {
180     NiceCandidate *candidate = i->data;
181     GSList *next = i->next;
182
183     if (!nice_socket_is_based_on (candidate->sockptr, nsocket)) {
184       i = next;
185       continue;
186     }
187
188     if (candidate == cmp->selected_pair.local) {
189       nice_component_clear_selected_pair (cmp);
190       agent_signal_component_state_change (agent, cmp->stream_id,
191           cmp->id, NICE_COMPONENT_STATE_FAILED);
192     }
193
194     refresh_prune_candidate (agent, candidate);
195     if (candidate->sockptr != nsocket && stream) {
196       discovery_prune_socket (agent, candidate->sockptr);
197       conn_check_prune_socket (agent, stream, cmp,
198           candidate->sockptr);
199       nice_component_detach_socket (cmp, candidate->sockptr);
200     }
201     agent_remove_local_candidate (agent, candidate);
202     nice_candidate_free (candidate);
203
204     cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i);
205     i = next;
206   }
207
208   /* The nsocket to be removed may also come from a
209    * peer-reflexive remote candidate
210    */
211   for (i = cmp->remote_candidates; i;) {
212     NiceCandidate *candidate = i->data;
213     GSList *next = i->next;
214
215     if (candidate->sockptr != nsocket) {
216       i = next;
217       continue;
218     }
219
220     if (candidate == cmp->selected_pair.remote) {
221       nice_component_clear_selected_pair (cmp);
222       agent_signal_component_state_change (agent, cmp->stream_id,
223           cmp->id, NICE_COMPONENT_STATE_FAILED);
224     }
225
226     if (stream)
227       conn_check_prune_socket (agent, stream, cmp, candidate->sockptr);
228
229     nice_candidate_free (candidate);
230
231     cmp->remote_candidates = g_slist_delete_link (cmp->remote_candidates, i);
232     i = next;
233   }
234
235   nice_component_detach_socket (cmp, nsocket);
236 }
237
238 static gboolean
239 on_candidate_refreshes_pruned (NiceAgent *agent, NiceCandidate *candidate)
240 {
241   NiceComponent *component;
242
243   if (agent_find_component (agent, candidate->stream_id,
244       candidate->component_id, NULL, &component)) {
245     nice_component_detach_socket (component, candidate->sockptr);
246   }
247
248   nice_candidate_free (candidate);
249
250   return G_SOURCE_REMOVE;
251 }
252
253 void
254 nice_component_clean_turn_servers (NiceAgent *agent, NiceComponent *cmp)
255 {
256   GSList *i;
257   GSList *relay_candidates = NULL;
258   NiceStream *stream;
259
260   stream = agent_find_stream (agent, cmp->stream_id);
261
262   g_list_free_full (cmp->turn_servers, (GDestroyNotify) turn_server_unref);
263   cmp->turn_servers = NULL;
264
265   for (i = cmp->local_candidates; i;) {
266     NiceCandidate *candidate = i->data;
267     GSList *next = i->next;
268
269     if (candidate->type != NICE_CANDIDATE_TYPE_RELAYED) {
270       i = next;
271       continue;
272     }
273
274     /* note: do not remove the remote candidate that is
275      *       currently part of the 'selected pair', see ICE
276      *       9.1.1.1. "ICE Restarts" (ID-19)
277      *
278      * So what we do instead is that we put the selected candidate
279      * in a special location and keep it "alive" that way. This is
280      * especially important for TURN, because refresh requests to the
281      * server need to keep happening.
282      */
283     if (candidate == cmp->selected_pair.local) {
284       if (cmp->turn_candidate) {
285         relay_candidates = g_slist_append(relay_candidates, cmp->turn_candidate);
286       }
287       /* Bring the priority down to 0, so that it will be replaced
288        * on the new run.
289        */
290       cmp->selected_pair.priority = 0;
291       cmp->turn_candidate = candidate;
292     } else {
293       agent_remove_local_candidate (agent, candidate);
294       relay_candidates = g_slist_append(relay_candidates, candidate);
295     }
296     cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i);
297     i = next;
298   }
299
300   for (i = relay_candidates; i; i = i->next) {
301     NiceCandidate * candidate = i->data;
302
303     discovery_prune_socket (agent, candidate->sockptr);
304     if (stream) {
305       conn_check_prune_socket (agent, stream, cmp, candidate->sockptr);
306     }
307
308     refresh_prune_candidate_async (agent, candidate,
309         (NiceTimeoutLockedCallback) on_candidate_refreshes_pruned);
310   }
311 }
312
313 static void
314 nice_component_clear_selected_pair (NiceComponent *component)
315 {
316   if (component->selected_pair.keepalive.tick_source != NULL) {
317     g_source_destroy (component->selected_pair.keepalive.tick_source);
318     g_source_unref (component->selected_pair.keepalive.tick_source);
319     component->selected_pair.keepalive.tick_source = NULL;
320   }
321
322   memset (&component->selected_pair, 0, sizeof(CandidatePair));
323 }
324
325 /* Must be called with the agent lock held as it touches internal Component
326  * state. */
327 void
328 nice_component_close (NiceAgent *agent, NiceComponent *cmp)
329 {
330   IOCallbackData *data;
331   GOutputVector *vec;
332   IncomingCheck *c;
333
334   /* Start closing the pseudo-TCP socket first. FIXME: There is a very big and
335    * reliably triggerable race here. pseudo_tcp_socket_close() does not block
336    * on the socket closing — it only sends the first packet of the FIN
337    * handshake. nice_component_close() will immediately afterwards close the
338    * underlying component sockets, aborting the handshake.
339    *
340    * On the principle that starting the FIN handshake is better than not
341    * starting it, even if it’s later truncated, call pseudo_tcp_socket_close().
342    * A long-term fix is needed in the form of making nice_component_close() (and
343    * all its callers) async, so we can properly block on closure. */
344   if (cmp->tcp) {
345     pseudo_tcp_socket_close (cmp->tcp, TRUE);
346   }
347
348   if (cmp->restart_candidate)
349     nice_candidate_free (cmp->restart_candidate),
350       cmp->restart_candidate = NULL;
351
352   if (cmp->turn_candidate)
353     nice_candidate_free (cmp->turn_candidate),
354         cmp->turn_candidate = NULL;
355
356   while (cmp->local_candidates) {
357     agent_remove_local_candidate (agent, cmp->local_candidates->data);
358     nice_candidate_free (cmp->local_candidates->data);
359     cmp->local_candidates = g_slist_delete_link (cmp->local_candidates,
360         cmp->local_candidates);
361   }
362
363   g_slist_free_full (cmp->remote_candidates,
364       (GDestroyNotify) nice_candidate_free);
365   cmp->remote_candidates = NULL;
366   nice_component_free_socket_sources (cmp);
367
368   while ((c = g_queue_pop_head (&cmp->incoming_checks)))
369     incoming_check_free (c);
370
371   nice_component_clean_turn_servers (agent, cmp);
372
373   if (cmp->tcp_clock) {
374     g_source_destroy (cmp->tcp_clock);
375     g_source_unref (cmp->tcp_clock);
376     cmp->tcp_clock = NULL;
377   }
378   if (cmp->tcp_writable_cancellable) {
379     g_cancellable_cancel (cmp->tcp_writable_cancellable);
380     g_clear_object (&cmp->tcp_writable_cancellable);
381   }
382
383   while ((data = g_queue_pop_head (&cmp->pending_io_messages)) != NULL)
384     io_callback_data_free (data);
385
386   nice_component_deschedule_io_callback (cmp);
387
388   g_cancellable_cancel (cmp->stop_cancellable);
389
390   while ((vec = g_queue_pop_head (&cmp->queued_tcp_packets)) != NULL) {
391     g_free ((gpointer) vec->buffer);
392     g_slice_free (GOutputVector, vec);
393   }
394 }
395
396 /*
397  * Finds a candidate pair that has matching foundation ids.
398  *
399  * @return TRUE if pair found, pointer to pair stored at 'pair'
400  */
401 gboolean
402 nice_component_find_pair (NiceComponent *cmp, NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair)
403 {
404   GSList *i;
405   CandidatePair result = { 0, };
406
407   for (i = cmp->local_candidates; i; i = i->next) {
408     NiceCandidate *candidate = i->data;
409     if (strncmp (candidate->foundation, lfoundation, NICE_CANDIDATE_MAX_FOUNDATION) == 0) {
410       result.local = candidate;
411       break;
412     }
413   }
414
415   for (i = cmp->remote_candidates; i; i = i->next) {
416     NiceCandidate *candidate = i->data;
417     if (strncmp (candidate->foundation, rfoundation, NICE_CANDIDATE_MAX_FOUNDATION) == 0) {
418       result.remote = candidate;
419       break;
420     }
421   }
422
423   if (result.local && result.remote) {
424     result.priority = agent_candidate_pair_priority (agent, result.local, result.remote);
425     if (pair)
426       *pair = result;
427     return TRUE;
428   }
429
430   return FALSE;
431 }
432
433 /*
434  * Resets the component state to that of a ICE restarted
435  * session.
436  */
437 void
438 nice_component_restart (NiceComponent *cmp)
439 {
440   GSList *i;
441   IncomingCheck *c;
442
443   for (i = cmp->remote_candidates; i; i = i->next) {
444     NiceCandidate *candidate = i->data;
445
446     /* note: do not remove the remote candidate that is
447      *       currently part of the 'selected pair', see ICE
448      *       9.1.1.1. "ICE Restarts" (ID-19) */
449     if (candidate == cmp->selected_pair.remote) {
450       if (cmp->restart_candidate)
451         nice_candidate_free (cmp->restart_candidate);
452       cmp->restart_candidate = candidate;
453     }
454     else 
455       nice_candidate_free (candidate);
456   }
457   g_slist_free (cmp->remote_candidates),
458     cmp->remote_candidates = NULL;
459
460   while ((c = g_queue_pop_head (&cmp->incoming_checks)))
461     incoming_check_free (c);
462
463   /* Reset the priority to 0 to make sure we get a new pair */
464   cmp->selected_pair.priority = 0;
465
466   /* note: component state managed by agent */
467 }
468
469 /*
470  * Changes the selected pair for the component to 'pair'. Does not
471  * emit the "selected-pair-changed" signal.
472  */ 
473 void
474 nice_component_update_selected_pair (NiceAgent *agent, NiceComponent *component, const CandidatePair *pair)
475 {
476   NiceStream *stream;
477   gchar priority[NICE_CANDIDATE_PAIR_PRIORITY_MAX_SIZE];
478
479   g_assert (component);
480   g_assert (pair);
481
482   stream = agent_find_stream (agent, component->stream_id);
483
484   nice_candidate_pair_priority_to_string (pair->priority, priority);
485   nice_debug ("setting SELECTED PAIR for component %u: %s:%s (prio:%s).",
486       component->id, pair->local->foundation,
487       pair->remote->foundation, priority);
488
489   if (component->selected_pair.local &&
490       component->selected_pair.local == component->turn_candidate) {
491     discovery_prune_socket (agent,
492         component->turn_candidate->sockptr);
493     if (stream)
494       conn_check_prune_socket (agent, stream, component,
495           component->turn_candidate->sockptr);
496     refresh_prune_candidate_async (agent, component->turn_candidate,
497         (NiceTimeoutLockedCallback) on_candidate_refreshes_pruned);
498     component->turn_candidate = NULL;
499   }
500
501   nice_component_clear_selected_pair (component);
502
503   component->selected_pair.local = pair->local;
504   component->selected_pair.remote = pair->remote;
505   component->selected_pair.priority = pair->priority;
506   component->selected_pair.stun_priority = pair->stun_priority;
507
508   nice_component_add_valid_candidate (agent, component, pair->remote);
509 }
510
511 /*
512  * Finds a remote candidate with matching address and 
513  * transport.
514  *
515  * @return pointer to candidate or NULL if not found
516  */
517 NiceCandidate *
518 nice_component_find_remote_candidate (NiceComponent *component, const NiceAddress *addr, NiceCandidateTransport transport)
519 {
520   GSList *i;
521
522   for (i = component->remote_candidates; i; i = i->next) {
523     NiceCandidate *candidate = i->data;
524
525     if (nice_address_equal(&candidate->addr, addr) &&
526         candidate->transport == transport)
527       return candidate;
528
529   }
530   
531   return NULL;
532 }
533
534 /*
535  * Sets the desired remote candidate as the selected pair
536  *
537  * It will start sending on the highest priority pair available with
538  * this candidate.
539  */
540
541 NiceCandidate *
542 nice_component_set_selected_remote_candidate (NiceComponent *component,
543     NiceAgent *agent, NiceCandidate *candidate)
544 {
545   NiceCandidate *local = NULL;
546   NiceCandidate *remote = NULL;
547   guint64 priority = 0;
548   GSList *item = NULL;
549
550   g_assert (candidate != NULL);
551
552   for (item = component->local_candidates; item; item = g_slist_next (item)) {
553     NiceCandidate *tmp = item->data;
554     guint64 tmp_prio = 0;
555
556     if (tmp->transport != conn_check_match_transport(candidate->transport) ||
557         tmp->addr.s.addr.sa_family != candidate->addr.s.addr.sa_family ||
558         tmp->type != NICE_CANDIDATE_TYPE_HOST)
559       continue;
560
561     tmp_prio = agent_candidate_pair_priority (agent, tmp, candidate);
562
563     if (tmp_prio > priority) {
564       priority = tmp_prio;
565       local = tmp;
566     }
567   }
568
569   if (local == NULL)
570     return NULL;
571
572   remote = nice_component_find_remote_candidate (component, &candidate->addr,
573       candidate->transport);
574
575   if (!remote) {
576     remote = nice_candidate_copy (candidate);
577     component->remote_candidates = g_slist_append (component->remote_candidates,
578         remote);
579     agent_signal_new_remote_candidate (agent, remote);
580   }
581
582   nice_component_clear_selected_pair (component);
583
584   component->selected_pair.local = local;
585   component->selected_pair.remote = remote;
586   component->selected_pair.priority = priority;
587
588   /* Get into fallback mode where packets from any source is accepted once
589    * this has been called. This is the expected behavior of pre-ICE SIP.
590    */
591   component->fallback_mode = TRUE;
592
593   return local;
594 }
595
596 static gint
597 _find_socket_source (gconstpointer a, gconstpointer b)
598 {
599   const SocketSource *source_a = a;
600   const NiceSocket *socket_b = b;
601
602   return (source_a->socket == socket_b) ? 0 : 1;
603 }
604
605 /* This takes ownership of the socket.
606  * It creates and attaches a source to the component’s context. */
607 void
608 nice_component_attach_socket (NiceComponent *component, NiceSocket *nicesock)
609 {
610   GSList *l;
611   SocketSource *socket_source;
612
613   g_assert (component != NULL);
614   g_assert (nicesock != NULL);
615
616   g_assert (component->ctx != NULL);
617
618   /* Find an existing SocketSource in the component which contains @socket, or
619    * create a new one.
620    *
621    * Whenever a source is added or remove to socket_sources, socket_sources_age
622    * must be incremented.
623    */
624   l = g_slist_find_custom (component->socket_sources, nicesock,
625           _find_socket_source);
626   if (l != NULL) {
627     socket_source = l->data;
628   } else {
629     socket_source = g_slice_new0 (SocketSource);
630     socket_source->socket = nicesock;
631     socket_source->component = component;
632     component->socket_sources =
633         g_slist_prepend (component->socket_sources, socket_source);
634     if (nicesock->fileno != NULL)
635       component->socket_sources_age++;
636   }
637
638   /* Create and attach a source */
639   nice_debug ("Component %p: Attach source (stream %u).",
640       component, component->stream_id);
641   socket_source_attach (socket_source, component->ctx);
642 }
643
644 /* Reattaches socket handles of @component to the main context.
645  *
646  * Must *not* take the agent lock, since it’s called from within
647  * nice_component_set_io_context(), which holds the Component’s I/O lock. */
648 static void
649 nice_component_reattach_all_sockets (NiceComponent *component)
650 {
651   GSList *i;
652
653   for (i = component->socket_sources; i != NULL; i = i->next) {
654     SocketSource *socket_source = i->data;
655     nice_debug ("Reattach source %p.", socket_source->source);
656     socket_source_detach (socket_source);
657     socket_source_attach (socket_source, component->ctx);
658   }
659 }
660
661 /**
662  * nice_component_detach_socket:
663  * @component: a #NiceComponent
664  * @socket: the socket to detach the source for
665  *
666  * Detach the #GSource for the single specified @socket. It also closes it
667  * and frees it!
668  *
669  * If the @socket doesn’t exist in this @component, do nothing.
670  */
671 static void
672 nice_component_detach_socket (NiceComponent *component, NiceSocket *nicesock)
673 {
674   GList *l;
675   GSList *s;
676   SocketSource *socket_source;
677
678   nice_debug ("Detach socket %p.", nicesock);
679
680   /* Remove the socket from various lists. */
681   for (l = component->incoming_checks.head; l != NULL;) {
682     IncomingCheck *icheck = l->data;
683     GList *next = l->next;
684
685     if (icheck->local_socket == nicesock) {
686       g_queue_delete_link (&component->incoming_checks, l);
687       incoming_check_free (icheck);
688     }
689
690     l = next;
691   }
692
693   /* Find the SocketSource for the socket. */
694   s = g_slist_find_custom (component->socket_sources, nicesock,
695           _find_socket_source);
696   if (s == NULL)
697     return;
698
699   /* Detach the source. */
700   socket_source = s->data;
701   component->socket_sources = g_slist_delete_link (component->socket_sources, s);
702   component->socket_sources_age++;
703
704   socket_source_free (socket_source);
705 }
706
707 /*
708  * Detaches socket handles of @component from the main context. Leaves the
709  * sockets themselves untouched.
710  *
711  * Must *not* take the agent lock, since it’s called from within
712  * nice_component_set_io_context(), which holds the Component’s I/O lock.
713  */
714 void
715 nice_component_detach_all_sockets (NiceComponent *component)
716 {
717   GSList *i;
718
719   for (i = component->socket_sources; i != NULL; i = i->next) {
720     SocketSource *socket_source = i->data;
721     nice_debug ("Detach source %p, socket %p.", socket_source->source,
722         socket_source->socket);
723     socket_source_detach (socket_source);
724   }
725 }
726
727 void
728 nice_component_free_socket_sources (NiceComponent *component)
729 {
730   nice_debug ("Free socket sources for component %p.", component);
731
732   g_slist_free_full (component->socket_sources,
733       (GDestroyNotify) socket_source_free);
734   component->socket_sources = NULL;
735   component->socket_sources_age++;
736
737   nice_component_clear_selected_pair (component);
738 }
739
740 GMainContext *
741 nice_component_dup_io_context (NiceComponent *component)
742 {
743   return g_main_context_ref (component->own_ctx);
744 }
745
746 /* If @context is %NULL, it's own context is used, so component->ctx is always
747  * guaranteed to be non-%NULL. */
748 void
749 nice_component_set_io_context (NiceComponent *component, GMainContext *context)
750 {
751   g_mutex_lock (&component->io_mutex);
752
753   if (component->ctx != context) {
754     if (context == NULL)
755       context = g_main_context_ref (component->own_ctx);
756     else
757       g_main_context_ref (context);
758
759     nice_component_detach_all_sockets (component);
760     g_main_context_unref (component->ctx);
761
762     component->ctx = context;
763     nice_component_reattach_all_sockets (component);
764   }
765
766   g_mutex_unlock (&component->io_mutex);
767 }
768
769 /* (func, user_data) and (recv_messages, n_recv_messages) are mutually
770  * exclusive. At most one of the two must be specified; if both are NULL, the
771  * Component will not receive any data (i.e. reception is paused).
772  *
773  * Apart from during setup, this must always be called with the agent lock held,
774  * and the I/O lock released (because it takes the I/O lock itself). Requiring
775  * the agent lock to be held means it can’t be called between a packet being
776  * dequeued from the kernel buffers in agent.c, and an I/O callback being
777  * emitted for it (which could cause data loss if the I/O callback function was
778  * unset in that time). */
779 void
780 nice_component_set_io_callback (NiceComponent *component,
781     NiceAgentRecvFunc func, gpointer user_data,
782     NiceInputMessage *recv_messages, guint n_recv_messages,
783     GError **error)
784 {
785   g_assert (func == NULL || recv_messages == NULL);
786   g_assert (n_recv_messages == 0 || recv_messages != NULL);
787   g_assert (error == NULL || *error == NULL);
788
789   g_mutex_lock (&component->io_mutex);
790
791   if (func != NULL) {
792     component->io_callback = func;
793     component->io_user_data = user_data;
794     component->recv_messages = NULL;
795     component->n_recv_messages = 0;
796
797     nice_component_schedule_io_callback (component);
798   } else {
799     component->io_callback = NULL;
800     component->io_user_data = NULL;
801     component->recv_messages = recv_messages;
802     component->n_recv_messages = n_recv_messages;
803
804     nice_component_deschedule_io_callback (component);
805   }
806
807   nice_input_message_iter_reset (&component->recv_messages_iter);
808   component->recv_buf_error = error;
809
810   g_mutex_unlock (&component->io_mutex);
811 }
812
813 gboolean
814 nice_component_has_io_callback (NiceComponent *component)
815 {
816   gboolean has_io_callback;
817
818   g_mutex_lock (&component->io_mutex);
819   has_io_callback = (component->io_callback != NULL);
820   g_mutex_unlock (&component->io_mutex);
821
822   return has_io_callback;
823 }
824
825 IOCallbackData *
826 io_callback_data_new (const guint8 *buf, gsize buf_len)
827 {
828   IOCallbackData *data;
829
830   data = g_slice_new0 (IOCallbackData);
831   data->buf = g_memdup (buf, buf_len);
832   data->buf_len = buf_len;
833   data->offset = 0;
834
835   return data;
836 }
837
838 void
839 io_callback_data_free (IOCallbackData *data)
840 {
841   g_free (data->buf);
842   g_slice_free (IOCallbackData, data);
843 }
844
845 /* This is called with the global agent lock released. It does not take that
846  * lock, but does take the io_mutex. */
847 static gboolean
848 emit_io_callback_cb (gpointer user_data)
849 {
850   NiceComponent *component = user_data;
851   IOCallbackData *data;
852   NiceAgentRecvFunc io_callback;
853   gpointer io_user_data;
854   guint stream_id, component_id;
855   NiceAgent *agent;
856
857   agent = g_weak_ref_get (&component->agent_ref);
858   if (agent == NULL) {
859     nice_debug ("Agent for component %p is gone", component);
860     return FALSE;
861   }
862
863   stream_id = component->stream_id;
864   component_id = component->id;
865
866   g_mutex_lock (&component->io_mutex);
867
868   /* The members of Component are guaranteed not to have changed since this
869    * GSource was attached in nice_component_emit_io_callback(). The Component’s agent
870    * and stream are immutable after construction, as are the stream and
871    * component IDs. The callback and its user data may have changed, but are
872    * guaranteed to be non-%NULL at the start as the idle source is removed when
873    * the callback is set to %NULL. They may become %NULL during the io_callback,
874    * so must be re-checked every loop iteration. The data buffer is copied into
875    * the #IOCallbackData closure.
876    *
877    * If the component is destroyed (which happens if the agent or stream are
878    * destroyed) between attaching the GSource and firing it, the GSource is
879    * detached during dispose and this callback is never invoked. If the
880    * agent is destroyed during an io_callback, its weak pointer will be
881    * nullified. Similarly, the Component needs to be re-queried for after every
882    * iteration, just in case the client has removed the stream in the
883    * callback. */
884   while (TRUE) {
885     io_callback = component->io_callback;
886     io_user_data = component->io_user_data;
887     data = g_queue_peek_head (&component->pending_io_messages);
888
889     if (data == NULL || io_callback == NULL)
890       break;
891
892     g_mutex_unlock (&component->io_mutex);
893
894     io_callback (agent, stream_id, component_id,
895         data->buf_len - data->offset, (gchar *) data->buf + data->offset,
896         io_user_data);
897
898     /* Check for the user destroying things underneath our feet. */
899     if (!agent_find_component (agent, stream_id, component_id,
900             NULL, &component)) {
901       nice_debug ("%s: Agent or component destroyed.", G_STRFUNC);
902       goto done;
903     }
904
905     g_queue_pop_head (&component->pending_io_messages);
906     io_callback_data_free (data);
907
908     g_mutex_lock (&component->io_mutex);
909   }
910
911   component->io_callback_id = 0;
912   g_mutex_unlock (&component->io_mutex);
913
914  done:
915   g_object_unref (agent);
916
917   return G_SOURCE_REMOVE;
918 }
919
920 /* This must be called with the agent lock *held*. */
921 void
922 nice_component_emit_io_callback (NiceAgent *agent, NiceComponent *component,
923     const guint8 *buf, gsize buf_len)
924 {
925   guint stream_id, component_id;
926   NiceAgentRecvFunc io_callback;
927   gpointer io_user_data;
928
929   g_assert (component != NULL);
930   g_assert (buf != NULL);
931   g_assert (buf_len > 0);
932
933   stream_id = component->stream_id;
934   component_id = component->id;
935
936   g_mutex_lock (&component->io_mutex);
937   io_callback = component->io_callback;
938   io_user_data = component->io_user_data;
939   g_mutex_unlock (&component->io_mutex);
940
941   /* Allow this to be called with a NULL io_callback, since the caller can’t
942    * lock io_mutex to check beforehand. */
943   if (io_callback == NULL)
944     return;
945
946   g_assert (NICE_IS_AGENT (agent));
947   g_assert_cmpuint (stream_id, >, 0);
948   g_assert_cmpuint (component_id, >, 0);
949   g_assert (io_callback != NULL);
950
951   /* Only allocate a closure if the callback is being deferred to an idle
952    * handler. */
953   if (g_main_context_is_owner (component->ctx)) {
954     /* Thread owns the main context, so invoke the callback directly. */
955     agent_unlock_and_emit (agent);
956     io_callback (agent, stream_id,
957         component_id, buf_len, (gchar *) buf, io_user_data);
958     agent_lock (agent);
959   } else {
960     IOCallbackData *data;
961
962     g_mutex_lock (&component->io_mutex);
963
964     /* Slow path: Current thread doesn’t own the Component’s context at the
965      * moment, so schedule the callback in an idle handler. */
966     data = io_callback_data_new (buf, buf_len);
967     g_queue_push_tail (&component->pending_io_messages,
968         data);  /* transfer ownership */
969
970     nice_debug ("%s: **WARNING: SLOW PATH**", G_STRFUNC);
971
972     nice_component_schedule_io_callback (component);
973
974     g_mutex_unlock (&component->io_mutex);
975   }
976 }
977
978 /* Note: Must be called with the io_mutex held. */
979 static void
980 nice_component_schedule_io_callback (NiceComponent *component)
981 {
982   GSource *source;
983
984   /* Already scheduled or nothing to schedule? */
985   if (component->io_callback_id != 0 ||
986       g_queue_is_empty (&component->pending_io_messages))
987     return;
988
989   /* Add the idle callback. If nice_agent_attach_recv() is called with a
990    * NULL callback before this source is dispatched, the source will be
991    * destroyed, but any pending data will remain in
992    * component->pending_io_messages, ready to be picked up when a callback
993    * is re-attached, or if nice_agent_recv() is called. */
994   source = g_idle_source_new ();
995   g_source_set_priority (source, G_PRIORITY_DEFAULT);
996   g_source_set_callback (source, emit_io_callback_cb, component, NULL);
997   component->io_callback_id = g_source_attach (source, component->ctx);
998   g_source_unref (source);
999 }
1000
1001 /* Note: Must be called with the io_mutex held. */
1002 static void
1003 nice_component_deschedule_io_callback (NiceComponent *component)
1004 {
1005   /* Already descheduled? */
1006   if (component->io_callback_id == 0)
1007     return;
1008
1009   g_source_remove (component->io_callback_id);
1010   component->io_callback_id = 0;
1011 }
1012
1013 static void
1014 nice_component_class_init (NiceComponentClass *klass)
1015 {
1016   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1017
1018   object_class->constructed = nice_component_constructed;
1019   object_class->get_property = nice_component_get_property;
1020   object_class->set_property = nice_component_set_property;
1021   object_class->finalize = nice_component_finalize;
1022
1023   /**
1024    * NiceComponent:id:
1025    *
1026    * The unique numeric ID of the component.
1027    *
1028    * Since: 0.1.14
1029    */
1030   g_object_class_install_property (object_class, PROP_ID,
1031       g_param_spec_uint (
1032          "id",
1033          "ID",
1034          "The unique numeric ID of the component.",
1035          1, G_MAXUINT, 1,
1036          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
1037
1038   /**
1039    * NiceComponent:agent:
1040    *
1041    * The #NiceAgent this component belongs to.
1042    *
1043    * Since: 0.1.14
1044    */
1045   g_object_class_install_property (object_class, PROP_AGENT,
1046       g_param_spec_object (
1047          "agent",
1048          "Agent",
1049          "The NiceAgent this component belongs to.",
1050          NICE_TYPE_AGENT,
1051          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
1052
1053   /**
1054    * NiceComponent:stream:
1055    *
1056    * The #NiceStream this component belongs to.
1057    *
1058    * Since: 0.1.14
1059    */
1060   g_object_class_install_property (object_class, PROP_STREAM,
1061       g_param_spec_object (
1062          "stream",
1063          "Stream",
1064          "The NiceStream this component belongs to.",
1065          NICE_TYPE_STREAM,
1066          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
1067 }
1068
1069 static gboolean
1070 dummy_callback (gpointer data)
1071 {
1072   return G_SOURCE_CONTINUE;
1073 }
1074
1075 static void
1076 source_set_dummy_callback (GSource *source)
1077 {
1078   g_source_set_callback (source, dummy_callback, NULL, NULL);
1079 }
1080
1081 static void
1082 nice_component_init (NiceComponent *component)
1083 {
1084   g_atomic_int_inc (&n_components_created);
1085   nice_debug ("Created NiceComponent (%u created, %u destroyed)",
1086       n_components_created, n_components_destroyed);
1087
1088   component->id = 0;
1089   component->state = NICE_COMPONENT_STATE_DISCONNECTED;
1090   component->restart_candidate = NULL;
1091   component->tcp = NULL;
1092   g_weak_ref_init (&component->agent_ref, NULL);
1093
1094   g_mutex_init (&component->io_mutex);
1095   g_queue_init (&component->pending_io_messages);
1096   component->io_callback_id = 0;
1097
1098   component->own_ctx = g_main_context_new ();
1099   component->stop_cancellable = g_cancellable_new ();
1100   component->stop_cancellable_source =
1101       g_cancellable_source_new (component->stop_cancellable);
1102   source_set_dummy_callback (component->stop_cancellable_source);
1103   g_source_attach (component->stop_cancellable_source, component->own_ctx);
1104   component->ctx = g_main_context_ref (component->own_ctx);
1105
1106   /* Start off with a fresh main context and all I/O paused. This
1107    * will be updated when nice_agent_attach_recv() or nice_agent_recv_messages()
1108    * are called. */
1109   nice_component_set_io_context (component, NULL);
1110   nice_component_set_io_callback (component, NULL, NULL, NULL, 0, NULL);
1111
1112   g_queue_init (&component->queued_tcp_packets);
1113   g_queue_init (&component->incoming_checks);
1114 }
1115
1116 static void
1117 nice_component_constructed (GObject *obj)
1118 {
1119   NiceComponent *component;
1120   NiceAgent *agent;
1121
1122   component = NICE_COMPONENT (obj);
1123
1124   agent = g_weak_ref_get (&component->agent_ref);
1125   g_assert (agent != NULL);
1126   nice_agent_init_stun_agent (agent, &component->stun_agent);
1127
1128   g_object_unref (agent);
1129
1130   G_OBJECT_CLASS (nice_component_parent_class)->constructed (obj);
1131 }
1132
1133 static void
1134 nice_component_get_property (GObject *obj,
1135     guint property_id, GValue *value, GParamSpec *pspec)
1136 {
1137   NiceComponent *component;
1138
1139   component = NICE_COMPONENT (obj);
1140
1141   switch ((NiceComponentProperty) property_id)
1142     {
1143     case PROP_ID:
1144       g_value_set_uint (value, component->id);
1145       break;
1146
1147     case PROP_AGENT:
1148       {
1149         NiceAgent *agent;
1150
1151         agent = g_weak_ref_get (&component->agent_ref);
1152         if (agent)
1153           g_value_take_object (value, agent);
1154         break;
1155       }
1156     case PROP_STREAM:
1157       {
1158         NiceAgent *agent;
1159         NiceStream *stream = NULL;
1160
1161         agent = g_weak_ref_get (&component->agent_ref);
1162         if (agent) {
1163           stream = agent_find_stream (agent, component->stream_id);
1164           g_value_set_object (value, stream);
1165           g_object_unref (agent);
1166         }
1167         break;
1168       }
1169     default:
1170       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
1171     }
1172 }
1173
1174 static void
1175 nice_component_set_property (GObject *obj,
1176     guint property_id, const GValue *value, GParamSpec *pspec)
1177 {
1178   NiceComponent *component;
1179
1180   component = NICE_COMPONENT (obj);
1181
1182   switch ((NiceComponentProperty) property_id)
1183     {
1184     case PROP_ID:
1185       component->id = g_value_get_uint (value);
1186       break;
1187
1188     case PROP_AGENT:
1189       g_weak_ref_set (&component->agent_ref, g_value_get_object (value));
1190       break;
1191
1192     case PROP_STREAM:
1193       {
1194         NiceStream *stream = g_value_get_object (value);
1195         component->stream_id = stream->id;
1196       }
1197       break;
1198
1199     default:
1200       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
1201     }
1202 }
1203
1204 /* Must be called with the agent lock released as it could dispose of
1205  * NiceIOStreams. */
1206 static void
1207 nice_component_finalize (GObject *obj)
1208 {
1209   NiceComponent *cmp;
1210
1211   cmp = NICE_COMPONENT (obj);
1212
1213   /* Component should have been closed already. */
1214   g_warn_if_fail (cmp->local_candidates == NULL);
1215   g_warn_if_fail (cmp->remote_candidates == NULL);
1216   g_warn_if_fail (g_queue_get_length (&cmp->incoming_checks) == 0);
1217
1218   g_list_free_full (cmp->valid_candidates,
1219       (GDestroyNotify) nice_candidate_free);
1220
1221   g_clear_object (&cmp->tcp);
1222   g_clear_object (&cmp->stop_cancellable);
1223   g_clear_object (&cmp->iostream);
1224   g_mutex_clear (&cmp->io_mutex);
1225
1226   if (cmp->stop_cancellable_source != NULL) {
1227     g_source_destroy (cmp->stop_cancellable_source);
1228     g_source_unref (cmp->stop_cancellable_source);
1229   }
1230
1231   if (cmp->ctx != NULL) {
1232     g_main_context_unref (cmp->ctx);
1233     cmp->ctx = NULL;
1234   }
1235
1236   g_main_context_unref (cmp->own_ctx);
1237
1238   g_weak_ref_clear (&cmp->agent_ref);
1239
1240   g_atomic_int_inc (&n_components_destroyed);
1241   nice_debug ("Destroyed NiceComponent (%u created, %u destroyed)",
1242       n_components_created, n_components_destroyed);
1243
1244   G_OBJECT_CLASS (nice_component_parent_class)->finalize (obj);
1245 }
1246
1247 /**
1248  * ComponentSource:
1249  *
1250  * This is a GSource which wraps a single Component and is dispatched whenever
1251  * any of its NiceSockets are dispatched, i.e. it proxies all poll() events for
1252  * every socket in the Component. It is designed for use by GPollableInputStream
1253  * and GPollableOutputStream, so that a Component can be incorporated into a
1254  * custom main context iteration.
1255  *
1256  * The callbacks dispatched by a ComponentSource have type GPollableSourceFunc.
1257  *
1258  * ComponentSource supports adding a GCancellable child source which will
1259  * additionally dispatch if a provided GCancellable is cancelled.
1260  *
1261  * Internally, ComponentSource adds a new GSocketSource for each socket in the
1262  * Component. Changes to the Component’s list of sockets are detected on each
1263  * call to component_source_prepare(), which compares a stored age with the
1264  * current age of the Component’s socket list — if the socket list has changed,
1265  * the age will have increased (indicating added sockets) or will have been
1266  * reset to 0 (indicating all sockets have been closed).
1267  */
1268 typedef struct {
1269   GSource parent;
1270
1271   GObject *pollable_stream;  /* owned */
1272
1273   GWeakRef agent_ref;
1274   guint stream_id;
1275   guint component_id;
1276   guint component_socket_sources_age;
1277
1278   /* SocketSource, free with free_child_socket_source() */
1279   GSList *socket_sources;
1280
1281   GIOCondition condition;
1282 } ComponentSource;
1283
1284 static gboolean
1285 component_source_prepare (GSource *source, gint *timeout_)
1286 {
1287   ComponentSource *component_source = (ComponentSource *) source;
1288   NiceAgent *agent;
1289   NiceComponent *component;
1290   GSList *parentl, *childl;
1291
1292   agent = g_weak_ref_get (&component_source->agent_ref);
1293   if (!agent)
1294     return FALSE;
1295
1296   /* Needed due to accessing the Component. */
1297   agent_lock (agent);
1298
1299   if (!agent_find_component (agent,
1300           component_source->stream_id, component_source->component_id, NULL,
1301           &component))
1302     goto done;
1303
1304
1305   if (component->socket_sources_age ==
1306       component_source->component_socket_sources_age)
1307     goto done;
1308
1309   /* If the age has changed, either
1310    *  - one or more new socket has been prepended
1311    *  - old sockets have been removed
1312    */
1313
1314   /* Add the new child sources. */
1315
1316   for (parentl = component->socket_sources; parentl; parentl = parentl->next) {
1317     SocketSource *parent_socket_source = parentl->data;
1318     SocketSource *child_socket_source;
1319
1320     if (parent_socket_source->socket->fileno == NULL)
1321       continue;
1322
1323     /* Iterating the list of socket sources every time isn't a big problem
1324      * because the number of pairs is limited ~100 normally, so there will
1325      * rarely be more than 10.
1326      */
1327     childl = g_slist_find_custom (component_source->socket_sources,
1328         parent_socket_source->socket, _find_socket_source);
1329
1330     /* If we have reached this state, then all sources new sources have been
1331      * added, because they are always prepended.
1332      */
1333     if (childl)
1334       break;
1335
1336     child_socket_source = g_slice_new0 (SocketSource);
1337     child_socket_source->socket = parent_socket_source->socket;
1338     child_socket_source->source =
1339         g_socket_create_source (child_socket_source->socket->fileno, G_IO_IN,
1340             NULL);
1341     source_set_dummy_callback (child_socket_source->source);
1342     g_source_add_child_source (source, child_socket_source->source);
1343     g_source_unref (child_socket_source->source);
1344     component_source->socket_sources =
1345         g_slist_prepend (component_source->socket_sources, child_socket_source);
1346   }
1347
1348
1349   for (childl = component_source->socket_sources;
1350        childl;) {
1351     SocketSource *child_socket_source = childl->data;
1352     GSList *next = childl->next;
1353
1354     parentl = g_slist_find_custom (component->socket_sources,
1355       child_socket_source->socket, _find_socket_source);
1356
1357     /* If this is not a currently used socket, remove the relevant source */
1358     if (!parentl) {
1359       g_source_remove_child_source (source, child_socket_source->source);
1360       g_slice_free (SocketSource, child_socket_source);
1361       component_source->socket_sources =
1362           g_slist_delete_link (component_source->socket_sources, childl);
1363     }
1364
1365     childl = next;
1366   }
1367
1368
1369   /* Update the age. */
1370   component_source->component_socket_sources_age = component->socket_sources_age;
1371
1372  done:
1373
1374   agent_unlock_and_emit (agent);
1375   g_object_unref (agent);
1376
1377   /* We can’t be sure if the ComponentSource itself needs to be dispatched until
1378    * poll() is called on all the child sources. */
1379   return FALSE;
1380 }
1381
1382 static gboolean
1383 component_source_dispatch (GSource *source, GSourceFunc callback,
1384     gpointer user_data)
1385 {
1386   ComponentSource *component_source = (ComponentSource *) source;
1387   GPollableSourceFunc func = (GPollableSourceFunc) G_CALLBACK (callback);
1388
1389   return func (component_source->pollable_stream, user_data);
1390 }
1391
1392 static void
1393 free_child_socket_source (gpointer data)
1394 {
1395   g_slice_free (SocketSource, data);
1396 }
1397
1398 static void
1399 component_source_finalize (GSource *source)
1400 {
1401   ComponentSource *component_source = (ComponentSource *) source;
1402
1403   g_slist_free_full (component_source->socket_sources, free_child_socket_source);
1404
1405   g_weak_ref_clear (&component_source->agent_ref);
1406   g_object_unref (component_source->pollable_stream);
1407   component_source->pollable_stream = NULL;
1408 }
1409
1410 static gboolean
1411 component_source_closure_callback (GObject *pollable_stream, gpointer user_data)
1412 {
1413   GClosure *closure = user_data;
1414   GValue param_value = G_VALUE_INIT;
1415   GValue result_value = G_VALUE_INIT;
1416   gboolean retval;
1417
1418   g_value_init (&result_value, G_TYPE_BOOLEAN);
1419   g_value_init (&param_value, G_TYPE_OBJECT);
1420   g_value_set_object (&param_value, pollable_stream);
1421
1422   g_closure_invoke (closure, &result_value, 1, &param_value, NULL);
1423   retval = g_value_get_boolean (&result_value);
1424
1425   g_value_unset (&param_value);
1426   g_value_unset (&result_value);
1427
1428   return retval;
1429 }
1430
1431 static GSourceFuncs component_source_funcs = {
1432   component_source_prepare,
1433   NULL,  /* check */
1434   component_source_dispatch,
1435   component_source_finalize,
1436   (GSourceFunc) G_CALLBACK (component_source_closure_callback),
1437 };
1438
1439 /**
1440  * nice_component_source_new:
1441  * @agent: a #NiceAgent
1442  * @stream_id: The stream's id
1443  * @component_id: The component's number
1444  * @pollable_stream: a #GPollableInputStream or #GPollableOutputStream to pass
1445  * to dispatched callbacks
1446  * @cancellable: (allow-none): a #GCancellable, or %NULL
1447  *
1448  * Create a new #ComponentSource, a type of #GSource which proxies poll events
1449  * from all sockets in the given @component.
1450  *
1451  * A callback function of type #GPollableSourceFunc must be connected to the
1452  * returned #GSource using g_source_set_callback(). @pollable_stream is passed
1453  * to all callbacks dispatched from the #GSource, and a reference is held on it
1454  * by the #GSource.
1455  *
1456  * The #GSource will automatically update to poll sockets as they’re added to
1457  * the @component (e.g. during peer discovery).
1458  *
1459  * Returns: (transfer full): a new #ComponentSource; unref with g_source_unref()
1460  */
1461 GSource *
1462 nice_component_input_source_new (NiceAgent *agent, guint stream_id,
1463     guint component_id, GPollableInputStream *pollable_istream,
1464     GCancellable *cancellable)
1465 {
1466   ComponentSource *component_source;
1467
1468   g_assert (G_IS_POLLABLE_INPUT_STREAM (pollable_istream));
1469
1470   component_source =
1471       (ComponentSource *)
1472           g_source_new (&component_source_funcs, sizeof (ComponentSource));
1473   g_source_set_name ((GSource *) component_source, "ComponentSource");
1474
1475   component_source->component_socket_sources_age = 0;
1476   component_source->pollable_stream = g_object_ref (pollable_istream);
1477   g_weak_ref_init (&component_source->agent_ref, agent);
1478   component_source->stream_id = stream_id;
1479   component_source->component_id = component_id;
1480
1481   /* Add a cancellable source. */
1482   if (cancellable != NULL) {
1483     GSource *cancellable_source;
1484
1485     cancellable_source = g_cancellable_source_new (cancellable);
1486     source_set_dummy_callback (cancellable_source);
1487     g_source_add_child_source ((GSource *) component_source,
1488         cancellable_source);
1489     g_source_unref (cancellable_source);
1490   }
1491
1492   return (GSource *) component_source;
1493 }
1494
1495
1496 TurnServer *
1497 turn_server_new (const gchar *server_ip, guint server_port,
1498     const gchar *username, const gchar *password, NiceRelayType type)
1499 {
1500   TurnServer *turn = g_slice_new (TurnServer);
1501
1502   nice_address_init (&turn->server);
1503
1504   turn->ref_count = 1;
1505   if (nice_address_set_from_string (&turn->server, server_ip)) {
1506     nice_address_set_port (&turn->server, server_port);
1507   } else {
1508     g_slice_free (TurnServer, turn);
1509     return NULL;
1510   }
1511   turn->username = g_strdup (username);
1512   turn->password = g_strdup (password);
1513   turn->decoded_username =
1514       g_base64_decode ((gchar *)username, &turn->decoded_username_len);
1515   turn->decoded_password =
1516       g_base64_decode ((gchar *)password, &turn->decoded_password_len);
1517   turn->type = type;
1518
1519   return turn;
1520 }
1521
1522 TurnServer *
1523 turn_server_ref (TurnServer *turn)
1524 {
1525   turn->ref_count++;
1526
1527   return turn;
1528 }
1529
1530 void
1531 turn_server_unref (TurnServer *turn)
1532 {
1533   turn->ref_count--;
1534
1535   if (turn->ref_count == 0) {
1536     g_free (turn->username);
1537     g_free (turn->password);
1538     g_free (turn->decoded_username);
1539     g_free (turn->decoded_password);
1540     g_slice_free (TurnServer, turn);
1541   }
1542 }
1543
1544 void
1545 nice_component_add_valid_candidate (NiceAgent *agent, NiceComponent *component,
1546     const NiceCandidate *candidate)
1547 {
1548   guint count = 0;
1549   GList *item, *last = NULL;
1550
1551   for (item = component->valid_candidates; item; item = item->next) {
1552     NiceCandidate *cand = item->data;
1553
1554     last = item;
1555     count++;
1556     if (nice_candidate_equal_target (cand, candidate))
1557       return;
1558   }
1559
1560   /* New candidate */
1561
1562   if (nice_debug_is_enabled ()) {
1563     char str[INET6_ADDRSTRLEN];
1564     nice_address_to_string (&candidate->addr, str);
1565     nice_debug ("Agent %p :  %d:%d Adding valid source"
1566         " candidate: %s:%d trans: %d", agent,
1567         candidate->stream_id, candidate->component_id, str,
1568         nice_address_get_port (&candidate->addr), candidate->transport);
1569   }
1570
1571   component->valid_candidates = g_list_prepend (
1572       component->valid_candidates, nice_candidate_copy (candidate));
1573
1574   /* Delete the last one to make sure we don't have a list that is too long,
1575    * the candidates are not freed on ICE restart as this would be more complex,
1576    * we just keep the list not too long.
1577    */
1578   if (count > NICE_COMPONENT_MAX_VALID_CANDIDATES) {
1579     NiceCandidate *cand = last->data;
1580
1581     component->valid_candidates = g_list_delete_link (
1582         component->valid_candidates, last);
1583     nice_candidate_free (cand);
1584   }
1585 }
1586
1587 gboolean
1588 nice_component_verify_remote_candidate (NiceComponent *component,
1589     const NiceAddress *address, NiceSocket *nicesock)
1590 {
1591   GList *item;
1592
1593   if (component->fallback_mode)
1594     return TRUE;
1595
1596   for (item = component->valid_candidates; item; item = item->next) {
1597     NiceCandidate *cand = item->data;
1598
1599     if ((((nicesock->type == NICE_SOCKET_TYPE_TCP_BSD ||
1600                     nicesock->type == NICE_SOCKET_TYPE_UDP_TURN) &&
1601                 (cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE ||
1602                     cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE ||
1603                     cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_SO)) ||
1604             cand->transport == NICE_CANDIDATE_TRANSPORT_UDP) &&
1605         nice_address_equal (address, &cand->addr)) {
1606       /* fast return if it's already the first */
1607       if (item == component->valid_candidates)
1608         return TRUE;
1609
1610       /* Put the current candidate at the top so that in the normal use-case,
1611        * this function becomes O(1).
1612        */
1613       component->valid_candidates = g_list_remove_link (
1614           component->valid_candidates, item);
1615       component->valid_candidates = g_list_concat (item,
1616           component->valid_candidates);
1617
1618       return TRUE;
1619     }
1620   }
1621
1622   return FALSE;
1623 }
1624
1625 /* Must be called with agent lock held */
1626 /* Returns a transfer full GPtrArray of GSocket */
1627 GPtrArray *
1628 nice_component_get_sockets (NiceComponent *component)
1629 {
1630   GPtrArray *array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
1631   GSList *item;
1632
1633   for (item = component->local_candidates; item; item = item->next) {
1634     NiceCandidate *cand = item->data;
1635     NiceSocket *nicesock = cand->sockptr;
1636
1637     if (nicesock->fileno && !g_ptr_array_find (array, nicesock->fileno, NULL))
1638       g_ptr_array_add (array, g_object_ref (nicesock->fileno));
1639   }
1640
1641   return array;
1642 }