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_grp_lock_t *grp_lock, 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

◆ pj_ice_cand_type

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.


Number of defined ICE candidate types.

◆ pj_ice_sess_check_state

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.

◆ pj_ice_sess_checklist_state

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.

◆ pj_ice_sess_role

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

◆ pj_ice_calc_foundation()

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.

poolPool to allocate the foundation string.
foundationPointer to receive the foundation string.
typeCandidate type.
base_addrBase address of the candidate.

◆ pj_ice_get_cand_type_name()

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.

typeCandidate type.
The string representation of the candidate type.

◆ pj_ice_sess_add_cand()

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.

iceICE session instance.
comp_idComponent ID of this candidate.
transport_idTransport ID to be used to send packets for this candidate.
typeCandidate type.
local_prefLocal preference for this candidate, which normally should be set to 65535.
foundationFoundation identification.
addrThe candidate address.
base_addrThe candidate's base address.
rel_addrOptional related address.
addr_lenLength of addresses.
p_cand_idOptional pointer to receive the candidate ID.
PJ_SUCCESS if candidate is successfully added.

◆ pj_ice_sess_change_role()

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.

iceThe ICE session.
new_roleThe new role to be set.
PJ_SUCCESS on success, or the appropriate error.

◆ pj_ice_sess_create()

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_grp_lock_t grp_lock,
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_cfgThe STUN configuration settings, containing among other things the timer heap instance to be used by the ICE session.
nameOptional name to identify this ICE instance in the log file.
roleICE role.
comp_cntNumber of components.
cbICE callback.
local_ufragOptional 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_passwdOptional string to be used as local password.
grp_lockOptional group lock to be used by this session. If NULL, the session will create one itself.
p_icePointer to receive the ICE session instance.
PJ_SUCCESS if ICE session is created successfully.

◆ pj_ice_sess_create_check_list()

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().

iceICE session instance.
rem_ufragRemote ufrag, as seen in the SDP received from the remote agent.
rem_passwdRemote password, as seen in the SDP received from the remote agent.
rem_cand_cntNumber of remote candidates.
rem_candRemote candidate array. Remote candidates are gathered from the SDP received from the remote agent.
PJ_SUCCESS or the appropriate error code.

◆ pj_ice_sess_destroy()

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.

iceICE session instance.
PJ_SUCCESS on success.

◆ pj_ice_sess_find_default_cand()

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.
iceThe ICE session instance.
comp_idThe component ID.
p_cand_idPointer to receive the candidate ID.
PJ_SUCCESS if a candidate has been selected.

◆ pj_ice_sess_get_options()

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.

iceThe ICE session.
optThe options to be initialized with the values from the ICE session.
PJ_SUCCESS on success, or the appropriate error.

◆ pj_ice_sess_on_rx_pkt()

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.

iceThe ICE session.
comp_idComponent ID.
transport_idNumber to identify where this packet was received from. This parameter will be returned back to application in on_tx_pkt() callback.
pktIncoming packet.
pkt_sizeSize of incoming packet.
src_addrSource address of the packet.
src_addr_lenLength of the address.
PJ_SUCCESS or the appropriate error code.

◆ pj_ice_sess_options_default()

void pj_ice_sess_options_default ( pj_ice_sess_options opt)

Initialize ICE session options with library default values.

optICE session options.

◆ pj_ice_sess_role_name()

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.

roleRole type.
The string representation of the role.

◆ pj_ice_sess_send_data()

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.

iceThe ICE session.
comp_idComponent ID.
dataThe data or packet to be sent.
data_lenSize of data or packet, in bytes.
If the callback on_tx_pkt() is called, this will contain the return value of the callback. Otherwise, it will indicate failure with the appropriate error code.

◆ pj_ice_sess_set_options()

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.

iceThe ICE session.
optOptions to be applied to the ICE session.
PJ_SUCCESS on success, or the appropriate error.

◆ pj_ice_sess_set_prefs()

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.

iceThe ICE session.
prefsArray 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_ice_sess_start_check()

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.

iceThe 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.