component.h 9.21 KB
Newer Older
1 2 3
/*
 * This file is part of the Nice GLib ICE library.
 *
4 5 6
 * (C) 2006-2010 Collabora Ltd.
 *  Contact: Youness Alaoui
 * (C) 2006-2010 Nokia Corporation. All rights reserved.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *  Contact: Kai Vehmanen
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Nice GLib ICE library.
 *
 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
 * Corporation. All Rights Reserved.
 *
 * Contributors:
 *   Dafydd Harries, Collabora Ltd.
26
 *   Youness Alaoui, Collabora Ltd.
27
 *   Kai Vehmanen, Nokia
28 29 30 31 32 33 34 35 36 37 38
 *
 * Alternatively, the contents of this file may be used under the terms of the
 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
 * case the provisions of LGPL are applicable instead of those above. If you
 * wish to allow use of your version of this file only under the terms of the
 * LGPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replace
 * them with the notice and other provisions required by the LGPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the LGPL.
 */
39 40 41 42 43 44

#ifndef _NICE_COMPONENT_H
#define _NICE_COMPONENT_H

#include <glib.h>

45 46
typedef struct _Component Component;

47
#include "agent.h"
48
#include "agent-priv.h"
49
#include "candidate.h"
50 51
#include "stun/stunagent.h"
#include "stun/usages/timer.h"
52 53
#include "pseudotcp.h"
#include "stream.h"
54
#include "socket.h"
55 56 57

G_BEGIN_DECLS

58

59 60
/* (ICE §4.1.1.1, ID-19)
 * ""For RTP-based media streams, the RTP itself has a component
61 62
 * ID of 1, and RTCP a component ID of 2.  If an agent is using RTCP it MUST
 * obtain a candidate for it.  If an agent is using both RTP and RTCP, it
Kai Vehmanen's avatar
Kai Vehmanen committed
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 71 72 73
struct _CandidatePairKeepalive
{
  NiceAgent *agent;
  GSource *tick_source;
74 75
  guint stream_id;
  guint component_id;
76 77 78 79 80
  StunTimer timer;
  uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE];
  StunMessage stun_message;
};

81 82 83 84
struct _CandidatePair
{
  NiceCandidate *local;
  NiceCandidate *remote;
85 86
  guint64 priority;           /**< candidate pair priority */
  CandidatePairKeepalive keepalive;
87
};
88

89 90 91
struct _IncomingCheck
{
  NiceAddress from;
92
  NiceSocket *local_socket;
93
  guint32 priority;
94
  gboolean use_candidate;
95 96
  uint8_t *username;
  uint16_t username_len;
97 98
};

99 100 101 102
/* A pair of a socket and the GSource which polls it from the main loop. All
 * GSources in a Component must be attached to the same main context:
 * component->ctx.
 *
103 104 105 106
 * Socket must be non-NULL, but source may be NULL if it has been detached.
 *
 * The Component is stored so this may be used as the user data for a GSource
 * callback. */
107 108 109
typedef struct {
  NiceSocket *socket;
  GSource *source;
110
  Component *component;
111 112
} SocketSource;

113

114
/* A message which has been received and processed (so is guaranteed not
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
 * to be a STUN packet, or to contain pseudo-TCP header bytes, for example), but
 * which hasn’t yet been sent to the client in an I/O callback. This could be
 * due to the main context not being run, or due to the I/O callback being
 * detached.
 *
 * The @offset member gives the byte offset into @buf which has already been
 * sent to the client. #IOCallbackData buffers remain in the
 * #Component::pending_io_messages queue until all of their bytes have been sent
 * to the client.
 *
 * @offset is guaranteed to be smaller than @buf_len. */
typedef struct {
  guint8 *buf;  /* owned */
  gsize buf_len;
  gsize offset;
} IOCallbackData;

IOCallbackData *
io_callback_data_new (const guint8 *buf, gsize buf_len);
void
io_callback_data_free (IOCallbackData *data);


138 139
struct _Component
{
140
  NiceComponentType type;
141
  guint id;                    /**< component id */
142
  NiceComponentState state;
143 144
  GSList *local_candidates;    /**< list of Candidate objs */
  GSList *remote_candidates;   /**< list of Candidate objs */
145 146
  GSList *socket_sources;      /**< list of SocketSource objs; must only grow monotonically */
  guint socket_sources_age;    /**< incremented when socket_sources changes */
147
  GSList *incoming_checks;     /**< list of IncomingCheck objs */
148
  GList *turn_servers;             /**< List of TURN servers */
149
  CandidatePair selected_pair; /**< independent from checklists, 
150
				    see ICE 11.1. "Sending Media" (ID-19) */
151
  NiceCandidate *restart_candidate; /**< for storing active remote candidate during a restart */
152

153 154
  /* I/O handling. The main context must always be non-NULL, and is used for all
   * socket recv() operations. All io_callback emissions are invoked in this
155 156
   * context too.
   *
157 158
   * recv_messages and io_callback are mutually exclusive, but it is allowed for
   * both to be NULL if the Component is not currently ready to receive data. */
159 160 161 162 163 164
  GMutex io_mutex;                  /**< protects io_callback, io_user_data,
                                         pending_io_messages and io_callback_id.
                                         immutable: can be accessed without
                                         holding the agent lock; if the agent
                                         lock is to be taken, it must always be
                                         taken before this one */
165 166
  NiceAgentRecvFunc io_callback;    /**< function called on io cb */
  gpointer io_user_data;            /**< data passed to the io function */
167
  GQueue pending_io_messages;       /**< queue of messages which have been
168 169 170 171 172 173
                                         received but not passed to the client
                                         in an I/O callback or recv() call yet.
                                         each element is an owned
                                         IOCallbackData */
  guint io_callback_id;             /* GSource ID of the I/O callback */

174
  GMainContext *own_ctx;            /**< own context for GSources for this
175
                                       component */
176 177
  GMainContext *ctx;                /**< context for GSources for this
                                       component (possibly set from the app) */
178 179 180 181
  NiceInputMessage *recv_messages;  /**< unowned messages for receiving into */
  guint n_recv_messages;            /**< length of recv_messages */
  NiceInputMessageIter recv_messages_iter; /**< current write position in
                                                recv_messages */
182 183
  GError **recv_buf_error;          /**< error information about failed reads */

184 185 186 187
  NiceAgent *agent;  /* unowned, immutable: can be accessed without holding the
                      * agent lock */
  Stream *stream;  /* unowned, immutable: can be accessed without holding the
                    * agent lock */
188

189 190
  GCancellable *stop_cancellable;

191 192
  PseudoTcpSocket *tcp;
  GSource* tcp_clock;
193
  long last_clock_timeout;
194
  gboolean tcp_readable;
195
  GCancellable *tcp_writable_cancellable;
196

197 198
  GIOStream *iostream;

199 200
  guint min_port;
  guint max_port;
201 202 203 204 205

  /* Queue of messages received before a selected socket was available to send
   * ACKs on. The messages are dequeued to the pseudo-TCP socket once a selected
   * UDP socket is available. This is only used for reliable Components. */
  GQueue queued_tcp_packets;
206 207 208
};

Component *
209
component_new (guint component_id, NiceAgent *agent, Stream *stream);
210 211 212 213

void
component_free (Component *cmp);

214 215 216
gboolean
component_find_pair (Component *cmp, NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair);

217 218 219
gboolean
component_restart (Component *cmp);

220 221 222
void
component_update_selected_pair (Component *component, const CandidatePair *pair);

223 224 225
NiceCandidate *
component_find_remote_candidate (const Component *component, const NiceAddress *addr, NiceCandidateTransport transport);

226 227 228 229
NiceCandidate *
component_set_selected_remote_candidate (NiceAgent *agent, Component *component,
    NiceCandidate *candidate);

230
void
231
component_attach_socket (Component *component, NiceSocket *socket);
232
void
233
component_detach_socket (Component *component, NiceSocket *socket);
234
void
235
component_detach_all_sockets (Component *component);
236 237 238
void
component_free_socket_sources (Component *component);

239
GSource *
240 241 242
component_source_new (NiceAgent *agent, guint stream_id,
    guint component_id, GObject *pollable_istream,
    GIOCondition condition, GCancellable *cancellable);
243

244 245
GMainContext *
component_dup_io_context (Component *component);
246
void
247 248 249
component_set_io_context (Component *component, GMainContext *context);
void
component_set_io_callback (Component *component,
250
    NiceAgentRecvFunc func, gpointer user_data,
251
    NiceInputMessage *recv_messages, guint n_recv_messages,
252
    GError **error);
253
void
254 255
component_emit_io_callback (Component *component,
    const guint8 *buf, gsize buf_len);
256

257 258 259
gboolean
component_has_io_callback (Component *component);

260 261 262 263
G_END_DECLS

#endif /* _NICE_COMPONENT_H */