1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

wrapper: make SSL_accept nonblocking

The mbedTLS / OpenSSL wrapper spins for the duration of the
handshake, which is a slow 31ms on my x86_64 box (by comparison
it's ~1ms on actual OpenSSL on the same box).

This doesn't change the 31ms but it stops us spinning during the
accept and has us retry on POLLIN instead like OpenSSL.

Note this also fixes the endemic mismatches in returncode
between mbedTLS and OpenSSL semantics...
This commit is contained in:
Andy Green 2017-10-06 21:23:59 +08:00
parent df2dc99c14
commit 46b04f4ba4
4 changed files with 32 additions and 14 deletions

View file

@ -3658,6 +3658,7 @@ lws_stats_log_dump(struct lws_context *context)
lwsl_notice("LWSSTATS_C_WRITEABLE_CB_REQ: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB_REQ));
lwsl_notice("LWSSTATS_C_WRITEABLE_CB_EFF_REQ: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB_EFF_REQ));
lwsl_notice("LWSSTATS_C_WRITEABLE_CB: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB));
lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN));
lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_FAILED: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_FAILED));
lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED));
lwsl_notice("LWSSTATS_C_SSL_CONNS_HAD_RX: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNS_HAD_RX));

View file

@ -5651,6 +5651,7 @@ enum {
LWSSTATS_C_WRITEABLE_CB, /**< count of writable callbacks */
LWSSTATS_C_SSL_CONNECTIONS_FAILED, /**< count of failed SSL connections */
LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, /**< count of accepted SSL connections */
LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN, /**< count of SSL_accept() attempts */
LWSSTATS_C_SSL_CONNS_HAD_RX, /**< count of accepted SSL conns that have had some RX */
LWSSTATS_C_TIMEOUTS, /**< count of timed-out connections */
LWSSTATS_C_SERVICE_ENTRY, /**< count of entries to lws service loop */

View file

@ -279,27 +279,41 @@ int ssl_pm_handshake(SSL *ssl)
if (ret)
return 0;
ssl_speed_up_enter();
if (ssl_pm->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER) {
ssl_speed_up_enter();
while((ret = mbedtls_handshake(&ssl_pm->ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
break;
}
/* mbedtls return codes
* 0 = successful, or MBEDTLS_ERR_SSL_WANT_READ/WRITE
* anything else = death
*/
ret = mbedtls_handshake(&ssl_pm->ssl);
ssl_speed_up_exit();
} else
ret = 0;
/*
* OpenSSL return codes:
* 0 = did not complete, but may be retried
* 1 = successfully completed
* <0 = death
*/
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -ret);
return 0; /* OpenSSL: did not complete but may be retried */
}
ssl_speed_up_exit();
if (ret) {
SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -ret);
ret = 0;
} else {
if (ret == 0) { /* successful */
struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm;
x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl);
ret = 1;
return 1; /* openssl successful */
}
return ret;
/* it's had it */
ssl->err = SSL_ERROR_SYSCALL;
return -1; /* openssl death */
}
int ssl_pm_shutdown(SSL *ssl)

View file

@ -843,7 +843,9 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
if (!wsi->accept_start_us)
wsi->accept_start_us = time_in_microseconds();
#endif
errno = 0;
lws_stats_atomic_bump(wsi->context, pt,
LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN, 1);
n = SSL_accept(wsi->ssl);
lws_latency(context, wsi,
"SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1);