static pj_bool_t ssock_on_connect_complete (pj_ssl_sock_t *ssock,
					    pj_status_t status)
{
    unsigned i;

    if (status != PJ_SUCCESS)
	goto on_return;

    /* Update local address */
    ssock->addr_len = sizeof(pj_sockaddr);
    status = get_localaddr(ssock, &ssock->local_addr, &ssock->addr_len);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Create SSL context */
    status = ssl_create(ssock);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Prepare read buffer */
    ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool, 
					       ssock->param.async_cnt,
					       sizeof(void*));
    if (!ssock->asock_rbuf)
        return PJ_ENOMEM;

    for (i = 0; i<ssock->param.async_cnt; ++i) {
	ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
					    ssock->pool, 
					    ssock->param.read_buffer_size + 
					    sizeof(read_data_t*));
        if (!ssock->asock_rbuf[i])
            return PJ_ENOMEM;
    }

    /* Start read */
#ifdef SSL_SOCK_IMP_USE_OWN_NETWORK
    status = network_start_read(ssock, ssock->param.async_cnt,
    				(unsigned)ssock->param.read_buffer_size,
				ssock->asock_rbuf, 0);
#else
    status = pj_activesock_start_read2(ssock->asock, ssock->pool, 
				       (unsigned)ssock->param.read_buffer_size,
				       ssock->asock_rbuf,
				       PJ_IOQUEUE_ALWAYS_ASYNC);
#endif
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Prepare write/send state */
    pj_assert(ssock->send_buf.max_len == 0);
    ssock->send_buf.buf = (char*)
			     pj_pool_alloc(ssock->pool, 
					   ssock->param.send_buffer_size);
    if (!ssock->send_buf.buf)
        return PJ_ENOMEM;

    ssock->send_buf.max_len = ssock->param.send_buffer_size;
    ssock->send_buf.start = ssock->send_buf.buf;
    ssock->send_buf.len = 0;

    /* Set peer name */
    ssl_set_peer_name(ssock);

    /* Start SSL handshake */
    ssock->ssl_state = SSL_STATE_HANDSHAKING;
    ssl_set_state(ssock, PJ_FALSE);

    status = ssl_do_handshake(ssock);
    if (status != PJ_EPENDING)
	goto on_return;

    return PJ_TRUE;

on_return:
    return on_handshake_complete(ssock, status);
}
static pj_bool_t ssock_on_connect_complete (pj_ssl_sock_t *ssock,
					    pj_status_t status)
{
    unsigned i;

    if (status != PJ_SUCCESS)
	goto on_return;

     
    ssock->addr_len = sizeof(pj_sockaddr);
    status = get_localaddr(ssock, &ssock->local_addr, &ssock->addr_len);
    if (status != PJ_SUCCESS)
	goto on_return;

     
    status = ssl_create(ssock);
    if (status != PJ_SUCCESS)
	goto on_return;

     
    ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool, 
					       ssock->param.async_cnt,
					       sizeof(void*));
    if (!ssock->asock_rbuf)
        return PJ_ENOMEM;

    for (i = 0; i<ssock->param.async_cnt; ++i) {
	ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
					    ssock->pool, 
					    ssock->param.read_buffer_size + 
					    sizeof(read_data_t*));
        if (!ssock->asock_rbuf[i])
            return PJ_ENOMEM;
    }

     
#ifdef SSL_SOCK_IMP_USE_OWN_NETWORK
    status = network_start_read(ssock, ssock->param.async_cnt,
    				(unsigned)ssock->param.read_buffer_size,
				ssock->asock_rbuf, 0);
#else
    status = pj_activesock_start_read2(ssock->asock, ssock->pool, 
				       (unsigned)ssock->param.read_buffer_size,
				       ssock->asock_rbuf,
				       PJ_IOQUEUE_ALWAYS_ASYNC);
#endif
    if (status != PJ_SUCCESS)
	goto on_return;

     
    pj_assert(ssock->send_buf.max_len == 0);
    ssock->send_buf.buf = (char*)
			     pj_pool_alloc(ssock->pool, 
					   ssock->param.send_buffer_size);
    if (!ssock->send_buf.buf)
        return PJ_ENOMEM;

    ssock->send_buf.max_len = ssock->param.send_buffer_size;
    ssock->send_buf.start = ssock->send_buf.buf;
    ssock->send_buf.len = 0;

     
    ssl_set_peer_name(ssock);

     
    ssock->ssl_state = SSL_STATE_HANDSHAKING;
    ssl_set_state(ssock, PJ_FALSE);

    status = ssl_do_handshake(ssock);
    if (status != PJ_EPENDING)
	goto on_return;

    return PJ_TRUE;

on_return:
    return on_handshake_complete(ssock, status);
}