2 * This file is part of the Nice GLib ICE library.
4 * (C) 2006-2010 Collabora Ltd.
5 * Contact: Youness Alaoui
6 * (C) 2006-2010 Nokia Corporation. All rights reserved.
7 * Contact: Kai Vehmanen
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/
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
19 * The Original Code is the Nice GLib ICE library.
21 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22 * Corporation. All Rights Reserved.
25 * Dafydd Harries, Collabora Ltd.
26 * Youness Alaoui, Collabora Ltd.
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.
40 #ifndef _NICE_COMPONENT_H
41 #define _NICE_COMPONENT_H
45 typedef struct _NiceComponent NiceComponent;
48 #include "agent-priv.h"
49 #include "candidate.h"
50 #include "stun/stunagent.h"
51 #include "stun/usages/timer.h"
52 #include "pseudotcp.h"
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.""
66 typedef struct _CandidatePair CandidatePair;
67 typedef struct _CandidatePairKeepalive CandidatePairKeepalive;
68 typedef struct _IncomingCheck IncomingCheck;
70 struct _CandidatePairKeepalive
72 guint64 next_tick; /* next tick timestamp */
77 uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE_IPV6];
78 StunMessage stun_message;
84 NiceCandidate *remote;
85 guint64 priority; /* candidate pair priority */
86 guint32 stun_priority;
87 CandidatePairKeepalive keepalive;
93 NiceSocket *local_socket;
95 gboolean use_candidate;
97 uint16_t username_len;
101 incoming_check_free (IncomingCheck *icheck);
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:
107 * Socket must be non-NULL, but source may be NULL if it has been detached.
109 * The Component is stored so this may be used as the user data for a GSource
114 NiceComponent *component;
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
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
129 * @offset is guaranteed to be smaller than @buf_len. */
131 guint8 *buf; /* owned */
137 io_callback_data_new (const guint8 *buf, gsize buf_len);
139 io_callback_data_free (IOCallbackData *data);
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))
153 struct _NiceComponent {
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 NiceCandidate *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
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
191 guint io_callback_id; /* GSource ID of the I/O callback */
193 GMainContext *own_ctx; /* own context for GSources for this
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
201 GError **recv_buf_error; /* error information about failed reads */
206 StunAgent stun_agent; /* This stun agent is used to validate all stun requests */
209 GCancellable *stop_cancellable;
210 GSource *stop_cancellable_source; /* owned */
212 PseudoTcpSocket *tcp;
214 guint64 last_clock_timeout;
215 gboolean tcp_readable;
216 GCancellable *tcp_writable_cancellable;
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;
230 GObjectClass parent_class;
231 } NiceComponentClass;
233 GType nice_component_get_type (void);
236 nice_component_new (guint component_id, NiceAgent *agent, NiceStream *stream);
239 nice_component_close (NiceAgent *agent, NiceComponent *component);
242 nice_component_find_pair (NiceComponent *component, NiceAgent *agent,
243 const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair);
246 nice_component_restart (NiceComponent *component);
249 nice_component_update_selected_pair (NiceAgent *agent, NiceComponent *component,
250 const CandidatePair *pair);
253 nice_component_find_remote_candidate (NiceComponent *component,
254 const NiceAddress *addr, NiceCandidateTransport transport);
257 nice_component_set_selected_remote_candidate (NiceComponent *component,
258 NiceAgent *agent, NiceCandidate *candidate);
261 nice_component_attach_socket (NiceComponent *component, NiceSocket *nsocket);
264 nice_component_remove_socket (NiceAgent *agent, NiceComponent *component,
265 NiceSocket *nsocket);
267 nice_component_detach_all_sockets (NiceComponent *component);
270 nice_component_free_socket_sources (NiceComponent *component);
273 nice_component_input_source_new (NiceAgent *agent, guint stream_id,
274 guint component_id, GPollableInputStream *pollable_istream,
275 GCancellable *cancellable);
278 nice_component_dup_io_context (NiceComponent *component);
280 nice_component_set_io_context (NiceComponent *component, GMainContext *context);
282 nice_component_set_io_callback (NiceComponent *component,
283 NiceAgentRecvFunc func, gpointer user_data,
284 NiceInputMessage *recv_messages, guint n_recv_messages,
287 nice_component_emit_io_callback (NiceAgent *agent, NiceComponent *component,
288 const guint8 *buf, gsize buf_len);
290 nice_component_has_io_callback (NiceComponent *component);
292 nice_component_clean_turn_servers (NiceAgent *agent, NiceComponent *component);
296 turn_server_new (const gchar *server_ip, guint server_port,
297 const gchar *username, const gchar *password, NiceRelayType type);
300 turn_server_ref (TurnServer *turn);
303 turn_server_unref (TurnServer *turn);
306 nice_component_add_valid_candidate (NiceAgent *agent, NiceComponent *component,
307 const NiceCandidate *candidate);
310 nice_component_verify_remote_candidate (NiceComponent *component,
311 const NiceAddress *address, NiceSocket *nicesock);
314 nice_component_get_sockets (NiceComponent *component);
318 #endif /* _NICE_COMPONENT_H */