Tristan Matthews | 0a329cc | 2013-07-17 13:20:14 -0400 | [diff] [blame] | 1 | /* $Id$ */ |
| 2 | /* |
| 3 | * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
| 4 | * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ |
| 20 | #ifndef __PJNATH_ICE_SESSION_H__ |
| 21 | #define __PJNATH_ICE_SESSION_H__ |
| 22 | |
| 23 | /** |
| 24 | * @file ice_session.h |
| 25 | * @brief ICE session management |
| 26 | */ |
| 27 | #include <pjnath/types.h> |
| 28 | #include <pjnath/stun_session.h> |
| 29 | #include <pjnath/errno.h> |
| 30 | #include <pj/sock.h> |
| 31 | #include <pj/timer.h> |
| 32 | |
| 33 | PJ_BEGIN_DECL |
| 34 | |
| 35 | |
| 36 | /** |
| 37 | * @addtogroup PJNATH_ICE_SESSION |
| 38 | * @{ |
| 39 | * |
| 40 | * This module describes #pj_ice_sess, a transport independent ICE session, |
| 41 | * part of PJNATH - the Open Source NAT helper library. |
| 42 | * |
| 43 | * \section pj_ice_sess_sec ICE Session |
| 44 | * |
| 45 | * An ICE session, represented by #pj_ice_sess structure, is the lowest |
| 46 | * abstraction of ICE in PJNATH, and it is used to perform and manage |
| 47 | * connectivity checks of transport address candidates <b>within a |
| 48 | * single media stream</b> (note: this differs from what is described |
| 49 | * in ICE draft, where an ICE session manages the whole media sessions |
| 50 | * rather than just a single stream). |
| 51 | * |
| 52 | * The ICE session described here is independent from any transports, |
| 53 | * meaning that the actual network I/O for this session would have to |
| 54 | * be performed by the application, or higher layer abstraction. |
| 55 | * Using this framework, application would give any incoming packets to |
| 56 | * the ICE session, and it would provide the ICE session with a callback |
| 57 | * to send outgoing message. |
| 58 | * |
| 59 | * For higher abstraction of ICE where transport is included, please |
| 60 | * see \ref PJNATH_ICE_STREAM_TRANSPORT. |
| 61 | * |
| 62 | * \subsection pj_ice_sess_using_sec Using The ICE Session |
| 63 | * |
| 64 | * The steps below describe how to use ICE session. Alternatively application |
| 65 | * can use the higher level ICE API, \ref PJNATH_ICE_STREAM_TRANSPORT, |
| 66 | * which has provided the integration of ICE with socket transport. |
| 67 | * |
| 68 | * The steps to use ICE session is similar for both offerer and |
| 69 | * answerer: |
| 70 | * - create ICE session with #pj_ice_sess_create(). Among other things, |
| 71 | * application needs to specify: |
| 72 | * - STUN configuration (pj_stun_config), containing STUN settings |
| 73 | * such as timeout values and the instances of timer heap and |
| 74 | * ioqueue. |
| 75 | * - Session name, useful for identifying this session in the log. |
| 76 | * - Initial ICE role (#pj_ice_sess_role). The role can be changed |
| 77 | * at later time with #pj_ice_sess_change_role(), and ICE session |
| 78 | * can also change its role automatically when it detects role |
| 79 | * conflict. |
| 80 | * - Number of components in the media session. |
| 81 | * - Callback to receive ICE events (#pj_ice_sess_cb) |
| 82 | * - Optional local ICE username and password. If these arguments |
| 83 | * are NULL, they will be generated randomly. |
| 84 | * - Add local candidates for each component, with #pj_ice_sess_add_cand(). |
| 85 | * A candidate is represented with #pj_ice_sess_cand structure. |
| 86 | * Each component must be provided with at least one candidate, and |
| 87 | * all components must have the same number of candidates. Failing |
| 88 | * to comply with this will cause failure during pairing process. |
| 89 | * - Create offer to describe local ICE candidates. ICE session does not |
| 90 | * provide a function to create such offer, but application should be |
| 91 | * able to create one since it knows about all components and candidates. |
| 92 | * If application uses \ref PJNATH_ICE_STREAM_TRANSPORT, it can |
| 93 | * enumerate local candidates by calling #pj_ice_strans_enum_cands(). |
| 94 | * Application may use #pj_ice_sess_find_default_cand() to let ICE |
| 95 | * session chooses the default transport address to be used in SDP |
| 96 | * c= and m= lines. |
| 97 | * - Send the offer to remote endpoint using signaling such as SIP. |
| 98 | * - Once application has received the answer, it should parse this |
| 99 | * answer, build array of remote candidates, and create check lists by |
| 100 | * calling #pj_ice_sess_create_check_list(). This process is known as |
| 101 | * pairing the candidates, and will result in the creation of check lists. |
| 102 | * - Once checklist has been created, application then can call |
| 103 | * #pj_ice_sess_start_check() to instruct ICE session to start |
| 104 | * performing connectivity checks. The ICE session performs the |
| 105 | * connectivity checks by processing each check in the checklists. |
| 106 | * - Application will be notified about the result of ICE connectivity |
| 107 | * checks via the callback that was given in #pj_ice_sess_create() |
| 108 | * above. |
| 109 | * |
| 110 | * To send data, application calls #pj_ice_sess_send_data(). If ICE |
| 111 | * negotiation has not completed, ICE session would simply drop the data, |
| 112 | * and return error to caller. If ICE negotiation has completed |
| 113 | * successfully, ICE session will in turn call the \a on_tx_pkt |
| 114 | * callback of #pj_ice_sess_cb instance that was previously registered |
| 115 | * in #pj_ice_sess_create() above. |
| 116 | * |
| 117 | * When application receives any packets on the underlying sockets, it |
| 118 | * must call #pj_ice_sess_on_rx_pkt(). The ICE session will inspect the |
| 119 | * packet to decide whether to process it locally (if the packet is a |
| 120 | * STUN message and is part of ICE session) or otherwise pass it back to |
| 121 | * application via \a on_rx_data callback. |
| 122 | */ |
| 123 | |
| 124 | /** |
| 125 | * Forward declaration for checklist. |
| 126 | */ |
| 127 | typedef struct pj_ice_sess_checklist pj_ice_sess_checklist; |
| 128 | |
| 129 | /** |
| 130 | * This enumeration describes the type of an ICE candidate. |
| 131 | */ |
| 132 | typedef enum pj_ice_cand_type |
| 133 | { |
| 134 | /** |
| 135 | * ICE host candidate. A host candidate represents the actual local |
| 136 | * transport address in the host. |
| 137 | */ |
| 138 | PJ_ICE_CAND_TYPE_HOST, |
| 139 | |
| 140 | /** |
| 141 | * ICE server reflexive candidate, which represents the public mapped |
| 142 | * address of the local address, and is obtained by sending STUN |
| 143 | * Binding request from the host candidate to a STUN server. |
| 144 | */ |
| 145 | PJ_ICE_CAND_TYPE_SRFLX, |
| 146 | |
| 147 | /** |
| 148 | * ICE peer reflexive candidate, which is the address as seen by peer |
| 149 | * agent during connectivity check. |
| 150 | */ |
| 151 | PJ_ICE_CAND_TYPE_PRFLX, |
| 152 | |
| 153 | /** |
| 154 | * ICE relayed candidate, which represents the address allocated in |
| 155 | * TURN server. |
| 156 | */ |
| 157 | PJ_ICE_CAND_TYPE_RELAYED |
| 158 | |
| 159 | } pj_ice_cand_type; |
| 160 | |
| 161 | |
| 162 | /** Forward declaration for pj_ice_sess */ |
| 163 | typedef struct pj_ice_sess pj_ice_sess; |
| 164 | |
| 165 | /** Forward declaration for pj_ice_sess_check */ |
| 166 | typedef struct pj_ice_sess_check pj_ice_sess_check; |
| 167 | |
| 168 | |
| 169 | /** |
| 170 | * This structure describes ICE component. |
| 171 | * A media stream may require multiple components, each of which has |
| 172 | * to work for the media stream as a whole to work. For media streams |
| 173 | * based on RTP, there are two components per media stream - one for RTP, |
| 174 | * and one for RTCP. |
| 175 | */ |
| 176 | typedef struct pj_ice_sess_comp |
| 177 | { |
| 178 | /** |
| 179 | * Pointer to ICE check with highest priority which connectivity check |
| 180 | * has been successful. The value will be NULL if a no successful check |
| 181 | * has not been found for this component. |
| 182 | */ |
| 183 | pj_ice_sess_check *valid_check; |
| 184 | |
| 185 | /** |
| 186 | * Pointer to ICE check with highest priority which connectivity check |
| 187 | * has been successful and it has been nominated. The value may be NULL |
| 188 | * if there is no such check yet. |
| 189 | */ |
| 190 | pj_ice_sess_check *nominated_check; |
| 191 | |
| 192 | /** |
| 193 | * The STUN session to be used to send and receive STUN messages for this |
| 194 | * component. |
| 195 | */ |
| 196 | pj_stun_session *stun_sess; |
| 197 | |
| 198 | } pj_ice_sess_comp; |
| 199 | |
| 200 | |
| 201 | /** |
| 202 | * Data structure to be attached to internal message processing. |
| 203 | */ |
| 204 | typedef struct pj_ice_msg_data |
| 205 | { |
| 206 | /** Transport ID for this message */ |
| 207 | unsigned transport_id; |
| 208 | |
| 209 | /** Flag to indicate whether data.req contains data */ |
| 210 | pj_bool_t has_req_data; |
| 211 | |
| 212 | /** The data */ |
| 213 | union data { |
| 214 | /** Request data */ |
| 215 | struct request_data { |
| 216 | pj_ice_sess *ice; /**< ICE session */ |
| 217 | pj_ice_sess_checklist *clist; /**< Checklist */ |
| 218 | unsigned ckid; /**< Check ID */ |
| 219 | } req; |
| 220 | } data; |
| 221 | |
| 222 | } pj_ice_msg_data; |
| 223 | |
| 224 | |
| 225 | /** |
| 226 | * This structure describes an ICE candidate. |
| 227 | * ICE candidate is a transport address that is to be tested by ICE |
| 228 | * procedures in order to determine its suitability for usage for |
| 229 | * receipt of media. Candidates also have properties - their type |
| 230 | * (server reflexive, relayed or host), priority, foundation, and |
| 231 | * base. |
| 232 | */ |
| 233 | typedef struct pj_ice_sess_cand |
| 234 | { |
| 235 | /** |
| 236 | * The candidate type, as described in #pj_ice_cand_type enumeration. |
| 237 | */ |
| 238 | pj_ice_cand_type type; |
| 239 | |
| 240 | /** |
| 241 | * Status of this candidate. The value will be PJ_SUCCESS if candidate |
| 242 | * address has been resolved successfully, PJ_EPENDING when the address |
| 243 | * resolution process is in progress, or other value when the address |
| 244 | * resolution has completed with failure. |
| 245 | */ |
| 246 | pj_status_t status; |
| 247 | |
| 248 | /** |
| 249 | * The component ID of this candidate. Note that component IDs starts |
| 250 | * with one for RTP and two for RTCP. In other words, it's not zero |
| 251 | * based. |
| 252 | */ |
| 253 | pj_uint8_t comp_id; |
| 254 | |
| 255 | /** |
| 256 | * Transport ID to be used to send packets for this candidate. |
| 257 | */ |
| 258 | pj_uint8_t transport_id; |
| 259 | |
| 260 | /** |
| 261 | * Local preference value, which typically is 65535. |
| 262 | */ |
| 263 | pj_uint16_t local_pref; |
| 264 | |
| 265 | /** |
| 266 | * The foundation string, which is an identifier which value will be |
| 267 | * equivalent for two candidates that are of the same type, share the |
| 268 | * same base, and come from the same STUN server. The foundation is |
| 269 | * used to optimize ICE performance in the Frozen algorithm. |
| 270 | */ |
| 271 | pj_str_t foundation; |
| 272 | |
| 273 | /** |
| 274 | * The candidate's priority, a 32-bit unsigned value which value will be |
| 275 | * calculated by the ICE session when a candidate is registered to the |
| 276 | * ICE session. |
| 277 | */ |
| 278 | pj_uint32_t prio; |
| 279 | |
| 280 | /** |
| 281 | * IP address of this candidate. For host candidates, this represents |
| 282 | * the local address of the socket. For reflexive candidates, the value |
| 283 | * will be the public address allocated in NAT router for the host |
| 284 | * candidate and as reported in MAPPED-ADDRESS or XOR-MAPPED-ADDRESS |
| 285 | * attribute of STUN Binding request. For relayed candidate, the value |
| 286 | * will be the address allocated in the TURN server by STUN Allocate |
| 287 | * request. |
| 288 | */ |
| 289 | pj_sockaddr addr; |
| 290 | |
| 291 | /** |
| 292 | * Base address of this candidate. "Base" refers to the address an agent |
| 293 | * sends from for a particular candidate. For host candidates, the base |
| 294 | * is the same as the host candidate itself. For reflexive candidates, |
| 295 | * the base is the local IP address of the socket. For relayed candidates, |
| 296 | * the base address is the transport address allocated in the TURN server |
| 297 | * for this candidate. |
| 298 | */ |
| 299 | pj_sockaddr base_addr; |
| 300 | |
| 301 | /** |
| 302 | * Related address, which is used for informational only and is not used |
| 303 | * in any way by the ICE session. |
| 304 | */ |
| 305 | pj_sockaddr rel_addr; |
| 306 | |
| 307 | } pj_ice_sess_cand; |
| 308 | |
| 309 | |
| 310 | /** |
| 311 | * This enumeration describes the state of ICE check. |
| 312 | */ |
| 313 | typedef enum pj_ice_sess_check_state |
| 314 | { |
| 315 | /** |
| 316 | * A check for this pair hasn't been performed, and it can't |
| 317 | * yet be performed until some other check succeeds, allowing this |
| 318 | * pair to unfreeze and move into the Waiting state. |
| 319 | */ |
| 320 | PJ_ICE_SESS_CHECK_STATE_FROZEN, |
| 321 | |
| 322 | /** |
| 323 | * A check has not been performed for this pair, and can be |
| 324 | * performed as soon as it is the highest priority Waiting pair on |
| 325 | * the check list. |
| 326 | */ |
| 327 | PJ_ICE_SESS_CHECK_STATE_WAITING, |
| 328 | |
| 329 | /** |
| 330 | * A check has not been performed for this pair, and can be |
| 331 | * performed as soon as it is the highest priority Waiting pair on |
| 332 | * the check list. |
| 333 | */ |
| 334 | PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS, |
| 335 | |
| 336 | /** |
| 337 | * A check has not been performed for this pair, and can be |
| 338 | * performed as soon as it is the highest priority Waiting pair on |
| 339 | * the check list. |
| 340 | */ |
| 341 | PJ_ICE_SESS_CHECK_STATE_SUCCEEDED, |
| 342 | |
| 343 | /** |
| 344 | * A check for this pair was already done and failed, either |
| 345 | * never producing any response or producing an unrecoverable failure |
| 346 | * response. |
| 347 | */ |
| 348 | PJ_ICE_SESS_CHECK_STATE_FAILED |
| 349 | |
| 350 | } pj_ice_sess_check_state; |
| 351 | |
| 352 | |
| 353 | /** |
| 354 | * This structure describes an ICE connectivity check. An ICE check |
| 355 | * contains a candidate pair, and will involve sending STUN Binding |
| 356 | * Request transaction for the purposes of verifying connectivity. |
| 357 | * A check is sent from the local candidate to the remote candidate |
| 358 | * of a candidate pair. |
| 359 | */ |
| 360 | struct pj_ice_sess_check |
| 361 | { |
| 362 | /** |
| 363 | * Pointer to local candidate entry of this check. |
| 364 | */ |
| 365 | pj_ice_sess_cand *lcand; |
| 366 | |
| 367 | /** |
| 368 | * Pointer to remote candidate entry of this check. |
| 369 | */ |
| 370 | pj_ice_sess_cand *rcand; |
| 371 | |
| 372 | /** |
| 373 | * Check priority. |
| 374 | */ |
| 375 | pj_timestamp prio; |
| 376 | |
| 377 | /** |
| 378 | * Connectivity check state. |
| 379 | */ |
| 380 | pj_ice_sess_check_state state; |
| 381 | |
| 382 | /** |
| 383 | * STUN transmit data containing STUN Binding request that was sent |
| 384 | * as part of this check. The value will only be set when this check |
| 385 | * has a pending transaction, and is used to cancel the transaction |
| 386 | * when other check has succeeded. |
| 387 | */ |
| 388 | pj_stun_tx_data *tdata; |
| 389 | |
| 390 | /** |
| 391 | * Flag to indicate whether this check is nominated. A nominated check |
| 392 | * contains USE-CANDIDATE attribute in its STUN Binding request. |
| 393 | */ |
| 394 | pj_bool_t nominated; |
| 395 | |
| 396 | /** |
| 397 | * When the check failed, this will contain the failure status of the |
| 398 | * STUN transaction. |
| 399 | */ |
| 400 | pj_status_t err_code; |
| 401 | }; |
| 402 | |
| 403 | |
| 404 | /** |
| 405 | * This enumeration describes ICE checklist state. |
| 406 | */ |
| 407 | typedef enum pj_ice_sess_checklist_state |
| 408 | { |
| 409 | /** |
| 410 | * The checklist is not yet running. |
| 411 | */ |
| 412 | PJ_ICE_SESS_CHECKLIST_ST_IDLE, |
| 413 | |
| 414 | /** |
| 415 | * In this state, ICE checks are still in progress for this |
| 416 | * media stream. |
| 417 | */ |
| 418 | PJ_ICE_SESS_CHECKLIST_ST_RUNNING, |
| 419 | |
| 420 | /** |
| 421 | * In this state, ICE checks have completed for this media stream, |
| 422 | * either successfully or with failure. |
| 423 | */ |
| 424 | PJ_ICE_SESS_CHECKLIST_ST_COMPLETED |
| 425 | |
| 426 | } pj_ice_sess_checklist_state; |
| 427 | |
| 428 | |
| 429 | /** |
| 430 | * This structure represents ICE check list, that is an ordered set of |
| 431 | * candidate pairs that an agent will use to generate checks. |
| 432 | */ |
| 433 | struct pj_ice_sess_checklist |
| 434 | { |
| 435 | /** |
| 436 | * The checklist state. |
| 437 | */ |
| 438 | pj_ice_sess_checklist_state state; |
| 439 | |
| 440 | /** |
| 441 | * Number of candidate pairs (checks). |
| 442 | */ |
| 443 | unsigned count; |
| 444 | |
| 445 | /** |
| 446 | * Array of candidate pairs (checks). |
| 447 | */ |
| 448 | pj_ice_sess_check checks[PJ_ICE_MAX_CHECKS]; |
| 449 | |
| 450 | /** |
| 451 | * A timer used to perform periodic check for this checklist. |
| 452 | */ |
| 453 | pj_timer_entry timer; |
| 454 | |
| 455 | }; |
| 456 | |
| 457 | |
| 458 | /** |
| 459 | * This structure contains callbacks that will be called by the ICE |
| 460 | * session. |
| 461 | */ |
| 462 | typedef struct pj_ice_sess_cb |
| 463 | { |
| 464 | /** |
| 465 | * An optional callback that will be called by the ICE session when |
| 466 | * ICE negotiation has completed, successfully or with failure. |
| 467 | * |
| 468 | * @param ice The ICE session. |
| 469 | * @param status Will contain PJ_SUCCESS if ICE negotiation is |
| 470 | * successful, or some error code. |
| 471 | */ |
| 472 | void (*on_ice_complete)(pj_ice_sess *ice, pj_status_t status); |
| 473 | |
| 474 | /** |
| 475 | * A mandatory callback which will be called by the ICE session when |
| 476 | * it needs to send outgoing STUN packet. |
| 477 | * |
| 478 | * @param ice The ICE session. |
| 479 | * @param comp_id ICE component ID. |
| 480 | * @param transport_id Transport ID. |
| 481 | * @param pkt The STUN packet. |
| 482 | * @param size The size of the packet. |
| 483 | * @param dst_addr Packet destination address. |
| 484 | * @param dst_addr_len Length of destination address. |
| 485 | */ |
| 486 | pj_status_t (*on_tx_pkt)(pj_ice_sess *ice, unsigned comp_id, |
| 487 | unsigned transport_id, |
| 488 | const void *pkt, pj_size_t size, |
| 489 | const pj_sockaddr_t *dst_addr, |
| 490 | unsigned dst_addr_len); |
| 491 | |
| 492 | /** |
| 493 | * A mandatory callback which will be called by the ICE session when |
| 494 | * it receives packet which is not part of ICE negotiation. |
| 495 | * |
| 496 | * @param ice The ICE session. |
| 497 | * @param comp_id ICE component ID. |
| 498 | * @param transport_id Transport ID. |
| 499 | * @param pkt The whole packet. |
| 500 | * @param size Size of the packet. |
| 501 | * @param src_addr Source address where this packet was received |
| 502 | * from. |
| 503 | * @param src_addr_len The length of source address. |
| 504 | */ |
| 505 | void (*on_rx_data)(pj_ice_sess *ice, unsigned comp_id, |
| 506 | unsigned transport_id, |
| 507 | void *pkt, pj_size_t size, |
| 508 | const pj_sockaddr_t *src_addr, |
| 509 | unsigned src_addr_len); |
| 510 | } pj_ice_sess_cb; |
| 511 | |
| 512 | |
| 513 | /** |
| 514 | * This enumeration describes the role of the ICE agent. |
| 515 | */ |
| 516 | typedef enum pj_ice_sess_role |
| 517 | { |
| 518 | /** |
| 519 | * The role is unknown. |
| 520 | */ |
| 521 | PJ_ICE_SESS_ROLE_UNKNOWN, |
| 522 | |
| 523 | /** |
| 524 | * The ICE agent is in controlled role. |
| 525 | */ |
| 526 | PJ_ICE_SESS_ROLE_CONTROLLED, |
| 527 | |
| 528 | /** |
| 529 | * The ICE agent is in controlling role. |
| 530 | */ |
| 531 | PJ_ICE_SESS_ROLE_CONTROLLING |
| 532 | |
| 533 | } pj_ice_sess_role; |
| 534 | |
| 535 | |
| 536 | /** |
| 537 | * This structure represents an incoming check (an incoming Binding |
| 538 | * request message), and is mainly used to keep early checks in the |
| 539 | * list in the ICE session. An early check is a request received |
| 540 | * from remote when we haven't received SDP answer yet, therefore we |
| 541 | * can't perform triggered check. For such cases, keep the incoming |
| 542 | * request in a list, and we'll do triggered checks (simultaneously) |
| 543 | * as soon as we receive answer. |
| 544 | */ |
| 545 | typedef struct pj_ice_rx_check |
| 546 | { |
| 547 | PJ_DECL_LIST_MEMBER(struct pj_ice_rx_check); /**< Standard list */ |
| 548 | |
| 549 | unsigned comp_id; /**< Component ID. */ |
| 550 | unsigned transport_id; /**< Transport ID. */ |
| 551 | |
| 552 | pj_sockaddr src_addr; /**< Source address of request */ |
| 553 | unsigned src_addr_len; /**< Length of src address. */ |
| 554 | |
| 555 | pj_bool_t use_candidate; /**< USE-CANDIDATE is present? */ |
| 556 | pj_uint32_t priority; /**< PRIORITY value in the req. */ |
| 557 | pj_stun_uint64_attr *role_attr; /**< ICE-CONTROLLING/CONTROLLED */ |
| 558 | |
| 559 | } pj_ice_rx_check; |
| 560 | |
| 561 | |
| 562 | /** |
| 563 | * This structure describes various ICE session options. Application |
| 564 | * configure the ICE session with these options by calling |
| 565 | * #pj_ice_sess_set_options(). |
| 566 | */ |
| 567 | typedef struct pj_ice_sess_options |
| 568 | { |
| 569 | /** |
| 570 | * Specify whether to use aggressive nomination. |
| 571 | */ |
| 572 | pj_bool_t aggressive; |
| 573 | |
| 574 | /** |
| 575 | * For controlling agent if it uses regular nomination, specify the delay |
| 576 | * to perform nominated check (connectivity check with USE-CANDIDATE |
| 577 | * attribute) after all components have a valid pair. |
| 578 | * |
| 579 | * Default value is PJ_ICE_NOMINATED_CHECK_DELAY. |
| 580 | */ |
| 581 | unsigned nominated_check_delay; |
| 582 | |
| 583 | /** |
| 584 | * For a controlled agent, specify how long it wants to wait (in |
| 585 | * milliseconds) for the controlling agent to complete sending |
| 586 | * connectivity check with nominated flag set to true for all components |
| 587 | * after the controlled agent has found that all connectivity checks in |
| 588 | * its checklist have been completed and there is at least one successful |
| 589 | * (but not nominated) check for every component. |
| 590 | * |
| 591 | * Default value for this option is |
| 592 | * ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT. Specify -1 to disable |
| 593 | * this timer. |
| 594 | */ |
| 595 | int controlled_agent_want_nom_timeout; |
| 596 | |
| 597 | } pj_ice_sess_options; |
| 598 | |
| 599 | |
| 600 | /** |
| 601 | * This structure describes the ICE session. For this version of PJNATH, |
| 602 | * an ICE session corresponds to a single media stream (unlike the ICE |
| 603 | * session described in the ICE standard where an ICE session covers the |
| 604 | * whole media and may consist of multiple media streams). The decision |
| 605 | * to support only a single media session was chosen for simplicity, |
| 606 | * while still allowing application to utilize multiple media streams by |
| 607 | * creating multiple ICE sessions, one for each media stream. |
| 608 | */ |
| 609 | struct pj_ice_sess |
| 610 | { |
| 611 | char obj_name[PJ_MAX_OBJ_NAME]; /**< Object name. */ |
| 612 | |
| 613 | pj_pool_t *pool; /**< Pool instance. */ |
| 614 | void *user_data; /**< App. data. */ |
| 615 | pj_grp_lock_t *grp_lock; /**< Group lock */ |
| 616 | pj_ice_sess_role role; /**< ICE role. */ |
| 617 | pj_ice_sess_options opt; /**< Options */ |
| 618 | pj_timestamp tie_breaker; /**< Tie breaker value */ |
| 619 | pj_uint8_t *prefs; /**< Type preference. */ |
| 620 | pj_bool_t is_nominating; /**< Nominating stage */ |
| 621 | pj_bool_t is_complete; /**< Complete? */ |
| 622 | pj_bool_t is_destroying; /**< Destroy is called */ |
| 623 | pj_status_t ice_status; /**< Error status. */ |
| 624 | pj_timer_entry timer; /**< ICE timer. */ |
| 625 | pj_ice_sess_cb cb; /**< Callback. */ |
| 626 | |
| 627 | pj_stun_config stun_cfg; /**< STUN settings. */ |
| 628 | |
| 629 | /* STUN credentials */ |
| 630 | pj_str_t tx_ufrag; /**< Remote ufrag. */ |
| 631 | pj_str_t tx_uname; /**< Uname for TX. */ |
| 632 | pj_str_t tx_pass; /**< Remote password. */ |
| 633 | pj_str_t rx_ufrag; /**< Local ufrag. */ |
| 634 | pj_str_t rx_uname; /**< Uname for RX */ |
| 635 | pj_str_t rx_pass; /**< Local password. */ |
| 636 | |
| 637 | /* Components */ |
| 638 | unsigned comp_cnt; /**< # of components. */ |
| 639 | pj_ice_sess_comp comp[PJ_ICE_MAX_COMP]; /**< Component array */ |
| 640 | unsigned comp_ka; /**< Next comp for KA */ |
| 641 | |
| 642 | /* Local candidates */ |
| 643 | unsigned lcand_cnt; /**< # of local cand. */ |
| 644 | pj_ice_sess_cand lcand[PJ_ICE_MAX_CAND]; /**< Array of cand. */ |
| 645 | |
| 646 | /* Remote candidates */ |
| 647 | unsigned rcand_cnt; /**< # of remote cand. */ |
| 648 | pj_ice_sess_cand rcand[PJ_ICE_MAX_CAND]; /**< Array of cand. */ |
| 649 | |
| 650 | /** Array of transport datas */ |
| 651 | pj_ice_msg_data tp_data[4]; |
| 652 | |
| 653 | /* List of eearly checks */ |
| 654 | pj_ice_rx_check early_check; /**< Early checks. */ |
| 655 | |
| 656 | /* Checklist */ |
| 657 | pj_ice_sess_checklist clist; /**< Active checklist */ |
| 658 | |
| 659 | /* Valid list */ |
| 660 | pj_ice_sess_checklist valid_list; /**< Valid list. */ |
| 661 | |
| 662 | /** Temporary buffer for misc stuffs to avoid using stack too much */ |
| 663 | union { |
| 664 | char txt[128]; |
| 665 | char errmsg[PJ_ERR_MSG_SIZE]; |
| 666 | } tmp; |
| 667 | }; |
| 668 | |
| 669 | |
| 670 | /** |
| 671 | * This is a utility function to retrieve the string name for the |
| 672 | * particular candidate type. |
| 673 | * |
| 674 | * @param type Candidate type. |
| 675 | * |
| 676 | * @return The string representation of the candidate type. |
| 677 | */ |
| 678 | PJ_DECL(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type); |
| 679 | |
| 680 | |
| 681 | /** |
| 682 | * This is a utility function to retrieve the string name for the |
| 683 | * particular role type. |
| 684 | * |
| 685 | * @param role Role type. |
| 686 | * |
| 687 | * @return The string representation of the role. |
| 688 | */ |
| 689 | PJ_DECL(const char*) pj_ice_sess_role_name(pj_ice_sess_role role); |
| 690 | |
| 691 | |
| 692 | /** |
| 693 | * This is a utility function to calculate the foundation identification |
| 694 | * for a candidate. |
| 695 | * |
| 696 | * @param pool Pool to allocate the foundation string. |
| 697 | * @param foundation Pointer to receive the foundation string. |
| 698 | * @param type Candidate type. |
| 699 | * @param base_addr Base address of the candidate. |
| 700 | */ |
| 701 | PJ_DECL(void) pj_ice_calc_foundation(pj_pool_t *pool, |
| 702 | pj_str_t *foundation, |
| 703 | pj_ice_cand_type type, |
| 704 | const pj_sockaddr *base_addr); |
| 705 | |
| 706 | /** |
| 707 | * Initialize ICE session options with library default values. |
| 708 | * |
| 709 | * @param opt ICE session options. |
| 710 | */ |
| 711 | PJ_DECL(void) pj_ice_sess_options_default(pj_ice_sess_options *opt); |
| 712 | |
| 713 | /** |
| 714 | * Create ICE session with the specified role and number of components. |
| 715 | * Application would typically need to create an ICE session before |
| 716 | * sending an offer or upon receiving one. After the session is created, |
| 717 | * application can register candidates to the ICE session by calling |
| 718 | * #pj_ice_sess_add_cand() function. |
| 719 | * |
| 720 | * @param stun_cfg The STUN configuration settings, containing among |
| 721 | * other things the timer heap instance to be used |
| 722 | * by the ICE session. |
| 723 | * @param name Optional name to identify this ICE instance in |
| 724 | * the log file. |
| 725 | * @param role ICE role. |
| 726 | * @param comp_cnt Number of components. |
| 727 | * @param cb ICE callback. |
| 728 | * @param local_ufrag Optional string to be used as local username to |
| 729 | * authenticate incoming STUN binding request. If |
| 730 | * the value is NULL, a random string will be |
| 731 | * generated. |
| 732 | * @param local_passwd Optional string to be used as local password. |
| 733 | * @param grp_lock Optional group lock to be used by this session. |
| 734 | * If NULL, the session will create one itself. |
| 735 | * @param p_ice Pointer to receive the ICE session instance. |
| 736 | * |
| 737 | * @return PJ_SUCCESS if ICE session is created successfully. |
| 738 | */ |
| 739 | PJ_DECL(pj_status_t) pj_ice_sess_create(pj_stun_config *stun_cfg, |
| 740 | const char *name, |
| 741 | pj_ice_sess_role role, |
| 742 | unsigned comp_cnt, |
| 743 | const pj_ice_sess_cb *cb, |
| 744 | const pj_str_t *local_ufrag, |
| 745 | const pj_str_t *local_passwd, |
| 746 | pj_grp_lock_t *grp_lock, |
| 747 | pj_ice_sess **p_ice); |
| 748 | |
| 749 | /** |
| 750 | * Get the value of various options of the ICE session. |
| 751 | * |
| 752 | * @param ice The ICE session. |
| 753 | * @param opt The options to be initialized with the values |
| 754 | * from the ICE session. |
| 755 | * |
| 756 | * @return PJ_SUCCESS on success, or the appropriate error. |
| 757 | */ |
| 758 | PJ_DECL(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice, |
| 759 | pj_ice_sess_options *opt); |
| 760 | |
| 761 | /** |
| 762 | * Specify various options for this ICE session. Application MUST only |
| 763 | * call this function after the ICE session has been created but before |
| 764 | * any connectivity check is started. |
| 765 | * |
| 766 | * Application should call #pj_ice_sess_get_options() to initialize the |
| 767 | * options with their default values. |
| 768 | * |
| 769 | * @param ice The ICE session. |
| 770 | * @param opt Options to be applied to the ICE session. |
| 771 | * |
| 772 | * @return PJ_SUCCESS on success, or the appropriate error. |
| 773 | */ |
| 774 | PJ_DECL(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice, |
| 775 | const pj_ice_sess_options *opt); |
| 776 | |
| 777 | /** |
| 778 | * Destroy ICE session. This will cancel any connectivity checks currently |
| 779 | * running, if any, and any other events scheduled by this session, as well |
| 780 | * as all memory resources. |
| 781 | * |
| 782 | * @param ice ICE session instance. |
| 783 | * |
| 784 | * @return PJ_SUCCESS on success. |
| 785 | */ |
| 786 | PJ_DECL(pj_status_t) pj_ice_sess_destroy(pj_ice_sess *ice); |
| 787 | |
| 788 | |
| 789 | /** |
| 790 | * Change session role. This happens for example when ICE session was |
| 791 | * created with controlled role when receiving an offer, but it turns out |
| 792 | * that the offer contains "a=ice-lite" attribute when the SDP gets |
| 793 | * inspected. |
| 794 | * |
| 795 | * @param ice The ICE session. |
| 796 | * @param new_role The new role to be set. |
| 797 | * |
| 798 | * @return PJ_SUCCESS on success, or the appropriate error. |
| 799 | */ |
| 800 | PJ_DECL(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice, |
| 801 | pj_ice_sess_role new_role); |
| 802 | |
| 803 | |
| 804 | /** |
| 805 | * Assign a custom preference values for ICE candidate types. By assigning |
| 806 | * custom preference value, application can control the order of candidates |
| 807 | * to be checked first. The default preference settings is to use 126 for |
| 808 | * host candidates, 100 for server reflexive candidates, 110 for peer |
| 809 | * reflexive candidates, an 0 for relayed candidates. |
| 810 | * |
| 811 | * Note that this function must be called before any candidates are added |
| 812 | * to the ICE session. |
| 813 | * |
| 814 | * @param ice The ICE session. |
| 815 | * @param prefs Array of candidate preference value. The values are |
| 816 | * put in the array indexed by the candidate type as |
| 817 | * specified in pj_ice_cand_type. |
| 818 | * |
| 819 | * @return PJ_SUCCESS on success, or the appropriate error code. |
| 820 | */ |
| 821 | PJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice, |
| 822 | const pj_uint8_t prefs[4]); |
| 823 | |
| 824 | |
| 825 | |
| 826 | /** |
| 827 | * Add a candidate to this ICE session. Application must add candidates for |
| 828 | * each components ID before it can start pairing the candidates and |
| 829 | * performing connectivity checks. |
| 830 | * |
| 831 | * @param ice ICE session instance. |
| 832 | * @param comp_id Component ID of this candidate. |
| 833 | * @param transport_id Transport ID to be used to send packets for this |
| 834 | * candidate. |
| 835 | * @param type Candidate type. |
| 836 | * @param local_pref Local preference for this candidate, which |
| 837 | * normally should be set to 65535. |
| 838 | * @param foundation Foundation identification. |
| 839 | * @param addr The candidate address. |
| 840 | * @param base_addr The candidate's base address. |
| 841 | * @param rel_addr Optional related address. |
| 842 | * @param addr_len Length of addresses. |
| 843 | * @param p_cand_id Optional pointer to receive the candidate ID. |
| 844 | * |
| 845 | * @return PJ_SUCCESS if candidate is successfully added. |
| 846 | */ |
| 847 | PJ_DECL(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, |
| 848 | unsigned comp_id, |
| 849 | unsigned transport_id, |
| 850 | pj_ice_cand_type type, |
| 851 | pj_uint16_t local_pref, |
| 852 | const pj_str_t *foundation, |
| 853 | const pj_sockaddr_t *addr, |
| 854 | const pj_sockaddr_t *base_addr, |
| 855 | const pj_sockaddr_t *rel_addr, |
| 856 | int addr_len, |
| 857 | unsigned *p_cand_id); |
| 858 | |
| 859 | /** |
| 860 | * Find default candidate for the specified component ID, using this |
| 861 | * rule: |
| 862 | * - if the component has a successful candidate pair, then the |
| 863 | * local candidate of this pair will be returned. |
| 864 | * - otherwise a relay, reflexive, or host candidate will be selected |
| 865 | * on that specified order. |
| 866 | * |
| 867 | * @param ice The ICE session instance. |
| 868 | * @param comp_id The component ID. |
| 869 | * @param p_cand_id Pointer to receive the candidate ID. |
| 870 | * |
| 871 | * @return PJ_SUCCESS if a candidate has been selected. |
| 872 | */ |
| 873 | PJ_DECL(pj_status_t) pj_ice_sess_find_default_cand(pj_ice_sess *ice, |
| 874 | unsigned comp_id, |
| 875 | int *p_cand_id); |
| 876 | |
| 877 | /** |
| 878 | * Pair the local and remote candidates to create check list. Application |
| 879 | * typically would call this function after receiving SDP containing ICE |
| 880 | * candidates from the remote host (either upon receiving the initial |
| 881 | * offer, for UAS, or upon receiving the answer, for UAC). |
| 882 | * |
| 883 | * Note that ICE connectivity check will not start until application calls |
| 884 | * #pj_ice_sess_start_check(). |
| 885 | * |
| 886 | * @param ice ICE session instance. |
| 887 | * @param rem_ufrag Remote ufrag, as seen in the SDP received from |
| 888 | * the remote agent. |
| 889 | * @param rem_passwd Remote password, as seen in the SDP received from |
| 890 | * the remote agent. |
| 891 | * @param rem_cand_cnt Number of remote candidates. |
| 892 | * @param rem_cand Remote candidate array. Remote candidates are |
| 893 | * gathered from the SDP received from the remote |
| 894 | * agent. |
| 895 | * |
| 896 | * @return PJ_SUCCESS or the appropriate error code. |
| 897 | */ |
| 898 | PJ_DECL(pj_status_t) |
| 899 | pj_ice_sess_create_check_list(pj_ice_sess *ice, |
| 900 | const pj_str_t *rem_ufrag, |
| 901 | const pj_str_t *rem_passwd, |
| 902 | unsigned rem_cand_cnt, |
| 903 | const pj_ice_sess_cand rem_cand[]); |
| 904 | |
| 905 | /** |
| 906 | * Start ICE periodic check. This function will return immediately, and |
| 907 | * application will be notified about the connectivity check status in |
| 908 | * #pj_ice_sess_cb callback. |
| 909 | * |
| 910 | * @param ice The ICE session instance. |
| 911 | * |
| 912 | * @return PJ_SUCCESS or the appropriate error code. |
| 913 | */ |
| 914 | PJ_DECL(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice); |
| 915 | |
| 916 | |
| 917 | /** |
| 918 | * Send data using this ICE session. If ICE checks have not produced a |
| 919 | * valid check for the specified component ID, this function will return |
| 920 | * with failure. Otherwise ICE session will send the packet to remote |
| 921 | * destination using the nominated local candidate for the specified |
| 922 | * component. |
| 923 | * |
| 924 | * This function will in turn call \a on_tx_pkt function in |
| 925 | * #pj_ice_sess_cb callback to actually send the packet to the wire. |
| 926 | * |
| 927 | * @param ice The ICE session. |
| 928 | * @param comp_id Component ID. |
| 929 | * @param data The data or packet to be sent. |
| 930 | * @param data_len Size of data or packet, in bytes. |
| 931 | * |
| 932 | * @return PJ_SUCCESS if data is sent successfully. |
| 933 | */ |
| 934 | PJ_DECL(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice, |
| 935 | unsigned comp_id, |
| 936 | const void *data, |
| 937 | pj_size_t data_len); |
| 938 | |
| 939 | /** |
| 940 | * Report the arrival of packet to the ICE session. Since ICE session |
| 941 | * itself doesn't have any transports, it relies on application or |
| 942 | * higher layer component to give incoming packets to the ICE session. |
| 943 | * If the packet is not a STUN packet, this packet will be given back |
| 944 | * to application via \a on_rx_data() callback in #pj_ice_sess_cb. |
| 945 | * |
| 946 | * @param ice The ICE session. |
| 947 | * @param comp_id Component ID. |
| 948 | * @param transport_id Number to identify where this packet was received |
| 949 | * from. This parameter will be returned back to |
| 950 | * application in \a on_tx_pkt() callback. |
| 951 | * @param pkt Incoming packet. |
| 952 | * @param pkt_size Size of incoming packet. |
| 953 | * @param src_addr Source address of the packet. |
| 954 | * @param src_addr_len Length of the address. |
| 955 | * |
| 956 | * @return PJ_SUCCESS or the appropriate error code. |
| 957 | */ |
| 958 | PJ_DECL(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, |
| 959 | unsigned comp_id, |
| 960 | unsigned transport_id, |
| 961 | void *pkt, |
| 962 | pj_size_t pkt_size, |
| 963 | const pj_sockaddr_t *src_addr, |
| 964 | int src_addr_len); |
| 965 | |
| 966 | |
| 967 | |
| 968 | /** |
| 969 | * @} |
| 970 | */ |
| 971 | |
| 972 | |
| 973 | PJ_END_DECL |
| 974 | |
| 975 | |
| 976 | #endif /* __PJNATH_ICE_SESSION_H__ */ |
| 977 | |