forked from enlightenment/efl
yet another ecore_con overhaul!
*internal function rename *******finally fix ssl handshaking to be non-blocking SVN revision: 52665
This commit is contained in:
parent
e7392af747
commit
60b4269b5f
|
@ -1266,7 +1266,7 @@ _ecore_con_client_free(Ecore_Con_Client *cl)
|
|||
}
|
||||
|
||||
static void
|
||||
kill_server(Ecore_Con_Server *svr)
|
||||
_ecore_con_server_kill(Ecore_Con_Server *svr)
|
||||
{
|
||||
if (!svr->delete_me)
|
||||
{
|
||||
|
@ -1385,7 +1385,7 @@ _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *net_info)
|
|||
|
||||
error:
|
||||
ecore_con_ssl_server_shutdown(svr);
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1461,7 +1461,7 @@ _ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *net_info)
|
|||
|
||||
error:
|
||||
ecore_con_ssl_server_shutdown(svr);
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1523,8 +1523,13 @@ _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info)
|
|||
svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
|
||||
_ecore_con_cl_handler, svr, NULL, NULL);
|
||||
|
||||
if ((svr->type & ECORE_CON_SSL) && (ecore_con_ssl_server_init(svr)))
|
||||
if (svr->type & ECORE_CON_SSL)
|
||||
{
|
||||
svr->handshaking = EINA_TRUE;
|
||||
svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
|
||||
if (ecore_con_ssl_server_init(svr))
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!svr->fd_handler)
|
||||
goto error;
|
||||
|
@ -1535,7 +1540,7 @@ _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info)
|
|||
|
||||
error:
|
||||
ecore_con_ssl_server_shutdown(svr);
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1586,7 +1591,7 @@ _ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *net_info)
|
|||
|
||||
error:
|
||||
ecore_con_ssl_server_shutdown(svr);
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
}
|
||||
|
||||
static Ecore_Con_State
|
||||
|
@ -1616,7 +1621,7 @@ svr_try_connect_plain(Ecore_Con_Server *svr)
|
|||
if (so_err != 0)
|
||||
{
|
||||
/* we lost our server! */
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
return ECORE_CON_DISCONNECTED;
|
||||
}
|
||||
|
||||
|
@ -1658,7 +1663,7 @@ static Ecore_Con_State svr_try_connect(Ecore_Con_Server *svr)
|
|||
return svr_try_connect_plain(svr);
|
||||
|
||||
case ECORE_CON_DISCONNECTED:
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
return ECORE_CON_DISCONNECTED;
|
||||
|
||||
default:
|
||||
|
@ -1740,8 +1745,13 @@ _ecore_con_svr_tcp_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
|
|||
cl->fd = new_fd;
|
||||
cl->host_server = svr;
|
||||
|
||||
if ((svr->type & ECORE_CON_SSL) && (ecore_con_ssl_client_init(cl)))
|
||||
if (svr->type & ECORE_CON_SSL)
|
||||
{
|
||||
cl->handshaking = EINA_TRUE;
|
||||
cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
|
||||
if (ecore_con_ssl_client_init(cl))
|
||||
goto error;
|
||||
}
|
||||
|
||||
cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
|
||||
_ecore_con_svr_cl_handler, cl, NULL, NULL);
|
||||
|
@ -1751,7 +1761,7 @@ _ecore_con_svr_tcp_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
|
|||
if (!svr->path)
|
||||
cl->ip = _ecore_con_pretty_ip((struct sockaddr *)&incoming, size_in);
|
||||
|
||||
if (!cl->delete_me)
|
||||
if ((!cl->delete_me) && (!cl->handshaking))
|
||||
{
|
||||
Ecore_Con_Event_Client_Add *e;
|
||||
|
||||
|
@ -1818,7 +1828,7 @@ _ecore_con_cl_read(Ecore_Con_Server *svr)
|
|||
}
|
||||
|
||||
if (lost_server)
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1851,6 +1861,17 @@ _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
|||
if (svr->delete_me)
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
|
||||
if (svr->handshaking)
|
||||
{
|
||||
if (ecore_con_ssl_server_init(svr))
|
||||
{
|
||||
ERR("ssl handshaking failed!");
|
||||
ecore_main_fd_handler_del(svr->fd_handler);
|
||||
close(svr->fd);
|
||||
}
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
|
||||
_ecore_con_cl_read(svr);
|
||||
else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
|
||||
|
@ -1912,7 +1933,7 @@ _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
|||
else if ((errno == EIO) || (errno == EBADF) ||
|
||||
(errno == EPIPE) || (errno == EINVAL) ||
|
||||
(errno == ENOSPC) || (errno == ECONNREFUSED))
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
}
|
||||
else if (ecore_main_fd_handler_active_get(fd_handler,
|
||||
ECORE_FD_WRITE))
|
||||
|
@ -2153,6 +2174,17 @@ _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
|||
if (cl->delete_me)
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
|
||||
if (cl->handshaking)
|
||||
{
|
||||
if (ecore_con_ssl_client_init(cl))
|
||||
{
|
||||
ERR("ssl handshaking failed!");
|
||||
ecore_main_fd_handler_del(cl->fd_handler);
|
||||
close(cl->fd);
|
||||
}
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
|
||||
_ecore_con_svr_cl_read(cl);
|
||||
|
||||
|
@ -2189,7 +2221,7 @@ _ecore_con_server_flush(Ecore_Con_Server *svr)
|
|||
if (count < 1)
|
||||
{
|
||||
/* we lost our server! */
|
||||
kill_server(svr);
|
||||
_ecore_con_server_kill(svr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,13 @@ typedef enum _Ecore_Con_Ssl_Error
|
|||
ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED
|
||||
} Ecore_Con_Ssl_Error;
|
||||
|
||||
typedef enum _Ecore_Con_Ssl_Handshake
|
||||
{
|
||||
ECORE_CON_SSL_STATE_DONE = 0,
|
||||
ECORE_CON_SSL_STATE_HANDSHAKING,
|
||||
ECORE_CON_SSL_STATE_INIT
|
||||
} Ecore_Con_Ssl_State;
|
||||
|
||||
struct _Ecore_Con_Client
|
||||
{
|
||||
ECORE_MAGIC;
|
||||
|
@ -98,6 +105,8 @@ struct _Ecore_Con_Client
|
|||
SSL *ssl;
|
||||
int ssl_err;
|
||||
#endif
|
||||
Eina_Bool handshaking : 1;
|
||||
Ecore_Con_Ssl_State ssl_state;
|
||||
Eina_Bool dead : 1;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
@ -139,6 +148,8 @@ struct _Ecore_Con_Server
|
|||
Eina_Bool dead : 1;
|
||||
Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */
|
||||
Eina_Bool connecting : 1;
|
||||
Eina_Bool handshaking : 1; /* EINA_TRUE if server is ssl handshaking */
|
||||
Ecore_Con_Ssl_State ssl_state;
|
||||
Eina_Bool reject_excess_clients : 1;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
|
|
@ -362,7 +362,11 @@ _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
|
|||
GNUTLS_SSL3,
|
||||
0
|
||||
};
|
||||
|
||||
switch (svr->ssl_state)
|
||||
{
|
||||
case ECORE_CON_SSL_STATE_DONE:
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
case ECORE_CON_SSL_STATE_INIT:
|
||||
if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
|
||||
return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
|
||||
|
||||
|
@ -406,12 +410,18 @@ _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
|
|||
|
||||
gnutls_dh_set_prime_bits(svr->session, 512);
|
||||
gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd);
|
||||
|
||||
do
|
||||
{
|
||||
svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
|
||||
case ECORE_CON_SSL_STATE_HANDSHAKING:
|
||||
ret = gnutls_handshake(svr->session);
|
||||
SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
|
||||
} while (ret < 0);
|
||||
if (!ret)
|
||||
{
|
||||
svr->handshaking = EINA_FALSE;
|
||||
svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
|
||||
|
@ -581,7 +591,11 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
|
|||
GNUTLS_TLS1_0,
|
||||
GNUTLS_SSL3,
|
||||
0 };
|
||||
|
||||
switch (cl->ssl_state)
|
||||
{
|
||||
case ECORE_CON_SSL_STATE_DONE:
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
case ECORE_CON_SSL_STATE_INIT:
|
||||
if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
|
||||
return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
|
||||
|
||||
|
@ -626,12 +640,19 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
|
|||
|
||||
gnutls_dh_set_prime_bits(cl->session, 2048);
|
||||
gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
|
||||
|
||||
do
|
||||
{
|
||||
cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
|
||||
case ECORE_CON_SSL_STATE_HANDSHAKING:
|
||||
ret = gnutls_handshake(cl->session);
|
||||
SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
|
||||
} while (ret < 0);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
cl->handshaking = EINA_FALSE;
|
||||
cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: add cert verification support */
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
|
@ -875,31 +896,42 @@ error:
|
|||
static Ecore_Con_Ssl_Error
|
||||
_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
|
||||
{
|
||||
int ret = -1;
|
||||
int err, ret = -1;
|
||||
|
||||
switch (svr->ssl_state)
|
||||
{
|
||||
case ECORE_CON_SSL_STATE_DONE:
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
case ECORE_CON_SSL_STATE_INIT:
|
||||
SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx)));
|
||||
|
||||
SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd));
|
||||
SSL_set_connect_state(svr->ssl);
|
||||
|
||||
do
|
||||
{
|
||||
int err;
|
||||
svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
|
||||
case ECORE_CON_SSL_STATE_HANDSHAKING:
|
||||
ret = SSL_do_handshake(svr->ssl);
|
||||
err = SSL_get_error(svr->ssl, ret);
|
||||
SSL_ERROR_CHECK_GOTO_ERROR((err == SSL_ERROR_SYSCALL) || (err == SSL_ERROR_SSL));
|
||||
} while (ret < 1);
|
||||
|
||||
if (ret == 1)
|
||||
{
|
||||
svr->handshaking = EINA_FALSE;
|
||||
svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
|
||||
error:
|
||||
do
|
||||
{
|
||||
unsigned long err;
|
||||
unsigned long sslerr;
|
||||
|
||||
err = ERR_get_error();
|
||||
if (!err) break;
|
||||
ERR("openssl error: %s", ERR_reason_error_string(err));
|
||||
sslerr = ERR_get_error();
|
||||
if (!sslerr) break;
|
||||
ERR("openssl error: %s", ERR_reason_error_string(sslerr));
|
||||
} while (1);
|
||||
_ecore_con_ssl_server_shutdown_openssl(svr);
|
||||
return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
|
||||
|
@ -1078,30 +1110,40 @@ _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, unsigned char *buf,
|
|||
static Ecore_Con_Ssl_Error
|
||||
_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
|
||||
{
|
||||
int ret = -1;
|
||||
int err, ret = -1;
|
||||
switch (cl->ssl_state)
|
||||
{
|
||||
case ECORE_CON_SSL_STATE_DONE:
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
case ECORE_CON_SSL_STATE_INIT:
|
||||
SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx)));
|
||||
|
||||
SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd));
|
||||
SSL_set_accept_state(cl->ssl);
|
||||
|
||||
do
|
||||
{
|
||||
int err;
|
||||
cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
|
||||
case ECORE_CON_SSL_STATE_HANDSHAKING:
|
||||
ret = SSL_do_handshake(cl->ssl);
|
||||
err = SSL_get_error(cl->ssl, ret);
|
||||
SSL_ERROR_CHECK_GOTO_ERROR((err == SSL_ERROR_SYSCALL) || (err == SSL_ERROR_SSL));
|
||||
} while (ret < 1);
|
||||
if (ret == 1)
|
||||
{
|
||||
cl->handshaking = EINA_FALSE;
|
||||
cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
|
||||
error:
|
||||
do
|
||||
{
|
||||
unsigned long err;
|
||||
unsigned long sslerr;
|
||||
|
||||
err = ERR_get_error();
|
||||
if (!err) break;
|
||||
ERR("openssl error: %s", ERR_reason_error_string(err));
|
||||
sslerr = ERR_get_error();
|
||||
if (!sslerr) break;
|
||||
ERR("openssl error: %s", ERR_reason_error_string(sslerr));
|
||||
} while (1);
|
||||
_ecore_con_ssl_client_shutdown_openssl(cl);
|
||||
return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
|
||||
|
|
Loading…
Reference in New Issue