/* $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/nat_detect.h>
#include <pjnath/errno.h>
#include <pj/assert.h>
#include <pj/ioqueue.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/rand.h>
#include <pj/string.h>
#include <pj/timer.h>
#include <pj/compat/socket.h>


static const char *nat_type_names[] =
{
    "Unknown",
    "ErrUnknown",
    "Open",
    "Blocked",
    "Symmetric UDP",
    "Full Cone",
    "Symmetric",
    "Restricted",
    "Port Restricted"
};


#define CHANGE_IP_FLAG		4
#define CHANGE_PORT_FLAG	2
#define CHANGE_IP_PORT_FLAG	(CHANGE_IP_FLAG | CHANGE_PORT_FLAG)
#define TEST_INTERVAL		50

enum test_type
{
    ST_TEST_1,
    ST_TEST_2,
    ST_TEST_3,
    ST_TEST_1B,
    ST_MAX
};

static const char *test_names[] =
{
    "Test I: Binding request",
    "Test II: Binding request with change address and port request",
    "Test III: Binding request with change port request",
    "Test IB: Binding request to alternate address"
};

enum timer_type
{
    TIMER_TEST	    = 1,
    TIMER_DESTROY   = 2
};

typedef struct nat_detect_session
{
    pj_pool_t		    *pool;
    pj_mutex_t		    *mutex;

    pj_timer_heap_t	    *timer_heap;
    pj_timer_entry	     timer;
    unsigned		     timer_executed;

    void		    *user_data;
    pj_stun_nat_detect_cb   *cb;
    pj_sock_t		     sock;
    pj_sockaddr_in	     local_addr;
    pj_ioqueue_key_t	    *key;
    pj_sockaddr_in	     server;
    pj_sockaddr_in	    *cur_server;
    pj_stun_session	    *stun_sess;

    pj_ioqueue_op_key_t	     read_op, write_op;
    pj_uint8_t		     rx_pkt[PJ_STUN_MAX_PKT_LEN];
    pj_ssize_t		     rx_pkt_len;
    pj_sockaddr_in	     src_addr;
    int			     src_addr_len;

    struct result
    {
	pj_bool_t	executed;
	pj_bool_t	complete;
	pj_status_t	status;
	pj_sockaddr_in	ma;
	pj_sockaddr_in	ca;
	pj_stun_tx_data	*tdata;
    } result[ST_MAX];

} nat_detect_session;


static void on_read_complete(pj_ioqueue_key_t *key, 
                             pj_ioqueue_op_key_t *op_key, 
                             pj_ssize_t bytes_read);
static void on_request_complete(pj_stun_session *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_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 send_test(nat_detect_session *sess,
			     enum test_type test_id,
			     const pj_sockaddr_in *alt_addr,
			     pj_uint32_t change_flag);
static void on_sess_timer(pj_timer_heap_t *th,
			     pj_timer_entry *te);
static void sess_destroy(nat_detect_session *sess);


/*
 * Get the NAT name from the specified NAT type.
 */
PJ_DEF(const char*) pj_stun_get_nat_name(pj_stun_nat_type type)
{
    PJ_ASSERT_RETURN(type >= 0 && type <= PJ_STUN_NAT_TYPE_PORT_RESTRICTED,
		     "*Invalid*");

    return nat_type_names[type];
}

static int test_executed(nat_detect_session *sess)
{
    unsigned i, count;
    for (i=0, count=0; i<PJ_ARRAY_SIZE(sess->result); ++i) {
	if (sess->result[i].executed)
	    ++count;
    }
    return count;
}

static int test_completed(nat_detect_session *sess)
{
    unsigned i, count;
    for (i=0, count=0; i<PJ_ARRAY_SIZE(sess->result); ++i) {
	if (sess->result[i].complete)
	    ++count;
    }
    return count;
}

static pj_status_t get_local_interface(const pj_sockaddr_in *server,
				       pj_in_addr *local_addr)
{
    pj_sock_t sock;
    pj_sockaddr_in tmp;
    int addr_len;
    pj_status_t status;

    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock);
    if (status != PJ_SUCCESS)
	return status;

    status = pj_sock_bind_in(sock, 0, 0);
    if (status != PJ_SUCCESS) {
	pj_sock_close(sock);
	return status;
    }

    status = pj_sock_connect(sock, server, sizeof(pj_sockaddr_in));
    if (status != PJ_SUCCESS) {
	pj_sock_close(sock);
	return status;
    }

    addr_len = sizeof(pj_sockaddr_in);
    status = pj_sock_getsockname(sock, &tmp, &addr_len);
    if (status != PJ_SUCCESS) {
	pj_sock_close(sock);
	return status;
    }

    local_addr->s_addr = tmp.sin_addr.s_addr;
    
    pj_sock_close(sock);
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,
					    pj_stun_config *stun_cfg,
					    void *user_data,
					    pj_stun_nat_detect_cb *cb)
{
    pj_pool_t *pool;
    nat_detect_session *sess;
    pj_stun_session_cb sess_cb;
    pj_ioqueue_callback ioqueue_cb;
    int addr_len;
    pj_status_t status;

    PJ_ASSERT_RETURN(server && stun_cfg, PJ_EINVAL);
    PJ_ASSERT_RETURN(stun_cfg->pf && stun_cfg->ioqueue && stun_cfg->timer_heap,
		     PJ_EINVAL);

    /*
     * Init NAT detection session.
     */
    pool = pj_pool_create(stun_cfg->pf, "natck%p", PJNATH_POOL_LEN_NATCK, 
			  PJNATH_POOL_INC_NATCK, NULL);
    if (!pool)
	return PJ_ENOMEM;

    sess = PJ_POOL_ZALLOC_T(pool, nat_detect_session);
    sess->pool = pool;
    sess->user_data = user_data;
    sess->cb = cb;

    status = pj_mutex_create_recursive(pool, pool->obj_name, &sess->mutex);
    if (status != PJ_SUCCESS)
	goto on_error;
    
    pj_memcpy(&sess->server, server, sizeof(pj_sockaddr_in));

    /*
     * Init timer to self-destroy.
     */
    sess->timer_heap = stun_cfg->timer_heap;
    sess->timer.cb = &on_sess_timer;
    sess->timer.user_data = sess;


    /*
     * Initialize socket.
     */
    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sess->sock);
    if (status != PJ_SUCCESS)
	goto on_error;

    /*
     * Bind to any.
     */
    pj_bzero(&sess->local_addr, sizeof(pj_sockaddr_in));
    sess->local_addr.sin_family = pj_AF_INET();
    status = pj_sock_bind(sess->sock, &sess->local_addr, 
			  sizeof(pj_sockaddr_in));
    if (status != PJ_SUCCESS)
	goto on_error;

    /*
     * Get local/bound address.
     */
    addr_len = sizeof(sess->local_addr);
    status = pj_sock_getsockname(sess->sock, &sess->local_addr, &addr_len);
    if (status != PJ_SUCCESS)
	goto on_error;

    /*
     * Find out which interface is used to send to the server.
     */
    status = get_local_interface(server, &sess->local_addr.sin_addr);
    if (status != PJ_SUCCESS)
	goto on_error;

    PJ_LOG(5,(sess->pool->obj_name, "Local address is %s:%d",
	      pj_inet_ntoa(sess->local_addr.sin_addr), 
	      pj_ntohs(sess->local_addr.sin_port)));

    PJ_LOG(5,(sess->pool->obj_name, "Server set to %s:%d",
	      pj_inet_ntoa(server->sin_addr), 
	      pj_ntohs(server->sin_port)));

    /*
     * Register socket to ioqueue to receive asynchronous input
     * notification.
     */
    pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb));
    ioqueue_cb.on_read_complete = &on_read_complete;

    status = pj_ioqueue_register_sock(sess->pool, stun_cfg->ioqueue, 
				      sess->sock, sess, &ioqueue_cb,
				      &sess->key);
    if (status != PJ_SUCCESS)
	goto on_error;

    /*
     * Create STUN session.
     */
    pj_bzero(&sess_cb, sizeof(sess_cb));
    sess_cb.on_request_complete = &on_request_complete;
    sess_cb.on_send_msg = &on_send_msg;
    status = pj_stun_session_create(stun_cfg, pool->obj_name, &sess_cb,
				    PJ_FALSE, NULL, &sess->stun_sess);
    if (status != PJ_SUCCESS)
	goto on_error;

    pj_stun_session_set_user_data(sess->stun_sess, sess);

    /*
     * Kick-off ioqueue reading.
     */
    pj_ioqueue_op_key_init(&sess->read_op, sizeof(sess->read_op));
    pj_ioqueue_op_key_init(&sess->write_op, sizeof(sess->write_op));
    on_read_complete(sess->key, &sess->read_op, 0);

    /*
     * Start TEST_1
     */
    sess->timer.id = TIMER_TEST;
    on_sess_timer(stun_cfg->timer_heap, &sess->timer);

    return PJ_SUCCESS;

on_error:
    sess_destroy(sess);
    return status;
}


static void sess_destroy(nat_detect_session *sess)
{
    if (sess->stun_sess) { 
	pj_stun_session_destroy(sess->stun_sess);
    }

    if (sess->key) {
	pj_ioqueue_unregister(sess->key);
    } else if (sess->sock && sess->sock != PJ_INVALID_SOCKET) {
	pj_sock_close(sess->sock);
    }

    if (sess->mutex) {
	pj_mutex_destroy(sess->mutex);
    }

    if (sess->pool) {
	pj_pool_release(sess->pool);
    }
}


static void end_session(nat_detect_session *sess,
			pj_status_t status,
			pj_stun_nat_type nat_type)
{
    pj_stun_nat_detect_result result;
    char errmsg[PJ_ERR_MSG_SIZE];
    pj_time_val delay;

    if (sess->timer.id != 0) {
	pj_timer_heap_cancel(sess->timer_heap, &sess->timer);
	sess->timer.id = 0;
    }

    pj_bzero(&result, sizeof(result));
    errmsg[0] = '\0';
    result.status_text = errmsg;

    result.status = status;
    pj_strerror(status, errmsg, sizeof(errmsg));
    result.nat_type = nat_type;
    result.nat_type_name = nat_type_names[result.nat_type];

    if (sess->cb)
	(*sess->cb)(sess->user_data, &result);

    delay.sec = 0;
    delay.msec = 0;

    sess->timer.id = TIMER_DESTROY;
    pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay);
}


/*
 * Callback upon receiving packet from network.
 */
static void on_read_complete(pj_ioqueue_key_t *key, 
                             pj_ioqueue_op_key_t *op_key, 
                             pj_ssize_t bytes_read)
{
    nat_detect_session *sess;
    pj_status_t status;

    sess = (nat_detect_session *) pj_ioqueue_get_user_data(key);
    pj_assert(sess != NULL);

    pj_mutex_lock(sess->mutex);

    if (bytes_read < 0) {
	if (-bytes_read != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) &&
	    -bytes_read != PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) && 
	    -bytes_read != PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) 
	{
	    /* Permanent error */
	    end_session(sess, (pj_status_t)-bytes_read, 
			PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
	    goto on_return;
	}

    } else if (bytes_read > 0) {
	pj_stun_session_on_rx_pkt(sess->stun_sess, sess->rx_pkt, bytes_read,
				  PJ_STUN_IS_DATAGRAM|PJ_STUN_CHECK_PACKET, 
				  NULL, NULL, 
				  &sess->src_addr, sess->src_addr_len);
    }


    sess->rx_pkt_len = sizeof(sess->rx_pkt);
    sess->src_addr_len = sizeof(sess->src_addr);
    status = pj_ioqueue_recvfrom(key, op_key, sess->rx_pkt, &sess->rx_pkt_len,
				 PJ_IOQUEUE_ALWAYS_ASYNC, 
				 &sess->src_addr, &sess->src_addr_len);

    if (status != PJ_EPENDING) {
	pj_assert(status != PJ_SUCCESS);
	end_session(sess, status, PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
    }

on_return:
    pj_mutex_unlock(sess->mutex);
}


/*
 * Callback to send outgoing packet from STUN session.
 */
static pj_status_t on_send_msg(pj_stun_session *stun_sess,
			       void *token,
			       const void *pkt,
			       pj_size_t pkt_size,
			       const pj_sockaddr_t *dst_addr,
			       unsigned addr_len)
{
    nat_detect_session *sess;
    pj_ssize_t pkt_len;
    pj_status_t status;

    PJ_UNUSED_ARG(token);

    sess = (nat_detect_session*) pj_stun_session_get_user_data(stun_sess);

    pkt_len = pkt_size;
    status = pj_ioqueue_sendto(sess->key, &sess->write_op, pkt, &pkt_len, 0,
			       dst_addr, addr_len);

    return status;

}

/*
 * Callback upon request completion.
 */
static void on_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)
{
    nat_detect_session *sess;
    pj_stun_sockaddr_attr *mattr = NULL;
    pj_stun_changed_addr_attr *ca = NULL;
    pj_uint32_t *tsx_id;
    int cmp;
    unsigned test_id;

    PJ_UNUSED_ARG(token);
    PJ_UNUSED_ARG(tdata);
    PJ_UNUSED_ARG(src_addr);
    PJ_UNUSED_ARG(src_addr_len);

    sess = (nat_detect_session*) pj_stun_session_get_user_data(stun_sess);

    pj_mutex_lock(sess->mutex);

    /* Find errors in the response */
    if (status == PJ_SUCCESS) {

	/* Check error message */
	if (PJ_STUN_IS_ERROR_RESPONSE(response->hdr.type)) {
	    pj_stun_errcode_attr *eattr;
	    int err_code;

	    eattr = (pj_stun_errcode_attr*)
		    pj_stun_msg_find_attr(response, PJ_STUN_ATTR_ERROR_CODE, 0);

	    if (eattr != NULL)
		err_code = eattr->err_code;
	    else
		err_code = PJ_STUN_SC_SERVER_ERROR;

	    status = PJ_STATUS_FROM_STUN_CODE(err_code);


	} else {

	    /* Get MAPPED-ADDRESS or XOR-MAPPED-ADDRESS */
	    mattr = (pj_stun_sockaddr_attr*)
		    pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0);
	    if (mattr == NULL) {
		mattr = (pj_stun_sockaddr_attr*)
			pj_stun_msg_find_attr(response, PJ_STUN_ATTR_MAPPED_ADDR, 0);
	    }

	    if (mattr == NULL) {
		status = PJNATH_ESTUNNOMAPPEDADDR;
	    }

	    /* Get CHANGED-ADDRESS attribute */
	    ca = (pj_stun_changed_addr_attr*)
		 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_CHANGED_ADDR, 0);

	    if (ca == NULL) {
		status = PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_SERVER_ERROR);
	    }

	}
    }

    /* Save the result */
    tsx_id = (pj_uint32_t*) tdata->msg->hdr.tsx_id;
    test_id = tsx_id[2];

    if (test_id >= ST_MAX) {
	PJ_LOG(4,(sess->pool->obj_name, "Invalid transaction ID %u in response",
		  test_id));
	end_session(sess, PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_SERVER_ERROR),
		    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
	goto on_return;
    }

    PJ_LOG(5,(sess->pool->obj_name, "Completed %s, status=%d",
	      test_names[test_id], status));

    sess->result[test_id].complete = PJ_TRUE;
    sess->result[test_id].status = status;
    if (status == PJ_SUCCESS) {
	pj_memcpy(&sess->result[test_id].ma, &mattr->sockaddr.ipv4,
		  sizeof(pj_sockaddr_in));
	pj_memcpy(&sess->result[test_id].ca, &ca->sockaddr.ipv4,
		  sizeof(pj_sockaddr_in));
    }

    /* Send Test 1B only when Test 2 completes. Must not send Test 1B
     * before Test 2 completes to avoid creating mapping on the NAT.
     */
    if (!sess->result[ST_TEST_1B].executed && 
	sess->result[ST_TEST_2].complete &&
	sess->result[ST_TEST_2].status != PJ_SUCCESS &&
	sess->result[ST_TEST_1].complete &&
	sess->result[ST_TEST_1].status == PJ_SUCCESS) 
    {
	cmp = pj_memcmp(&sess->local_addr, &sess->result[ST_TEST_1].ma,
			sizeof(pj_sockaddr_in));
	if (cmp != 0)
	    send_test(sess, ST_TEST_1B, &sess->result[ST_TEST_1].ca, 0);
    }

    if (test_completed(sess)<3 || test_completed(sess)!=test_executed(sess))
	goto on_return;

    /* Handle the test result according to RFC 3489 page 22:


                        +--------+
                        |  Test  |
                        |   1    |
                        +--------+
                             |
                             |
                             V
                            /\              /\
                         N /  \ Y          /  \ Y             +--------+
          UDP     <-------/Resp\--------->/ IP \------------->|  Test  |
          Blocked         \ ?  /          \Same/              |   2    |
                           \  /            \? /               +--------+
                            \/              \/                    |
                                             | N                  |
                                             |                    V
                                             V                    /\
                                         +--------+  Sym.      N /  \
                                         |  Test  |  UDP    <---/Resp\
                                         |   2    |  Firewall   \ ?  /
                                         +--------+              \  /
                                             |                    \/
                                             V                     |Y
                  /\                         /\                    |
   Symmetric  N  /  \       +--------+   N  /  \                   V
      NAT  <--- / IP \<-----|  Test  |<--- /Resp\               Open
                \Same/      |   1B   |     \ ?  /               Internet
                 \? /       +--------+      \  /
                  \/                         \/
                  |                           |Y
                  |                           |
                  |                           V
                  |                           Full
                  |                           Cone
                  V              /\
              +--------+        /  \ Y
              |  Test  |------>/Resp\---->Restricted
              |   3    |       \ ?  /
              +--------+        \  /
                                 \/
                                  |N
                                  |       Port
                                  +------>Restricted

                 Figure 2: Flow for type discovery process
     */

    switch (sess->result[ST_TEST_1].status) {
    case PJNATH_ESTUNTIMEDOUT:
	/*
	 * Test 1 has timed-out. Conclude with NAT_TYPE_BLOCKED. 
	 */
	end_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_BLOCKED);
	break;
    case PJ_SUCCESS:
	/*
	 * Test 1 is successful. Further tests are needed to detect
	 * NAT type. Compare the MAPPED-ADDRESS with the local address.
	 */
	cmp = pj_memcmp(&sess->local_addr, &sess->result[ST_TEST_1].ma,
			sizeof(pj_sockaddr_in));
	if (cmp==0) {
	    /*
	     * MAPPED-ADDRESS and local address is equal. Need one more
	     * test to determine NAT type.
	     */
	    switch (sess->result[ST_TEST_2].status) {
	    case PJ_SUCCESS:
		/*
		 * Test 2 is also successful. We're in the open.
		 */
		end_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_OPEN);
		break;
	    case PJNATH_ESTUNTIMEDOUT:
		/*
		 * Test 2 has timed out. We're behind somekind of UDP
		 * firewall.
		 */
		end_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_SYMMETRIC_UDP);
		break;
	    default:
		/*
		 * We've got other error with Test 2.
		 */
		end_session(sess, sess->result[ST_TEST_2].status, 
			    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
		break;
	    }
	} else {
	    /*
	     * MAPPED-ADDRESS is different than local address.
	     * We're behind NAT.
	     */
	    switch (sess->result[ST_TEST_2].status) {
	    case PJ_SUCCESS:
		/*
		 * Test 2 is successful. We're behind a full-cone NAT.
		 */
		end_session(sess, PJ_SUCCESS, PJ_STUN_NAT_TYPE_FULL_CONE);
		break;
	    case PJNATH_ESTUNTIMEDOUT:
		/*
		 * Test 2 has timed-out Check result of test 1B..
		 */
		switch (sess->result[ST_TEST_1B].status) {
		case PJ_SUCCESS:
		    /*
		     * Compare the MAPPED-ADDRESS of test 1B with the
		     * MAPPED-ADDRESS returned in test 1..
		     */
		    cmp = pj_memcmp(&sess->result[ST_TEST_1].ma,
				    &sess->result[ST_TEST_1B].ma,
				    sizeof(pj_sockaddr_in));
		    if (cmp != 0) {
			/*
			 * MAPPED-ADDRESS is different, we're behind a
			 * symmetric NAT.
			 */
			end_session(sess, PJ_SUCCESS,
				    PJ_STUN_NAT_TYPE_SYMMETRIC);
		    } else {
			/*
			 * MAPPED-ADDRESS is equal. We're behind a restricted
			 * or port-restricted NAT, depending on the result of
			 * test 3.
			 */
			switch (sess->result[ST_TEST_3].status) {
			case PJ_SUCCESS:
			    /*
			     * Test 3 is successful, we're behind a restricted
			     * NAT.
			     */
			    end_session(sess, PJ_SUCCESS,
					PJ_STUN_NAT_TYPE_RESTRICTED);
			    break;
			case PJNATH_ESTUNTIMEDOUT:
			    /*
			     * Test 3 failed, we're behind a port restricted
			     * NAT.
			     */
			    end_session(sess, PJ_SUCCESS,
					PJ_STUN_NAT_TYPE_PORT_RESTRICTED);
			    break;
			default:
			    /*
			     * Got other error with test 3.
			     */
			    end_session(sess, sess->result[ST_TEST_3].status,
					PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
			    break;
			}
		    }
		    break;
		case PJNATH_ESTUNTIMEDOUT:
		    /*
		     * Strangely test 1B has failed. Maybe connectivity was
		     * lost? Or perhaps port 3489 (the usual port number in
		     * CHANGED-ADDRESS) is blocked?
		     */
		    switch (sess->result[ST_TEST_3].status) {
		    case PJ_SUCCESS:
			/* Although test 1B failed, test 3 was successful.
			 * It could be that port 3489 is blocked, while the
			 * NAT itself looks to be a Restricted one.
			 */
			end_session(sess, PJ_SUCCESS, 
				    PJ_STUN_NAT_TYPE_RESTRICTED);
			break;
		    default:
			/* Can't distinguish between Symmetric and Port
			 * Restricted, so set the type to Unknown
			 */
			end_session(sess, PJ_SUCCESS, 
				    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
			break;
		    }
		    break;
		default:
		    /*
		     * Got other error with test 1B.
		     */
		    end_session(sess, sess->result[ST_TEST_1B].status,
				PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
		    break;
		}
		break;
	    default:
		/*
		 * We've got other error with Test 2.
		 */
		end_session(sess, sess->result[ST_TEST_2].status, 
			    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
		break;
	    }
	}
	break;
    default:
	/*
	 * We've got other error with Test 1.
	 */
	end_session(sess, sess->result[ST_TEST_1].status, 
		    PJ_STUN_NAT_TYPE_ERR_UNKNOWN);
	break;
    }

on_return:
    pj_mutex_unlock(sess->mutex);
}


/* Perform test */
static pj_status_t send_test(nat_detect_session *sess,
			     enum test_type test_id,
			     const pj_sockaddr_in *alt_addr,
			     pj_uint32_t change_flag)
{
    pj_uint32_t magic, tsx_id[3];
    pj_status_t status;

    sess->result[test_id].executed = PJ_TRUE;

    /* Randomize tsx id */
    do {
	magic = pj_rand();
    } while (magic == PJ_STUN_MAGIC);

    tsx_id[0] = pj_rand();
    tsx_id[1] = pj_rand();
    tsx_id[2] = test_id;

    /* Create BIND request */
    status = pj_stun_session_create_req(sess->stun_sess, 
					PJ_STUN_BINDING_REQUEST, magic,
					(pj_uint8_t*)tsx_id, 
					&sess->result[test_id].tdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Add CHANGE-REQUEST attribute */
    status = pj_stun_msg_add_uint_attr(sess->pool, 
				       sess->result[test_id].tdata->msg,
				       PJ_STUN_ATTR_CHANGE_REQUEST,
				       change_flag);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Configure alternate address */
    if (alt_addr)
	sess->cur_server = (pj_sockaddr_in*) alt_addr;
    else
	sess->cur_server = &sess->server;

    PJ_LOG(5,(sess->pool->obj_name, 
              "Performing %s to %s:%d", 
	      test_names[test_id],
	      pj_inet_ntoa(sess->cur_server->sin_addr),
	      pj_ntohs(sess->cur_server->sin_port)));

    /* Send the request */
    status = pj_stun_session_send_msg(sess->stun_sess, NULL, PJ_TRUE,
				      PJ_TRUE, sess->cur_server, 
				      sizeof(pj_sockaddr_in),
				      sess->result[test_id].tdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    return PJ_SUCCESS;

on_error:
    sess->result[test_id].complete = PJ_TRUE;
    sess->result[test_id].status = status;

    return status;
}


/* Timer callback */
static void on_sess_timer(pj_timer_heap_t *th,
			     pj_timer_entry *te)
{
    nat_detect_session *sess;

    sess = (nat_detect_session*) te->user_data;

    if (te->id == TIMER_DESTROY) {
	pj_mutex_lock(sess->mutex);
	pj_ioqueue_unregister(sess->key);
	sess->key = NULL;
	sess->sock = PJ_INVALID_SOCKET;
	te->id = 0;
	pj_mutex_unlock(sess->mutex);

	sess_destroy(sess);

    } else if (te->id == TIMER_TEST) {

	pj_bool_t next_timer;

	pj_mutex_lock(sess->mutex);

	next_timer = PJ_FALSE;

	if (sess->timer_executed == 0) {
	    send_test(sess, ST_TEST_1, NULL, 0);
	    next_timer = PJ_TRUE;
	} else if (sess->timer_executed == 1) {
	    send_test(sess, ST_TEST_2, NULL, CHANGE_IP_PORT_FLAG);
	    next_timer = PJ_TRUE;
	} else if (sess->timer_executed == 2) {
	    send_test(sess, ST_TEST_3, NULL, CHANGE_PORT_FLAG);
	} else {
	    pj_assert(!"Shouldn't have timer at this state");
	}

	++sess->timer_executed;

	if (next_timer) {
	    pj_time_val delay = {0, TEST_INTERVAL};
	    pj_timer_heap_schedule(th, te, &delay);
	} else {
	    te->id = 0;
	}

	pj_mutex_unlock(sess->mutex);

    } else {
	pj_assert(!"Invalid timer ID");
    }
}

