/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjnath/ice_session.h>
#include <pj/addr_resolv.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/guid.h>
#include <pj/hash.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/rand.h>
#include <pj/string.h>

/* String names for candidate types */
static const char *cand_type_names[] =
{
    "host",
    "srflx",
    "prflx",
    "relay"

};

/* String names for pj_ice_sess_check_state */
#if PJ_LOG_MAX_LEVEL >= 4
static const char *check_state_name[] = 
{
    "Frozen",
    "Waiting",
    "In Progress",
    "Succeeded",
    "Failed"
};

static const char *clist_state_name[] =
{
    "Idle",
    "Running",
    "Completed"
};
#endif	/* PJ_LOG_MAX_LEVEL >= 4 */

static const char *role_names[] = 
{
    "Unknown",
    "Controlled",
    "Controlling"
};

enum timer_type
{
    TIMER_NONE,			/**< Timer not active			*/
    TIMER_COMPLETION_CALLBACK,	/**< Call on_ice_complete() callback    */
    TIMER_CONTROLLED_WAIT_NOM,	/**< Controlled agent is waiting for 
				     controlling agent to send connectivity
				     check with nominated flag after it has
				     valid check for every components.	*/
    TIMER_START_NOMINATED_CHECK,/**< Controlling agent start connectivity
				     checks with USE-CANDIDATE flag.	*/
    TIMER_KEEP_ALIVE		/**< ICE keep-alive timer.		*/

};

/* Candidate type preference */
static pj_uint8_t cand_type_prefs[4] =
{
#if PJ_ICE_CAND_TYPE_PREF_BITS < 8
    /* Keep it to 2 bits */
    3,	    /**< PJ_ICE_HOST_PREF	*/
    1,	    /**< PJ_ICE_SRFLX_PREF.	*/
    2,	    /**< PJ_ICE_PRFLX_PREF	*/
    0	    /**< PJ_ICE_RELAYED_PREF	*/
#else
    /* Default ICE session preferences, according to draft-ice */
    126,    /**< PJ_ICE_HOST_PREF	*/
    100,    /**< PJ_ICE_SRFLX_PREF.	*/
    110,    /**< PJ_ICE_PRFLX_PREF	*/
    0	    /**< PJ_ICE_RELAYED_PREF	*/
#endif
};

#define THIS_FILE		"ice_session.c"
#define CHECK_NAME_LEN		128
#define LOG4(expr)		PJ_LOG(4,expr)
#define LOG5(expr)		PJ_LOG(4,expr)
#define GET_LCAND_ID(cand)	(unsigned)(cand - ice->lcand)
#define GET_CHECK_ID(cl, chk)	(chk - (cl)->checks)


/* The data that will be attached to the STUN session on each
 * component.
 */
typedef struct stun_data
{
    pj_ice_sess		*ice;
    unsigned		 comp_id;
    pj_ice_sess_comp	*comp;
} stun_data;


/* The data that will be attached to the timer to perform
 * periodic check.
 */
typedef struct timer_data
{
    pj_ice_sess		    *ice;
    pj_ice_sess_checklist   *clist;
} timer_data;


/* This is the data that will be attached as token to outgoing
 * STUN messages.
 */


/* Forward declarations */
static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te);
static void on_ice_complete(pj_ice_sess *ice, pj_status_t status);
static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now);
static void ice_on_destroy(void *obj);
static void destroy_ice(pj_ice_sess *ice,
			pj_status_t reason);
static pj_status_t start_periodic_check(pj_timer_heap_t *th, 
					pj_timer_entry *te);
static void start_nominated_check(pj_ice_sess *ice);
static void periodic_timer(pj_timer_heap_t *th, 
			  pj_timer_entry *te);
static void handle_incoming_check(pj_ice_sess *ice,
				  const pj_ice_rx_check *rcheck);

/* These are the callbacks registered to the STUN sessions */
static pj_status_t on_stun_send_msg(pj_stun_session *sess,
				    void *token,
				    const void *pkt,
				    pj_size_t pkt_size,
				    const pj_sockaddr_t *dst_addr,
				    unsigned addr_len);
static pj_status_t on_stun_rx_request(pj_stun_session *sess,
				      const pj_uint8_t *pkt,
				      unsigned pkt_len,
				      const pj_stun_rx_data *rdata,
				      void *token,
				      const pj_sockaddr_t *src_addr,
				      unsigned src_addr_len);
static void on_stun_request_complete(pj_stun_session *stun_sess,
				     pj_status_t status,
				     void *token,
				     pj_stun_tx_data *tdata,
				     const pj_stun_msg *response,
				     const pj_sockaddr_t *src_addr,
				     unsigned src_addr_len);
static pj_status_t on_stun_rx_indication(pj_stun_session *sess,
					 const pj_uint8_t *pkt,
					 unsigned pkt_len,
					 const pj_stun_msg *msg,
					 void *token,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len);

/* These are the callbacks for performing STUN authentication */
static pj_status_t stun_auth_get_auth(void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *nonce);
static pj_status_t stun_auth_get_cred(const pj_stun_msg *msg,
				      void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *username,
				      pj_str_t *nonce,
				      pj_stun_passwd_type *data_type,
				      pj_str_t *data);
static pj_status_t stun_auth_get_password(const pj_stun_msg *msg,
					  void *user_data, 
					  const pj_str_t *realm,
					  const pj_str_t *username,
					  pj_pool_t *pool,
					  pj_stun_passwd_type *data_type,
					  pj_str_t *data);


PJ_DEF(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type)
{
    PJ_ASSERT_RETURN(type <= PJ_ICE_CAND_TYPE_RELAYED, "???");
    return cand_type_names[type];
}


PJ_DEF(const char*) pj_ice_sess_role_name(pj_ice_sess_role role)
{
    switch (role) {
    case PJ_ICE_SESS_ROLE_UNKNOWN:
	return "Unknown";
    case PJ_ICE_SESS_ROLE_CONTROLLED:
	return "Controlled";
    case PJ_ICE_SESS_ROLE_CONTROLLING:
	return "Controlling";
    default:
	return "??";
    }
}


/* Get the prefix for the foundation */
static int get_type_prefix(pj_ice_cand_type type)
{
    switch (type) {
    case PJ_ICE_CAND_TYPE_HOST:	    return 'H';
    case PJ_ICE_CAND_TYPE_SRFLX:    return 'S';
    case PJ_ICE_CAND_TYPE_PRFLX:    return 'P';
    case PJ_ICE_CAND_TYPE_RELAYED:  return 'R';
    default:
	pj_assert(!"Invalid type");
	return 'U';
    }
}

/* Calculate foundation:
 * Two candidates have the same foundation when they are "similar" - of
 * the same type and obtained from the same host candidate and STUN
 * server using the same protocol.  Otherwise, their foundation is
 * different.
 */
PJ_DEF(void) pj_ice_calc_foundation(pj_pool_t *pool,
				    pj_str_t *foundation,
				    pj_ice_cand_type type,
				    const pj_sockaddr *base_addr)
{
#if PJNATH_ICE_PRIO_STD
    char buf[64];
    pj_uint32_t val;

    if (base_addr->addr.sa_family == pj_AF_INET()) {
	val = pj_ntohl(base_addr->ipv4.sin_addr.s_addr);
    } else {
	val = pj_hash_calc(0, pj_sockaddr_get_addr(base_addr),
			   pj_sockaddr_get_addr_len(base_addr));
    }
    pj_ansi_snprintf(buf, sizeof(buf), "%c%x",
		     get_type_prefix(type), val);
    pj_strdup2(pool, foundation, buf);
#else
    /* Much shorter version, valid for candidates added by
     * pj_ice_strans.
     */
    foundation->ptr = (char*) pj_pool_alloc(pool, 1);
    *foundation->ptr = (char)get_type_prefix(type);
    foundation->slen = 1;

    PJ_UNUSED_ARG(base_addr);
#endif
}


/* Init component */
static pj_status_t init_comp(pj_ice_sess *ice,
			     unsigned comp_id,
			     pj_ice_sess_comp *comp)
{
    pj_stun_session_cb sess_cb;
    pj_stun_auth_cred auth_cred;
    stun_data *sd;
    pj_status_t status;

    /* Init STUN callbacks */
    pj_bzero(&sess_cb, sizeof(sess_cb));
    sess_cb.on_request_complete = &on_stun_request_complete;
    sess_cb.on_rx_indication = &on_stun_rx_indication;
    sess_cb.on_rx_request = &on_stun_rx_request;
    sess_cb.on_send_msg = &on_stun_send_msg;

    /* Create STUN session for this candidate */
    status = pj_stun_session_create(&ice->stun_cfg, NULL, 
			            &sess_cb, PJ_TRUE,
			            ice->grp_lock,
				    &comp->stun_sess);
    if (status != PJ_SUCCESS)
	return status;

    /* Associate data with this STUN session */
    sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data);
    sd->ice = ice;
    sd->comp_id = comp_id;
    sd->comp = comp;
    pj_stun_session_set_user_data(comp->stun_sess, sd);

    /* Init STUN authentication credential */
    pj_bzero(&auth_cred, sizeof(auth_cred));
    auth_cred.type = PJ_STUN_AUTH_CRED_DYNAMIC;
    auth_cred.data.dyn_cred.get_auth = &stun_auth_get_auth;
    auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred;
    auth_cred.data.dyn_cred.get_password = &stun_auth_get_password;
    auth_cred.data.dyn_cred.user_data = comp->stun_sess;
    pj_stun_session_set_credential(comp->stun_sess, PJ_STUN_AUTH_SHORT_TERM,
				   &auth_cred);

    return PJ_SUCCESS;
}


/* Init options with default values */
PJ_DEF(void) pj_ice_sess_options_default(pj_ice_sess_options *opt)
{
    opt->aggressive = PJ_TRUE;
    opt->nominated_check_delay = PJ_ICE_NOMINATED_CHECK_DELAY;
    opt->controlled_agent_want_nom_timeout = 
	ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT;
}

/*
 * Create ICE session.
 */
PJ_DEF(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_pool_t *pool;
    pj_ice_sess *ice;
    unsigned i;
    pj_status_t status;

    PJ_ASSERT_RETURN(stun_cfg && cb && p_ice, PJ_EINVAL);

    if (name == NULL)
	name = "icess%p";

    pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_SESS, 
			  PJNATH_POOL_INC_ICE_SESS, NULL);
    ice = PJ_POOL_ZALLOC_T(pool, pj_ice_sess);
    ice->pool = pool;
    ice->role = role;
    ice->tie_breaker.u32.hi = pj_rand();
    ice->tie_breaker.u32.lo = pj_rand();
    ice->prefs = cand_type_prefs;
    pj_ice_sess_options_default(&ice->opt);

    pj_timer_entry_init(&ice->timer, TIMER_NONE, (void*)ice, &on_timer);

    pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name),
		     name, ice);

    if (grp_lock) {
	ice->grp_lock = grp_lock;
    } else {
	status = pj_grp_lock_create(pool, NULL, &ice->grp_lock);
	if (status != PJ_SUCCESS) {
	    pj_pool_release(pool);
	    return status;
	}
    }

    pj_grp_lock_add_ref(ice->grp_lock);
    pj_grp_lock_add_handler(ice->grp_lock, pool, ice,
                            &ice_on_destroy);

    pj_memcpy(&ice->cb, cb, sizeof(*cb));
    pj_memcpy(&ice->stun_cfg, stun_cfg, sizeof(*stun_cfg));

    ice->comp_cnt = comp_cnt;
    for (i=0; i<comp_cnt; ++i) {
	pj_ice_sess_comp *comp;
	comp = &ice->comp[i];
	comp->valid_check = NULL;
	comp->nominated_check = NULL;

	status = init_comp(ice, i+1, comp);
	if (status != PJ_SUCCESS) {
	    destroy_ice(ice, status);
	    return status;
	}
    }

    /* Initialize transport datas */
    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) {
	ice->tp_data[i].transport_id = i;
	ice->tp_data[i].has_req_data = PJ_FALSE;
    }

    if (local_ufrag == NULL) {
	ice->rx_ufrag.ptr = (char*) pj_pool_alloc(ice->pool, PJ_ICE_UFRAG_LEN);
	pj_create_random_string(ice->rx_ufrag.ptr, PJ_ICE_UFRAG_LEN);
	ice->rx_ufrag.slen = PJ_ICE_UFRAG_LEN;
    } else {
	pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag);
    }

    if (local_passwd == NULL) {
	ice->rx_pass.ptr = (char*) pj_pool_alloc(ice->pool, PJ_ICE_UFRAG_LEN);
	pj_create_random_string(ice->rx_pass.ptr, PJ_ICE_UFRAG_LEN);
	ice->rx_pass.slen = PJ_ICE_UFRAG_LEN;
    } else {
	pj_strdup(ice->pool, &ice->rx_pass, local_passwd);
    }

    pj_list_init(&ice->early_check);

    /* Done */
    *p_ice = ice;

    LOG4((ice->obj_name, 
	 "ICE session created, comp_cnt=%d, role is %s agent",
	 comp_cnt, role_names[ice->role]));

    return PJ_SUCCESS;
}


/*
 * Get the value of various options of the ICE session.
 */
PJ_DEF(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice,
					    pj_ice_sess_options *opt)
{
    PJ_ASSERT_RETURN(ice, PJ_EINVAL);
    pj_memcpy(opt, &ice->opt, sizeof(*opt));
    return PJ_SUCCESS;
}

/*
 * Specify various options for this ICE session.
 */
PJ_DEF(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice,
					    const pj_ice_sess_options *opt)
{
    PJ_ASSERT_RETURN(ice && opt, PJ_EINVAL);
    pj_memcpy(&ice->opt, opt, sizeof(*opt));
    LOG5((ice->obj_name, "ICE nomination type set to %s",
	  (ice->opt.aggressive ? "aggressive" : "regular")));
    return PJ_SUCCESS;
}


/*
 * Callback to really destroy the session
 */
static void ice_on_destroy(void *obj)
{
    pj_ice_sess *ice = (pj_ice_sess*) obj;

    if (ice->pool) {
	pj_pool_t *pool = ice->pool;
	ice->pool = NULL;
	pj_pool_release(pool);
    }
    LOG4((THIS_FILE, "ICE session %p destroyed", ice));
}

/*
 * Destroy
 */
static void destroy_ice(pj_ice_sess *ice,
			pj_status_t reason)
{
    unsigned i;

    if (reason == PJ_SUCCESS) {
	LOG4((ice->obj_name, "Destroying ICE session %p", ice));
    }

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    ice->is_destroying = PJ_TRUE;

    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,
                                   &ice->timer, PJ_FALSE);

    for (i=0; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].stun_sess) {
	    pj_stun_session_destroy(ice->comp[i].stun_sess);
	    ice->comp[i].stun_sess = NULL;
	}
    }

    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,
                                   &ice->clist.timer,
                                   PJ_FALSE);

    pj_grp_lock_dec_ref(ice->grp_lock);
    pj_grp_lock_release(ice->grp_lock);
}


/*
 * Destroy
 */
PJ_DEF(pj_status_t) pj_ice_sess_destroy(pj_ice_sess *ice)
{
    PJ_ASSERT_RETURN(ice, PJ_EINVAL);
    destroy_ice(ice, PJ_SUCCESS);
    return PJ_SUCCESS;
}


/*
 * Change session role. 
 */
PJ_DEF(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice,
					    pj_ice_sess_role new_role)
{
    PJ_ASSERT_RETURN(ice, PJ_EINVAL);

    if (new_role != ice->role) {
	ice->role = new_role;
	LOG4((ice->obj_name, "Role changed to %s", role_names[new_role]));
    }

    return PJ_SUCCESS;
}


/*
 * Change type preference
 */
PJ_DEF(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,
					  const pj_uint8_t prefs[4])
{
    unsigned i;
    PJ_ASSERT_RETURN(ice && prefs, PJ_EINVAL);
    ice->prefs = (pj_uint8_t*) pj_pool_calloc(ice->pool, PJ_ARRAY_SIZE(prefs),
					      sizeof(pj_uint8_t));
    for (i=0; i<4; ++i) {
#if PJ_ICE_CAND_TYPE_PREF_BITS < 8
	pj_assert(prefs[i] < (2 << PJ_ICE_CAND_TYPE_PREF_BITS));
#endif
	ice->prefs[i] = prefs[i];
    }
    return PJ_SUCCESS;
}


/* Find component by ID */
static pj_ice_sess_comp *find_comp(const pj_ice_sess *ice, unsigned comp_id)
{
    pj_assert(comp_id > 0 && comp_id <= ice->comp_cnt);
    return (pj_ice_sess_comp*) &ice->comp[comp_id-1];
}


/* Callback by STUN authentication when it needs to send 401 */
static pj_status_t stun_auth_get_auth(void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *nonce)
{
    PJ_UNUSED_ARG(user_data);
    PJ_UNUSED_ARG(pool);

    realm->slen = 0;
    nonce->slen = 0;

    return PJ_SUCCESS;
}


/* Get credential to be sent with outgoing message */
static pj_status_t stun_auth_get_cred(const pj_stun_msg *msg,
				      void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *username,
				      pj_str_t *nonce,
				      pj_stun_passwd_type *data_type,
				      pj_str_t *data)
{
    pj_stun_session *sess = (pj_stun_session *)user_data;
    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);
    pj_ice_sess *ice = sd->ice;

    PJ_UNUSED_ARG(pool);
    realm->slen = nonce->slen = 0;

    if (PJ_STUN_IS_RESPONSE(msg->hdr.type)) {
	/* Outgoing responses need to have the same credential as
	 * incoming requests.
	 */
	*username = ice->rx_uname;
	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->rx_pass;
    }
    else {
	*username = ice->tx_uname;
	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->tx_pass;
    }

    return PJ_SUCCESS;
}

/* Get password to be used to authenticate incoming message */
static pj_status_t stun_auth_get_password(const pj_stun_msg *msg,
					  void *user_data, 
					  const pj_str_t *realm,
					  const pj_str_t *username,
					  pj_pool_t *pool,
					  pj_stun_passwd_type *data_type,
					  pj_str_t *data)
{
    pj_stun_session *sess = (pj_stun_session *)user_data;
    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);
    pj_ice_sess *ice = sd->ice;

    PJ_UNUSED_ARG(realm);
    PJ_UNUSED_ARG(pool);

    if (PJ_STUN_IS_SUCCESS_RESPONSE(msg->hdr.type) ||
	PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))
    {
	/* Incoming response is authenticated with TX credential */
	/* Verify username */
	if (pj_strcmp(username, &ice->tx_uname) != 0)
	    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);
	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->tx_pass;

    } else {
	/* Incoming request is authenticated with RX credential */
	/* The agent MUST accept a credential if the username consists
	 * of two values separated by a colon, where the first value is
	 * equal to the username fragment generated by the agent in an offer
	 * or answer for a session in-progress, and the MESSAGE-INTEGRITY 
	 * is the output of a hash of the password and the STUN packet's 
	 * contents.
	 */
	const char *pos;
	pj_str_t ufrag;

	pos = (const char*)pj_memchr(username->ptr, ':', username->slen);
	if (pos == NULL)
	    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);

	ufrag.ptr = (char*)username->ptr;
	ufrag.slen = (pos - username->ptr);

	if (pj_strcmp(&ufrag, &ice->rx_ufrag) != 0)
	    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);

	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->rx_pass;

    }

    return PJ_SUCCESS;
}


static pj_uint32_t CALC_CAND_PRIO(pj_ice_sess *ice,
				  pj_ice_cand_type type,
				  pj_uint32_t local_pref,
				  pj_uint32_t comp_id)
{
#if PJNATH_ICE_PRIO_STD
    return ((ice->prefs[type] & 0xFF) << 24) + 
	   ((local_pref & 0xFFFF)    << 8) +
	   (((256 - comp_id) & 0xFF) << 0);
#else
    enum {
	type_mask   = ((2 << PJ_ICE_CAND_TYPE_PREF_BITS) - 1),
	local_mask  = ((2 << PJ_ICE_LOCAL_PREF_BITS) - 1),
	comp_mask   = ((2 << PJ_ICE_COMP_BITS) - 1),

	comp_shift  = 0,
	local_shift = (PJ_ICE_COMP_BITS),
	type_shift  = (comp_shift + local_shift),

	max_comp    = (2<<PJ_ICE_COMP_BITS),
    };

    return ((ice->prefs[type] & type_mask) << type_shift) + 
	   ((local_pref & local_mask) << local_shift) +
	   (((max_comp - comp_id) & comp_mask) << comp_shift);
#endif
}


/*
 * Add ICE candidate
 */
PJ_DEF(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_ice_sess_cand *lcand;
    pj_status_t status = PJ_SUCCESS;
    char address[PJ_INET6_ADDRSTRLEN];

    PJ_ASSERT_RETURN(ice && comp_id && 
		     foundation && addr && base_addr && addr_len,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL);

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->lcand_cnt >= PJ_ARRAY_SIZE(ice->lcand)) {
	status = PJ_ETOOMANY;
	goto on_error;
    }

    lcand = &ice->lcand[ice->lcand_cnt];
    lcand->comp_id = (pj_uint8_t)comp_id;
    lcand->transport_id = (pj_uint8_t)transport_id;
    lcand->type = type;
    pj_strdup(ice->pool, &lcand->foundation, foundation);
    lcand->prio = CALC_CAND_PRIO(ice, type, local_pref, lcand->comp_id);
    pj_sockaddr_cp(&lcand->addr, addr);
    pj_sockaddr_cp(&lcand->base_addr, base_addr);
    if (rel_addr == NULL)
	rel_addr = base_addr;
    pj_memcpy(&lcand->rel_addr, rel_addr, addr_len);

    pj_ansi_strcpy(ice->tmp.txt, pj_sockaddr_print(&lcand->addr, address,
                                                   sizeof(address), 0));
    LOG4((ice->obj_name, 
	 "Candidate %d added: comp_id=%d, type=%s, foundation=%.*s, "
	 "addr=%s:%d, base=%s:%d, prio=0x%x (%u)",
	 ice->lcand_cnt, 
	 lcand->comp_id, 
	 cand_type_names[lcand->type],
	 (int)lcand->foundation.slen,
	 lcand->foundation.ptr,
	 ice->tmp.txt, 
	  pj_sockaddr_get_port(&lcand->addr),
	  pj_sockaddr_print(&lcand->base_addr, address, sizeof(address), 0),
	  pj_sockaddr_get_port(&lcand->base_addr),
	 lcand->prio, lcand->prio));

    if (p_cand_id)
	*p_cand_id = ice->lcand_cnt;

    ++ice->lcand_cnt;

on_error:
    pj_grp_lock_release(ice->grp_lock);
    return status;
}


/* Find default candidate ID for the component */
PJ_DEF(pj_status_t) pj_ice_sess_find_default_cand(pj_ice_sess *ice,
						  unsigned comp_id,
						  int *cand_id)
{
    unsigned i;

    PJ_ASSERT_RETURN(ice && comp_id && cand_id, PJ_EINVAL);
    PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL);

    *cand_id = -1;

    pj_grp_lock_acquire(ice->grp_lock);

    /* First find in valid list if we have nominated pair */
    for (i=0; i<ice->valid_list.count; ++i) {
	pj_ice_sess_check *check = &ice->valid_list.checks[i];
	
	if (check->lcand->comp_id == comp_id) {
	    *cand_id = GET_LCAND_ID(check->lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* If there's no nominated pair, find relayed candidate */
    for (i=0; i<ice->lcand_cnt; ++i) {
	pj_ice_sess_cand *lcand = &ice->lcand[i];
	if (lcand->comp_id==comp_id &&
	    lcand->type == PJ_ICE_CAND_TYPE_RELAYED) 
	{
	    *cand_id = GET_LCAND_ID(lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* If there's no relayed candidate, find reflexive candidate */
    for (i=0; i<ice->lcand_cnt; ++i) {
	pj_ice_sess_cand *lcand = &ice->lcand[i];
	if (lcand->comp_id==comp_id &&
	    (lcand->type == PJ_ICE_CAND_TYPE_SRFLX ||
	     lcand->type == PJ_ICE_CAND_TYPE_PRFLX)) 
	{
	    *cand_id = GET_LCAND_ID(lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* Otherwise return host candidate */
    for (i=0; i<ice->lcand_cnt; ++i) {
	pj_ice_sess_cand *lcand = &ice->lcand[i];
	if (lcand->comp_id==comp_id &&
	    lcand->type == PJ_ICE_CAND_TYPE_HOST) 
	{
	    *cand_id = GET_LCAND_ID(lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* Still no candidate is found! :( */
    pj_grp_lock_release(ice->grp_lock);

    pj_assert(!"Should have a candidate by now");
    return PJ_EBUG;
}


#ifndef MIN
#   define MIN(a,b) (a < b ? a : b)
#endif

#ifndef MAX
#   define MAX(a,b) (a > b ? a : b)
#endif

static pj_timestamp CALC_CHECK_PRIO(const pj_ice_sess *ice, 
				    const pj_ice_sess_cand *lcand,
				    const pj_ice_sess_cand *rcand)
{
    pj_uint32_t O, A;
    pj_timestamp prio;

    /* Original formula:
     *   pair priority = 2^32*MIN(O,A) + 2*MAX(O,A) + (O>A?1:0)
     */

    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) {
	O = lcand->prio; 
	A = rcand->prio;
    } else {
	O = rcand->prio;
	A = lcand->prio;
    }

    /*
    return ((pj_uint64_t)1 << 32) * MIN(O, A) +
	   (pj_uint64_t)2 * MAX(O, A) + (O>A ? 1 : 0);
    */

    prio.u32.hi = MIN(O,A);
    prio.u32.lo = (MAX(O, A) << 1) + (O>A ? 1 : 0);

    return prio;
}


PJ_INLINE(int) CMP_CHECK_PRIO(const pj_ice_sess_check *c1,
			      const pj_ice_sess_check *c2)
{
    return pj_cmp_timestamp(&c1->prio, &c2->prio);
}


#if PJ_LOG_MAX_LEVEL >= 4
static const char *dump_check(char *buffer, unsigned bufsize,
			      const pj_ice_sess_checklist *clist,
			      const pj_ice_sess_check *check)
{
    const pj_ice_sess_cand *lcand = check->lcand;
    const pj_ice_sess_cand *rcand = check->rcand;
    char laddr[PJ_INET6_ADDRSTRLEN], raddr[PJ_INET6_ADDRSTRLEN];
    int len;

    PJ_CHECK_STACK();

    pj_ansi_strcpy(laddr, pj_sockaddr_print(&lcand->addr, laddr,
                                            sizeof(laddr), 0));

    len = pj_ansi_snprintf(buffer, bufsize,
			   "%d: [%d] %s:%d-->%s:%d",
			   (int)GET_CHECK_ID(clist, check),
			   check->lcand->comp_id,
			   pj_sockaddr_print(&lcand->addr, laddr,
			                     sizeof(laddr), 0),
			   pj_sockaddr_get_port(&lcand->addr),
			   pj_sockaddr_print(&rcand->addr, raddr,
			                     sizeof(raddr), 0),
			   pj_sockaddr_get_port(&rcand->addr));

    if (len < 0)
	len = 0;
    else if (len >= (int)bufsize)
	len = bufsize - 1;

    buffer[len] = '\0';
    return buffer;
}

static void dump_checklist(const char *title, pj_ice_sess *ice, 
			   const pj_ice_sess_checklist *clist)
{
    unsigned i;

    LOG4((ice->obj_name, "%s", title));
    for (i=0; i<clist->count; ++i) {
	const pj_ice_sess_check *c = &clist->checks[i];
	LOG4((ice->obj_name, " %s (%s, state=%s)",
	     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, c),
	     (c->nominated ? "nominated" : "not nominated"), 
	     check_state_name[c->state]));
    }
}

#else
#define dump_checklist(title, ice, clist)
#endif

static void check_set_state(pj_ice_sess *ice, pj_ice_sess_check *check,
			    pj_ice_sess_check_state st, 
			    pj_status_t err_code)
{
    pj_assert(check->state < PJ_ICE_SESS_CHECK_STATE_SUCCEEDED);

    LOG5((ice->obj_name, "Check %s: state changed from %s to %s",
	 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), &ice->clist, check),
	 check_state_name[check->state],
	 check_state_name[st]));
    check->state = st;
    check->err_code = err_code;
}

static void clist_set_state(pj_ice_sess *ice, pj_ice_sess_checklist *clist,
			    pj_ice_sess_checklist_state st)
{
    if (clist->state != st) {
	LOG5((ice->obj_name, "Checklist: state changed from %s to %s",
	     clist_state_name[clist->state],
	     clist_state_name[st]));
	clist->state = st;
    }
}

/* Sort checklist based on priority */
static void sort_checklist(pj_ice_sess *ice, pj_ice_sess_checklist *clist)
{
    unsigned i;
    pj_ice_sess_check **check_ptr[PJ_ICE_MAX_COMP*2];
    unsigned check_ptr_cnt = 0;

    for (i=0; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].valid_check) {
	    check_ptr[check_ptr_cnt++] = &ice->comp[i].valid_check;
	}
	if (ice->comp[i].nominated_check) {
	    check_ptr[check_ptr_cnt++] = &ice->comp[i].nominated_check;
	}
    }

    pj_assert(clist->count > 0);
    for (i=0; i<clist->count-1; ++i) {
	unsigned j, highest = i;

	for (j=i+1; j<clist->count; ++j) {
	    if (CMP_CHECK_PRIO(&clist->checks[j], &clist->checks[highest]) > 0) {
		highest = j;
	    }
	}

	if (highest != i) {
	    pj_ice_sess_check tmp;
	    unsigned k;

	    pj_memcpy(&tmp, &clist->checks[i], sizeof(pj_ice_sess_check));
	    pj_memcpy(&clist->checks[i], &clist->checks[highest], 
		      sizeof(pj_ice_sess_check));
	    pj_memcpy(&clist->checks[highest], &tmp, 
		      sizeof(pj_ice_sess_check));

	    /* Update valid and nominated check pointers, since we're moving
	     * around checks
	     */
	    for (k=0; k<check_ptr_cnt; ++k) {
		if (*check_ptr[k] == &clist->checks[highest])
		    *check_ptr[k] = &clist->checks[i];
		else if (*check_ptr[k] == &clist->checks[i])
		    *check_ptr[k] = &clist->checks[highest];
	    }
	}
    }
}

/* Prune checklist, this must have been done after the checklist
 * is sorted.
 */
static pj_status_t prune_checklist(pj_ice_sess *ice, 
				   pj_ice_sess_checklist *clist)
{
    unsigned i;

    /* Since an agent cannot send requests directly from a reflexive
     * candidate, but only from its base, the agent next goes through the
     * sorted list of candidate pairs.  For each pair where the local
     * candidate is server reflexive, the server reflexive candidate MUST be
     * replaced by its base.  Once this has been done, the agent MUST prune
     * the list.  This is done by removing a pair if its local and remote
     * candidates are identical to the local and remote candidates of a pair
     * higher up on the priority list.  The result is a sequence of ordered
     * candidate pairs, called the check list for that media stream.    
     */
    /* First replace SRFLX candidates with their base */
    for (i=0; i<clist->count; ++i) {
	pj_ice_sess_cand *srflx = clist->checks[i].lcand;

	if (clist->checks[i].lcand->type == PJ_ICE_CAND_TYPE_SRFLX) {
	    /* Find the base for this candidate */
	    unsigned j;
	    for (j=0; j<ice->lcand_cnt; ++j) {
		pj_ice_sess_cand *host = &ice->lcand[j];

		if (host->type != PJ_ICE_CAND_TYPE_HOST)
		    continue;

		if (pj_sockaddr_cmp(&srflx->base_addr, &host->addr) == 0) {
		    /* Replace this SRFLX with its BASE */
		    clist->checks[i].lcand = host;
		    break;
		}
	    }

	    if (j==ice->lcand_cnt) {
		char baddr[PJ_INET6_ADDRSTRLEN];
		/* Host candidate not found this this srflx! */
		LOG4((ice->obj_name, 
		      "Base candidate %s:%d not found for srflx candidate %d",
		      pj_sockaddr_print(&srflx->base_addr, baddr,
		                        sizeof(baddr), 0),
		      pj_sockaddr_get_port(&srflx->base_addr),
		      GET_LCAND_ID(clist->checks[i].lcand)));
		return PJNATH_EICENOHOSTCAND;
	    }
	}
    }

    /* Next remove a pair if its local and remote candidates are identical
     * to the local and remote candidates of a pair higher up on the priority
     * list
     */
    /*
     * Not in ICE!
     * Remove host candidates if their base are the the same!
     */
    for (i=0; i<clist->count; ++i) {
	pj_ice_sess_cand *licand = clist->checks[i].lcand;
	pj_ice_sess_cand *ricand = clist->checks[i].rcand;
	unsigned j;

	for (j=i+1; j<clist->count;) {
	    pj_ice_sess_cand *ljcand = clist->checks[j].lcand;
	    pj_ice_sess_cand *rjcand = clist->checks[j].rcand;
	    const char *reason = NULL;

	    if ((licand == ljcand) && (ricand == rjcand)) {
		reason = "duplicate found";
	    } else if ((rjcand == ricand) &&
		       (pj_sockaddr_cmp(&ljcand->base_addr, 
				     &licand->base_addr)==0)) 
	    {
		reason = "equal base";
	    }

	    if (reason != NULL) {
		/* Found duplicate, remove it */
		LOG5((ice->obj_name, "Check %s pruned (%s)",
		      dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
				 &ice->clist, &clist->checks[j]),
		      reason));

		pj_array_erase(clist->checks, sizeof(clist->checks[0]),
			       clist->count, j);
		--clist->count;

	    } else {
		++j;
	    }
	}
    }

    return PJ_SUCCESS;
}

/* Timer callback */
static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te)
{
    pj_ice_sess *ice = (pj_ice_sess*) te->user_data;
    enum timer_type type = (enum timer_type)te->id;

    PJ_UNUSED_ARG(th);

    pj_grp_lock_acquire(ice->grp_lock);

    te->id = TIMER_NONE;

    if (ice->is_destroying) {
	/* Stray timer, could happen when destroy is invoked while callback
	 * is pending. */
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    switch (type) {
    case TIMER_CONTROLLED_WAIT_NOM:
	LOG4((ice->obj_name, 
	      "Controlled agent timed-out in waiting for the controlling "
	      "agent to send nominated check. Setting state to fail now.."));
	on_ice_complete(ice, PJNATH_EICENOMTIMEOUT);
	break;
    case TIMER_COMPLETION_CALLBACK:
	{
	    void (*on_ice_complete)(pj_ice_sess *ice, pj_status_t status);
	    pj_status_t ice_status;

	    /* Start keep-alive timer but don't send any packets yet.
	     * Need to do it here just in case app destroy the session
	     * in the callback.
	     */
	    if (ice->ice_status == PJ_SUCCESS)
		ice_keep_alive(ice, PJ_FALSE);

	    /* Release mutex in case app destroy us in the callback */
	    ice_status = ice->ice_status;
	    on_ice_complete = ice->cb.on_ice_complete;

	    /* Notify app about ICE completion*/
	    if (on_ice_complete)
		(*on_ice_complete)(ice, ice_status);
	}
	break;
    case TIMER_START_NOMINATED_CHECK:
	start_nominated_check(ice);
	break;
    case TIMER_KEEP_ALIVE:
	ice_keep_alive(ice, PJ_TRUE);
	break;
    case TIMER_NONE:
	/* Nothing to do, just to get rid of gcc warning */
	break;
    }

    pj_grp_lock_release(ice->grp_lock);
}

/* Send keep-alive */
static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now)
{
    if (send_now) {
	/* Send Binding Indication for the component */
	pj_ice_sess_comp *comp = &ice->comp[ice->comp_ka];
	pj_stun_tx_data *tdata;
	pj_ice_sess_check *the_check;
	pj_ice_msg_data *msg_data;
	int addr_len;
	pj_bool_t saved;
	pj_status_t status;

	/* Must have nominated check by now */
	pj_assert(comp->nominated_check != NULL);
	the_check = comp->nominated_check;

	/* Create the Binding Indication */
	status = pj_stun_session_create_ind(comp->stun_sess, 
					    PJ_STUN_BINDING_INDICATION,
					    &tdata);
	if (status != PJ_SUCCESS)
	    goto done;

	/* Need the transport_id */
	msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);
	msg_data->transport_id = the_check->lcand->transport_id;

	/* Temporarily disable FINGERPRINT. The Binding Indication 
	 * SHOULD NOT contain any attributes.
	 */
	saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_FALSE);

	/* Send to session */
	addr_len = pj_sockaddr_get_len(&the_check->rcand->addr);
	status = pj_stun_session_send_msg(comp->stun_sess, msg_data,
					  PJ_FALSE, PJ_FALSE, 
					  &the_check->rcand->addr, 
					  addr_len, tdata);

	/* Restore FINGERPRINT usage */
	pj_stun_session_use_fingerprint(comp->stun_sess, saved);

done:
	ice->comp_ka = (ice->comp_ka + 1) % ice->comp_cnt;
    }

    if (ice->timer.id == TIMER_NONE) {
	pj_time_val delay = { 0, 0 };

	delay.msec = (PJ_ICE_SESS_KEEP_ALIVE_MIN + 
		      (pj_rand() % PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND)) * 1000 / 
		     ice->comp_cnt;
	pj_time_val_normalize(&delay);

	pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
	                                  &ice->timer, &delay,
	                                  TIMER_KEEP_ALIVE,
	                                  ice->grp_lock);

    } else {
	pj_assert(!"Not expected any timer active");
    }
}

/* This function is called when ICE processing completes */
static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
{
    if (!ice->is_complete) {
	ice->is_complete = PJ_TRUE;
	ice->ice_status = status;
    
	pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,
	                               TIMER_NONE);

	/* Log message */
	LOG4((ice->obj_name, "ICE process complete, status=%s", 
	     pj_strerror(status, ice->tmp.errmsg, 
			 sizeof(ice->tmp.errmsg)).ptr));

	dump_checklist("Valid list", ice, &ice->valid_list);

	/* Call callback */
	if (ice->cb.on_ice_complete) {
	    pj_time_val delay = {0, 0};

	    pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
	                                      &ice->timer, &delay,
	                                      TIMER_COMPLETION_CALLBACK,
	                                      ice->grp_lock);
	}
    }
}

/* Update valid check and nominated check for the candidate */
static void update_comp_check(pj_ice_sess *ice, unsigned comp_id, 
			      pj_ice_sess_check *check)
{
    pj_ice_sess_comp *comp;

    comp = find_comp(ice, comp_id);
    if (comp->valid_check == NULL) {
	comp->valid_check = check;
    } else {
	if (CMP_CHECK_PRIO(comp->valid_check, check) < 0)
	    comp->valid_check = check;
    }

    if (check->nominated) {
	/* Update the nominated check for the component */
	if (comp->nominated_check == NULL) {
	    comp->nominated_check = check;
	} else {
	    if (CMP_CHECK_PRIO(comp->nominated_check, check) < 0)
		comp->nominated_check = check;
	}
    }
}

/* This function is called when one check completes */
static pj_bool_t on_check_complete(pj_ice_sess *ice,
				   pj_ice_sess_check *check)
{
    pj_ice_sess_comp *comp;
    unsigned i;

    pj_assert(check->state >= PJ_ICE_SESS_CHECK_STATE_SUCCEEDED);

    comp = find_comp(ice, check->lcand->comp_id);

    /* 7.1.2.2.2.  Updating Pair States
     * 
     * The agent sets the state of the pair that generated the check to
     * Succeeded.  The success of this check might also cause the state of
     * other checks to change as well.  The agent MUST perform the following
     * two steps:
     * 
     * 1.  The agent changes the states for all other Frozen pairs for the
     *     same media stream and same foundation to Waiting.  Typically
     *     these other pairs will have different component IDs but not
     *     always.
     */
    if (check->err_code==PJ_SUCCESS) {

	for (i=0; i<ice->clist.count; ++i) {
	    pj_ice_sess_check *c = &ice->clist.checks[i];
	    if (pj_strcmp(&c->lcand->foundation, &check->lcand->foundation)==0
		 && c->state == PJ_ICE_SESS_CHECK_STATE_FROZEN)
	    {
		check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_WAITING, 0);
	    }
	}

	LOG5((ice->obj_name, "Check %d is successful%s",
	     GET_CHECK_ID(&ice->clist, check),
	     (check->nominated ? "  and nominated" : "")));

    }

    /* 8.2.  Updating States
     * 
     * For both controlling and controlled agents, the state of ICE
     * processing depends on the presence of nominated candidate pairs in
     * the valid list and on the state of the check list:
     *
     * o  If there are no nominated pairs in the valid list for a media
     *    stream and the state of the check list is Running, ICE processing
     *    continues.
     *
     * o  If there is at least one nominated pair in the valid list:
     *
     *    - The agent MUST remove all Waiting and Frozen pairs in the check
     *      list for the same component as the nominated pairs for that
     *      media stream
     *
     *    - If an In-Progress pair in the check list is for the same
     *      component as a nominated pair, the agent SHOULD cease
     *      retransmissions for its check if its pair priority is lower
     *      than the lowest priority nominated pair for that component
     */
    if (check->err_code==PJ_SUCCESS && check->nominated) {

	for (i=0; i<ice->clist.count; ++i) {

	    pj_ice_sess_check *c = &ice->clist.checks[i];

	    if (c->lcand->comp_id == check->lcand->comp_id) {

		if (c->state < PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS) {

		    /* Just fail Frozen/Waiting check */
		    LOG5((ice->obj_name, 
			 "Check %s to be failed because state is %s",
			 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
				    &ice->clist, c), 
			 check_state_name[c->state]));
		    check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_FAILED,
				    PJ_ECANCELLED);

		} else if (c->state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS
			   && (PJ_ICE_CANCEL_ALL ||
			        CMP_CHECK_PRIO(c, check) < 0)) {

		    /* State is IN_PROGRESS, cancel transaction */
		    if (c->tdata) {
			LOG5((ice->obj_name, 
			     "Cancelling check %s (In Progress)",
			     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
					&ice->clist, c)));
			pj_stun_session_cancel_req(comp->stun_sess, 
						   c->tdata, PJ_FALSE, 0);
			c->tdata = NULL;
			check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_FAILED,
					PJ_ECANCELLED);
		    }
		}
	    }
	}
    }


    /* Still in 8.2.  Updating States
     * 
     * o  Once there is at least one nominated pair in the valid list for
     *    every component of at least one media stream and the state of the
     *    check list is Running:
     *    
     *    *  The agent MUST change the state of processing for its check
     *       list for that media stream to Completed.
     *    
     *    *  The agent MUST continue to respond to any checks it may still
     *       receive for that media stream, and MUST perform triggered
     *       checks if required by the processing of Section 7.2.
     *    
     *    *  The agent MAY begin transmitting media for this media stream as
     *       described in Section 11.1
     */

    /* See if all components have nominated pair. If they do, then mark
     * ICE processing as success, otherwise wait.
     */
    for (i=0; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].nominated_check == NULL)
	    break;
    }
    if (i == ice->comp_cnt) {
	/* All components have nominated pair */
	on_ice_complete(ice, PJ_SUCCESS);
	return PJ_TRUE;
    }

    /* Note: this is the stuffs that we don't do in 7.1.2.2.2, since our
     *       ICE session only supports one media stream for now:
     * 
     * 7.1.2.2.2.  Updating Pair States
     *
     * 2.  If there is a pair in the valid list for every component of this
     *     media stream (where this is the actual number of components being
     *     used, in cases where the number of components signaled in the SDP
     *     differs from offerer to answerer), the success of this check may
     *     unfreeze checks for other media streams. 
     */

    /* 7.1.2.3.  Check List and Timer State Updates
     * Regardless of whether the check was successful or failed, the
     * completion of the transaction may require updating of check list and
     * timer states.
     * 
     * If all of the pairs in the check list are now either in the Failed or
     * Succeeded state, and there is not a pair in the valid list for each
     * component of the media stream, the state of the check list is set to
     * Failed.  
     */

    /* 
     * See if all checks in the checklist have completed. If we do,
     * then mark ICE processing as failed.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (c->state < PJ_ICE_SESS_CHECK_STATE_SUCCEEDED) {
	    break;
	}
    }

    if (i == ice->clist.count) {
	/* All checks have completed, but we don't have nominated pair.
	 * If agent's role is controlled, check if all components have
	 * valid pair. If it does, this means the controlled agent has
	 * finished the check list and it's waiting for controlling
	 * agent to send checks with USE-CANDIDATE flag set.
	 */
	if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLED) {
	    for (i=0; i < ice->comp_cnt; ++i) {
		if (ice->comp[i].valid_check == NULL)
		    break;
	    }

	    if (i < ice->comp_cnt) {
		/* This component ID doesn't have valid pair.
		 * Mark ICE as failed. 
		 */
		on_ice_complete(ice, PJNATH_EICEFAILED);
		return PJ_TRUE;
	    } else {
		/* All components have a valid pair.
		 * We should wait until we receive nominated checks.
		 */
		if (ice->timer.id == TIMER_NONE &&
		    ice->opt.controlled_agent_want_nom_timeout >= 0) 
		{
		    pj_time_val delay;

		    delay.sec = 0;
		    delay.msec = ice->opt.controlled_agent_want_nom_timeout;
		    pj_time_val_normalize(&delay);

		    pj_timer_heap_schedule_w_grp_lock(
					ice->stun_cfg.timer_heap,
		                        &ice->timer, &delay,
		                        TIMER_CONTROLLED_WAIT_NOM,
		                        ice->grp_lock);

		    LOG5((ice->obj_name, 
			  "All checks have completed. Controlled agent now "
			  "waits for nomination from controlling agent "
			  "(timeout=%d msec)",
			  ice->opt.controlled_agent_want_nom_timeout));
		}
		return PJ_FALSE;
	    }

	    /* Unreached */

	} else if (ice->is_nominating) {
	    /* We are controlling agent and all checks have completed but
	     * there's at least one component without nominated pair (or
	     * more likely we don't have any nominated pairs at all).
	     */
	    on_ice_complete(ice, PJNATH_EICEFAILED);
	    return PJ_TRUE;

	} else {
	    /* We are controlling agent and all checks have completed. If
	     * we have valid list for every component, then move on to
	     * sending nominated check, otherwise we have failed.
	     */
	    for (i=0; i<ice->comp_cnt; ++i) {
		if (ice->comp[i].valid_check == NULL)
		    break;
	    }

	    if (i < ice->comp_cnt) {
		/* At least one component doesn't have a valid check. Mark
		 * ICE as failed.
		 */
		on_ice_complete(ice, PJNATH_EICEFAILED);
		return PJ_TRUE;
	    }

	    /* Now it's time to send connectivity check with nomination 
	     * flag set.
	     */
	    LOG4((ice->obj_name, 
		  "All checks have completed, starting nominated checks now"));
	    start_nominated_check(ice);
	    return PJ_FALSE;
	}
    }

    /* If this connectivity check has been successful, scan all components
     * and see if they have a valid pair, if we are controlling and we haven't
     * started our nominated check yet.
     */
    if (check->err_code == PJ_SUCCESS && 
	ice->role==PJ_ICE_SESS_ROLE_CONTROLLING &&
	!ice->is_nominating &&
	ice->timer.id == TIMER_NONE) 
    {
	pj_time_val delay;

	for (i=0; i<ice->comp_cnt; ++i) {
	    if (ice->comp[i].valid_check == NULL)
		break;
	}

	if (i < ice->comp_cnt) {
	    /* Some components still don't have valid pair, continue
	     * processing.
	     */
	    return PJ_FALSE;
	}

	LOG4((ice->obj_name, 
	      "Scheduling nominated check in %d ms",
	      ice->opt.nominated_check_delay));

	pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,
	                               TIMER_NONE);

	/* All components have valid pair. Let connectivity checks run for
	 * a little bit more time, then start our nominated check.
	 */
	delay.sec = 0;
	delay.msec = ice->opt.nominated_check_delay;
	pj_time_val_normalize(&delay);

	pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
	                                  &ice->timer, &delay,
	                                  TIMER_START_NOMINATED_CHECK,
	                                  ice->grp_lock);
	return PJ_FALSE;
    }

    /* We still have checks to perform */
    return PJ_FALSE;
}


/* Create checklist by pairing local candidates with remote candidates */
PJ_DEF(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 rcand_cnt,
			      const pj_ice_sess_cand rcand[])
{
    pj_ice_sess_checklist *clist;
    char buf[128];
    pj_str_t username;
    timer_data *td;
    unsigned i, j;
    unsigned highest_comp = 0;
    pj_status_t status;

    PJ_ASSERT_RETURN(ice && rem_ufrag && rem_passwd && rcand_cnt && rcand,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(rcand_cnt + ice->rcand_cnt <= PJ_ICE_MAX_CAND, 
		     PJ_ETOOMANY);

    pj_grp_lock_acquire(ice->grp_lock);

    /* Save credentials */
    username.ptr = buf;

    pj_strcpy(&username, rem_ufrag);
    pj_strcat2(&username, ":");
    pj_strcat(&username, &ice->rx_ufrag);

    pj_strdup(ice->pool, &ice->tx_uname, &username);
    pj_strdup(ice->pool, &ice->tx_ufrag, rem_ufrag);
    pj_strdup(ice->pool, &ice->tx_pass, rem_passwd);

    pj_strcpy(&username, &ice->rx_ufrag);
    pj_strcat2(&username, ":");
    pj_strcat(&username, rem_ufrag);

    pj_strdup(ice->pool, &ice->rx_uname, &username);


    /* Save remote candidates */
    ice->rcand_cnt = 0;
    for (i=0; i<rcand_cnt; ++i) {
	pj_ice_sess_cand *cn = &ice->rcand[ice->rcand_cnt];

	/* Ignore candidate which has no matching component ID */
	if (rcand[i].comp_id==0 || rcand[i].comp_id > ice->comp_cnt) {
	    continue;
	}

	if (rcand[i].comp_id > highest_comp)
	    highest_comp = rcand[i].comp_id;

	pj_memcpy(cn, &rcand[i], sizeof(pj_ice_sess_cand));
	pj_strdup(ice->pool, &cn->foundation, &rcand[i].foundation);
	ice->rcand_cnt++;
    }

    /* Generate checklist */
    clist = &ice->clist;
    for (i=0; i<ice->lcand_cnt; ++i) {
	for (j=0; j<ice->rcand_cnt; ++j) {

	    pj_ice_sess_cand *lcand = &ice->lcand[i];
	    pj_ice_sess_cand *rcand = &ice->rcand[j];
	    pj_ice_sess_check *chk = &clist->checks[clist->count];

	    if (clist->count >= PJ_ICE_MAX_CHECKS) {
		pj_grp_lock_release(ice->grp_lock);
		return PJ_ETOOMANY;
	    } 

	    /* A local candidate is paired with a remote candidate if
	     * and only if the two candidates have the same component ID 
	     * and have the same IP address version. 
	     */
	    if ((lcand->comp_id != rcand->comp_id) ||
		(lcand->addr.addr.sa_family != rcand->addr.addr.sa_family))
	    {
		continue;
	    }


	    chk->lcand = lcand;
	    chk->rcand = rcand;
	    chk->state = PJ_ICE_SESS_CHECK_STATE_FROZEN;

	    chk->prio = CALC_CHECK_PRIO(ice, lcand, rcand);

	    clist->count++;
	}
    }

    /* This could happen if candidates have no matching address families */
    if (clist->count == 0) {
	LOG4((ice->obj_name,  "Error: no checklist can be created"));
	pj_grp_lock_release(ice->grp_lock);
	return PJ_ENOTFOUND;
    }

    /* Sort checklist based on priority */
    sort_checklist(ice, clist);

    /* Prune the checklist */
    status = prune_checklist(ice, clist);
    if (status != PJ_SUCCESS) {
	pj_grp_lock_release(ice->grp_lock);
	return status;
    }

    /* Disable our components which don't have matching component */
    for (i=highest_comp; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].stun_sess) {
	    pj_stun_session_destroy(ice->comp[i].stun_sess);
	    pj_bzero(&ice->comp[i], sizeof(ice->comp[i]));
	}
    }
    ice->comp_cnt = highest_comp;

    /* Init timer entry in the checklist. Initially the timer ID is FALSE
     * because timer is not running.
     */
    clist->timer.id = PJ_FALSE;
    td = PJ_POOL_ZALLOC_T(ice->pool, timer_data);
    td->ice = ice;
    td->clist = clist;
    clist->timer.user_data = (void*)td;
    clist->timer.cb = &periodic_timer;


    /* Log checklist */
    dump_checklist("Checklist created:", ice, clist);

    pj_grp_lock_release(ice->grp_lock);

    return PJ_SUCCESS;
}

/* Perform check on the specified candidate pair. */
static pj_status_t perform_check(pj_ice_sess *ice, 
				 pj_ice_sess_checklist *clist,
				 unsigned check_id,
				 pj_bool_t nominate)
{
    pj_ice_sess_comp *comp;
    pj_ice_msg_data *msg_data;
    pj_ice_sess_check *check;
    const pj_ice_sess_cand *lcand;
    const pj_ice_sess_cand *rcand;
    pj_uint32_t prio;
    pj_status_t status;

    check = &clist->checks[check_id];
    lcand = check->lcand;
    rcand = check->rcand;
    comp = find_comp(ice, lcand->comp_id);

    LOG5((ice->obj_name, 
	 "Sending connectivity check for check %s", 
	 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, check)));
    pj_log_push_indent();

    /* Create request */
    status = pj_stun_session_create_req(comp->stun_sess, 
					PJ_STUN_BINDING_REQUEST, PJ_STUN_MAGIC,
					NULL, &check->tdata);
    if (status != PJ_SUCCESS) {
	pjnath_perror(ice->obj_name, "Error creating STUN request", status);
	pj_log_pop_indent();
	return status;
    }

    /* Attach data to be retrieved later when STUN request transaction
     * completes and on_stun_request_complete() callback is called.
     */
    msg_data = PJ_POOL_ZALLOC_T(check->tdata->pool, pj_ice_msg_data);
    msg_data->transport_id = lcand->transport_id;
    msg_data->has_req_data = PJ_TRUE;
    msg_data->data.req.ice = ice;
    msg_data->data.req.clist = clist;
    msg_data->data.req.ckid = check_id;

    /* Add PRIORITY */
#if PJNATH_ICE_PRIO_STD
    prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 65535, 
			  lcand->comp_id);
#else
    prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 0, 
			  lcand->comp_id);
#endif
    pj_stun_msg_add_uint_attr(check->tdata->pool, check->tdata->msg, 
			      PJ_STUN_ATTR_PRIORITY, prio);

    /* Add USE-CANDIDATE and set this check to nominated.
     * Also add ICE-CONTROLLING or ICE-CONTROLLED
     */
    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) {
	if (nominate) {
	    pj_stun_msg_add_empty_attr(check->tdata->pool, check->tdata->msg,
				       PJ_STUN_ATTR_USE_CANDIDATE);
	    check->nominated = PJ_TRUE;
	}

	pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, 
				    PJ_STUN_ATTR_ICE_CONTROLLING,
				    &ice->tie_breaker);

    } else {
	pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, 
				    PJ_STUN_ATTR_ICE_CONTROLLED,
				    &ice->tie_breaker);
    }


    /* Note that USERNAME and MESSAGE-INTEGRITY will be added by the 
     * STUN session.
     */

    /* Initiate STUN transaction to send the request */
    status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE, 
				      PJ_TRUE, &rcand->addr, 
				      pj_sockaddr_get_len(&rcand->addr),
				      check->tdata);
    if (status != PJ_SUCCESS) {
	check->tdata = NULL;
	pjnath_perror(ice->obj_name, "Error sending STUN request", status);
	pj_log_pop_indent();
	return status;
    }

    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS, 
	            PJ_SUCCESS);
    pj_log_pop_indent();
    return PJ_SUCCESS;
}


/* Start periodic check for the specified checklist.
 * This callback is called by timer on every Ta (20msec by default)
 */
static pj_status_t start_periodic_check(pj_timer_heap_t *th, 
					pj_timer_entry *te)
{
    timer_data *td;
    pj_ice_sess *ice;
    pj_ice_sess_checklist *clist;
    unsigned i, start_count=0;
    pj_status_t status;

    td = (struct timer_data*) te->user_data;
    ice = td->ice;
    clist = td->clist;

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_SUCCESS;
    }

    /* Set timer ID to FALSE first */
    te->id = PJ_FALSE;

    /* Set checklist state to Running */
    clist_set_state(ice, clist, PJ_ICE_SESS_CHECKLIST_ST_RUNNING);

    LOG5((ice->obj_name, "Starting checklist periodic check"));
    pj_log_push_indent();

    /* Send STUN Binding request for check with highest priority on
     * Waiting state.
     */
    for (i=0; i<clist->count; ++i) {
	pj_ice_sess_check *check = &clist->checks[i];

	if (check->state == PJ_ICE_SESS_CHECK_STATE_WAITING) {
	    status = perform_check(ice, clist, i, ice->is_nominating);
	    if (status != PJ_SUCCESS) {
		pj_grp_lock_release(ice->grp_lock);
		pj_log_pop_indent();
		return status;
	    }

	    ++start_count;
	    break;
	}
    }

    /* If we don't have anything in Waiting state, perform check to
     * highest priority pair that is in Frozen state.
     */
    if (start_count==0) {
	for (i=0; i<clist->count; ++i) {
	    pj_ice_sess_check *check = &clist->checks[i];

	    if (check->state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {
		status = perform_check(ice, clist, i, ice->is_nominating);
		if (status != PJ_SUCCESS) {
		    pj_grp_lock_release(ice->grp_lock);
		    pj_log_pop_indent();
		    return status;
		}

		++start_count;
		break;
	    }
	}
    }

    /* Cannot start check because there's no suitable candidate pair.
     */
    if (start_count!=0) {
	/* Schedule for next timer */
	pj_time_val timeout = {0, PJ_ICE_TA_VAL};

	pj_time_val_normalize(&timeout);
	pj_timer_heap_schedule_w_grp_lock(th, te, &timeout, PJ_TRUE,
	                                  ice->grp_lock);
    }

    pj_grp_lock_release(ice->grp_lock);
    pj_log_pop_indent();
    return PJ_SUCCESS;
}


/* Start sending connectivity check with USE-CANDIDATE */
static void start_nominated_check(pj_ice_sess *ice)
{
    pj_time_val delay;
    unsigned i;
    pj_status_t status;

    LOG4((ice->obj_name, "Starting nominated check.."));
    pj_log_push_indent();

    pj_assert(ice->is_nominating == PJ_FALSE);

    /* Stop our timer if it's active */
    if (ice->timer.id == TIMER_START_NOMINATED_CHECK) {
	pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,
	                               TIMER_NONE);
    }

    /* For each component, set the check state of valid check with
     * highest priority to Waiting (it should have Success state now).
     */
    for (i=0; i<ice->comp_cnt; ++i) {
	unsigned j;
	const pj_ice_sess_check *vc = ice->comp[i].valid_check;

	pj_assert(ice->comp[i].nominated_check == NULL);
	pj_assert(vc->err_code == PJ_SUCCESS);

	for (j=0; j<ice->clist.count; ++j) {
	    pj_ice_sess_check *c = &ice->clist.checks[j];
	    if (c->lcand->transport_id == vc->lcand->transport_id &&
		c->rcand == vc->rcand)
	    {
		pj_assert(c->err_code == PJ_SUCCESS);
		c->state = PJ_ICE_SESS_CHECK_STATE_FROZEN;
		check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_WAITING, 
			        PJ_SUCCESS);
		break;
	    }
	}
    }

    /* And (re)start the periodic check */
    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,
                                   &ice->clist.timer, PJ_FALSE);

    delay.sec = delay.msec = 0;
    status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
                                               &ice->clist.timer, &delay,
                                               PJ_TRUE,
                                               ice->grp_lock);
    if (status == PJ_SUCCESS) {
	LOG5((ice->obj_name, "Periodic timer rescheduled.."));
    }

    ice->is_nominating = PJ_TRUE;
    pj_log_pop_indent();
}

/* Timer callback to perform periodic check */
static void periodic_timer(pj_timer_heap_t *th, 
			   pj_timer_entry *te)
{
    start_periodic_check(th, te);
}


/* Utility: find string in string array */
const pj_str_t *find_str(const pj_str_t *strlist[], unsigned count,
			 const pj_str_t *str)
{
    unsigned i;
    for (i=0; i<count; ++i) {
	if (pj_strcmp(strlist[i], str)==0)
	    return strlist[i];
    }
    return NULL;
}


/*
 * 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.
 */
PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice)
{
    pj_ice_sess_checklist *clist;
    const pj_ice_sess_cand *cand0;
    const pj_str_t *flist[PJ_ICE_MAX_CAND]; // XXX
    pj_ice_rx_check *rcheck;
    unsigned i, flist_cnt = 0;
    pj_time_val delay;
    pj_status_t status;

    PJ_ASSERT_RETURN(ice, PJ_EINVAL);

    /* Checklist must have been created */
    PJ_ASSERT_RETURN(ice->clist.count > 0, PJ_EINVALIDOP);

    /* Lock session */
    pj_grp_lock_acquire(ice->grp_lock);

    LOG4((ice->obj_name, "Starting ICE check.."));
    pj_log_push_indent();

    /* If we are using aggressive nomination, set the is_nominating state */
    if (ice->opt.aggressive)
	ice->is_nominating = PJ_TRUE;

    /* The agent examines the check list for the first media stream (a
     * media stream is the first media stream when it is described by
     * the first m-line in the SDP offer and answer).  For that media
     * stream, it:
     * 
     * -  Groups together all of the pairs with the same foundation,
     * 
     * -  For each group, sets the state of the pair with the lowest
     *    component ID to Waiting.  If there is more than one such pair,
     *    the one with the highest priority is used.
     */

    clist = &ice->clist;

    /* Pickup the first pair for component 1. */
    for (i=0; i<clist->count; ++i) {
	if (clist->checks[i].lcand->comp_id == 1)
	    break;
    }
    if (i == clist->count) {
	pj_assert(!"Unable to find checklist for component 1");
	pj_grp_lock_release(ice->grp_lock);
	pj_log_pop_indent();
	return PJNATH_EICEINCOMPID;
    }

    /* Set this check to WAITING only if state is frozen. It may be possible
     * that this check has already been started by a trigger check
     */
    if (clist->checks[i].state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {
	check_set_state(ice, &clist->checks[i], 
			PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS);
    }

    cand0 = clist->checks[i].lcand;
    flist[flist_cnt++] = &clist->checks[i].lcand->foundation;

    /* Find all of the other pairs in that check list with the same
     * component ID, but different foundations, and sets all of their
     * states to Waiting as well.
     */
    for (++i; i<clist->count; ++i) {
	const pj_ice_sess_cand *cand1;

	cand1 = clist->checks[i].lcand;

	if (cand1->comp_id==cand0->comp_id &&
	    find_str(flist, flist_cnt, &cand1->foundation)==NULL)
	{
	    if (clist->checks[i].state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {
		check_set_state(ice, &clist->checks[i], 
				PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS);
	    }
	    flist[flist_cnt++] = &cand1->foundation;
	}
    }

    /* First, perform all pending triggered checks, simultaneously. */
    rcheck = ice->early_check.next;
    while (rcheck != &ice->early_check) {
	LOG4((ice->obj_name, 
	      "Performing delayed triggerred check for component %d",
	      rcheck->comp_id));
	pj_log_push_indent();
	handle_incoming_check(ice, rcheck);
	rcheck = rcheck->next;
	pj_log_pop_indent();
    }
    pj_list_init(&ice->early_check);

    /* Start periodic check */
    /* We could start it immediately like below, but lets schedule timer 
     * instead to reduce stack usage:
     * return start_periodic_check(ice->stun_cfg.timer_heap, &clist->timer);
     */
    delay.sec = delay.msec = 0;
    status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
                                               &clist->timer, &delay,
                                               PJ_TRUE, ice->grp_lock);
    if (status != PJ_SUCCESS) {
	clist->timer.id = PJ_FALSE;
    }

    pj_grp_lock_release(ice->grp_lock);
    pj_log_pop_indent();
    return status;
}


//////////////////////////////////////////////////////////////////////////////

/* Callback called by STUN session to send the STUN message.
 * STUN session also doesn't have a transport, remember?!
 */
static pj_status_t on_stun_send_msg(pj_stun_session *sess,
				    void *token,
				    const void *pkt,
				    pj_size_t pkt_size,
				    const pj_sockaddr_t *dst_addr,
				    unsigned addr_len)
{
    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);
    pj_ice_sess *ice = sd->ice;
    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token;
    pj_status_t status;
    
    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	/* Stray retransmit timer that could happen while
	 * we're being destroyed */
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    status = (*ice->cb.on_tx_pkt)(ice, sd->comp_id, msg_data->transport_id,
				  pkt, pkt_size, dst_addr, addr_len);

    pj_grp_lock_release(ice->grp_lock);
    return status;
}


/* This callback is called when outgoing STUN request completed */
static void on_stun_request_complete(pj_stun_session *stun_sess,
				     pj_status_t status,
				     void *token,
				     pj_stun_tx_data *tdata,
				     const pj_stun_msg *response,
				     const pj_sockaddr_t *src_addr,
				     unsigned src_addr_len)
{
    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token;
    pj_ice_sess *ice;
    pj_ice_sess_check *check, *new_check;
    pj_ice_sess_cand *lcand;
    pj_ice_sess_checklist *clist;
    pj_stun_xor_mapped_addr_attr *xaddr;
    unsigned i;

    PJ_UNUSED_ARG(stun_sess);
    PJ_UNUSED_ARG(src_addr_len);

    pj_assert(msg_data->has_req_data);

    ice = msg_data->data.req.ice;
    clist = msg_data->data.req.clist;
    check = &clist->checks[msg_data->data.req.ckid];
    

    /* Mark STUN transaction as complete */
    pj_assert(tdata == check->tdata);
    check->tdata = NULL;

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	/* Not sure if this is possible but just in case */
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    /* Init lcand to NULL. lcand will be found from the mapped address
     * found in the response.
     */
    lcand = NULL;

    if (status != PJ_SUCCESS) {
	char errmsg[PJ_ERR_MSG_SIZE];

	if (status==PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_ROLE_CONFLICT)) {

	    /* Role conclict response.
	     *
	     * 7.1.2.1.  Failure Cases:
	     *
	     * If the request had contained the ICE-CONTROLLED attribute, 
	     * the agent MUST switch to the controlling role if it has not
	     * already done so.  If the request had contained the 
	     * ICE-CONTROLLING attribute, the agent MUST switch to the 
	     * controlled role if it has not already done so.  Once it has
	     * switched, the agent MUST immediately retry the request with
	     * the ICE-CONTROLLING or ICE-CONTROLLED attribute reflecting 
	     * its new role.
	     */
	    pj_ice_sess_role new_role = PJ_ICE_SESS_ROLE_UNKNOWN;
	    pj_stun_msg *req = tdata->msg;

	    if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLING, 0)) {
		new_role = PJ_ICE_SESS_ROLE_CONTROLLED;
	    } else if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLED, 
					     0)) {
		new_role = PJ_ICE_SESS_ROLE_CONTROLLING;
	    } else {
		pj_assert(!"We should have put CONTROLLING/CONTROLLED attr!");
		new_role = PJ_ICE_SESS_ROLE_CONTROLLED;
	    }

	    if (new_role != ice->role) {
		LOG4((ice->obj_name, 
		      "Changing role because of role conflict response"));
		pj_ice_sess_change_role(ice, new_role);
	    }

	    /* Resend request */
	    LOG4((ice->obj_name, "Resending check because of role conflict"));
	    pj_log_push_indent();
	    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0);
	    perform_check(ice, clist, msg_data->data.req.ckid, 
			  check->nominated || ice->is_nominating);
	    pj_log_pop_indent();
	    pj_grp_lock_release(ice->grp_lock);
	    return;
	}

	pj_strerror(status, errmsg, sizeof(errmsg));
	LOG4((ice->obj_name, 
	     "Check %s%s: connectivity check FAILED: %s",
	     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
			&ice->clist, check),
	     (check->nominated ? " (nominated)" : " (not nominated)"),
	     errmsg));
	pj_log_push_indent();
	check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status);
	on_check_complete(ice, check);
	pj_log_pop_indent();
	pj_grp_lock_release(ice->grp_lock);
	return;
    }


    /* 7.1.2.1.  Failure Cases
     *
     * The agent MUST check that the source IP address and port of the
     * response equals the destination IP address and port that the Binding
     * Request was sent to, and that the destination IP address and port of
     * the response match the source IP address and port that the Binding
     * Request was sent from.
     */
    if (pj_sockaddr_cmp(&check->rcand->addr, (const pj_sockaddr*)src_addr)!=0)
    {
	status = PJNATH_EICEINSRCADDR;
	LOG4((ice->obj_name, 
	     "Check %s%s: connectivity check FAILED: source address mismatch",
	     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
			&ice->clist, check),
	     (check->nominated ? " (nominated)" : " (not nominated)")));
	pj_log_push_indent();
	check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status);
	on_check_complete(ice, check);
	pj_log_pop_indent();
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    /* 7.1.2.2.  Success Cases
     * 
     * A check is considered to be a success if all of the following are
     * true:
     * 
     * o  the STUN transaction generated a success response
     * 
     * o  the source IP address and port of the response equals the
     *    destination IP address and port that the Binding Request was sent
     *    to
     * 
     * o  the destination IP address and port of the response match the
     *    source IP address and port that the Binding Request was sent from
     */


    LOG4((ice->obj_name, 
	 "Check %s%s: connectivity check SUCCESS",
	 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
		    &ice->clist, check),
	 (check->nominated ? " (nominated)" : " (not nominated)")));

    /* Get the STUN XOR-MAPPED-ADDRESS attribute. */
    xaddr = (pj_stun_xor_mapped_addr_attr*)
	    pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR,0);
    if (!xaddr) {
	check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, 
			PJNATH_ESTUNNOMAPPEDADDR);
	on_check_complete(ice, check);
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    /* Find local candidate that matches the XOR-MAPPED-ADDRESS */
    pj_assert(lcand == NULL);
    for (i=0; i<ice->lcand_cnt; ++i) {
	if (pj_sockaddr_cmp(&xaddr->sockaddr, &ice->lcand[i].addr) == 0) {
	    /* Match */
	    lcand = &ice->lcand[i];
	    break;
	}
    }

    /* 7.1.2.2.1.  Discovering Peer Reflexive Candidates
     * If the transport address returned in XOR-MAPPED-ADDRESS does not match
     * any of the local candidates that the agent knows about, the mapped 
     * address represents a new candidate - a peer reflexive candidate.
     */
    if (lcand == NULL) {
	unsigned cand_id;
	pj_str_t foundation;

	pj_ice_calc_foundation(ice->pool, &foundation, PJ_ICE_CAND_TYPE_PRFLX,
			       &check->lcand->base_addr);

	/* Still in 7.1.2.2.1.  Discovering Peer Reflexive Candidates
	 * Its priority is set equal to the value of the PRIORITY attribute
         * in the Binding Request.
	 *
	 * I think the priority calculated by add_cand() should be the same
	 * as the one calculated in perform_check(), so there's no need to
	 * get the priority from the PRIORITY attribute.
	 */

	/* Add new peer reflexive candidate */
	status = pj_ice_sess_add_cand(ice, check->lcand->comp_id, 
				      msg_data->transport_id,
				      PJ_ICE_CAND_TYPE_PRFLX,
				      65535, &foundation,
				      &xaddr->sockaddr, 
				      &check->lcand->base_addr, 
				      &check->lcand->base_addr,
				      pj_sockaddr_get_len(&xaddr->sockaddr),
				      &cand_id);
	if (status != PJ_SUCCESS) {
	    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, 
			    status);
	    on_check_complete(ice, check);
	    pj_grp_lock_release(ice->grp_lock);
	    return;
	}

	/* Update local candidate */
	lcand = &ice->lcand[cand_id];

    }

    /* 7.1.2.2.3.  Constructing a Valid Pair
     * Next, the agent constructs a candidate pair whose local candidate
     * equals the mapped address of the response, and whose remote candidate
     * equals the destination address to which the request was sent.    
     */

    /* Add pair to valid list, if it's not there, otherwise just update
     * nominated flag
     */
    for (i=0; i<ice->valid_list.count; ++i) {
	if (ice->valid_list.checks[i].lcand == lcand &&
	    ice->valid_list.checks[i].rcand == check->rcand)
	    break;
    }

    if (i==ice->valid_list.count) {
	pj_assert(ice->valid_list.count < PJ_ICE_MAX_CHECKS);
	new_check = &ice->valid_list.checks[ice->valid_list.count++];
	new_check->lcand = lcand;
	new_check->rcand = check->rcand;
	new_check->prio = CALC_CHECK_PRIO(ice, lcand, check->rcand);
	new_check->state = PJ_ICE_SESS_CHECK_STATE_SUCCEEDED;
	new_check->nominated = check->nominated;
	new_check->err_code = PJ_SUCCESS;
    } else {
	new_check = &ice->valid_list.checks[i];
	ice->valid_list.checks[i].nominated = check->nominated;
    }

    /* Update valid check and nominated check for the component */
    update_comp_check(ice, new_check->lcand->comp_id, new_check);

    /* Sort valid_list (must do so after update_comp_check(), otherwise
     * new_check will point to something else (#953)
     */
    sort_checklist(ice, &ice->valid_list);

    /* 7.1.2.2.2.  Updating Pair States
     * 
     * The agent sets the state of the pair that generated the check to
     * Succeeded.  The success of this check might also cause the state of
     * other checks to change as well.
     */
    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_SUCCEEDED, 
		    PJ_SUCCESS);

    /* Perform 7.1.2.2.2.  Updating Pair States.
     * This may terminate ICE processing.
     */
    if (on_check_complete(ice, check)) {
	/* ICE complete! */
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    pj_grp_lock_release(ice->grp_lock);
}


/* This callback is called by the STUN session associated with a candidate
 * when it receives incoming request.
 */
static pj_status_t on_stun_rx_request(pj_stun_session *sess,
				      const pj_uint8_t *pkt,
				      unsigned pkt_len,
				      const pj_stun_rx_data *rdata,
				      void *token,
				      const pj_sockaddr_t *src_addr,
				      unsigned src_addr_len)
{
    stun_data *sd;
    const pj_stun_msg *msg = rdata->msg;
    pj_ice_msg_data *msg_data;
    pj_ice_sess *ice;
    pj_stun_priority_attr *prio_attr;
    pj_stun_use_candidate_attr *uc_attr;
    pj_stun_uint64_attr *role_attr;
    pj_stun_tx_data *tdata;
    pj_ice_rx_check *rcheck, tmp_rcheck;
    pj_status_t status;

    PJ_UNUSED_ARG(pkt);
    PJ_UNUSED_ARG(pkt_len);
    
    /* Reject any requests except Binding request */
    if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) {
	pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, 
				NULL, token, PJ_TRUE, 
				src_addr, src_addr_len);
	return PJ_SUCCESS;
    }


    sd = (stun_data*) pj_stun_session_get_user_data(sess);
    ice = sd->ice;

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    /*
     * Note:
     *  Be aware that when STUN request is received, we might not get
     *  SDP answer yet, so we might not have remote candidates and
     *  checklist yet. This case will be handled after we send
     *  a response.
     */

    /* Get PRIORITY attribute */
    prio_attr = (pj_stun_priority_attr*)
	        pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_PRIORITY, 0);
    if (prio_attr == NULL) {
	LOG5((ice->obj_name, "Received Binding request with no PRIORITY"));
	pj_grp_lock_release(ice->grp_lock);
	return PJ_SUCCESS;
    }

    /* Get USE-CANDIDATE attribute */
    uc_attr = (pj_stun_use_candidate_attr*)
	      pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USE_CANDIDATE, 0);


    /* Get ICE-CONTROLLING or ICE-CONTROLLED */
    role_attr = (pj_stun_uint64_attr*)
	        pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICE_CONTROLLING, 0);
    if (role_attr == NULL) {
	role_attr = (pj_stun_uint64_attr*)
	            pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICE_CONTROLLED, 0);
    }

    /* Handle the case when request comes before answer is received.
     * We need to put credential in the response, and since we haven't
     * got the response, copy the username from the request.
     */
    if (ice->rcand_cnt == 0) {
	pj_stun_string_attr *uname_attr;

	uname_attr = (pj_stun_string_attr*)
		     pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0);
	pj_assert(uname_attr != NULL);
	pj_strdup(ice->pool, &ice->rx_uname, &uname_attr->value);
    }

    /* 7.2.1.1.  Detecting and Repairing Role Conflicts
     */
    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING &&
	role_attr && role_attr->hdr.type == PJ_STUN_ATTR_ICE_CONTROLLING)
    {
	if (pj_cmp_timestamp(&ice->tie_breaker, &role_attr->value) < 0) {
	    /* Switch role to controlled */
	    LOG4((ice->obj_name, 
		  "Changing role because of ICE-CONTROLLING attribute"));
	    pj_ice_sess_change_role(ice, PJ_ICE_SESS_ROLE_CONTROLLED);
	} else {
	    /* Generate 487 response */
	    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, 
				    NULL, token, PJ_TRUE, 
				    src_addr, src_addr_len);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}

    } else if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLED &&
	       role_attr && role_attr->hdr.type == PJ_STUN_ATTR_ICE_CONTROLLED)
    {
	if (pj_cmp_timestamp(&ice->tie_breaker, &role_attr->value) < 0) {
	    /* Generate 487 response */
	    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, 
				    NULL, token, PJ_TRUE, 
				    src_addr, src_addr_len);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	} else {
	    /* Switch role to controlled */
	    LOG4((ice->obj_name, 
		  "Changing role because of ICE-CONTROLLED attribute"));
	    pj_ice_sess_change_role(ice, PJ_ICE_SESS_ROLE_CONTROLLING);
	}
    }

    /* 
     * First send response to this request 
     */
    status = pj_stun_session_create_res(sess, rdata, 0, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	pj_grp_lock_release(ice->grp_lock);
	return status;
    }

    /* Add XOR-MAPPED-ADDRESS attribute */
    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
					   PJ_STUN_ATTR_XOR_MAPPED_ADDR,
					   PJ_TRUE, src_addr, src_addr_len);

    /* Create a msg_data to be associated with this response */
    msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);
    msg_data->transport_id = ((pj_ice_msg_data*)token)->transport_id;
    msg_data->has_req_data = PJ_FALSE;

    /* Send the response */
    status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE, PJ_TRUE,
				      src_addr, src_addr_len, tdata);


    /* 
     * Handling early check.
     *
     * It's possible that we receive this request before we receive SDP
     * answer. In this case, we can't perform trigger check since we
     * don't have checklist yet, so just save this check in a pending
     * triggered check array to be acted upon later.
     */
    if (ice->rcand_cnt == 0) {
	rcheck = PJ_POOL_ZALLOC_T(ice->pool, pj_ice_rx_check);
    } else {
	rcheck = &tmp_rcheck;
    }

    /* Init rcheck */
    rcheck->comp_id = sd->comp_id;
    rcheck->transport_id = ((pj_ice_msg_data*)token)->transport_id;
    rcheck->src_addr_len = src_addr_len;
    pj_sockaddr_cp(&rcheck->src_addr, src_addr);
    rcheck->use_candidate = (uc_attr != NULL);
    rcheck->priority = prio_attr->value;
    rcheck->role_attr = role_attr;

    if (ice->rcand_cnt == 0) {
	/* We don't have answer yet, so keep this request for later */
	LOG4((ice->obj_name, "Received an early check for comp %d",
	      rcheck->comp_id));
	pj_list_push_back(&ice->early_check, rcheck);
    } else {
	/* Handle this check */
	handle_incoming_check(ice, rcheck);
    }

    pj_grp_lock_release(ice->grp_lock);
    return PJ_SUCCESS;
}


/* Handle incoming Binding request and perform triggered check.
 * This function may be called by on_stun_rx_request(), or when
 * SDP answer is received and we have received early checks.
 */
static void handle_incoming_check(pj_ice_sess *ice,
				  const pj_ice_rx_check *rcheck)
{
    pj_ice_sess_comp *comp;
    pj_ice_sess_cand *lcand = NULL;
    pj_ice_sess_cand *rcand;
    unsigned i;

    comp = find_comp(ice, rcheck->comp_id);

    /* Find remote candidate based on the source transport address of 
     * the request.
     */
    for (i=0; i<ice->rcand_cnt; ++i) {
	if (pj_sockaddr_cmp(&rcheck->src_addr, &ice->rcand[i].addr)==0)
	    break;
    }

    /* 7.2.1.3.  Learning Peer Reflexive Candidates
     * If the source transport address of the request does not match any
     * existing remote candidates, it represents a new peer reflexive remote
     * candidate.
     */
    if (i == ice->rcand_cnt) {
	char raddr[PJ_INET6_ADDRSTRLEN];
	if (ice->rcand_cnt >= PJ_ICE_MAX_CAND) {
	    LOG4((ice->obj_name, 
	          "Unable to add new peer reflexive candidate: too many "
		  "candidates already (%d)", PJ_ICE_MAX_CAND));
	    return;
	}

	rcand = &ice->rcand[ice->rcand_cnt++];
	rcand->comp_id = (pj_uint8_t)rcheck->comp_id;
	rcand->type = PJ_ICE_CAND_TYPE_PRFLX;
	rcand->prio = rcheck->priority;
	pj_sockaddr_cp(&rcand->addr, &rcheck->src_addr);

	/* Foundation is random, unique from other foundation */
	rcand->foundation.ptr = (char*) pj_pool_alloc(ice->pool, 36);
	rcand->foundation.slen = pj_ansi_snprintf(rcand->foundation.ptr, 36,
						  "f%p", 
						  rcand->foundation.ptr);

	LOG4((ice->obj_name, 
	      "Added new remote candidate from the request: %s:%d",
	      pj_sockaddr_print(&rcand->addr, raddr, sizeof(raddr), 0),
	      pj_sockaddr_get_port(&rcand->addr)));

    } else {
	/* Remote candidate found */
	rcand = &ice->rcand[i];
    }

#if 0
    /* Find again the local candidate by matching the base address
     * with the local candidates in the checklist. Checks may have
     * been pruned before, so it's possible that if we use the lcand
     * as it is, we wouldn't be able to find the check in the checklist
     * and we will end up creating a new check unnecessarily.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (/*c->lcand == lcand ||*/
	    pj_sockaddr_cmp(&c->lcand->base_addr, &lcand->base_addr)==0)
	{
	    lcand = c->lcand;
	    break;
	}
    }
#else
    /* Just get candidate with the highest priority and same transport ID
     * for the specified  component ID in the checklist.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (c->lcand->comp_id == rcheck->comp_id &&
	    c->lcand->transport_id == rcheck->transport_id) 
	{
	    lcand = c->lcand;
	    break;
	}
    }
    if (lcand == NULL) {
	/* Should not happen, but just in case remote is sending a
	 * Binding request for a component which it doesn't have.
	 */
	LOG4((ice->obj_name, 
	     "Received Binding request but no local candidate is found!"));
	return;
    }
#endif

    /* 
     * Create candidate pair for this request. 
     */

    /* 
     * 7.2.1.4.  Triggered Checks
     *
     * Now that we have local and remote candidate, check if we already
     * have this pair in our checklist.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (c->lcand == lcand && c->rcand == rcand)
	    break;
    }

    /* If the pair is already on the check list:
     * - If the state of that pair is Waiting or Frozen, its state is
     *   changed to In-Progress and a check for that pair is performed
     *   immediately.  This is called a triggered check.
     *
     * - If the state of that pair is In-Progress, the agent SHOULD
     *   generate an immediate retransmit of the Binding Request for the
     *   check in progress.  This is to facilitate rapid completion of
     *   ICE when both agents are behind NAT.
     * 
     * - If the state of that pair is Failed or Succeeded, no triggered
     *   check is sent.
     */
    if (i != ice->clist.count) {
	pj_ice_sess_check *c = &ice->clist.checks[i];

	/* If USE-CANDIDATE is present, set nominated flag 
	 * Note: DO NOT overwrite nominated flag if one is already set.
	 */
	c->nominated = ((rcheck->use_candidate) || c->nominated);

	if (c->state == PJ_ICE_SESS_CHECK_STATE_FROZEN ||
	    c->state == PJ_ICE_SESS_CHECK_STATE_WAITING)
	{
	    /* See if we shall nominate this check */
	    pj_bool_t nominate = (c->nominated || ice->is_nominating);

	    LOG5((ice->obj_name, "Performing triggered check for check %d",i));
	    pj_log_push_indent();
	    perform_check(ice, &ice->clist, i, nominate);
	    pj_log_pop_indent();

	} else if (c->state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS) {
	    /* Should retransmit immediately
	     */
	    LOG5((ice->obj_name, "Triggered check for check %d not performed "
		  "because it's in progress. Retransmitting", i));
	    pj_log_push_indent();
	    pj_stun_session_retransmit_req(comp->stun_sess, c->tdata, PJ_FALSE);
	    pj_log_pop_indent();

	} else if (c->state == PJ_ICE_SESS_CHECK_STATE_SUCCEEDED) {
	    /* Check complete for this component.
	     * Note this may end ICE process.
	     */
	    pj_bool_t complete;
	    unsigned j;

	    /* If this check is nominated, scan the valid_list for the
	     * same check and update the nominated flag. A controlled 
	     * agent might have finished the check earlier.
	     */
	    if (rcheck->use_candidate) {
		for (j=0; j<ice->valid_list.count; ++j) {
		    pj_ice_sess_check *vc = &ice->valid_list.checks[j];
		    if (vc->lcand->transport_id == c->lcand->transport_id && 
			vc->rcand == c->rcand) 
		    {
			/* Set nominated flag */
			vc->nominated = PJ_TRUE;

			/* Update valid check and nominated check for the component */
			update_comp_check(ice, vc->lcand->comp_id, vc);

			LOG5((ice->obj_name, "Valid check %s is nominated", 
			      dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
					 &ice->valid_list, vc)));
		    }
		}
	    }

	    LOG5((ice->obj_name, "Triggered check for check %d not performed "
				"because it's completed", i));
	    pj_log_push_indent();
	    complete = on_check_complete(ice, c);
	    pj_log_pop_indent();
	    if (complete) {
		return;
	    }
	}

    }
    /* If the pair is not already on the check list:
     * - The pair is inserted into the check list based on its priority.
     * - Its state is set to In-Progress
     * - A triggered check for that pair is performed immediately.
     */
    /* Note: only do this if we don't have too many checks in checklist */
    else if (ice->clist.count < PJ_ICE_MAX_CHECKS) {

	pj_ice_sess_check *c = &ice->clist.checks[ice->clist.count];
	pj_bool_t nominate;

	c->lcand = lcand;
	c->rcand = rcand;
	c->prio = CALC_CHECK_PRIO(ice, lcand, rcand);
	c->state = PJ_ICE_SESS_CHECK_STATE_WAITING;
	c->nominated = rcheck->use_candidate;
	c->err_code = PJ_SUCCESS;

	nominate = (c->nominated || ice->is_nominating);

	LOG4((ice->obj_name, "New triggered check added: %d", 
	     ice->clist.count));
	pj_log_push_indent();
	perform_check(ice, &ice->clist, ice->clist.count++, nominate);
	pj_log_pop_indent();

    } else {
	LOG4((ice->obj_name, "Error: unable to perform triggered check: "
	     "TOO MANY CHECKS IN CHECKLIST!"));
    }
}


static pj_status_t on_stun_rx_indication(pj_stun_session *sess,
					 const pj_uint8_t *pkt,
					 unsigned pkt_len,
					 const pj_stun_msg *msg,
					 void *token,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len)
{
    struct stun_data *sd;

    PJ_UNUSED_ARG(sess);
    PJ_UNUSED_ARG(pkt);
    PJ_UNUSED_ARG(pkt_len);
    PJ_UNUSED_ARG(msg);
    PJ_UNUSED_ARG(token);
    PJ_UNUSED_ARG(src_addr);
    PJ_UNUSED_ARG(src_addr_len);

    sd = (struct stun_data*) pj_stun_session_get_user_data(sess);

    pj_log_push_indent();

    if (msg->hdr.type == PJ_STUN_BINDING_INDICATION) {
	LOG5((sd->ice->obj_name, "Received Binding Indication keep-alive "
	      "for component %d", sd->comp_id));
    } else {
	LOG4((sd->ice->obj_name, "Received unexpected %s indication "
	      "for component %d", pj_stun_get_method_name(msg->hdr.type), 
	      sd->comp_id));
    }

    pj_log_pop_indent();

    return PJ_SUCCESS;
}


PJ_DEF(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 status = PJ_SUCCESS;
    pj_ice_sess_comp *comp;
    pj_ice_sess_cand *cand;
    pj_uint8_t transport_id;
    pj_sockaddr addr;

    PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL);
    
    /* It is possible that comp_cnt is less than comp_id, when remote
     * doesn't support all the components that we have.
     */
    if (comp_id > ice->comp_cnt) {
	return PJNATH_EICEINCOMPID;
    }

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    comp = find_comp(ice, comp_id);
    if (comp == NULL) {
	status = PJNATH_EICEINCOMPID;
	pj_grp_lock_release(ice->grp_lock);
	goto on_return;
    }

    if (comp->valid_check == NULL) {
	status = PJNATH_EICEINPROGRESS;
	pj_grp_lock_release(ice->grp_lock);
	goto on_return;
    }

    cand = comp->valid_check->lcand;
    transport_id = cand->transport_id;
    pj_sockaddr_cp(&addr, &comp->valid_check->rcand->addr);

    /* Release the mutex now to avoid deadlock (see ticket #1451). */
    pj_grp_lock_release(ice->grp_lock);

    PJ_RACE_ME(5);

    status = (*ice->cb.on_tx_pkt)(ice, comp_id, transport_id, 
				  data, data_len, 
				  &addr, 
				  pj_sockaddr_get_len(&addr));

on_return:
    return status;
}


PJ_DEF(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)
{
    pj_status_t status = PJ_SUCCESS;
    pj_ice_sess_comp *comp;
    pj_ice_msg_data *msg_data = NULL;
    unsigned i;

    PJ_ASSERT_RETURN(ice, PJ_EINVAL);

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    comp = find_comp(ice, comp_id);
    if (comp == NULL) {
	pj_grp_lock_release(ice->grp_lock);
	return PJNATH_EICEINCOMPID;
    }

    /* Find transport */
    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) {
	if (ice->tp_data[i].transport_id == transport_id) {
	    msg_data = &ice->tp_data[i];
	    break;
	}
    }
    if (msg_data == NULL) {
	pj_assert(!"Invalid transport ID");
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVAL;
    }

    /* Don't check fingerprint. We only need to distinguish STUN and non-STUN
     * packets. We don't need to verify the STUN packet too rigorously, that
     * will be done by the user.
     */
    status = pj_stun_msg_check((const pj_uint8_t*)pkt, pkt_size, 
    			       PJ_STUN_IS_DATAGRAM |
    			         PJ_STUN_NO_FINGERPRINT_CHECK);
    if (status == PJ_SUCCESS) {
	status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size,
					   PJ_STUN_IS_DATAGRAM, msg_data,
					   NULL, src_addr, src_addr_len);
	if (status != PJ_SUCCESS) {
	    pj_strerror(status, ice->tmp.errmsg, sizeof(ice->tmp.errmsg));
	    LOG4((ice->obj_name, "Error processing incoming message: %s",
		  ice->tmp.errmsg));
	}
	pj_grp_lock_release(ice->grp_lock);
    } else {
	/* Not a STUN packet. Call application's callback instead, but release
	 * the mutex now or otherwise we may get deadlock.
	 */
	pj_grp_lock_release(ice->grp_lock);

	PJ_RACE_ME(5);

	(*ice->cb.on_rx_data)(ice, comp_id, transport_id, pkt, pkt_size, 
			      src_addr, src_addr_len);
	status = PJ_SUCCESS;
    }

    return status;
}


