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