Group PJNATH_ICE_SESSION

group PJNATH_ICE_SESSION

Transport Independent ICE Session.

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.

Enums

enum pj_ice_cand_type

This enumeration describes the type of an ICE candidate.

Values:

enumerator PJ_ICE_CAND_TYPE_HOST

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

enumerator PJ_ICE_CAND_TYPE_SRFLX

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.

enumerator PJ_ICE_CAND_TYPE_PRFLX

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

enumerator PJ_ICE_CAND_TYPE_RELAYED

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

enum pj_ice_sess_check_state

This enumeration describes the state of ICE check.

Values:

enumerator PJ_ICE_SESS_CHECK_STATE_FROZEN

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.

enumerator PJ_ICE_SESS_CHECK_STATE_WAITING

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.

enumerator PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS

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.

enumerator PJ_ICE_SESS_CHECK_STATE_SUCCEEDED

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.

enumerator PJ_ICE_SESS_CHECK_STATE_FAILED

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

enum pj_ice_sess_checklist_state

This enumeration describes ICE checklist state.

Values:

enumerator PJ_ICE_SESS_CHECKLIST_ST_IDLE

The checklist is not yet running.

enumerator PJ_ICE_SESS_CHECKLIST_ST_RUNNING

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

enumerator PJ_ICE_SESS_CHECKLIST_ST_COMPLETED

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

enum pj_ice_sess_role

This enumeration describes the role of the ICE agent.

Values:

enumerator PJ_ICE_SESS_ROLE_UNKNOWN

The role is unknown.

enumerator PJ_ICE_SESS_ROLE_CONTROLLED

The ICE agent is in controlled role.

enumerator PJ_ICE_SESS_ROLE_CONTROLLING

The ICE agent is in controlling role.

Functions

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.

Parameters

type – Candidate type.

Returns

The string representation of the candidate type.

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.

Parameters

role – Role type.

Returns

The string representation of the role.

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.

Parameters
  • pool – Pool to allocate the foundation string.

  • foundation – Pointer to receive the foundation string.

  • type – Candidate type.

  • base_addr – Base address of the candidate.

void pj_ice_sess_options_default(pj_ice_sess_options *opt)

Initialize ICE session options with library default values.

Parameters

opt – ICE session options.

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.

Parameters
  • 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.

Returns

PJ_SUCCESS if ICE session is created successfully.

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.

Parameters
  • ice – The ICE session.

  • opt – The options to be initialized with the values from the ICE session.

Returns

PJ_SUCCESS on success, or the appropriate error.

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.

Parameters
  • ice – The ICE session.

  • opt – Options to be applied to the ICE session.

Returns

PJ_SUCCESS on success, or the appropriate error.

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.

Parameters

ice – ICE session instance.

Returns

PJ_SUCCESS on success.

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.

Parameters
  • ice – The ICE session.

  • new_role – The new role to be set.

Returns

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.

Parameters
  • 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.

Returns

PJ_SUCCESS on success, or the appropriate error code.

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.

Parameters
  • 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.

Returns

PJ_SUCCESS if candidate is successfully added.

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.

Parameters
  • ice – The ICE session instance.

  • comp_id – The component ID.

  • p_cand_id – Pointer to receive the candidate ID.

Returns

PJ_SUCCESS if a candidate has been selected.

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

Parameters
  • 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.

Returns

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

Parameters

ice – The ICE session instance.

Returns

PJ_SUCCESS or the appropriate error code.

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.

Parameters
  • 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.

Returns

PJ_SUCCESS if data is sent successfully.

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.

Parameters
  • 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.

Returns

PJ_SUCCESS or the appropriate error code.

struct pj_ice_sess_comp
#include <ice_session.h>

This structure describes ICE component. A media stream may require multiple components, each of which has to work for the media stream as a whole to work. For media streams based on RTP, there are two components per media stream - one for RTP, and one for RTCP.

struct pj_ice_msg_data
#include <ice_session.h>

Data structure to be attached to internal message processing.

struct pj_ice_sess_cand
#include <ice_session.h>

This structure describes an ICE candidate. ICE candidate is a transport address that is to be tested by ICE procedures in order to determine its suitability for usage for receipt of media. Candidates also have properties - their type (server reflexive, relayed or host), priority, foundation, and base.

struct pj_ice_sess_check
#include <ice_session.h>

This structure describes an ICE connectivity check. An ICE check contains a candidate pair, and will involve sending STUN Binding Request transaction for the purposes of verifying connectivity. A check is sent from the local candidate to the remote candidate of a candidate pair.

Forward declaration for pj_ice_sess_check

struct pj_ice_sess_checklist
#include <ice_session.h>

This structure represents ICE check list, that is an ordered set of candidate pairs that an agent will use to generate checks.

Forward declaration for checklist.

struct pj_ice_sess_cb
#include <ice_session.h>

This structure contains callbacks that will be called by the ICE session.

struct pj_ice_rx_check
#include <ice_session.h>

This structure represents an incoming check (an incoming Binding request message), and is mainly used to keep early checks in the list in the ICE session. An early check is a request received from remote when we haven’t received SDP answer yet, therefore we can’t perform triggered check. For such cases, keep the incoming request in a list, and we’ll do triggered checks (simultaneously) as soon as we receive answer.

struct pj_ice_sess_options
#include <ice_session.h>

This structure describes various ICE session options. Application configure the ICE session with these options by calling pj_ice_sess_set_options().

struct pj_ice_sess
#include <ice_session.h>

This structure describes the ICE session. For this version of PJNATH, an ICE session corresponds to a single media stream (unlike the ICE session described in the ICE standard where an ICE session covers the whole media and may consist of multiple media streams). The decision to support only a single media session was chosen for simplicity, while still allowing application to utilize multiple media streams by creating multiple ICE sessions, one for each media stream.

Forward declaration for pj_ice_sess