diff --git a/doc/configuration.txt b/doc/configuration.txt index 61376fc78..49bfd858c 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1294,7 +1294,11 @@ ssl-engine [algo ] ssl-mode-async Adds SSL_MODE_ASYNC mode to the SSL context. This enables asynchronous TLS I/O operations if asynchronous capable SSL engines are used. The current - implementation supports a maximum of 32 engines. + implementation supports a maximum of 32 engines. The Openssl ASYNC API + doesn't support moving read/write buffers and is not compliant with + haproxy's buffer management. So the asynchronous mode is disabled on + read/write operations (it is only enabled during initial and reneg + handshakes). tune.buffers.limit Sets a hard limit on the number of buffers which may be allocated per process. diff --git a/src/ssl_sock.c b/src/ssl_sock.c index c8e6b57b6..f9b236a8f 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -4757,6 +4757,15 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag) } reneg_ok: + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + /* ASYNC engine API doesn't support moving read/write + * buffers. So we disable ASYNC mode right after + * the handshake to avoid buffer oveflows. + */ + if (global_ssl.async) + SSL_clear_mode(conn->xprt_ctx, SSL_MODE_ASYNC); +#endif /* Handshake succeeded */ if (!SSL_session_reused(conn->xprt_ctx)) { if (objt_server(conn->target)) { @@ -4875,6 +4884,11 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun /* handshake is running, and it needs to enable write */ conn->flags |= CO_FL_SSL_WAIT_HS; __conn_sock_want_send(conn); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + /* Async mode can be re-enabled, because we're leaving data state.*/ + if (global_ssl.async) + SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC); +#endif break; } else if (ret == SSL_ERROR_WANT_READ) { @@ -4882,18 +4896,17 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun /* handshake is running, and it may need to re-enable read */ conn->flags |= CO_FL_SSL_WAIT_HS; __conn_sock_want_recv(conn); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + /* Async mode can be re-enabled, because we're leaving data state.*/ + if (global_ssl.async) + SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC); +#endif break; } /* we need to poll for retry a read later */ fd_cant_recv(conn->t.sock.fd); break; } -#if OPENSSL_VERSION_NUMBER >= 0x1010000fL - else if (ret == SSL_ERROR_WANT_ASYNC) { - ssl_async_process_fds(conn, conn->xprt_ctx); - break; - } -#endif /* otherwise it's a real error */ goto out_error; } @@ -4984,6 +4997,11 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl /* handshake is running, and it may need to re-enable write */ conn->flags |= CO_FL_SSL_WAIT_HS; __conn_sock_want_send(conn); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + /* Async mode can be re-enabled, because we're leaving data state.*/ + if (global_ssl.async) + SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC); +#endif break; } /* we need to poll to retry a write later */ @@ -4994,14 +5012,13 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl /* handshake is running, and it needs to enable read */ conn->flags |= CO_FL_SSL_WAIT_HS; __conn_sock_want_recv(conn); - break; - } #if OPENSSL_VERSION_NUMBER >= 0x1010000fL - else if (ret == SSL_ERROR_WANT_ASYNC) { - ssl_async_process_fds(conn, conn->xprt_ctx); + /* Async mode can be re-enabled, because we're leaving data state.*/ + if (global_ssl.async) + SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC); +#endif break; } -#endif goto out_error; } }