Home --> Documentations --> PJNATH Reference

Transport Independent ICE Session. More...

Data Structures

struct  pj_ice_sess_comp
struct  pj_ice_msg_data
struct  pj_ice_sess_cand
struct  pj_ice_sess_check
struct  pj_ice_sess_checklist
struct  pj_ice_sess_cb
struct  pj_ice_rx_check
struct  pj_ice_sess_options
struct  pj_ice_sess


enum  pj_ice_cand_type {
enum  pj_ice_sess_check_state {
enum  pj_ice_sess_checklist_state {
enum  pj_ice_sess_role {


const char * pj_ice_get_cand_type_name (pj_ice_cand_type type)
const char * pj_ice_sess_role_name (pj_ice_sess_role role)
void pj_ice_calc_foundation (pj_pool_t *pool, pj_str_t *foundation, pj_ice_cand_type type, const pj_sockaddr *base_addr)
void pj_ice_sess_options_default (pj_ice_sess_options *opt)
pj_status_t pj_ice_sess_create (pj_stun_config *stun_cfg, const char *name, pj_ice_sess_role role, unsigned comp_cnt, const pj_ice_sess_cb *cb, const pj_str_t *local_ufrag, const pj_str_t *local_passwd, pj_ice_sess **p_ice)
pj_status_t pj_ice_sess_get_options (pj_ice_sess *ice, pj_ice_sess_options *opt)
pj_status_t pj_ice_sess_set_options (pj_ice_sess *ice, const pj_ice_sess_options *opt)
pj_status_t pj_ice_sess_destroy (pj_ice_sess *ice)
pj_status_t pj_ice_sess_change_role (pj_ice_sess *ice, pj_ice_sess_role new_role)
pj_status_t pj_ice_sess_set_prefs (pj_ice_sess *ice, const pj_uint8_t prefs[4])
pj_status_t pj_ice_sess_add_cand (pj_ice_sess *ice, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref, const pj_str_t *foundation, const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len, unsigned *p_cand_id)
pj_status_t pj_ice_sess_find_default_cand (pj_ice_sess *ice, unsigned comp_id, int *p_cand_id)
pj_status_t pj_ice_sess_create_check_list (pj_ice_sess *ice, const pj_str_t *rem_ufrag, const pj_str_t *rem_passwd, unsigned rem_cand_cnt, const pj_ice_sess_cand rem_cand[])
pj_status_t pj_ice_sess_start_check (pj_ice_sess *ice)
pj_status_t pj_ice_sess_send_data (pj_ice_sess *ice, unsigned comp_id, const void *data, pj_size_t data_len)
pj_status_t pj_ice_sess_on_rx_pkt (pj_ice_sess *ice, unsigned comp_id, unsigned transport_id, void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *src_addr, int src_addr_len)

Detailed Description

This module describes pj_ice_sess, a transport independent ICE session, part of PJNATH - the Open Source NAT helper library.

ICE Session

An ICE session, represented by pj_ice_sess structure, is the lowest abstraction of ICE in PJNATH, and it is used to perform and manage connectivity checks of transport address candidates within a single media stream (note: this differs from what is described in ICE draft, where an ICE session manages the whole media sessions rather than just a single stream).

The ICE session described here is independent from any transports, meaning that the actual network I/O for this session would have to be performed by the application, or higher layer abstraction. Using this framework, application would give any incoming packets to the ICE session, and it would provide the ICE session with a callback to send outgoing message.

For higher abstraction of ICE where transport is included, please see ICE stream transport.

Using The ICE Session

The steps below describe how to use ICE session. Alternatively application can use the higher level ICE API, ICE stream transport, which has provided the integration of ICE with socket transport.

The steps to use ICE session is similar for both offerer and answerer:

  • create ICE session with pj_ice_sess_create(). Among other things, application needs to specify:
    • STUN configuration (pj_stun_config), containing STUN settings such as timeout values and the instances of timer heap and ioqueue.
    • Session name, useful for identifying this session in the log.
    • Initial ICE role (pj_ice_sess_role). The role can be changed at later time with pj_ice_sess_change_role(), and ICE session can also change its role automatically when it detects role conflict.
    • Number of components in the media session.
    • Callback to receive ICE events (pj_ice_sess_cb)
    • Optional local ICE username and password. If these arguments are NULL, they will be generated randomly.
  • Add local candidates for each component, with pj_ice_sess_add_cand(). A candidate is represented with pj_ice_sess_cand structure. Each component must be provided with at least one candidate, and all components must have the same number of candidates. Failing to comply with this will cause failure during pairing process.
  • Create offer to describe local ICE candidates. ICE session does not provide a function to create such offer, but application should be able to create one since it knows about all components and candidates. If application uses ICE stream transport, it can enumerate local candidates by calling pj_ice_strans_enum_cands(). Application may use pj_ice_sess_find_default_cand() to let ICE session chooses the default transport address to be used in SDP c= and m= lines.
  • Send the offer to remote endpoint using signaling such as SIP.
  • Once application has received the answer, it should parse this answer, build array of remote candidates, and create check lists by calling pj_ice_sess_create_check_list(). This process is known as pairing the candidates, and will result in the creation of check lists.
  • Once checklist has been created, application then can call pj_ice_sess_start_check() to instruct ICE session to start performing connectivity checks. The ICE session performs the connectivity checks by processing each check in the checklists.
  • Application will be notified about the result of ICE connectivity checks via the callback that was given in pj_ice_sess_create() above.

To send data, application calls pj_ice_sess_send_data(). If ICE negotiation has not completed, ICE session would simply drop the data, and return error to caller. If ICE negotiation has completed successfully, ICE session will in turn call the on_tx_pkt callback of pj_ice_sess_cb instance that was previously registered in pj_ice_sess_create() above.

When application receives any packets on the underlying sockets, it must call pj_ice_sess_on_rx_pkt(). The ICE session will inspect the packet to decide whether to process it locally (if the packet is a STUN message and is part of ICE session) or otherwise pass it back to application via on_rx_data callback.

Enumeration Type Documentation

This enumeration describes the type of an ICE candidate.


ICE host candidate. A host candidate represents the actual local transport address in the host.


ICE server reflexive candidate, which represents the public mapped address of the local address, and is obtained by sending STUN Binding request from the host candidate to a STUN server.


ICE peer reflexive candidate, which is the address as seen by peer agent during connectivity check.


ICE relayed candidate, which represents the address allocated in TURN server.

This enumeration describes the state of ICE check.


A check for this pair hasn't been performed, and it can't yet be performed until some other check succeeds, allowing this pair to unfreeze and move into the Waiting state.


A check has not been performed for this pair, and can be performed as soon as it is the highest priority Waiting pair on the check list.


A check has not been performed for this pair, and can be performed as soon as it is the highest priority Waiting pair on the check list.


A check has not been performed for this pair, and can be performed as soon as it is the highest priority Waiting pair on the check list.


A check for this pair was already done and failed, either never producing any response or producing an unrecoverable failure response.

This enumeration describes ICE checklist state.


The checklist is not yet running.


In this state, ICE checks are still in progress for this media stream.


In this state, ICE checks have completed for this media stream, either successfully or with failure.

This enumeration describes the role of the ICE agent.


The role is unknown.


The ICE agent is in controlled role.


The ICE agent is in controlling role.

Function Documentation

void pj_ice_calc_foundation ( pj_pool_t pool,
pj_str_t foundation,
pj_ice_cand_type  type,
const pj_sockaddr base_addr 

This is a utility function to calculate the foundation identification for a candidate.

pool Pool to allocate the foundation string.
foundation Pointer to receive the foundation string.
type Candidate type.
base_addr Base address of the candidate.
const char* pj_ice_get_cand_type_name ( pj_ice_cand_type  type  ) 

This is a utility function to retrieve the string name for the particular candidate type.

type Candidate type.
The string representation of the candidate type.
pj_status_t pj_ice_sess_add_cand ( pj_ice_sess ice,
unsigned  comp_id,
unsigned  transport_id,
pj_ice_cand_type  type,
pj_uint16_t  local_pref,
const pj_str_t foundation,
const pj_sockaddr_t addr,
const pj_sockaddr_t base_addr,
const pj_sockaddr_t rel_addr,
int  addr_len,
unsigned *  p_cand_id 

Add a candidate to this ICE session. Application must add candidates for each components ID before it can start pairing the candidates and performing connectivity checks.

ice ICE session instance.
comp_id Component ID of this candidate.
transport_id Transport ID to be used to send packets for this candidate.
type Candidate type.
local_pref Local preference for this candidate, which normally should be set to 65535.
foundation Foundation identification.
addr The candidate address.
base_addr The candidate's base address.
rel_addr Optional related address.
addr_len Length of addresses.
p_cand_id Optional pointer to receive the candidate ID.
PJ_SUCCESS if candidate is successfully added.
pj_status_t pj_ice_sess_change_role ( pj_ice_sess ice,
pj_ice_sess_role  new_role 

Change session role. This happens for example when ICE session was created with controlled role when receiving an offer, but it turns out that the offer contains "a=ice-lite" attribute when the SDP gets inspected.

ice The ICE session.
new_role The new role to be set.
PJ_SUCCESS on success, or the appropriate error.
pj_status_t pj_ice_sess_create ( pj_stun_config stun_cfg,
const char *  name,
pj_ice_sess_role  role,
unsigned  comp_cnt,
const pj_ice_sess_cb cb,
const pj_str_t local_ufrag,
const pj_str_t local_passwd,
pj_ice_sess **  p_ice 

Create ICE session with the specified role and number of components. Application would typically need to create an ICE session before sending an offer or upon receiving one. After the session is created, application can register candidates to the ICE session by calling pj_ice_sess_add_cand() function.

stun_cfg The STUN configuration settings, containing among other things the timer heap instance to be used by the ICE session.
name Optional name to identify this ICE instance in the log file.
role ICE role.
comp_cnt Number of components.
cb ICE callback.
local_ufrag Optional string to be used as local username to authenticate incoming STUN binding request. If the value is NULL, a random string will be generated.
local_passwd Optional string to be used as local password.
p_ice Pointer to receive the ICE session instance.
PJ_SUCCESS if ICE session is created successfully.
pj_status_t pj_ice_sess_create_check_list ( pj_ice_sess ice,
const pj_str_t rem_ufrag,
const pj_str_t rem_passwd,
unsigned  rem_cand_cnt,
const pj_ice_sess_cand  rem_cand[] 

Pair the local and remote candidates to create check list. Application typically would call this function after receiving SDP containing ICE candidates from the remote host (either upon receiving the initial offer, for UAS, or upon receiving the answer, for UAC).

Note that ICE connectivity check will not start until application calls pj_ice_sess_start_check().

ice ICE session instance.
rem_ufrag Remote ufrag, as seen in the SDP received from the remote agent.
rem_passwd Remote password, as seen in the SDP received from the remote agent.
rem_cand_cnt Number of remote candidates.
rem_cand Remote candidate array. Remote candidates are gathered from the SDP received from the remote agent.
PJ_SUCCESS or the appropriate error code.
pj_status_t pj_ice_sess_destroy ( pj_ice_sess ice  ) 

Destroy ICE session. This will cancel any connectivity checks currently running, if any, and any other events scheduled by this session, as well as all memory resources.

ice ICE session instance.
PJ_SUCCESS on success.
pj_status_t pj_ice_sess_find_default_cand ( pj_ice_sess ice,
unsigned  comp_id,
int p_cand_id 

Find default candidate for the specified component ID, using this rule:

  • if the component has a successful candidate pair, then the local candidate of this pair will be returned.
  • otherwise a relay, reflexive, or host candidate will be selected on that specified order.
ice The ICE session instance.
comp_id The component ID.
p_cand_id Pointer to receive the candidate ID.
PJ_SUCCESS if a candidate has been selected.
pj_status_t pj_ice_sess_get_options ( pj_ice_sess ice,
pj_ice_sess_options opt 

Get the value of various options of the ICE session.

ice The ICE session.
opt The options to be initialized with the values from the ICE session.
PJ_SUCCESS on success, or the appropriate error.
pj_status_t pj_ice_sess_on_rx_pkt ( pj_ice_sess ice,
unsigned  comp_id,
unsigned  transport_id,
void *  pkt,
pj_size_t  pkt_size,
const pj_sockaddr_t src_addr,
int  src_addr_len 

Report the arrival of packet to the ICE session. Since ICE session itself doesn't have any transports, it relies on application or higher layer component to give incoming packets to the ICE session. If the packet is not a STUN packet, this packet will be given back to application via on_rx_data() callback in pj_ice_sess_cb.

ice The ICE session.
comp_id Component ID.
transport_id Number to identify where this packet was received from. This parameter will be returned back to application in on_tx_pkt() callback.
pkt Incoming packet.
pkt_size Size of incoming packet.
src_addr Source address of the packet.
src_addr_len Length of the address.
PJ_SUCCESS or the appropriate error code.
void pj_ice_sess_options_default ( pj_ice_sess_options opt  ) 

Initialize ICE session options with library default values.

opt ICE session options.
const char* pj_ice_sess_role_name ( pj_ice_sess_role  role  ) 

This is a utility function to retrieve the string name for the particular role type.

role Role type.
The string representation of the role.
pj_status_t pj_ice_sess_send_data ( pj_ice_sess ice,
unsigned  comp_id,
const void *  data,
pj_size_t  data_len 

Send data using this ICE session. If ICE checks have not produced a valid check for the specified component ID, this function will return with failure. Otherwise ICE session will send the packet to remote destination using the nominated local candidate for the specified component.

This function will in turn call on_tx_pkt function in pj_ice_sess_cb callback to actually send the packet to the wire.

ice The ICE session.
comp_id Component ID.
data The data or packet to be sent.
data_len Size of data or packet, in bytes.
PJ_SUCCESS if data is sent successfully.
pj_status_t pj_ice_sess_set_options ( pj_ice_sess ice,
const pj_ice_sess_options opt 

Specify various options for this ICE session. Application MUST only call this function after the ICE session has been created but before any connectivity check is started.

Application should call pj_ice_sess_get_options() to initialize the options with their default values.

ice The ICE session.
opt Options to be applied to the ICE session.
PJ_SUCCESS on success, or the appropriate error.
pj_status_t pj_ice_sess_set_prefs ( pj_ice_sess ice,
const pj_uint8_t  prefs[4] 

Assign a custom preference values for ICE candidate types. By assigning custom preference value, application can control the order of candidates to be checked first. The default preference settings is to use 126 for host candidates, 100 for server reflexive candidates, 110 for peer reflexive candidates, an 0 for relayed candidates.

Note that this function must be called before any candidates are added to the ICE session.

ice The ICE session.
prefs Array of candidate preference value. The values are put in the array indexed by the candidate type as specified in pj_ice_cand_type.
PJ_SUCCESS on success, or the appropriate error code.
pj_status_t pj_ice_sess_start_check ( pj_ice_sess ice  ) 

Start ICE periodic check. This function will return immediately, and application will be notified about the connectivity check status in pj_ice_sess_cb callback.

ice The ICE session instance.
PJ_SUCCESS or the appropriate error code.


PJNATH - Open Source NAT traversal helper library supporting STUN, TURN, and ICE
Copyright (C) 2006-2009 Teluu Inc.