1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2006-2010 Collabora Ltd.
5  *  Contact: Youness Alaoui
6  * (C) 2006-2010 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 #ifndef _NICE_COMPONENT_H
41 #define _NICE_COMPONENT_H
42 
43 #include <glib.h>
44 
45 typedef struct _NiceComponent NiceComponent;
46 
47 #include "agent.h"
48 #include "agent-priv.h"
49 #include "candidate-priv.h"
50 #include "stun/stunagent.h"
51 #include "stun/usages/timer.h"
52 #include "pseudotcp.h"
53 #include "stream.h"
54 #include "socket.h"
55 
56 G_BEGIN_DECLS
57 
58 
59 /* (ICE §4.1.1.1, ID-19)
60  * ""For RTP-based media streams, the RTP itself has a component
61  * ID of 1, and RTCP a component ID of 2.  If an agent is using RTCP it MUST
62  * obtain a candidate for it.  If an agent is using both RTP and RTCP, it
63  * would end up with 2*K host candidates if an agent has K interfaces.""
64  */
65 
66 typedef struct _CandidatePair CandidatePair;
67 typedef struct _CandidatePairKeepalive CandidatePairKeepalive;
68 typedef struct _IncomingCheck IncomingCheck;
69 
70 struct _CandidatePairKeepalive
71 {
72   guint64 next_tick;    /* next tick timestamp */
73   GSource *tick_source;
74   guint stream_id;
75   guint component_id;
76   StunTimer timer;
77   uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE_IPV6];
78   StunMessage stun_message;
79 };
80 
81 struct _CandidatePair
82 {
83   NiceCandidateImpl *local;
84   NiceCandidateImpl *remote;
85   guint64 priority;           /* candidate pair priority */
86   guint32 stun_priority;
87   CandidatePairKeepalive keepalive;
88 };
89 
90 struct _IncomingCheck
91 {
92   NiceAddress from;
93   NiceSocket *local_socket;
94   guint32 priority;
95   gboolean use_candidate;
96   uint8_t *username;
97   uint16_t username_len;
98 };
99 
100 void
101 incoming_check_free (IncomingCheck *icheck);
102 
103 /* A pair of a socket and the GSource which polls it from the main loop. All
104  * GSources in a Component must be attached to the same main context:
105  * component->ctx.
106  *
107  * Socket must be non-NULL, but source may be NULL if it has been detached.
108  *
109  * The Component is stored so this may be used as the user data for a GSource
110  * callback. */
111 typedef struct {
112   NiceSocket *socket;
113   GSource *source;
114   NiceComponent *component;
115 } SocketSource;
116 
117 
118 /* A message which has been received and processed (so is guaranteed not
119  * to be a STUN packet, or to contain pseudo-TCP header bytes, for example), but
120  * which hasn’t yet been sent to the client in an I/O callback. This could be
121  * due to the main context not being run, or due to the I/O callback being
122  * detached.
123  *
124  * The @offset member gives the byte offset into @buf which has already been
125  * sent to the client. #IOCallbackData buffers remain in the
126  * #Component::pending_io_messages queue until all of their bytes have been sent
127  * to the client.
128  *
129  * @offset is guaranteed to be smaller than @buf_len. */
130 typedef struct {
131   guint8 *buf;  /* owned */
132   gsize buf_len;
133   gsize offset;
134 } IOCallbackData;
135 
136 IOCallbackData *
137 io_callback_data_new (const guint8 *buf, gsize buf_len);
138 void
139 io_callback_data_free (IOCallbackData *data);
140 
141 #define NICE_TYPE_COMPONENT nice_component_get_type()
142 #define NICE_COMPONENT(obj) \
143   (G_TYPE_CHECK_INSTANCE_CAST ((obj), NICE_TYPE_COMPONENT, NiceComponent))
144 #define NICE_COMPONENT_CLASS(klass) \
145   (G_TYPE_CHECK_CLASS_CAST ((klass), NICE_TYPE_COMPONENT, NiceComponentClass))
146 #define NICE_IS_COMPONENT(obj) \
147   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NICE_TYPE_COMPONENT))
148 #define NICE_IS_COMPONENT_CLASS(klass) \
149   (G_TYPE_CHECK_CLASS_TYPE ((klass), NICE_TYPE_COMPONENT))
150 #define NICE_COMPONENT_GET_CLASS(obj) \
151   (G_TYPE_INSTANCE_GET_CLASS ((obj), NICE_TYPE_COMPONENT, NiceComponentClass))
152 
153 struct _NiceComponent {
154   /*< private >*/
155   GObject parent;
156 
157   NiceComponentType type;
158   guint id;                    /* component id */
159   NiceComponentState state;
160   GSList *local_candidates;    /* list of NiceCandidate objs */
161   GSList *remote_candidates;   /* list of NiceCandidate objs */
162   GList *valid_candidates;     /* list of owned remote NiceCandidates that are part of valid pairs */
163   GSList *socket_sources;      /* list of SocketSource objs; must only grow monotonically */
164   guint socket_sources_age;    /* incremented when socket_sources changes */
165   GQueue incoming_checks;     /* list of IncomingCheck objs */
166   GList *turn_servers;             /* List of TurnServer objs */
167   CandidatePair selected_pair; /* independent from checklists,
168 				    see ICE 11.1. "Sending Media" (ID-19) */
169   gboolean fallback_mode;      /* in this case, accepts packets from all, ignore candidate validation */
170   NiceCandidate *restart_candidate; /* for storing active remote candidate during a restart */
171   NiceCandidateImpl *turn_candidate; /* for storing active turn candidate if turn servers have been cleared */
172   /* I/O handling. The main context must always be non-NULL, and is used for all
173    * socket recv() operations. All io_callback emissions are invoked in this
174    * context too.
175    *
176    * recv_messages and io_callback are mutually exclusive, but it is allowed for
177    * both to be NULL if the Component is not currently ready to receive data. */
178   GMutex io_mutex;                  /* protects io_callback, io_user_data,
179                                          pending_io_messages and io_callback_id.
180                                          immutable: can be accessed without
181                                          holding the agent lock; if the agent
182                                          lock is to be taken, it must always be
183                                          taken before this one */
184   NiceAgentRecvFunc io_callback;    /* function called on io cb */
185   gpointer io_user_data;            /* data passed to the io function */
186   GQueue pending_io_messages;       /* queue of messages which have been
187                                          received but not passed to the client
188                                          in an I/O callback or recv() call yet.
189                                          each element is an owned
190                                          IOCallbackData */
191   guint io_callback_id;             /* GSource ID of the I/O callback */
192 
193   GMainContext *own_ctx;            /* own context for GSources for this
194                                        component */
195   GMainContext *ctx;                /* context for GSources for this
196                                        component (possibly set from the app) */
197   NiceInputMessage *recv_messages;  /* unowned messages for receiving into */
198   guint n_recv_messages;            /* length of recv_messages */
199   NiceInputMessageIter recv_messages_iter; /* current write position in
200                                                 recv_messages */
201   GError **recv_buf_error;          /* error information about failed reads */
202 
203   GWeakRef agent_ref;
204   guint stream_id;
205 
206   StunAgent stun_agent; /* This stun agent is used to validate all stun requests */
207 
208 
209   GCancellable *stop_cancellable;
210   GSource *stop_cancellable_source;  /* owned */
211 
212   PseudoTcpSocket *tcp;
213   GSource* tcp_clock;
214   guint64 last_clock_timeout;
215   gboolean tcp_readable;
216   GCancellable *tcp_writable_cancellable;
217 
218   GIOStream *iostream;
219 
220   guint min_port;
221   guint max_port;
222 
223   /* Queue of messages received before a selected socket was available to send
224    * ACKs on. The messages are dequeued to the pseudo-TCP socket once a selected
225    * UDP socket is available. This is only used for reliable Components. */
226   GQueue queued_tcp_packets;
227 };
228 
229 typedef struct {
230   GObjectClass parent_class;
231 } NiceComponentClass;
232 
233 GType nice_component_get_type (void);
234 
235 NiceComponent *
236 nice_component_new (guint component_id, NiceAgent *agent, NiceStream *stream);
237 
238 void
239 nice_component_close (NiceAgent *agent, NiceComponent *component);
240 
241 gboolean
242 nice_component_find_pair (NiceComponent *component, NiceAgent *agent,
243     const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair);
244 
245 void
246 nice_component_restart (NiceComponent *component);
247 
248 void
249 nice_component_update_selected_pair (NiceAgent *agent, NiceComponent *component,
250     const CandidatePair *pair);
251 
252 NiceCandidate *
253 nice_component_find_remote_candidate (NiceComponent *component,
254     const NiceAddress *addr, NiceCandidateTransport transport);
255 
256 NiceCandidateImpl *
257 nice_component_set_selected_remote_candidate (NiceComponent *component,
258     NiceAgent *agent, NiceCandidate *candidate);
259 
260 void
261 nice_component_attach_socket (NiceComponent *component, NiceSocket *nsocket);
262 
263 void
264 nice_component_remove_socket (NiceAgent *agent, NiceComponent *component,
265     NiceSocket *nsocket);
266 void
267 nice_component_detach_all_sockets (NiceComponent *component);
268 
269 void
270 nice_component_free_socket_sources (NiceComponent *component);
271 
272 GSource *
273 nice_component_input_source_new (NiceAgent *agent, guint stream_id,
274     guint component_id, GPollableInputStream *pollable_istream,
275     GCancellable *cancellable);
276 
277 GMainContext *
278 nice_component_dup_io_context (NiceComponent *component);
279 void
280 nice_component_set_io_context (NiceComponent *component, GMainContext *context);
281 void
282 nice_component_set_io_callback (NiceComponent *component,
283     NiceAgentRecvFunc func, gpointer user_data,
284     NiceInputMessage *recv_messages, guint n_recv_messages,
285     GError **error);
286 void
287 nice_component_emit_io_callback (NiceAgent *agent, NiceComponent *component,
288     const guint8 *buf, gsize buf_len);
289 gboolean
290 nice_component_has_io_callback (NiceComponent *component);
291 void
292 nice_component_clean_turn_servers (NiceAgent *agent, NiceComponent *component);
293 
294 
295 TurnServer *
296 turn_server_new (const gchar *server_ip, guint server_port,
297     const gchar *username, const gchar *password, NiceRelayType type);
298 
299 TurnServer *
300 turn_server_ref (TurnServer *turn);
301 
302 void
303 turn_server_unref (TurnServer *turn);
304 
305 void
306 nice_component_add_valid_candidate (NiceAgent *agent, NiceComponent *component,
307     const NiceCandidate *candidate);
308 
309 gboolean
310 nice_component_verify_remote_candidate (NiceComponent *component,
311     const NiceAddress *address, NiceSocket *nicesock);
312 
313 GPtrArray *
314 nice_component_get_sockets (NiceComponent *component);
315 
316 G_END_DECLS
317 
318 #endif /* _NICE_COMPONENT_H */
319 
320