michael@0: /* michael@0: Copyright (c) 2007, Adobe Systems, Incorporated michael@0: All rights reserved. michael@0: michael@0: Redistribution and use in source and binary forms, with or without michael@0: modification, are permitted provided that the following conditions are michael@0: met: michael@0: michael@0: * Redistributions of source code must retain the above copyright michael@0: notice, this list of conditions and the following disclaimer. michael@0: michael@0: * Redistributions in binary form must reproduce the above copyright michael@0: notice, this list of conditions and the following disclaimer in the michael@0: documentation and/or other materials provided with the distribution. michael@0: michael@0: * Neither the name of Adobe Systems, Network Resonance nor the names of its michael@0: contributors may be used to endorse or promote products derived from michael@0: this software without specific prior written permission. michael@0: michael@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: */ michael@0: michael@0: michael@0: michael@0: #ifndef _ice_ctx_h michael@0: #define _ice_ctx_h michael@0: #ifdef __cplusplus michael@0: using namespace std; michael@0: extern "C" { michael@0: #endif /* __cplusplus */ michael@0: michael@0: /* Not good practice but making includes simpler */ michael@0: #include "transport_addr.h" michael@0: #include "nr_socket.h" michael@0: #include "nr_resolver.h" michael@0: #include "nr_interface_prioritizer.h" michael@0: #include "stun_client_ctx.h" michael@0: #include "stun_server_ctx.h" michael@0: #include "turn_client_ctx.h" michael@0: michael@0: #define NR_ICE_STUN_SERVER_TYPE_ADDR 1 michael@0: #define NR_ICE_STUN_SERVER_TYPE_DNSNAME 2 michael@0: michael@0: typedef struct nr_ice_stun_server_ { michael@0: int type; michael@0: union { michael@0: nr_transport_addr addr; michael@0: struct { michael@0: char host[256]; /* Limit from RFC 1034, plus a 0 byte */ michael@0: UINT2 port; michael@0: } dnsname; michael@0: } u; michael@0: int index; michael@0: } nr_ice_stun_server; michael@0: michael@0: typedef struct nr_ice_turn_server_ { michael@0: nr_ice_stun_server turn_server; michael@0: int transport; michael@0: char *username; michael@0: Data *password; michael@0: } nr_ice_turn_server; michael@0: michael@0: typedef struct nr_ice_foundation_ { michael@0: int index; michael@0: michael@0: nr_transport_addr addr; michael@0: int type; michael@0: nr_ice_stun_server *stun_server; michael@0: michael@0: STAILQ_ENTRY(nr_ice_foundation_) entry; michael@0: } nr_ice_foundation; michael@0: michael@0: typedef STAILQ_HEAD(nr_ice_foundation_head_,nr_ice_foundation_) nr_ice_foundation_head; michael@0: michael@0: typedef TAILQ_HEAD(nr_ice_candidate_head_,nr_ice_candidate_) nr_ice_candidate_head; michael@0: typedef TAILQ_HEAD(nr_ice_cand_pair_head_,nr_ice_cand_pair_) nr_ice_cand_pair_head; michael@0: typedef struct nr_ice_component_ nr_ice_component; michael@0: typedef struct nr_ice_media_stream_ nr_ice_media_stream; michael@0: typedef struct nr_ice_ctx_ nr_ice_ctx; michael@0: typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx; michael@0: typedef struct nr_ice_candidate_ nr_ice_candidate; michael@0: typedef struct nr_ice_cand_pair_ nr_ice_cand_pair; michael@0: typedef void (*nr_ice_trickle_candidate_cb) (void *cb_arg, michael@0: nr_ice_ctx *ctx, nr_ice_media_stream *stream, int component_id, michael@0: nr_ice_candidate *candidate); michael@0: michael@0: #include "ice_socket.h" michael@0: #include "ice_component.h" michael@0: #include "ice_media_stream.h" michael@0: #include "ice_candidate.h" michael@0: #include "ice_candidate_pair.h" michael@0: #include "ice_handler.h" michael@0: #include "ice_peer_ctx.h" michael@0: michael@0: typedef struct nr_ice_stun_id_ { michael@0: UCHAR id[12]; michael@0: michael@0: STAILQ_ENTRY(nr_ice_stun_id_) entry; michael@0: } nr_ice_stun_id; michael@0: michael@0: typedef STAILQ_HEAD(nr_ice_stun_id_head_,nr_ice_stun_id_) nr_ice_stun_id_head; michael@0: michael@0: struct nr_ice_ctx_ { michael@0: UINT4 flags; michael@0: int state; michael@0: #define NR_ICE_STATE_CREATED 1 michael@0: #define NR_ICE_STATE_INITIALIZING 2 michael@0: #define NR_ICE_STATE_INITIALIZED 3 michael@0: char *label; michael@0: michael@0: char *ufrag; michael@0: char *pwd; michael@0: michael@0: UINT4 Ta; michael@0: michael@0: nr_ice_stun_server *stun_servers; /* The list of stun servers */ michael@0: int stun_server_ct; michael@0: nr_ice_turn_server *turn_servers; /* The list of turn servers */ michael@0: int turn_server_ct; michael@0: nr_local_addr *local_addrs; /* The list of available local addresses and corresponding interface information */ michael@0: int local_addr_ct; michael@0: michael@0: nr_resolver *resolver; /* The resolver to use */ michael@0: nr_interface_prioritizer *interface_prioritizer; /* Priority decision logic */ michael@0: michael@0: nr_ice_foundation_head foundations; michael@0: michael@0: nr_ice_media_stream_head streams; /* Media streams */ michael@0: int stream_ct; michael@0: nr_ice_socket_head sockets; /* The sockets we're using */ michael@0: int uninitialized_candidates; michael@0: michael@0: UINT4 gather_rto; michael@0: UINT4 stun_delay; michael@0: michael@0: nr_ice_peer_ctx_head peers; michael@0: nr_ice_stun_id_head ids; michael@0: michael@0: NR_async_cb done_cb; michael@0: void *cb_arg; michael@0: michael@0: nr_ice_trickle_candidate_cb trickle_cb; michael@0: void *trickle_cb_arg; michael@0: }; michael@0: michael@0: int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp); michael@0: #define NR_ICE_CTX_FLAGS_OFFERER 1 michael@0: #define NR_ICE_CTX_FLAGS_ANSWERER (1<<1) michael@0: #define NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION (1<<2) michael@0: #define NR_ICE_CTX_FLAGS_LITE (1<<3) michael@0: michael@0: int nr_ice_ctx_destroy(nr_ice_ctx **ctxp); michael@0: int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg); michael@0: int nr_ice_add_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand); michael@0: void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg); michael@0: int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp); michael@0: int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp); michael@0: int nr_ice_ctx_deliver_packet(nr_ice_ctx *ctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len); michael@0: int nr_ice_ctx_is_known_id(nr_ice_ctx *ctx, UCHAR id[12]); michael@0: int nr_ice_ctx_remember_id(nr_ice_ctx *ctx, nr_stun_message *msg); michael@0: int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx); michael@0: int nr_ice_ctx_set_stun_servers(nr_ice_ctx *ctx,nr_ice_stun_server *servers, int ct); michael@0: int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers, int ct); michael@0: int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver); michael@0: int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *prioritizer); michael@0: int nr_ice_ctx_set_trickle_cb(nr_ice_ctx *ctx, nr_ice_trickle_candidate_cb cb, void *cb_arg); michael@0: michael@0: #define NR_ICE_MAX_ATTRIBUTE_SIZE 256 michael@0: michael@0: extern int LOG_ICE; michael@0: michael@0: #ifdef __cplusplus michael@0: } michael@0: #endif /* __cplusplus */ michael@0: #endif michael@0: