PJ_DEF(pj_status_t) pjsua_cancel_stun_resolution( void *token,
						  pj_bool_t notify_cb)
{
    pjsua_stun_resolve *sess;
    unsigned cancelled_count = 0;

    PJSUA_LOCK();
    sess = pjsua_var.stun_res.next;
    while (sess != &pjsua_var.stun_res) {
	pjsua_stun_resolve *next = sess->next;

	if (sess->token == token) {
	    sess->has_result = PJ_TRUE;
	    sess->status = PJ_ECANCELLED;
	    if (notify_cb) {
		pj_stun_resolve_result result;

		pj_bzero(&result, sizeof(result));
		result.token = token;
		result.status = PJ_ECANCELLED;

		sess->cb(&result);
	    }	    
	    ++cancelled_count;
	}

	sess = next;
    }
    PJSUA_UNLOCK();

    return cancelled_count ? PJ_SUCCESS : PJ_ENOTFOUND;
}
PJ_DEF(pj_status_t) pjsua_cancel_stun_resolution( void *token,
						  pj_bool_t notify_cb)
{
    pjsua_stun_resolve *sess;
    unsigned cancelled_count = 0;

    PJSUA_LOCK();
    sess = pjsua_var.stun_res.next;
    while (sess != &pjsua_var.stun_res) {
	pjsua_stun_resolve *next = sess->next;

	if (sess->token == token) {
	    sess->has_result = PJ_TRUE;
	    sess->status = PJ_ECANCELLED;
	    if (notify_cb) {
		pj_stun_resolve_result result;

		pj_bzero(&result, sizeof(result));
		result.token = token;
		result.status = PJ_ECANCELLED;

		sess->cb(&result);
	    }	    
	    ++cancelled_count;
	}

	sess = next;
    }
    PJSUA_UNLOCK();

    return cancelled_count ? PJ_SUCCESS : PJ_ENOTFOUND;
}