/* $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/stun_session.h>
#include <pjnath/errno.h>
#include <pjlib.h>

struct pj_stun_session
{
    pj_stun_config	*cfg;
    pj_pool_t		*pool;
    pj_grp_lock_t	*grp_lock;
    pj_stun_session_cb	 cb;
    void		*user_data;
    pj_bool_t		 is_destroying;

    pj_bool_t		 use_fingerprint;

    pj_pool_t		*rx_pool;

#if PJ_LOG_MAX_LEVEL >= 5
    char		 dump_buf[1000];
#endif
    unsigned		 log_flag;

    pj_stun_auth_type	 auth_type;
    pj_stun_auth_cred	 cred;
    int			 auth_retry;
    pj_str_t		 next_nonce;
    pj_str_t		 server_realm;

    pj_str_t		 srv_name;

    pj_stun_tx_data	 pending_request_list;
    pj_stun_tx_data	 cached_response_list;
};

#define SNAME(s_)		    ((s_)->pool->obj_name)
#define THIS_FILE		    "stun_session.c"

#if 1
#   define TRACE_(expr)		    PJ_LOG(5,expr)
#else
#   define TRACE_(expr)
#endif

#define LOG_ERR_(sess,title,rc) PJ_PERROR(3,(sess->pool->obj_name,rc,title))

#define TDATA_POOL_SIZE		    PJNATH_POOL_LEN_STUN_TDATA
#define TDATA_POOL_INC		    PJNATH_POOL_INC_STUN_TDATA


static void stun_tsx_on_complete(pj_stun_client_tsx *tsx,
				 pj_status_t status, 
				 const pj_stun_msg *response,
				 const pj_sockaddr_t *src_addr,
				 unsigned src_addr_len);
static pj_status_t stun_tsx_on_send_msg(pj_stun_client_tsx *tsx,
					const void *stun_pkt,
					pj_size_t pkt_size);
static void stun_tsx_on_destroy(pj_stun_client_tsx *tsx);
static void stun_sess_on_destroy(void *comp);

static pj_stun_tsx_cb tsx_cb = 
{
    &stun_tsx_on_complete,
    &stun_tsx_on_send_msg,
    &stun_tsx_on_destroy
};


static pj_status_t tsx_add(pj_stun_session *sess,
			   pj_stun_tx_data *tdata)
{
    pj_list_push_front(&sess->pending_request_list, tdata);
    return PJ_SUCCESS;
}

static pj_status_t tsx_erase(pj_stun_session *sess,
			     pj_stun_tx_data *tdata)
{
    PJ_UNUSED_ARG(sess);
    pj_list_erase(tdata);
    return PJ_SUCCESS;
}

static pj_stun_tx_data* tsx_lookup(pj_stun_session *sess,
				   const pj_stun_msg *msg)
{
    pj_stun_tx_data *tdata;

    tdata = sess->pending_request_list.next;
    while (tdata != &sess->pending_request_list) {
	pj_assert(sizeof(tdata->msg_key)==sizeof(msg->hdr.tsx_id));
	if (tdata->msg_magic == msg->hdr.magic &&
	    pj_memcmp(tdata->msg_key, msg->hdr.tsx_id, 
		      sizeof(msg->hdr.tsx_id))==0)
	{
	    return tdata;
	}
	tdata = tdata->next;
    }

    return NULL;
}

static pj_status_t create_tdata(pj_stun_session *sess,
			        pj_stun_tx_data **p_tdata)
{
    pj_pool_t *pool;
    pj_stun_tx_data *tdata;

    /* Create pool and initialize basic tdata attributes */
    pool = pj_pool_create(sess->cfg->pf, "tdata%p", 
			  TDATA_POOL_SIZE, TDATA_POOL_INC, NULL);
    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);

    tdata = PJ_POOL_ZALLOC_T(pool, pj_stun_tx_data);
    tdata->pool = pool;
    tdata->sess = sess;

    pj_list_init(tdata);

    *p_tdata = tdata;

    return PJ_SUCCESS;
}

static void stun_tsx_on_destroy(pj_stun_client_tsx *tsx)
{
    pj_stun_tx_data *tdata;

    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);
    pj_stun_client_tsx_stop(tsx);
    if (tdata) {
	tsx_erase(tdata->sess, tdata);
	pj_pool_release(tdata->pool);
    }

    TRACE_((THIS_FILE, "STUN transaction %p destroyed", tsx));
}

static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
{
    TRACE_((THIS_FILE, "tdata %p destroy request, force=%d, tsx=%p", tdata,
	    force, tdata->client_tsx));

    if (tdata->res_timer.id != PJ_FALSE) {
	pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,
	                               &tdata->res_timer, PJ_FALSE);
	pj_list_erase(tdata);
    }

    if (force) {
	pj_list_erase(tdata);
	if (tdata->client_tsx) {
	    pj_stun_client_tsx_stop(tdata->client_tsx);
	    pj_stun_client_tsx_set_data(tdata->client_tsx, NULL);
	}
	pj_pool_release(tdata->pool);

    } else {
	if (tdata->client_tsx) {
	    /* "Probably" this is to absorb retransmission */
	    pj_time_val delay = {0, 300};
	    pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay);

	} else {
	    pj_pool_release(tdata->pool);
	}
    }
}

/*
 * Destroy the transmit data.
 */
PJ_DEF(void) pj_stun_msg_destroy_tdata( pj_stun_session *sess,
					pj_stun_tx_data *tdata)
{
    PJ_UNUSED_ARG(sess);
    destroy_tdata(tdata, PJ_FALSE);
}


/* Timer callback to be called when it's time to destroy response cache */
static void on_cache_timeout(pj_timer_heap_t *timer_heap,
			     struct pj_timer_entry *entry)
{
    pj_stun_tx_data *tdata;

    PJ_UNUSED_ARG(timer_heap);

    entry->id = PJ_FALSE;
    tdata = (pj_stun_tx_data*) entry->user_data;

    PJ_LOG(5,(SNAME(tdata->sess), "Response cache deleted"));

    pj_list_erase(tdata);
    destroy_tdata(tdata, PJ_FALSE);
}

static pj_status_t apply_msg_options(pj_stun_session *sess,
				     pj_pool_t *pool,
				     const pj_stun_req_cred_info *auth_info,
				     pj_stun_msg *msg)
{
    pj_status_t status = 0;
    pj_str_t realm, username, nonce, auth_key;

    /* If the agent is sending a request, it SHOULD add a SOFTWARE attribute
     * to the request. The server SHOULD include a SOFTWARE attribute in all 
     * responses.
     *
     * If magic value is not PJ_STUN_MAGIC, only apply the attribute for
     * responses.
     */
    if (sess->srv_name.slen && 
	pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_SOFTWARE, 0)==NULL &&
	(PJ_STUN_IS_RESPONSE(msg->hdr.type) ||
	 (PJ_STUN_IS_REQUEST(msg->hdr.type) && msg->hdr.magic==PJ_STUN_MAGIC))) 
    {
	pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE,
				    &sess->srv_name);
    }

    if (pj_stun_auth_valid_for_msg(msg) && auth_info) {
	realm = auth_info->realm;
	username = auth_info->username;
	nonce = auth_info->nonce;
	auth_key = auth_info->auth_key;
    } else {
	realm.slen = username.slen = nonce.slen = auth_key.slen = 0;
    }

    /* Create and add USERNAME attribute if needed */
    if (username.slen && PJ_STUN_IS_REQUEST(msg->hdr.type)) {
	status = pj_stun_msg_add_string_attr(pool, msg,
					     PJ_STUN_ATTR_USERNAME,
					     &username);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }

    /* Add REALM only when long term credential is used */
    if (realm.slen &&  PJ_STUN_IS_REQUEST(msg->hdr.type)) {
	status = pj_stun_msg_add_string_attr(pool, msg,
					    PJ_STUN_ATTR_REALM,
					    &realm);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }

    /* Add NONCE when desired */
    if (nonce.slen && 
	(PJ_STUN_IS_REQUEST(msg->hdr.type) ||
	 PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))) 
    {
	status = pj_stun_msg_add_string_attr(pool, msg,
					    PJ_STUN_ATTR_NONCE,
					    &nonce);
    }

    /* Add MESSAGE-INTEGRITY attribute */
    if (username.slen && auth_key.slen) {
	status = pj_stun_msg_add_msgint_attr(pool, msg);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }


    /* Add FINGERPRINT attribute if necessary */
    if (sess->use_fingerprint) {
	status = pj_stun_msg_add_uint_attr(pool, msg, 
					  PJ_STUN_ATTR_FINGERPRINT, 0);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    }

    return PJ_SUCCESS;
}

static pj_status_t handle_auth_challenge(pj_stun_session *sess,
					 const pj_stun_tx_data *request,
					 const pj_stun_msg *response,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len,
					 pj_bool_t *notify_user)
{
    const pj_stun_errcode_attr *ea;

    *notify_user = PJ_TRUE;

    if (response==NULL)
	return PJ_SUCCESS;

    if (sess->auth_type != PJ_STUN_AUTH_LONG_TERM)
	return PJ_SUCCESS;
    
    if (!PJ_STUN_IS_ERROR_RESPONSE(response->hdr.type)) {
	sess->auth_retry = 0;
	return PJ_SUCCESS;
    }

    ea = (const pj_stun_errcode_attr*)
	 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_ERROR_CODE, 0);
    if (!ea) {
	PJ_LOG(4,(SNAME(sess), "Invalid error response: no ERROR-CODE"
		  " attribute"));
	*notify_user = PJ_FALSE;
	return PJNATH_EINSTUNMSG;
    }

    if (ea->err_code == PJ_STUN_SC_UNAUTHORIZED || 
	ea->err_code == PJ_STUN_SC_STALE_NONCE)
    {
	const pj_stun_nonce_attr *anonce;
	const pj_stun_realm_attr *arealm;
	pj_stun_tx_data *tdata;
	unsigned i;
	pj_status_t status;

	anonce = (const pj_stun_nonce_attr*)
		 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_NONCE, 0);
	if (!anonce) {
	    PJ_LOG(4,(SNAME(sess), "Invalid response: missing NONCE"));
	    *notify_user = PJ_FALSE;
	    return PJNATH_EINSTUNMSG;
	}

	/* Bail out if we've supplied the correct nonce */
	if (pj_strcmp(&anonce->value, &sess->next_nonce)==0) {
	    return PJ_SUCCESS;
	}

	/* Bail out if we've tried too many */
	if (++sess->auth_retry > 3) {
	    PJ_LOG(4,(SNAME(sess), "Error: authentication failed (too "
		      "many retries)"));
	    return PJ_STATUS_FROM_STUN_CODE(401);
	}

	/* Save next_nonce */
	pj_strdup(sess->pool, &sess->next_nonce, &anonce->value);

	/* Copy the realm from the response */
	arealm = (pj_stun_realm_attr*)
		 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_REALM, 0);
	if (arealm) {
	    pj_strdup(sess->pool, &sess->server_realm, &arealm->value);
	    while (sess->server_realm.slen &&
		    !sess->server_realm.ptr[sess->server_realm.slen-1])
	    {
		--sess->server_realm.slen;
	    }
	}

	/* Create new request */
	status = pj_stun_session_create_req(sess, request->msg->hdr.type,
					    request->msg->hdr.magic,
					    NULL, &tdata);
	if (status != PJ_SUCCESS)
	    return status;

	/* Duplicate all the attributes in the old request, except
	 * USERNAME, REALM, M-I, and NONCE, which will be filled in
	 * later.
	 */
	for (i=0; i<request->msg->attr_count; ++i) {
	    const pj_stun_attr_hdr *asrc = request->msg->attr[i];

	    if (asrc->type == PJ_STUN_ATTR_USERNAME ||
		asrc->type == PJ_STUN_ATTR_REALM ||
		asrc->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY ||
		asrc->type == PJ_STUN_ATTR_NONCE)
	    {
		continue;
	    }

	    tdata->msg->attr[tdata->msg->attr_count++] = 
		pj_stun_attr_clone(tdata->pool, asrc);
	}

	/* Will retry the request with authentication, no need to
	 * notify user.
	 */
	*notify_user = PJ_FALSE;

	PJ_LOG(4,(SNAME(sess), "Retrying request with new authentication"));

	/* Retry the request */
	status = pj_stun_session_send_msg(sess, request->token, PJ_TRUE, 
					  request->retransmit, src_addr, 
					  src_addr_len, tdata);

    } else {
	sess->auth_retry = 0;
    }

    return PJ_SUCCESS;
}

static void stun_tsx_on_complete(pj_stun_client_tsx *tsx,
				 pj_status_t status, 
				 const pj_stun_msg *response,
				 const pj_sockaddr_t *src_addr,
				 unsigned src_addr_len)
{
    pj_stun_session *sess;
    pj_bool_t notify_user = PJ_TRUE;
    pj_stun_tx_data *tdata;

    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);
    sess = tdata->sess;

    /* Lock the session and prevent user from destroying us in the callback */
    pj_grp_lock_acquire(sess->grp_lock);
    if (sess->is_destroying) {
	pj_stun_msg_destroy_tdata(sess, tdata);
	pj_grp_lock_release(sess->grp_lock);
	return;
    }

    /* Handle authentication challenge */
    handle_auth_challenge(sess, tdata, response, src_addr,
		          src_addr_len, &notify_user);

    if (notify_user && sess->cb.on_request_complete) {
	(*sess->cb.on_request_complete)(sess, status, tdata->token, tdata, 
					response, src_addr, src_addr_len);
    }

    /* Destroy the transmit data. This will remove the transaction
     * from the pending list too. 
     */
    if (status == PJNATH_ESTUNTIMEDOUT)
	destroy_tdata(tdata, PJ_TRUE);
    else
	destroy_tdata(tdata, PJ_FALSE);
    tdata = NULL;

    pj_grp_lock_release(sess->grp_lock);
}

static pj_status_t stun_tsx_on_send_msg(pj_stun_client_tsx *tsx,
					const void *stun_pkt,
					pj_size_t pkt_size)
{
    pj_stun_tx_data *tdata;
    pj_stun_session *sess;
    pj_status_t status;

    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);
    sess = tdata->sess;

    /* Lock the session and prevent user from destroying us in the callback */
    pj_grp_lock_acquire(sess->grp_lock);
    
    if (sess->is_destroying) {
	/* Stray timer */
	pj_grp_lock_release(sess->grp_lock);
	return PJ_EINVALIDOP;
    }

    status = sess->cb.on_send_msg(tdata->sess, tdata->token, stun_pkt, 
				  pkt_size, tdata->dst_addr, 
				  tdata->addr_len);
    if (pj_grp_lock_release(sess->grp_lock))
	return PJ_EGONE;

    return status;
}

/* **************************************************************************/

PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_config *cfg,
					    const char *name,
					    const pj_stun_session_cb *cb,
					    pj_bool_t fingerprint,
					    pj_grp_lock_t *grp_lock,
					    pj_stun_session **p_sess)
{
    pj_pool_t	*pool;
    pj_stun_session *sess;
    pj_status_t status;

    PJ_ASSERT_RETURN(cfg && cb && p_sess, PJ_EINVAL);

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

    pool = pj_pool_create(cfg->pf, name, PJNATH_POOL_LEN_STUN_SESS, 
			  PJNATH_POOL_INC_STUN_SESS, NULL);
    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);

    sess = PJ_POOL_ZALLOC_T(pool, pj_stun_session);
    sess->cfg = cfg;
    sess->pool = pool;
    pj_memcpy(&sess->cb, cb, sizeof(*cb));
    sess->use_fingerprint = fingerprint;
    sess->log_flag = 0xFFFF;

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

    pj_grp_lock_add_ref(sess->grp_lock);
    pj_grp_lock_add_handler(sess->grp_lock, pool, sess,
                            &stun_sess_on_destroy);

    pj_stun_session_set_software_name(sess, &cfg->software_name);

    sess->rx_pool = pj_pool_create(sess->cfg->pf, name,
				   PJNATH_POOL_LEN_STUN_TDATA,
				   PJNATH_POOL_INC_STUN_TDATA, NULL);

    pj_list_init(&sess->pending_request_list);
    pj_list_init(&sess->cached_response_list);

    *p_sess = sess;

    return PJ_SUCCESS;
}

static void stun_sess_on_destroy(void *comp)
{
    pj_stun_session *sess = (pj_stun_session*)comp;

    while (!pj_list_empty(&sess->pending_request_list)) {
	pj_stun_tx_data *tdata = sess->pending_request_list.next;
	destroy_tdata(tdata, PJ_TRUE);
    }

    while (!pj_list_empty(&sess->cached_response_list)) {
	pj_stun_tx_data *tdata = sess->cached_response_list.next;
	destroy_tdata(tdata, PJ_TRUE);
    }

    if (sess->rx_pool) {
	pj_pool_release(sess->rx_pool);
	sess->rx_pool = NULL;
    }

    pj_pool_release(sess->pool);

    TRACE_((THIS_FILE, "STUN session %p destroyed", sess));
}

PJ_DEF(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess)
{
    pj_stun_tx_data *tdata;

    PJ_ASSERT_RETURN(sess, PJ_EINVAL);

    TRACE_((SNAME(sess), "STUN session %p destroy request, ref_cnt=%d",
	     sess, pj_grp_lock_get_ref(sess->grp_lock)));

    pj_grp_lock_acquire(sess->grp_lock);

    if (sess->is_destroying) {
	/* Prevent from decrementing the ref counter more than once */
	pj_grp_lock_release(sess->grp_lock);
	return PJ_EINVALIDOP;
    }

    sess->is_destroying = PJ_TRUE;

    /* We need to stop transactions and cached response because they are
     * holding the group lock's reference counter while retransmitting.
     */
    tdata = sess->pending_request_list.next;
    while (tdata != &sess->pending_request_list) {
	if (tdata->client_tsx)
	    pj_stun_client_tsx_stop(tdata->client_tsx);
	tdata = tdata->next;
    }

    tdata = sess->cached_response_list.next;
    while (tdata != &sess->cached_response_list) {
	pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,
				       &tdata->res_timer, PJ_FALSE);
	tdata = tdata->next;
    }

    pj_grp_lock_dec_ref(sess->grp_lock);
    pj_grp_lock_release(sess->grp_lock);
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pj_stun_session_set_user_data( pj_stun_session *sess,
						   void *user_data)
{
    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
    pj_grp_lock_acquire(sess->grp_lock);
    sess->user_data = user_data;
    pj_grp_lock_release(sess->grp_lock);
    return PJ_SUCCESS;
}

PJ_DEF(void*) pj_stun_session_get_user_data(pj_stun_session *sess)
{
    PJ_ASSERT_RETURN(sess, NULL);
    return sess->user_data;
}

PJ_DEF(pj_status_t) pj_stun_session_set_software_name(pj_stun_session *sess,
						      const pj_str_t *sw)
{
    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
    pj_grp_lock_acquire(sess->grp_lock);
    if (sw && sw->slen)
	pj_strdup(sess->pool, &sess->srv_name, sw);
    else
	sess->srv_name.slen = 0;
    pj_grp_lock_release(sess->grp_lock);
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_stun_session_set_credential(pj_stun_session *sess,
						 pj_stun_auth_type auth_type,
						 const pj_stun_auth_cred *cred)
{
    PJ_ASSERT_RETURN(sess, PJ_EINVAL);

    pj_grp_lock_acquire(sess->grp_lock);
    sess->auth_type = auth_type;
    if (cred) {
	pj_stun_auth_cred_dup(sess->pool, &sess->cred, cred);
    } else {
	sess->auth_type = PJ_STUN_AUTH_NONE;
	pj_bzero(&sess->cred, sizeof(sess->cred));
    }
    pj_grp_lock_release(sess->grp_lock);

    return PJ_SUCCESS;
}

PJ_DEF(void) pj_stun_session_set_log( pj_stun_session *sess,
				      unsigned flags)
{
    PJ_ASSERT_ON_FAIL(sess, return);
    sess->log_flag = flags;
}

PJ_DEF(pj_bool_t) pj_stun_session_use_fingerprint(pj_stun_session *sess,
						  pj_bool_t use)
{
    pj_bool_t old_use;

    PJ_ASSERT_RETURN(sess, PJ_FALSE);

    old_use = sess->use_fingerprint;
    sess->use_fingerprint = use;
    return old_use;
}

static pj_status_t get_auth(pj_stun_session *sess,
			    pj_stun_tx_data *tdata)
{
    if (sess->cred.type == PJ_STUN_AUTH_CRED_STATIC) {
	//tdata->auth_info.realm = sess->cred.data.static_cred.realm;
	tdata->auth_info.realm = sess->server_realm;
	tdata->auth_info.username = sess->cred.data.static_cred.username;
	tdata->auth_info.nonce = sess->cred.data.static_cred.nonce;

	pj_stun_create_key(tdata->pool, &tdata->auth_info.auth_key, 
			   &tdata->auth_info.realm,
			   &tdata->auth_info.username,
			   sess->cred.data.static_cred.data_type,
			   &sess->cred.data.static_cred.data);

    } else if (sess->cred.type == PJ_STUN_AUTH_CRED_DYNAMIC) {
	pj_str_t password;
	void *user_data = sess->cred.data.dyn_cred.user_data;
	pj_stun_passwd_type data_type = PJ_STUN_PASSWD_PLAIN;
	pj_status_t rc;

	rc = (*sess->cred.data.dyn_cred.get_cred)(tdata->msg, user_data, 
						  tdata->pool,
						  &tdata->auth_info.realm, 
						  &tdata->auth_info.username,
						  &tdata->auth_info.nonce, 
						  &data_type, &password);
	if (rc != PJ_SUCCESS)
	    return rc;

	pj_stun_create_key(tdata->pool, &tdata->auth_info.auth_key, 
			   &tdata->auth_info.realm, &tdata->auth_info.username,
			   data_type, &password);

    } else {
	pj_assert(!"Unknown credential type");
	return PJ_EBUG;
    }

    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_stun_session_create_req(pj_stun_session *sess,
					       int method,
					       pj_uint32_t magic,
					       const pj_uint8_t tsx_id[12],
					       pj_stun_tx_data **p_tdata)
{
    pj_stun_tx_data *tdata = NULL;
    pj_status_t status;

    PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL);

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

    status = create_tdata(sess, &tdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Create STUN message */
    status = pj_stun_msg_create(tdata->pool, method,  magic, 
				tsx_id, &tdata->msg);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* copy the request's transaction ID as the transaction key. */
    pj_assert(sizeof(tdata->msg_key)==sizeof(tdata->msg->hdr.tsx_id));
    tdata->msg_magic = tdata->msg->hdr.magic;
    pj_memcpy(tdata->msg_key, tdata->msg->hdr.tsx_id,
	      sizeof(tdata->msg->hdr.tsx_id));

    
    /* Get authentication information for the request */
    if (sess->auth_type == PJ_STUN_AUTH_NONE) {
	/* No authentication */

    } else if (sess->auth_type == PJ_STUN_AUTH_SHORT_TERM) {
	/* MUST put authentication in request */
	status = get_auth(sess, tdata);
	if (status != PJ_SUCCESS)
	    goto on_error;

    } else if (sess->auth_type == PJ_STUN_AUTH_LONG_TERM) {
	/* Only put authentication information if we've received
	 * response from server.
	 */
	if (sess->next_nonce.slen != 0) {
	    status = get_auth(sess, tdata);
	    if (status != PJ_SUCCESS)
		goto on_error;
	    tdata->auth_info.nonce = sess->next_nonce;
	    tdata->auth_info.realm = sess->server_realm;
	}

    } else {
	pj_assert(!"Invalid authentication type");
	status = PJ_EBUG;
	goto on_error;
    }

    *p_tdata = tdata;
    pj_grp_lock_release(sess->grp_lock);
    return PJ_SUCCESS;

on_error:
    if (tdata)
	pj_pool_release(tdata->pool);
    pj_grp_lock_release(sess->grp_lock);
    return status;
}

PJ_DEF(pj_status_t) pj_stun_session_create_ind(pj_stun_session *sess,
					       int msg_type,
					       pj_stun_tx_data **p_tdata)
{
    pj_stun_tx_data *tdata = NULL;
    pj_status_t status;

    PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL);

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

    status = create_tdata(sess, &tdata);
    if (status != PJ_SUCCESS) {
	pj_grp_lock_release(sess->grp_lock);
	return status;
    }

    /* Create STUN message */
    msg_type |= PJ_STUN_INDICATION_BIT;
    status = pj_stun_msg_create(tdata->pool, msg_type,  PJ_STUN_MAGIC, 
				NULL, &tdata->msg);
    if (status != PJ_SUCCESS) {
	pj_pool_release(tdata->pool);
	pj_grp_lock_release(sess->grp_lock);
	return status;
    }

    *p_tdata = tdata;

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

/*
 * Create a STUN response message.
 */
PJ_DEF(pj_status_t) pj_stun_session_create_res( pj_stun_session *sess,
						const pj_stun_rx_data *rdata,
						unsigned err_code,
						const pj_str_t *err_msg,
						pj_stun_tx_data **p_tdata)
{
    pj_status_t status;
    pj_stun_tx_data *tdata = NULL;

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

    status = create_tdata(sess, &tdata);
    if (status != PJ_SUCCESS) {
	pj_grp_lock_release(sess->grp_lock);
	return status;
    }

    /* Create STUN response message */
    status = pj_stun_msg_create_response(tdata->pool, rdata->msg, 
					 err_code, err_msg, &tdata->msg);
    if (status != PJ_SUCCESS) {
	pj_pool_release(tdata->pool);
	pj_grp_lock_release(sess->grp_lock);
	return status;
    }

    /* copy the request's transaction ID as the transaction key. */
    pj_assert(sizeof(tdata->msg_key)==sizeof(rdata->msg->hdr.tsx_id));
    tdata->msg_magic = rdata->msg->hdr.magic;
    pj_memcpy(tdata->msg_key, rdata->msg->hdr.tsx_id, 
	      sizeof(rdata->msg->hdr.tsx_id));

    /* copy the credential found in the request */
    pj_stun_req_cred_info_dup(tdata->pool, &tdata->auth_info, &rdata->info);

    *p_tdata = tdata;

    pj_grp_lock_release(sess->grp_lock);

    return PJ_SUCCESS;
}


/* Print outgoing message to log */
static void dump_tx_msg(pj_stun_session *sess, const pj_stun_msg *msg,
			unsigned pkt_size, const pj_sockaddr_t *addr)
{
    char dst_name[PJ_INET6_ADDRSTRLEN+10];
    
    if ((PJ_STUN_IS_REQUEST(msg->hdr.type) && 
	 (sess->log_flag & PJ_STUN_SESS_LOG_TX_REQ)==0) ||
	(PJ_STUN_IS_RESPONSE(msg->hdr.type) &&
	 (sess->log_flag & PJ_STUN_SESS_LOG_TX_RES)==0) ||
	(PJ_STUN_IS_INDICATION(msg->hdr.type) &&
	 (sess->log_flag & PJ_STUN_SESS_LOG_TX_IND)==0))
    {
	return;
    }

    pj_sockaddr_print(addr, dst_name, sizeof(dst_name), 3);

    PJ_LOG(5,(SNAME(sess), 
	      "TX %d bytes STUN message to %s:\n"
	      "--- begin STUN message ---\n"
	      "%s"
	      "--- end of STUN message ---\n",
	      pkt_size, dst_name, 
	      pj_stun_msg_dump(msg, sess->dump_buf, sizeof(sess->dump_buf), 
			       NULL)));

}


PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess,
					      void *token,
					      pj_bool_t cache_res,
					      pj_bool_t retransmit,
					      const pj_sockaddr_t *server,
					      unsigned addr_len,
					      pj_stun_tx_data *tdata)
{
    pj_status_t status;

    PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL);

    /* Lock the session and prevent user from destroying us in the callback */
    pj_grp_lock_acquire(sess->grp_lock);
    if (sess->is_destroying) {
	pj_grp_lock_release(sess->grp_lock);
	return PJ_EINVALIDOP;
    }

    pj_log_push_indent();

    /* Allocate packet */
    tdata->max_len = PJ_STUN_MAX_PKT_LEN;
    tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len);

    tdata->token = token;
    tdata->retransmit = retransmit;

    /* Apply options */
    status = apply_msg_options(sess, tdata->pool, &tdata->auth_info, 
			       tdata->msg);
    if (status != PJ_SUCCESS) {
	pj_stun_msg_destroy_tdata(sess, tdata);
	LOG_ERR_(sess, "Error applying options", status);
	goto on_return;
    }

    /* Encode message */
    status = pj_stun_msg_encode(tdata->msg, (pj_uint8_t*)tdata->pkt, 
    				tdata->max_len, 0, 
    				&tdata->auth_info.auth_key,
				&tdata->pkt_size);
    if (status != PJ_SUCCESS) {
	pj_stun_msg_destroy_tdata(sess, tdata);
	LOG_ERR_(sess, "STUN encode() error", status);
	goto on_return;
    }

    /* Dump packet */
    dump_tx_msg(sess, tdata->msg, (unsigned)tdata->pkt_size, server);

    /* If this is a STUN request message, then send the request with
     * a new STUN client transaction.
     */
    if (PJ_STUN_IS_REQUEST(tdata->msg->hdr.type)) {

	/* Create STUN client transaction */
	status = pj_stun_client_tsx_create(sess->cfg, tdata->pool,
	                                   sess->grp_lock,
					   &tsx_cb, &tdata->client_tsx);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
	pj_stun_client_tsx_set_data(tdata->client_tsx, (void*)tdata);

	/* Save the remote address */
	tdata->addr_len = addr_len;
	tdata->dst_addr = server;

	/* Send the request! */
	status = pj_stun_client_tsx_send_msg(tdata->client_tsx, retransmit,
					     tdata->pkt, 
					     (unsigned)tdata->pkt_size);
	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	    pj_stun_msg_destroy_tdata(sess, tdata);
	    LOG_ERR_(sess, "Error sending STUN request", status);
	    goto on_return;
	}

	/* Add to pending request list */
	tsx_add(sess, tdata);

    } else {
	if (cache_res && 
	    (PJ_STUN_IS_SUCCESS_RESPONSE(tdata->msg->hdr.type) ||
	     PJ_STUN_IS_ERROR_RESPONSE(tdata->msg->hdr.type))) 
	{
	    /* Requested to keep the response in the cache */
	    pj_time_val timeout;
	    
	    pj_memset(&tdata->res_timer, 0, sizeof(tdata->res_timer));
	    pj_timer_entry_init(&tdata->res_timer, PJ_FALSE, tdata,
				&on_cache_timeout);

	    timeout.sec = sess->cfg->res_cache_msec / 1000;
	    timeout.msec = sess->cfg->res_cache_msec % 1000;

	    status = pj_timer_heap_schedule_w_grp_lock(sess->cfg->timer_heap,
	                                               &tdata->res_timer,
	                                               &timeout, PJ_TRUE,
	                                               sess->grp_lock);
	    if (status != PJ_SUCCESS) {
		pj_stun_msg_destroy_tdata(sess, tdata);
		LOG_ERR_(sess, "Error scheduling response timer", status);
		goto on_return;
	    }

	    pj_list_push_back(&sess->cached_response_list, tdata);
	}
    
	/* Otherwise for non-request message, send directly to transport. */
	status = sess->cb.on_send_msg(sess, token, tdata->pkt, 
				      tdata->pkt_size, server, addr_len);

	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	    pj_stun_msg_destroy_tdata(sess, tdata);
	    LOG_ERR_(sess, "Error sending STUN request", status);
	    goto on_return;
	}

	/* Destroy only when response is not cached*/
	if (tdata->res_timer.id == 0) {
	    pj_stun_msg_destroy_tdata(sess, tdata);
	}
    }

on_return:
    pj_log_pop_indent();

    if (pj_grp_lock_release(sess->grp_lock))
	return PJ_EGONE;

    return status;
}


/*
 * Create and send STUN response message.
 */
PJ_DEF(pj_status_t) pj_stun_session_respond( pj_stun_session *sess, 
					     const pj_stun_rx_data *rdata,
					     unsigned code, 
					     const char *errmsg,
					     void *token,
					     pj_bool_t cache, 
					     const pj_sockaddr_t *dst_addr, 
					     unsigned addr_len)
{
    pj_status_t status;
    pj_str_t reason;
    pj_stun_tx_data *tdata;

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

    status = pj_stun_session_create_res(sess, rdata, code, 
					(errmsg?pj_cstr(&reason,errmsg):NULL), 
					&tdata);
    if (status != PJ_SUCCESS) {
	pj_grp_lock_release(sess->grp_lock);
	return status;
    }

    status = pj_stun_session_send_msg(sess, token, cache, PJ_FALSE,
                                      dst_addr,  addr_len, tdata);

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


/*
 * Cancel outgoing STUN transaction. 
 */
PJ_DEF(pj_status_t) pj_stun_session_cancel_req( pj_stun_session *sess,
						pj_stun_tx_data *tdata,
						pj_bool_t notify,
						pj_status_t notify_status)
{
    PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL);
    PJ_ASSERT_RETURN(!notify || notify_status!=PJ_SUCCESS, PJ_EINVAL);
    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL);

    /* Lock the session and prevent user from destroying us in the callback */
    pj_grp_lock_acquire(sess->grp_lock);
    if (sess->is_destroying) {
	pj_grp_lock_release(sess->grp_lock);
	return PJ_EINVALIDOP;
    }

    if (notify) {
	(sess->cb.on_request_complete)(sess, notify_status, tdata->token, 
				       tdata, NULL, NULL, 0);
    }

    /* Just destroy tdata. This will destroy the transaction as well */
    pj_stun_msg_destroy_tdata(sess, tdata);

    pj_grp_lock_release(sess->grp_lock);

    return PJ_SUCCESS;
}

/*
 * Explicitly request retransmission of the request.
 */
PJ_DEF(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess,
						   pj_stun_tx_data *tdata,
                                                   pj_bool_t mod_count)
{
    pj_status_t status;

    PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL);
    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL);

    /* Lock the session and prevent user from destroying us in the callback */
    pj_grp_lock_acquire(sess->grp_lock);
    if (sess->is_destroying) {
	pj_grp_lock_release(sess->grp_lock);
	return PJ_EINVALIDOP;
    }

    status = pj_stun_client_tsx_retransmit(tdata->client_tsx, mod_count);

    pj_grp_lock_release(sess->grp_lock);

    return status;
}


/* Send response */
static pj_status_t send_response(pj_stun_session *sess, void *token,
				 pj_pool_t *pool, pj_stun_msg *response,
				 const pj_stun_req_cred_info *auth_info,
				 pj_bool_t retransmission,
				 const pj_sockaddr_t *addr, unsigned addr_len)
{
    pj_uint8_t *out_pkt;
    pj_size_t out_max_len, out_len;
    pj_status_t status;

    /* Apply options */
    if (!retransmission) {
	status = apply_msg_options(sess, pool, auth_info, response);
	if (status != PJ_SUCCESS)
	    return status;
    }

    /* Alloc packet buffer */
    out_max_len = PJ_STUN_MAX_PKT_LEN;
    out_pkt = (pj_uint8_t*) pj_pool_alloc(pool, out_max_len);

    /* Encode */
    status = pj_stun_msg_encode(response, out_pkt, out_max_len, 0, 
				&auth_info->auth_key, &out_len);
    if (status != PJ_SUCCESS) {
	LOG_ERR_(sess, "Error encoding message", status);
	return status;
    }

    /* Print log */
    dump_tx_msg(sess, response, (unsigned)out_len, addr);

    /* Send packet */
    status = sess->cb.on_send_msg(sess, token, out_pkt, (unsigned)out_len, 
				  addr, addr_len);

    return status;
}

/* Authenticate incoming message */
static pj_status_t authenticate_req(pj_stun_session *sess,
				    void *token,
				    const pj_uint8_t *pkt,
				    unsigned pkt_len,
				    pj_stun_rx_data *rdata,
				    pj_pool_t *tmp_pool,
				    const pj_sockaddr_t *src_addr,
				    unsigned src_addr_len)
{
    pj_stun_msg *response;
    pj_status_t status;

    if (PJ_STUN_IS_ERROR_RESPONSE(rdata->msg->hdr.type) || 
	sess->auth_type == PJ_STUN_AUTH_NONE)
    {
	return PJ_SUCCESS;
    }

    status = pj_stun_authenticate_request(pkt, pkt_len, rdata->msg, 
					  &sess->cred, tmp_pool, &rdata->info,
					  &response);
    if (status != PJ_SUCCESS && response != NULL) {
	PJ_LOG(5,(SNAME(sess), "Message authentication failed"));
	send_response(sess, token, tmp_pool, response, &rdata->info, 
		      PJ_FALSE, src_addr, src_addr_len);
    }

    return status;
}


/* Handle incoming response */
static pj_status_t on_incoming_response(pj_stun_session *sess,
					unsigned options,
					const pj_uint8_t *pkt,
					unsigned pkt_len,
					pj_stun_msg *msg,
					const pj_sockaddr_t *src_addr,
					unsigned src_addr_len)
{
    pj_stun_tx_data *tdata;
    pj_status_t status;

    /* Lookup pending client transaction */
    tdata = tsx_lookup(sess, msg);
    if (tdata == NULL) {
	PJ_LOG(5,(SNAME(sess), 
		  "Transaction not found, response silently discarded"));
	return PJ_SUCCESS;
    }

    if (sess->auth_type == PJ_STUN_AUTH_NONE)
	options |= PJ_STUN_NO_AUTHENTICATE;

    /* Authenticate the message, unless PJ_STUN_NO_AUTHENTICATE
     * is specified in the option.
     */
    if ((options & PJ_STUN_NO_AUTHENTICATE) == 0 && 
	tdata->auth_info.auth_key.slen != 0 && 
	pj_stun_auth_valid_for_msg(msg))
    {
	status = pj_stun_authenticate_response(pkt, pkt_len, msg, 
					       &tdata->auth_info.auth_key);
	if (status != PJ_SUCCESS) {
	    PJ_LOG(5,(SNAME(sess), 
		      "Response authentication failed"));
	    return status;
	}
    }

    /* Pass the response to the transaction. 
     * If the message is accepted, transaction callback will be called,
     * and this will call the session callback too.
     */
    status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg, 
					  src_addr, src_addr_len);
    if (status != PJ_SUCCESS) {
	return status;
    }

    return PJ_SUCCESS;
}


/* For requests, check if we cache the response */
static pj_status_t check_cached_response(pj_stun_session *sess,
					 pj_pool_t *tmp_pool,
					 const pj_stun_msg *msg,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len)
{
    pj_stun_tx_data *t;

    /* First lookup response in response cache */
    t = sess->cached_response_list.next;
    while (t != &sess->cached_response_list) {
	if (t->msg_magic == msg->hdr.magic &&
	    t->msg->hdr.type == msg->hdr.type &&
	    pj_memcmp(t->msg_key, msg->hdr.tsx_id, 
		      sizeof(msg->hdr.tsx_id))==0)
	{
	    break;
	}
	t = t->next;
    }

    if (t != &sess->cached_response_list) {
	/* Found response in the cache */

	PJ_LOG(5,(SNAME(sess), 
		 "Request retransmission, sending cached response"));

	send_response(sess, t->token, tmp_pool, t->msg, &t->auth_info, 
		      PJ_TRUE, src_addr, src_addr_len);
	return PJ_SUCCESS;
    }

    return PJ_ENOTFOUND;
}

/* Handle incoming request */
static pj_status_t on_incoming_request(pj_stun_session *sess,
				       unsigned options,
				       void *token,
				       pj_pool_t *tmp_pool,
				       const pj_uint8_t *in_pkt,
				       unsigned in_pkt_len,
				       pj_stun_msg *msg,
				       const pj_sockaddr_t *src_addr,
				       unsigned src_addr_len)
{
    pj_stun_rx_data rdata;
    pj_status_t status;

    /* Init rdata */
    rdata.msg = msg;
    pj_bzero(&rdata.info, sizeof(rdata.info));

    if (sess->auth_type == PJ_STUN_AUTH_NONE)
	options |= PJ_STUN_NO_AUTHENTICATE;

    /* Authenticate the message, unless PJ_STUN_NO_AUTHENTICATE
     * is specified in the option.
     */
    if ((options & PJ_STUN_NO_AUTHENTICATE) == 0) {
	status = authenticate_req(sess, token, (const pj_uint8_t*) in_pkt, 
				  in_pkt_len,&rdata, tmp_pool, src_addr, 
				  src_addr_len);
	if (status != PJ_SUCCESS) {
	    return status;
	}
    }

    /* Distribute to handler, or respond with Bad Request */
    if (sess->cb.on_rx_request) {
	status = (*sess->cb.on_rx_request)(sess, in_pkt, in_pkt_len, &rdata,
					   token, src_addr, src_addr_len);
    } else {
	pj_str_t err_text;
	pj_stun_msg *response;

	err_text = pj_str("Callback is not set to handle request");
	status = pj_stun_msg_create_response(tmp_pool, msg, 
					     PJ_STUN_SC_BAD_REQUEST, 
					     &err_text, &response);
	if (status == PJ_SUCCESS && response) {
	    status = send_response(sess, token, tmp_pool, response, 
				   NULL, PJ_FALSE, src_addr, src_addr_len);
	}
    }

    return status;
}


/* Handle incoming indication */
static pj_status_t on_incoming_indication(pj_stun_session *sess,
					  void *token,
					  pj_pool_t *tmp_pool,
					  const pj_uint8_t *in_pkt,
					  unsigned in_pkt_len,
					  const pj_stun_msg *msg,
					  const pj_sockaddr_t *src_addr,
					  unsigned src_addr_len)
{
    PJ_UNUSED_ARG(tmp_pool);

    /* Distribute to handler */
    if (sess->cb.on_rx_indication) {
	return (*sess->cb.on_rx_indication)(sess, in_pkt, in_pkt_len, msg,
					    token, src_addr, src_addr_len);
    } else {
	return PJ_SUCCESS;
    }
}


/* Print outgoing message to log */
static void dump_rx_msg(pj_stun_session *sess, const pj_stun_msg *msg,
			unsigned pkt_size, const pj_sockaddr_t *addr)
{
    char src_info[PJ_INET6_ADDRSTRLEN+10];
    
    if ((PJ_STUN_IS_REQUEST(msg->hdr.type) && 
	 (sess->log_flag & PJ_STUN_SESS_LOG_RX_REQ)==0) ||
	(PJ_STUN_IS_RESPONSE(msg->hdr.type) &&
	 (sess->log_flag & PJ_STUN_SESS_LOG_RX_RES)==0) ||
	(PJ_STUN_IS_INDICATION(msg->hdr.type) &&
	 (sess->log_flag & PJ_STUN_SESS_LOG_RX_IND)==0))
    {
	return;
    }

    pj_sockaddr_print(addr, src_info, sizeof(src_info), 3);

    PJ_LOG(5,(SNAME(sess),
	      "RX %d bytes STUN message from %s:\n"
	      "--- begin STUN message ---\n"
	      "%s"
	      "--- end of STUN message ---\n",
	      pkt_size, src_info,
	      pj_stun_msg_dump(msg, sess->dump_buf, sizeof(sess->dump_buf), 
			       NULL)));

}

/* Incoming packet */
PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
					      const void *packet,
					      pj_size_t pkt_size,
					      unsigned options,
					      void *token,
					      pj_size_t *parsed_len,
					      const pj_sockaddr_t *src_addr,
					      unsigned src_addr_len)
{
    pj_stun_msg *msg, *response;
    pj_status_t status;

    PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL);

    /* Lock the session and prevent user from destroying us in the callback */
    pj_grp_lock_acquire(sess->grp_lock);

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

    pj_log_push_indent();

    /* Reset pool */
    pj_pool_reset(sess->rx_pool);

    /* Try to parse the message */
    status = pj_stun_msg_decode(sess->rx_pool, (const pj_uint8_t*)packet,
			        pkt_size, options, 
				&msg, parsed_len, &response);
    if (status != PJ_SUCCESS) {
	LOG_ERR_(sess, "STUN msg_decode() error", status);
	if (response) {
	    send_response(sess, token, sess->rx_pool, response, NULL,
			  PJ_FALSE, src_addr, src_addr_len);
	}
	goto on_return;
    }

    dump_rx_msg(sess, msg, (unsigned)pkt_size, src_addr);

    /* For requests, check if we have cached response */
    status = check_cached_response(sess, sess->rx_pool, msg, 
				   src_addr, src_addr_len);
    if (status == PJ_SUCCESS) {
	goto on_return;
    }

    /* Handle message */
    if (PJ_STUN_IS_SUCCESS_RESPONSE(msg->hdr.type) ||
	PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))
    {
	status = on_incoming_response(sess, options, 
				      (const pj_uint8_t*) packet, 
				      (unsigned)pkt_size, msg, 
				      src_addr, src_addr_len);

    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) {

	status = on_incoming_request(sess, options, token, sess->rx_pool, 
				     (const pj_uint8_t*) packet, 
				     (unsigned)pkt_size, 
				     msg, src_addr, src_addr_len);

    } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) {

	status = on_incoming_indication(sess, token, sess->rx_pool, 
					(const pj_uint8_t*) packet, 
					(unsigned)pkt_size, msg, src_addr, 
					src_addr_len);

    } else {
	pj_assert(!"Unexpected!");
	status = PJ_EBUG;
    }

on_return:
    pj_log_pop_indent();

    if (pj_grp_lock_release(sess->grp_lock))
	return PJ_EGONE;

    return status;
}

