/* $Id$ */
/* 
 * Copyright (C) 2008-2009 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 "test.h"
#include <pjlib.h>


#define CERT_DIR		    "../build/"
#define CERT_CA_FILE		    CERT_DIR "cacert.pem"
#define CERT_FILE		    CERT_DIR "cacert.pem"
#define CERT_PRIVKEY_FILE	    CERT_DIR "privkey.pem"
#define CERT_PRIVKEY_PASS	    ""


#if INCLUDE_SSLSOCK_TEST

/* Global vars */
static int clients_num;

struct send_key {
    pj_ioqueue_op_key_t	op_key;
};


static int get_cipher_list(void) {
    pj_status_t status;
    pj_ssl_cipher ciphers[100];
    unsigned cipher_num;
    unsigned i;

    cipher_num = PJ_ARRAY_SIZE(ciphers);
    status = pj_ssl_cipher_get_availables(ciphers, &cipher_num);
    if (status != PJ_SUCCESS) {
	app_perror("...FAILED to get available ciphers", status);
	return status;
    }

    PJ_LOG(3, ("", "...Found %u ciphers:", cipher_num));
    for (i = 0; i < cipher_num; ++i) {
	const char* st;
	st = pj_ssl_cipher_name(ciphers[i]);
	if (st == NULL)
	    st = "[Unknown]";

	PJ_LOG(3, ("", "...%3u: 0x%08x=%s", i+1, ciphers[i], st));
    }

    return PJ_SUCCESS;
}


struct test_state
{
    pj_pool_t	   *pool;	    /* pool				    */
    pj_ioqueue_t   *ioqueue;	    /* ioqueue				    */
    pj_bool_t	    is_server;	    /* server role flag			    */
    pj_bool_t	    is_verbose;	    /* verbose flag, e.g: cert info	    */
    pj_bool_t	    echo;	    /* echo received data		    */
    pj_status_t	    err;	    /* error flag			    */
    unsigned	    sent;	    /* bytes sent			    */
    unsigned	    recv;	    /* bytes received			    */
    pj_uint8_t	    read_buf[256];  /* read buffer			    */
    pj_bool_t	    done;	    /* test done flag			    */
    char	   *send_str;	    /* data to send once connected	    */
    unsigned	    send_str_len;   /* send data length			    */
    pj_bool_t	    check_echo;	    /* flag to compare sent & echoed data   */
    const char	   *check_echo_ptr; /* pointer/cursor for comparing data    */
    struct send_key send_key;	    /* send op key			    */
};

static void dump_ssl_info(const pj_ssl_sock_info *si)
{
    const char *tmp_st;

    /* Print cipher name */
    tmp_st = pj_ssl_cipher_name(si->cipher);
    if (tmp_st == NULL)
	tmp_st = "[Unknown]";
    PJ_LOG(3, ("", ".....Cipher: %s", tmp_st));

    /* Print remote certificate info and verification result */
    if (si->remote_cert_info && si->remote_cert_info->subject.info.slen) 
    {
	char buf[2048];
	const char *verif_msgs[32];
	unsigned verif_msg_cnt;

	/* Dump remote TLS certificate info */
	PJ_LOG(3, ("", ".....Remote certificate info:"));
	pj_ssl_cert_info_dump(si->remote_cert_info, "  ", buf, sizeof(buf));
	PJ_LOG(3,("", "\n%s", buf));

	/* Dump remote TLS certificate verification result */
	verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs);
	pj_ssl_cert_get_verify_status_strings(si->verify_status,
					      verif_msgs, &verif_msg_cnt);
	PJ_LOG(3,("", ".....Remote certificate verification result: %s",
		  (verif_msg_cnt == 1? verif_msgs[0]:"")));
	if (verif_msg_cnt > 1) {
	    unsigned i;
	    for (i = 0; i < verif_msg_cnt; ++i)
		PJ_LOG(3,("", "..... - %s", verif_msgs[i]));
	}
    }
}


static pj_bool_t ssl_on_connect_complete(pj_ssl_sock_t *ssock,
					 pj_status_t status)
{
    struct test_state *st = (struct test_state*) 
		    	    pj_ssl_sock_get_user_data(ssock);
    void *read_buf[1];
    pj_ssl_sock_info info;
    char buf1[64], buf2[64];

    if (status != PJ_SUCCESS) {
	app_perror("...ERROR ssl_on_connect_complete()", status);
	goto on_return;
    }

    status = pj_ssl_sock_get_info(ssock, &info);
    if (status != PJ_SUCCESS) {
	app_perror("...ERROR pj_ssl_sock_get_info()", status);
	goto on_return;
    }

    pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf1, sizeof(buf1), 1);
    pj_sockaddr_print((pj_sockaddr_t*)&info.remote_addr, buf2, sizeof(buf2), 1);
    PJ_LOG(3, ("", "...Connected %s -> %s!", buf1, buf2));

    if (st->is_verbose)
	dump_ssl_info(&info);

    /* Start reading data */
    read_buf[0] = st->read_buf;
    status = pj_ssl_sock_start_read2(ssock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
    if (status != PJ_SUCCESS) {
	app_perror("...ERROR pj_ssl_sock_start_read2()", status);
	goto on_return;
    }

    /* Start sending data */
    while (st->sent < st->send_str_len) {
	pj_ssize_t size;

	size = st->send_str_len - st->sent;
	status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, 
				  st->send_str + st->sent, &size, 0);
	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	    app_perror("...ERROR pj_ssl_sock_send()", status);
	    goto on_return;
	}

	if (status == PJ_SUCCESS)
	    st->sent += size;
	else
	    break;
    }

on_return:
    st->err = status;

    if (st->err != PJ_SUCCESS) {
	pj_ssl_sock_close(ssock);
	clients_num--;
	return PJ_FALSE;
    }

    return PJ_TRUE;
}


static pj_bool_t ssl_on_accept_complete(pj_ssl_sock_t *ssock,
					pj_ssl_sock_t *newsock,
					const pj_sockaddr_t *src_addr,
					int src_addr_len)
{
    struct test_state *parent_st = (struct test_state*) 
				   pj_ssl_sock_get_user_data(ssock);
    struct test_state *st;
    void *read_buf[1];
    pj_ssl_sock_info info;
    char buf[64];
    pj_status_t status;

    PJ_UNUSED_ARG(src_addr_len);

    /* Duplicate parent test state to newly accepted test state */
    st = (struct test_state*)pj_pool_zalloc(parent_st->pool, sizeof(struct test_state));
    *st = *parent_st;
    pj_ssl_sock_set_user_data(newsock, st);

    status = pj_ssl_sock_get_info(newsock, &info);
    if (status != PJ_SUCCESS) {
	app_perror("...ERROR pj_ssl_sock_get_info()", status);
	goto on_return;
    }

    pj_sockaddr_print(src_addr, buf, sizeof(buf), 1);
    PJ_LOG(3, ("", "...Accepted connection from %s", buf));

    if (st->is_verbose)
	dump_ssl_info(&info);

    /* Start reading data */
    read_buf[0] = st->read_buf;
    status = pj_ssl_sock_start_read2(newsock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
    if (status != PJ_SUCCESS) {
	app_perror("...ERROR pj_ssl_sock_start_read2()", status);
	goto on_return;
    }

    /* Start sending data */
    while (st->sent < st->send_str_len) {
	pj_ssize_t size;

	size = st->send_str_len - st->sent;
	status = pj_ssl_sock_send(newsock, (pj_ioqueue_op_key_t*)&st->send_key, 
				  st->send_str + st->sent, &size, 0);
	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	    app_perror("...ERROR pj_ssl_sock_send()", status);
	    goto on_return;
	}

	if (status == PJ_SUCCESS)
	    st->sent += size;
	else
	    break;
    }

on_return:
    st->err = status;

    if (st->err != PJ_SUCCESS) {
	pj_ssl_sock_close(newsock);
	return PJ_FALSE;
    }

    return PJ_TRUE;
}

static pj_bool_t ssl_on_data_read(pj_ssl_sock_t *ssock,
				  void *data,
				  pj_size_t size,
				  pj_status_t status,
				  pj_size_t *remainder)
{
    struct test_state *st = (struct test_state*) 
			     pj_ssl_sock_get_user_data(ssock);

    PJ_UNUSED_ARG(remainder);
    PJ_UNUSED_ARG(data);

    if (size > 0) {
	pj_size_t consumed;

	/* Set random remainder */
	*remainder = pj_rand() % 100;

	/* Apply zero remainder if:
	 * - remainder is less than size, or
	 * - connection closed/error
	 * - echo/check_eco set
	 */
	if (*remainder > size || status != PJ_SUCCESS || st->echo || st->check_echo)
	    *remainder = 0;

	consumed = size - *remainder;
	st->recv += consumed;

	//printf("%.*s", consumed, (char*)data);

	pj_memmove(data, (char*)data + consumed, *remainder);

	/* Echo data when specified to */
	if (st->echo) {
	    pj_ssize_t size_ = consumed;
	    status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, data, &size_, 0);
	    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
		app_perror("...ERROR pj_ssl_sock_send()", status);
		goto on_return;
	    }

	    if (status == PJ_SUCCESS)
		st->sent += size_;
	}

	/* Verify echoed data when specified to */
	if (st->check_echo) {
	    if (!st->check_echo_ptr)
		st->check_echo_ptr = st->send_str;

	    if (pj_memcmp(st->check_echo_ptr, data, consumed)) {
		status = PJ_EINVAL;
		app_perror("...ERROR echoed data not exact", status);
		goto on_return;
	    }
	    st->check_echo_ptr += consumed;

	    /* Echo received completely */
	    if (st->send_str_len == st->recv) {
		pj_ssl_sock_info info;
		char buf[64];

		status = pj_ssl_sock_get_info(ssock, &info);
		if (status != PJ_SUCCESS) {
		    app_perror("...ERROR pj_ssl_sock_get_info()", status);
		    goto on_return;
		}

		pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf, sizeof(buf), 1);
		PJ_LOG(3, ("", "...%s successfully recv %d bytes echo", buf, st->recv));
		st->done = PJ_TRUE;
	    }
	}
    }

    if (status != PJ_SUCCESS) {
	if (status == PJ_EEOF) {
	    status = PJ_SUCCESS;
	    st->done = PJ_TRUE;
	} else {
	    app_perror("...ERROR ssl_on_data_read()", status);
	}
    }

on_return:
    st->err = status;

    if (st->err != PJ_SUCCESS || st->done) {
	pj_ssl_sock_close(ssock);
	if (!st->is_server)
	    clients_num--;
	return PJ_FALSE;
    }

    return PJ_TRUE;
}

static pj_bool_t ssl_on_data_sent(pj_ssl_sock_t *ssock,
				  pj_ioqueue_op_key_t *op_key,
				  pj_ssize_t sent)
{
    struct test_state *st = (struct test_state*)
			     pj_ssl_sock_get_user_data(ssock);
    PJ_UNUSED_ARG(op_key);

    if (sent < 0) {
	st->err = -sent;
    } else {
	st->sent += sent;

	/* Send more if any */
	while (st->sent < st->send_str_len) {
	    pj_ssize_t size;
	    pj_status_t status;

	    size = st->send_str_len - st->sent;
	    status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, 
				      st->send_str + st->sent, &size, 0);
	    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
		app_perror("...ERROR pj_ssl_sock_send()", status);
		st->err = status;
		break;
	    }

	    if (status == PJ_SUCCESS)
		st->sent += size;
	    else
		break;
	}
    }

    if (st->err != PJ_SUCCESS) {
	pj_ssl_sock_close(ssock);
	if (!st->is_server)
	    clients_num--;
	return PJ_FALSE;
    }

    return PJ_TRUE;
}

#define HTTP_REQ		"GET / HTTP/1.0\r\n\r\n";
#define HTTP_SERVER_ADDR	"trac.pjsip.org"
#define HTTP_SERVER_PORT	443

static int https_client_test(unsigned ms_timeout)
{
    pj_pool_t *pool = NULL;
    pj_ioqueue_t *ioqueue = NULL;
    pj_timer_heap_t *timer = NULL;
    pj_ssl_sock_t *ssock = NULL;
    pj_ssl_sock_param param;
    pj_status_t status;
    struct test_state state = {0};
    pj_sockaddr local_addr, rem_addr;
    pj_str_t tmp_st;

    pool = pj_pool_create(mem, "https_get", 256, 256, NULL);

    status = pj_ioqueue_create(pool, 4, &ioqueue);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_timer_heap_create(pool, 4, &timer);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    state.pool = pool;
    state.send_str = HTTP_REQ;
    state.send_str_len = pj_ansi_strlen(state.send_str);
    state.is_verbose = PJ_TRUE;

    pj_ssl_sock_param_default(&param);
    param.cb.on_connect_complete = &ssl_on_connect_complete;
    param.cb.on_data_read = &ssl_on_data_read;
    param.cb.on_data_sent = &ssl_on_data_sent;
    param.ioqueue = ioqueue;
    param.user_data = &state;
    param.server_name = pj_str((char*)HTTP_SERVER_ADDR);
    param.timer_heap = timer;
    param.timeout.sec = 0;
    param.timeout.msec = ms_timeout;
    param.proto = PJ_SSL_SOCK_PROTO_SSL23;
    pj_time_val_normalize(&param.timeout);

    status = pj_ssl_sock_create(pool, &param, &ssock);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    pj_sockaddr_init(PJ_AF_INET, &local_addr, pj_strset2(&tmp_st, "0.0.0.0"), 0);
    pj_sockaddr_init(PJ_AF_INET, &rem_addr, pj_strset2(&tmp_st, HTTP_SERVER_ADDR), HTTP_SERVER_PORT);
    status = pj_ssl_sock_start_connect(ssock, pool, &local_addr, &rem_addr, sizeof(rem_addr));
    if (status == PJ_SUCCESS) {
	ssl_on_connect_complete(ssock, PJ_SUCCESS);
    } else if (status == PJ_EPENDING) {
	status = PJ_SUCCESS;
    } else {
	goto on_return;
    }

    /* Wait until everything has been sent/received */
    while (state.err == PJ_SUCCESS && !state.done) {
#ifdef PJ_SYMBIAN
	pj_symbianos_poll(-1, 1000);
#else
	pj_time_val delay = {0, 100};
	pj_ioqueue_poll(ioqueue, &delay);
	pj_timer_heap_poll(timer, &delay);
#endif
    }

    if (state.err) {
	status = state.err;
	goto on_return;
    }

    PJ_LOG(3, ("", "...Done!"));
    PJ_LOG(3, ("", ".....Sent/recv: %d/%d bytes", state.sent, state.recv));

on_return:
    if (ssock && !state.err && !state.done) 
	pj_ssl_sock_close(ssock);
    if (ioqueue)
	pj_ioqueue_destroy(ioqueue);
    if (timer)
	pj_timer_heap_destroy(timer);
    if (pool)
	pj_pool_release(pool);

    return status;
}


static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
		     pj_ssl_cipher srv_cipher, pj_ssl_cipher cli_cipher,
		     pj_bool_t req_client_cert, pj_bool_t client_provide_cert)
{
    pj_pool_t *pool = NULL;
    pj_ioqueue_t *ioqueue = NULL;
    pj_ssl_sock_t *ssock_serv = NULL;
    pj_ssl_sock_t *ssock_cli = NULL;
    pj_ssl_sock_param param;
    struct test_state state_serv = { 0 };
    struct test_state state_cli = { 0 };
    pj_sockaddr addr, listen_addr;
    pj_ssl_cipher ciphers[1];
    pj_ssl_cert_t *cert = NULL;
    pj_status_t status;

    pool = pj_pool_create(mem, "ssl_echo", 256, 256, NULL);

    status = pj_ioqueue_create(pool, 4, &ioqueue);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    pj_ssl_sock_param_default(&param);
    param.cb.on_accept_complete = &ssl_on_accept_complete;
    param.cb.on_connect_complete = &ssl_on_connect_complete;
    param.cb.on_data_read = &ssl_on_data_read;
    param.cb.on_data_sent = &ssl_on_data_sent;
    param.ioqueue = ioqueue;
    param.ciphers = ciphers;

    /* Init default bind address */
    {
	pj_str_t tmp_st;
	pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
    }

    /* === SERVER === */
    param.proto = srv_proto;
    param.user_data = &state_serv;
    param.ciphers_num = (srv_cipher == -1)? 0 : 1;
    param.require_client_cert = req_client_cert;
    ciphers[0] = srv_cipher;

    state_serv.pool = pool;
    state_serv.echo = PJ_TRUE;
    state_serv.is_server = PJ_TRUE;
    state_serv.is_verbose = PJ_TRUE;

    status = pj_ssl_sock_create(pool, &param, &ssock_serv);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Set server cert */
    {
	pj_str_t tmp1, tmp2, tmp3, tmp4;

	status = pj_ssl_cert_load_from_files(pool, 
					     pj_strset2(&tmp1, (char*)CERT_CA_FILE), 
					     pj_strset2(&tmp2, (char*)CERT_FILE), 
					     pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE), 
					     pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS), 
					     &cert);
	if (status != PJ_SUCCESS) {
	    goto on_return;
	}

	status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
	if (status != PJ_SUCCESS) {
	    goto on_return;
	}
    }

    status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Get listener address */
    {
	pj_ssl_sock_info info;

	pj_ssl_sock_get_info(ssock_serv, &info);
	pj_sockaddr_cp(&listen_addr, &info.local_addr);
    }

    /* === CLIENT === */
    param.proto = cli_proto;
    param.user_data = &state_cli;
    param.ciphers_num = (cli_cipher == -1)? 0 : 1;
    ciphers[0] = cli_cipher;

    state_cli.pool = pool;
    state_cli.check_echo = PJ_TRUE;
    state_cli.is_verbose = PJ_TRUE;

    {
	pj_time_val now;

	pj_gettimeofday(&now);
	pj_srand((unsigned)now.sec);
	state_cli.send_str_len = (pj_rand() % 5 + 1) * 1024 + pj_rand() % 1024;
    }
    state_cli.send_str = (char*)pj_pool_alloc(pool, state_cli.send_str_len);
    {
	unsigned i;
	for (i = 0; i < state_cli.send_str_len; ++i)
	    state_cli.send_str[i] = (char)(pj_rand() % 256);
    }

    status = pj_ssl_sock_create(pool, &param, &ssock_cli);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Set cert for client */
    {

	if (!client_provide_cert) {
	    pj_str_t tmp1, tmp2;

	    pj_strset2(&tmp1, (char*)CERT_CA_FILE);
	    pj_strset2(&tmp2, NULL);
	    status = pj_ssl_cert_load_from_files(pool, 
						 &tmp1, &tmp2, &tmp2, &tmp2,
						 &cert);
	    if (status != PJ_SUCCESS) {
		goto on_return;
	    }
	}

	status = pj_ssl_sock_set_certificate(ssock_cli, pool, cert);
	if (status != PJ_SUCCESS) {
	    goto on_return;
	}
    }

    status = pj_ssl_sock_start_connect(ssock_cli, pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
    if (status == PJ_SUCCESS) {
	ssl_on_connect_complete(ssock_cli, PJ_SUCCESS);
    } else if (status == PJ_EPENDING) {
	status = PJ_SUCCESS;
    } else {
	goto on_return;
    }

    /* Wait until everything has been sent/received or error */
    while (!state_serv.err && !state_cli.err && !state_serv.done && !state_cli.done)
    {
#ifdef PJ_SYMBIAN
	pj_symbianos_poll(-1, 1000);
#else
	pj_time_val delay = {0, 100};
	pj_ioqueue_poll(ioqueue, &delay);
#endif
    }

    /* Clean up sockets */
    {
	pj_time_val delay = {0, 100};
	while (pj_ioqueue_poll(ioqueue, &delay) > 0);
    }

    if (state_serv.err || state_cli.err) {
	if (state_serv.err != PJ_SUCCESS)
	    status = state_serv.err;
	else
	    status = state_cli.err;

	goto on_return;
    }

    PJ_LOG(3, ("", "...Done!"));
    PJ_LOG(3, ("", ".....Sent/recv: %d/%d bytes", state_cli.sent, state_cli.recv));

on_return:
    if (ssock_serv)
	pj_ssl_sock_close(ssock_serv);
    if (ssock_cli && !state_cli.err && !state_cli.done) 
	pj_ssl_sock_close(ssock_cli);
    if (ioqueue)
	pj_ioqueue_destroy(ioqueue);
    if (pool)
	pj_pool_release(pool);

    return status;
}


static pj_bool_t asock_on_data_read(pj_activesock_t *asock,
				    void *data,
				    pj_size_t size,
				    pj_status_t status,
				    pj_size_t *remainder)
{
    struct test_state *st = (struct test_state*)
			     pj_activesock_get_user_data(asock);

    PJ_UNUSED_ARG(data);
    PJ_UNUSED_ARG(size);
    PJ_UNUSED_ARG(remainder);

    if (status != PJ_SUCCESS) {
	if (status == PJ_EEOF) {
	    status = PJ_SUCCESS;
	    st->done = PJ_TRUE;
	} else {
	    app_perror("...ERROR asock_on_data_read()", status);
	}
    }

    st->err = status;

    if (st->err != PJ_SUCCESS || st->done) {
	pj_activesock_close(asock);
	if (!st->is_server)
	    clients_num--;
	return PJ_FALSE;
    }

    return PJ_TRUE;
}


static pj_bool_t asock_on_connect_complete(pj_activesock_t *asock,
					   pj_status_t status)
{
    struct test_state *st = (struct test_state*)
			     pj_activesock_get_user_data(asock);

    if (status == PJ_SUCCESS) {
	void *read_buf[1];

	/* Start reading data */
	read_buf[0] = st->read_buf;
	status = pj_activesock_start_read2(asock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
	if (status != PJ_SUCCESS) {
	    app_perror("...ERROR pj_ssl_sock_start_read2()", status);
	}
    }

    st->err = status;

    if (st->err != PJ_SUCCESS) {
	pj_activesock_close(asock);
	if (!st->is_server)
	    clients_num--;
	return PJ_FALSE;
    }

    return PJ_TRUE;
}

static pj_bool_t asock_on_accept_complete(pj_activesock_t *asock,
					  pj_sock_t newsock,
					  const pj_sockaddr_t *src_addr,
					  int src_addr_len)
{
    struct test_state *st;
    void *read_buf[1];
    pj_activesock_t *new_asock;
    pj_activesock_cb asock_cb = { 0 };
    pj_status_t status;

    PJ_UNUSED_ARG(src_addr);
    PJ_UNUSED_ARG(src_addr_len);

    st = (struct test_state*) pj_activesock_get_user_data(asock);

    asock_cb.on_data_read = &asock_on_data_read;
    status = pj_activesock_create(st->pool, newsock, pj_SOCK_STREAM(), NULL, 
				  st->ioqueue, &asock_cb, st, &new_asock);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Start reading data */
    read_buf[0] = st->read_buf;
    status = pj_activesock_start_read2(new_asock, st->pool, 
				       sizeof(st->read_buf), 
				       (void**)read_buf, 0);
    if (status != PJ_SUCCESS) {
	app_perror("...ERROR pj_ssl_sock_start_read2()", status);
    }

on_return:
    st->err = status;

    if (st->err != PJ_SUCCESS)
	pj_activesock_close(new_asock);

    return PJ_TRUE;
}


/* Raw TCP socket try to connect to SSL socket server, once
 * connection established, it will just do nothing, SSL socket
 * server should be able to close the connection after specified
 * timeout period (set ms_timeout to 0 to disable timer).
 */
static int client_non_ssl(unsigned ms_timeout)
{
    pj_pool_t *pool = NULL;
    pj_ioqueue_t *ioqueue = NULL;
    pj_timer_heap_t *timer = NULL;
    pj_ssl_sock_t *ssock_serv = NULL;
    pj_activesock_t *asock_cli = NULL;
    pj_activesock_cb asock_cb = { 0 };
    pj_sock_t sock = PJ_INVALID_SOCKET;
    pj_ssl_sock_param param;
    struct test_state state_serv = { 0 };
    struct test_state state_cli = { 0 };
    pj_sockaddr listen_addr;
    pj_ssl_cert_t *cert = NULL;
    pj_status_t status;

    pool = pj_pool_create(mem, "ssl_accept_raw_tcp", 256, 256, NULL);

    status = pj_ioqueue_create(pool, 4, &ioqueue);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_timer_heap_create(pool, 4, &timer);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Set cert */
    {
	pj_str_t tmp1, tmp2, tmp3, tmp4;
	status = pj_ssl_cert_load_from_files(pool, 
					     pj_strset2(&tmp1, (char*)CERT_CA_FILE), 
					     pj_strset2(&tmp2, (char*)CERT_FILE), 
					     pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE), 
					     pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS), 
					     &cert);
	if (status != PJ_SUCCESS) {
	    goto on_return;
	}
    }

    pj_ssl_sock_param_default(&param);
    param.cb.on_accept_complete = &ssl_on_accept_complete;
    param.cb.on_data_read = &ssl_on_data_read;
    param.cb.on_data_sent = &ssl_on_data_sent;
    param.ioqueue = ioqueue;
    param.timer_heap = timer;
    param.timeout.sec = 0;
    param.timeout.msec = ms_timeout;
    pj_time_val_normalize(&param.timeout);

    /* SERVER */
    param.user_data = &state_serv;
    state_serv.pool = pool;
    state_serv.is_server = PJ_TRUE;
    state_serv.is_verbose = PJ_TRUE;

    status = pj_ssl_sock_create(pool, &param, &ssock_serv);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Init bind address */
    {
	pj_str_t tmp_st;
	pj_sockaddr_init(PJ_AF_INET, &listen_addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
    }

    status = pj_ssl_sock_start_accept(ssock_serv, pool, &listen_addr, pj_sockaddr_get_len(&listen_addr));
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Update listener address */
    {
	pj_ssl_sock_info info;

	pj_ssl_sock_get_info(ssock_serv, &info);
	pj_sockaddr_cp(&listen_addr, &info.local_addr);
    }

    /* CLIENT */
    state_cli.pool = pool;
    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &sock);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    asock_cb.on_connect_complete = &asock_on_connect_complete;
    asock_cb.on_data_read = &asock_on_data_read;
    status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), NULL, 
				  ioqueue, &asock_cb, &state_cli, &asock_cli);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_activesock_start_connect(asock_cli, pool, (pj_sockaddr_t*)&listen_addr, 
					 pj_sockaddr_get_len(&listen_addr));
    if (status == PJ_SUCCESS) {
	asock_on_connect_complete(asock_cli, PJ_SUCCESS);
    } else if (status == PJ_EPENDING) {
	status = PJ_SUCCESS;
    } else {
	goto on_return;
    }

    /* Wait until everything has been sent/received or error */
    while (!state_serv.err && !state_cli.err && !state_serv.done && !state_cli.done)
    {
#ifdef PJ_SYMBIAN
	pj_symbianos_poll(-1, 1000);
#else
	pj_time_val delay = {0, 100};
	pj_ioqueue_poll(ioqueue, &delay);
	pj_timer_heap_poll(timer, &delay);
#endif
    }

    if (state_serv.err || state_cli.err) {
	if (state_serv.err != PJ_SUCCESS)
	    status = state_serv.err;
	else
	    status = state_cli.err;

	goto on_return;
    }

    PJ_LOG(3, ("", "...Done!"));

on_return:
    if (ssock_serv)
	pj_ssl_sock_close(ssock_serv);
    if (asock_cli && !state_cli.err && !state_cli.done)
	pj_activesock_close(asock_cli);
    if (timer)
	pj_timer_heap_destroy(timer);
    if (ioqueue)
	pj_ioqueue_destroy(ioqueue);
    if (pool)
	pj_pool_release(pool);

    return status;
}


/* SSL socket try to connect to raw TCP socket server, once
 * connection established, SSL socket will try to perform SSL
 * handshake. SSL client socket should be able to close the
 * connection after specified timeout period (set ms_timeout to 
 * 0 to disable timer).
 */
static int server_non_ssl(unsigned ms_timeout)
{
    pj_pool_t *pool = NULL;
    pj_ioqueue_t *ioqueue = NULL;
    pj_timer_heap_t *timer = NULL;
    pj_activesock_t *asock_serv = NULL;
    pj_ssl_sock_t *ssock_cli = NULL;
    pj_activesock_cb asock_cb = { 0 };
    pj_sock_t sock = PJ_INVALID_SOCKET;
    pj_ssl_sock_param param;
    struct test_state state_serv = { 0 };
    struct test_state state_cli = { 0 };
    pj_sockaddr addr, listen_addr;
    pj_status_t status;

    pool = pj_pool_create(mem, "ssl_connect_raw_tcp", 256, 256, NULL);

    status = pj_ioqueue_create(pool, 4, &ioqueue);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_timer_heap_create(pool, 4, &timer);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* SERVER */
    state_serv.pool = pool;
    state_serv.ioqueue = ioqueue;

    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &sock);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Init bind address */
    {
	pj_str_t tmp_st;
	pj_sockaddr_init(PJ_AF_INET, &listen_addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
    }

    status = pj_sock_bind(sock, (pj_sockaddr_t*)&listen_addr, 
			  pj_sockaddr_get_len((pj_sockaddr_t*)&listen_addr));
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_sock_listen(sock, PJ_SOMAXCONN);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    asock_cb.on_accept_complete = &asock_on_accept_complete;
    status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), NULL, 
				  ioqueue, &asock_cb, &state_serv, &asock_serv);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_activesock_start_accept(asock_serv, pool);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Update listener address */
    {
	int addr_len;

	addr_len = sizeof(listen_addr);
	pj_sock_getsockname(sock, (pj_sockaddr_t*)&listen_addr, &addr_len);
    }

    /* CLIENT */
    pj_ssl_sock_param_default(&param);
    param.cb.on_connect_complete = &ssl_on_connect_complete;
    param.cb.on_data_read = &ssl_on_data_read;
    param.cb.on_data_sent = &ssl_on_data_sent;
    param.ioqueue = ioqueue;
    param.timer_heap = timer;
    param.timeout.sec = 0;
    param.timeout.msec = ms_timeout;
    pj_time_val_normalize(&param.timeout);
    param.user_data = &state_cli;

    state_cli.pool = pool;
    state_cli.is_server = PJ_FALSE;
    state_cli.is_verbose = PJ_TRUE;

    status = pj_ssl_sock_create(pool, &param, &ssock_cli);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Init default bind address */
    {
	pj_str_t tmp_st;
	pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
    }

    status = pj_ssl_sock_start_connect(ssock_cli, pool, 
				       (pj_sockaddr_t*)&addr, 
				       (pj_sockaddr_t*)&listen_addr, 
				       pj_sockaddr_get_len(&listen_addr));
    if (status != PJ_EPENDING) {
	goto on_return;
    }

    /* Wait until everything has been sent/received or error */
    while ((!state_serv.err && !state_serv.done) || (!state_cli.err && !state_cli.done))
    {
#ifdef PJ_SYMBIAN
	pj_symbianos_poll(-1, 1000);
#else
	pj_time_val delay = {0, 100};
	pj_ioqueue_poll(ioqueue, &delay);
	pj_timer_heap_poll(timer, &delay);
#endif
    }

    if (state_serv.err || state_cli.err) {
	if (state_cli.err != PJ_SUCCESS)
	    status = state_cli.err;
	else
	    status = state_serv.err;

	goto on_return;
    }

    PJ_LOG(3, ("", "...Done!"));

on_return:
    if (asock_serv)
	pj_activesock_close(asock_serv);
    if (ssock_cli && !state_cli.err && !state_cli.done)
	pj_ssl_sock_close(ssock_cli);
    if (timer)
	pj_timer_heap_destroy(timer);
    if (ioqueue)
	pj_ioqueue_destroy(ioqueue);
    if (pool)
	pj_pool_release(pool);

    return status;
}


/* Test will perform multiple clients trying to connect to single server.
 * Once SSL connection established, echo test will be performed.
 */
static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
{
    pj_pool_t *pool = NULL;
    pj_ioqueue_t *ioqueue = NULL;
    pj_timer_heap_t *timer = NULL;
    pj_ssl_sock_t *ssock_serv = NULL;
    pj_ssl_sock_t **ssock_cli = NULL;
    pj_ssl_sock_param param;
    struct test_state state_serv = { 0 };
    struct test_state *state_cli = NULL;
    pj_sockaddr addr, listen_addr;
    pj_ssl_cert_t *cert = NULL;
    pj_status_t status;
    unsigned i, cli_err = 0, tot_sent = 0, tot_recv = 0;
    pj_time_val start;

    pool = pj_pool_create(mem, "ssl_perf", 256, 256, NULL);

    status = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioqueue);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_timer_heap_create(pool, PJ_IOQUEUE_MAX_HANDLES, &timer);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Set cert */
    {
	pj_str_t tmp1, tmp2, tmp3, tmp4;

	status = pj_ssl_cert_load_from_files(pool, 
					     pj_strset2(&tmp1, (char*)CERT_CA_FILE), 
					     pj_strset2(&tmp2, (char*)CERT_FILE), 
					     pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE), 
					     pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS), 
					     &cert);
	if (status != PJ_SUCCESS) {
	    goto on_return;
	}
    }

    pj_ssl_sock_param_default(&param);
    param.cb.on_accept_complete = &ssl_on_accept_complete;
    param.cb.on_connect_complete = &ssl_on_connect_complete;
    param.cb.on_data_read = &ssl_on_data_read;
    param.cb.on_data_sent = &ssl_on_data_sent;
    param.ioqueue = ioqueue;
    param.timer_heap = timer;
    param.timeout.sec = 0;
    param.timeout.msec = ms_handshake_timeout;
    pj_time_val_normalize(&param.timeout);

    /* Init default bind address */
    {
	pj_str_t tmp_st;
	pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
    }

    /* SERVER */
    param.user_data = &state_serv;

    state_serv.pool = pool;
    state_serv.echo = PJ_TRUE;
    state_serv.is_server = PJ_TRUE;

    status = pj_ssl_sock_create(pool, &param, &ssock_serv);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
    if (status != PJ_SUCCESS) {
	goto on_return;
    }

    /* Get listening address for clients to connect to */
    {
	pj_ssl_sock_info info;
	char buf[64];

	pj_ssl_sock_get_info(ssock_serv, &info);
	pj_sockaddr_cp(&listen_addr, &info.local_addr);

	pj_sockaddr_print((pj_sockaddr_t*)&listen_addr, buf, sizeof(buf), 1);
	PJ_LOG(3, ("", "...Listener ready at %s", buf));
    }


    /* CLIENTS */
    clients_num = clients;
    param.timeout.sec = 0;
    param.timeout.msec = 0;

    /* Init random seed */
    {
	pj_time_val now;

	pj_gettimeofday(&now);
	pj_srand((unsigned)now.sec);
    }

    /* Allocate SSL socket pointers and test state */
    ssock_cli = (pj_ssl_sock_t**)pj_pool_calloc(pool, clients, sizeof(pj_ssl_sock_t*));
    state_cli = (struct test_state*)pj_pool_calloc(pool, clients, sizeof(struct test_state));

    /* Get start timestamp */
    pj_gettimeofday(&start);

    /* Setup clients */
    for (i = 0; i < clients; ++i) {
	param.user_data = &state_cli[i];

	state_cli[i].pool = pool;
	state_cli[i].check_echo = PJ_TRUE;
	state_cli[i].send_str_len = (pj_rand() % 5 + 1) * 1024 + pj_rand() % 1024;
	state_cli[i].send_str = (char*)pj_pool_alloc(pool, state_cli[i].send_str_len);
	{
	    unsigned j;
	    for (j = 0; j < state_cli[i].send_str_len; ++j)
		state_cli[i].send_str[j] = (char)(pj_rand() % 256);
	}

	status = pj_ssl_sock_create(pool, &param, &ssock_cli[i]);
	if (status != PJ_SUCCESS) {
	    app_perror("...ERROR pj_ssl_sock_create()", status);
	    cli_err++;
	    clients_num--;
	    continue;
	}

	status = pj_ssl_sock_start_connect(ssock_cli[i], pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
	if (status == PJ_SUCCESS) {
	    ssl_on_connect_complete(ssock_cli[i], PJ_SUCCESS);
	} else if (status == PJ_EPENDING) {
	    status = PJ_SUCCESS;
	} else {
	    app_perror("...ERROR pj_ssl_sock_create()", status);
	    pj_ssl_sock_close(ssock_cli[i]);
	    ssock_cli[i] = NULL;
	    clients_num--;
	    cli_err++;
	    continue;
	}

	/* Give chance to server to accept this client */
	{
	    unsigned n = 5;

#ifdef PJ_SYMBIAN
	    while(n && pj_symbianos_poll(-1, 1000))
		n--;
#else
	    pj_time_val delay = {0, 100};
	    while(n && pj_ioqueue_poll(ioqueue, &delay) > 0)
		n--;
#endif
	}
    }

    /* Wait until everything has been sent/received or error */
    while (clients_num)
    {
#ifdef PJ_SYMBIAN
	pj_symbianos_poll(-1, 1000);
#else
	pj_time_val delay = {0, 100};
	pj_ioqueue_poll(ioqueue, &delay);
	pj_timer_heap_poll(timer, &delay);
#endif
    }

    /* Clean up sockets */
    {
	pj_time_val delay = {0, 500};
	while (pj_ioqueue_poll(ioqueue, &delay) > 0);
    }

    if (state_serv.err != PJ_SUCCESS) {
	status = state_serv.err;
	goto on_return;
    }

    PJ_LOG(3, ("", "...Done!"));

    /* SSL setup and data transfer duration */
    {
	pj_time_val stop;
	
	pj_gettimeofday(&stop);
	PJ_TIME_VAL_SUB(stop, start);

	PJ_LOG(3, ("", ".....Setup & data transfer duration: %d.%03ds", stop.sec, stop.msec));
    }

    /* Check clients status */
    for (i = 0; i < clients; ++i) {
	if (state_cli[i].err != PJ_SUCCESS)
	    cli_err++;

	tot_sent += state_cli[1].sent;
	tot_recv += state_cli[1].recv;
    }

    PJ_LOG(3, ("", ".....Clients: %d (%d errors)", clients, cli_err));
    PJ_LOG(3, ("", ".....Total sent/recv: %d/%d bytes", tot_sent, tot_recv));

on_return:
    if (ssock_serv) 
	pj_ssl_sock_close(ssock_serv);

    for (i = 0; i < clients; ++i) {
	if (ssock_cli[i] && !state_cli[i].err && !state_cli[i].done)
	    pj_ssl_sock_close(ssock_cli[i]);
    }
    if (ioqueue)
	pj_ioqueue_destroy(ioqueue);
    if (pool)
	pj_pool_release(pool);

    return status;
}


int ssl_sock_test(void)
{
    int ret;

    PJ_LOG(3,("", "..get cipher list test"));
    ret = get_cipher_list();
    if (ret != 0)
	return ret;

    PJ_LOG(3,("", "..https client test"));
    ret = https_client_test(30000);
    // Ignore test result as internet connection may not be available.
    //if (ret != 0)
	//return ret;

#ifndef PJ_SYMBIAN
   
    /* On Symbian platforms, SSL socket is implemented using CSecureSocket, 
     * and it hasn't supported server mode, so exclude the following tests,
     * which require SSL server, for now.
     */

    PJ_LOG(3,("", "..echo test w/ TLSv1 and PJ_TLS_RSA_WITH_DES_CBC_SHA cipher"));
    ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_TLS1, 
		    PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_DES_CBC_SHA, 
		    PJ_FALSE, PJ_FALSE);
    if (ret != 0)
	return ret;

    PJ_LOG(3,("", "..echo test w/ SSLv23 and PJ_TLS_RSA_WITH_AES_256_CBC_SHA cipher"));
    ret = echo_test(PJ_SSL_SOCK_PROTO_SSL23, PJ_SSL_SOCK_PROTO_SSL23, 
		    PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
		    PJ_FALSE, PJ_FALSE);
    if (ret != 0)
	return ret;

    PJ_LOG(3,("", "..echo test w/ incompatible proto"));
    ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_SSL3, 
		    PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_DES_CBC_SHA,
		    PJ_FALSE, PJ_FALSE);
    if (ret == 0)
	return PJ_EBUG;

    PJ_LOG(3,("", "..echo test w/ incompatible ciphers"));
    ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT, 
		    PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
		    PJ_FALSE, PJ_FALSE);
    if (ret == 0)
	return PJ_EBUG;

    PJ_LOG(3,("", "..echo test w/ client cert required but not provided"));
    ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT, 
		    PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
		    PJ_TRUE, PJ_FALSE);
    if (ret == 0)
	return PJ_EBUG;

    PJ_LOG(3,("", "..echo test w/ client cert required and provided"));
    ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT, 
		    PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
		    PJ_TRUE, PJ_TRUE);
    if (ret != 0)
	return ret;

    PJ_LOG(3,("", "..performance test"));
    ret = perf_test(PJ_IOQUEUE_MAX_HANDLES/2 - 1, 0);
    if (ret != 0)
	return ret;

    PJ_LOG(3,("", "..client non-SSL (handshake timeout 5 secs)"));
    ret = client_non_ssl(5000);
    /* PJ_TIMEDOUT won't be returned as accepted socket is deleted silently */
    if (ret != 0)
	return ret;

#endif

    PJ_LOG(3,("", "..server non-SSL (handshake timeout 5 secs)"));
    ret = server_non_ssl(5000);
    if (ret != PJ_ETIMEDOUT)
	return ret;

    return 0;
}

#else	/* INCLUDE_SSLSOCK_TEST */
/* To prevent warning about "translation unit is empty"
 * when this test is disabled. 
 */
int dummy_ssl_sock_test;
#endif	/* INCLUDE_SSLSOCK_TEST */

