summaryrefslogtreecommitdiffstats
path: root/src/plugins/tlsopenssl/tls_openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/tlsopenssl/tls_openssl.c')
-rw-r--r--src/plugins/tlsopenssl/tls_openssl.c211
1 files changed, 169 insertions, 42 deletions
diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c
index c8e685f20c5..d7adbed3269 100644
--- a/src/plugins/tlsopenssl/tls_openssl.c
+++ b/src/plugins/tlsopenssl/tls_openssl.c
@@ -74,9 +74,16 @@ openssl_ctx_free (tls_ctx_t * ctx)
SSL_free (oc->ssl);
vec_free (ctx->srv_hostname);
SSL_CTX_free (oc->client_ssl_ctx);
-#ifdef HAVE_OPENSSL_ASYNC
- openssl_evt_free (ctx->evt_index, ctx->c_thread_index);
-#endif
+
+ if (openssl_main.async)
+ {
+ openssl_evt_free (oc->evt_index[SSL_ASYNC_EVT_INIT],
+ ctx->c_thread_index);
+ openssl_evt_free (oc->evt_index[SSL_ASYNC_EVT_RD],
+ ctx->c_thread_index);
+ openssl_evt_free (oc->evt_index[SSL_ASYNC_EVT_WR],
+ ctx->c_thread_index);
+ }
}
pool_put_index (openssl_main.ctx_pool[ctx->c_thread_index],
@@ -159,17 +166,43 @@ openssl_lctx_get (u32 lctx_index)
return pool_elt_at_index (openssl_main.lctx_pool, lctx_index);
}
-#define ossl_check_err_is_fatal(_ssl, _rv) \
- if (PREDICT_FALSE (_rv < 0 && SSL_get_error (_ssl, _rv) == SSL_ERROR_SSL)) \
- return -1;
-
static int
-openssl_read_from_ssl_into_fifo (svm_fifo_t *f, SSL *ssl, u32 max_len)
+openssl_handle_want_async (tls_ctx_t *ctx, int evt_type,
+ transport_send_params_t *sp, int size)
+{
+ int ret;
+ openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
+
+ if (evt_type >= SSL_ASYNC_EVT_MAX || evt_type == 0)
+ {
+ clib_warning ("return 0 [illegal evt_type value:%d]\n", evt_type);
+ return 0;
+ }
+
+ if (evt_type == SSL_ASYNC_EVT_WR)
+ {
+ /* de-schedule transport connection */
+ transport_connection_deschedule (&ctx->connection);
+ sp->flags |= TRANSPORT_SND_F_DESCHED;
+ oc->total_async_write = size;
+ }
+ ret = vpp_tls_async_enqueue_event (oc, evt_type, sp, size);
+
+ return ret;
+}
+
+int
+openssl_read_from_ssl_into_fifo (svm_fifo_t *f, tls_ctx_t *ctx, u32 max_len)
{
int read, rv, n_fs, i;
+ openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
const int n_segs = 2;
svm_fifo_seg_t fs[n_segs];
u32 max_enq;
+ SSL *ssl = oc->ssl;
+
+ if (ctx->flags & TLS_CONN_F_ASYNC_RD)
+ return 0;
max_enq = svm_fifo_max_enqueue_prod (f);
if (!max_enq)
@@ -184,6 +217,12 @@ openssl_read_from_ssl_into_fifo (svm_fifo_t *f, SSL *ssl, u32 max_len)
read = SSL_read (ssl, fs[0].data, fs[0].len);
if (read <= 0)
{
+ if (openssl_main.async && SSL_want_async (oc->ssl))
+ {
+ ctx->flags |= TLS_CONN_F_ASYNC_RD;
+ openssl_handle_want_async (ctx, SSL_ASYNC_EVT_RD, NULL, 0);
+ return 0;
+ }
ossl_check_err_is_fatal (ssl, read);
return 0;
}
@@ -208,11 +247,14 @@ openssl_read_from_ssl_into_fifo (svm_fifo_t *f, SSL *ssl, u32 max_len)
}
static int
-openssl_write_from_fifo_into_ssl (svm_fifo_t *f, SSL *ssl, u32 max_len)
+openssl_write_from_fifo_into_ssl (svm_fifo_t *f, tls_ctx_t *ctx,
+ transport_send_params_t *sp, u32 max_len)
{
int wrote = 0, rv, i = 0, len;
u32 n_segs = 2;
svm_fifo_seg_t fs[n_segs];
+ openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
+ SSL *ssl = oc->ssl;
len = svm_fifo_segments (f, 0, fs, &n_segs, max_len);
if (len <= 0)
@@ -230,6 +272,11 @@ openssl_write_from_fifo_into_ssl (svm_fifo_t *f, SSL *ssl, u32 max_len)
i++;
}
+ if (openssl_main.async && SSL_want_async (ssl))
+ {
+ openssl_handle_want_async (ctx, SSL_ASYNC_EVT_WR, sp, max_len);
+ return 0;
+ }
if (wrote)
svm_fifo_dequeue_drop (f, wrote);
@@ -247,11 +294,15 @@ openssl_check_async_status (tls_ctx_t * ctx, openssl_resume_handler * handler,
SSL_get_async_status (oc->ssl, &estatus);
if (estatus == ASYNC_STATUS_EAGAIN)
{
- vpp_tls_async_update_event (ctx, 1);
+ vpp_tls_async_update_event (ctx, 1, SSL_ASYNC_EVT_INIT);
+ vpp_tls_async_update_event (ctx, 1, SSL_ASYNC_EVT_RD);
+ vpp_tls_async_update_event (ctx, 1, SSL_ASYNC_EVT_WR);
}
else
{
- vpp_tls_async_update_event (ctx, 0);
+ vpp_tls_async_update_event (ctx, 0, SSL_ASYNC_EVT_INIT);
+ vpp_tls_async_update_event (ctx, 0, SSL_ASYNC_EVT_RD);
+ vpp_tls_async_update_event (ctx, 0, SSL_ASYNC_EVT_WR);
}
return 1;
@@ -260,8 +311,8 @@ openssl_check_async_status (tls_ctx_t * ctx, openssl_resume_handler * handler,
#endif
-static void
-openssl_handle_handshake_failure (tls_ctx_t * ctx)
+void
+openssl_handle_handshake_failure (tls_ctx_t *ctx)
{
/* Failed to renegotiate handshake */
if (ctx->flags & TLS_CONN_F_HS_DONE)
@@ -304,19 +355,17 @@ openssl_ctx_handshake_rx (tls_ctx_t * ctx, session_t * tls_session)
rv = SSL_do_handshake (oc->ssl);
err = SSL_get_error (oc->ssl, rv);
-#ifdef HAVE_OPENSSL_ASYNC
- if (err == SSL_ERROR_WANT_ASYNC)
+ if (openssl_main.async && err == SSL_ERROR_WANT_ASYNC)
{
- openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
- tls_session);
+ openssl_handle_want_async (ctx, SSL_ASYNC_EVT_INIT, NULL, 0);
+ return -1;
}
-#endif
+
if (err == SSL_ERROR_SSL)
{
char buf[512];
ERR_error_string (ERR_get_error (), buf);
clib_warning ("Err: %s", buf);
-
openssl_handle_handshake_failure (ctx);
return -1;
}
@@ -385,8 +434,8 @@ openssl_ctx_handshake_rx (tls_ctx_t * ctx, session_t * tls_session)
return rv;
}
-static void
-openssl_confirm_app_close (tls_ctx_t * ctx)
+void
+openssl_confirm_app_close (tls_ctx_t *ctx)
{
openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
SSL_shutdown (oc->ssl);
@@ -425,7 +474,7 @@ openssl_ctx_write_tls (tls_ctx_t *ctx, session_t *app_session,
if (svm_fifo_provision_chunks (ts->tx_fifo, 0, 0, deq_max + TLSO_CTRL_BYTES))
goto check_tls_fifo;
- wrote = openssl_write_from_fifo_into_ssl (f, oc->ssl, deq_max);
+ wrote = openssl_write_from_fifo_into_ssl (f, ctx, sp, deq_max);
/* Unrecoverable protocol error. Reset connection */
if (PREDICT_FALSE (wrote < 0))
@@ -556,7 +605,7 @@ openssl_ctx_read_tls (tls_ctx_t *ctx, session_t *tls_session)
app_session = session_get_from_handle (ctx->app_session_handle);
f = app_session->rx_fifo;
- read = openssl_read_from_ssl_into_fifo (f, oc->ssl, max_len);
+ read = openssl_read_from_ssl_into_fifo (f, ctx, max_len);
/* Unrecoverable protocol error. Reset connection */
if (PREDICT_FALSE (read < 0))
@@ -753,10 +802,9 @@ openssl_ctx_init_client (tls_ctx_t * ctx)
SSL_CTX_set_ecdh_auto (oc->client_ssl_ctx, 1);
SSL_CTX_set_mode (oc->client_ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
-#ifdef HAVE_OPENSSL_ASYNC
if (om->async)
SSL_CTX_set_mode (oc->client_ssl_ctx, SSL_MODE_ASYNC);
-#endif
+
rv =
SSL_CTX_set_cipher_list (oc->client_ssl_ctx, (const char *) om->ciphers);
if (rv != 1)
@@ -801,7 +849,17 @@ openssl_ctx_init_client (tls_ctx_t * ctx)
{
TLS_DBG (1, "Couldn't set client certificate-key pair");
}
-
+ /* Set TLS Record size */
+ if (om->record_size)
+ {
+ rv = SSL_CTX_set_max_send_fragment (oc->client_ssl_ctx, om->record_size);
+ if (rv != 1)
+ {
+ TLS_DBG (1, "Couldn't set TLS record-size");
+ return -1;
+ }
+ TLS_DBG (1, "Using TLS record-size of %d", om->record_size);
+ }
/*
* 2. Do the first steps in the handshake.
*/
@@ -810,7 +868,7 @@ openssl_ctx_init_client (tls_ctx_t * ctx)
#ifdef HAVE_OPENSSL_ASYNC
session_t *tls_session = session_get_from_handle (ctx->tls_session_handle);
- vpp_tls_async_init_event (ctx, openssl_ctx_handshake_rx, tls_session);
+ vpp_tls_async_init_events (ctx, openssl_ctx_handshake_rx, tls_session);
#endif
while (1)
{
@@ -828,7 +886,7 @@ openssl_ctx_init_client (tls_ctx_t * ctx)
break;
}
- TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
+ TLS_DBG (2, "tls state for [%u]%u is %s", ctx->c_thread_index,
oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
return 0;
}
@@ -895,6 +953,39 @@ openssl_start_listen (tls_ctx_t * lctx)
return -1;
}
+ /* Set TLS Record size */
+ if (om->record_size)
+ {
+ rv = SSL_CTX_set_max_send_fragment (ssl_ctx, om->record_size);
+ if (rv != 1)
+ {
+ TLS_DBG (1, "Couldn't set TLS record-size");
+ return -1;
+ }
+ }
+
+ /* Set TLS Record Split size */
+ if (om->record_split_size)
+ {
+ rv = SSL_CTX_set_split_send_fragment (ssl_ctx, om->record_split_size);
+ if (rv != 1)
+ {
+ TLS_DBG (1, "Couldn't set TLS record-split-size");
+ return -1;
+ }
+ }
+
+ /* Set TLS Max Pipeline count */
+ if (om->max_pipelines)
+ {
+ rv = SSL_CTX_set_max_pipelines (ssl_ctx, om->max_pipelines);
+ if (rv != 1)
+ {
+ TLS_DBG (1, "Couldn't set TLS max-pipelines");
+ return -1;
+ }
+ }
+
/*
* Set the key and cert
*/
@@ -1012,22 +1103,23 @@ openssl_ctx_init_server (tls_ctx_t * ctx)
TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
oc->openssl_ctx_index);
-#ifdef HAVE_OPENSSL_ASYNC
- session_t *tls_session = session_get_from_handle (ctx->tls_session_handle);
- vpp_tls_async_init_event (ctx, openssl_ctx_handshake_rx, tls_session);
-#endif
+ if (openssl_main.async)
+ {
+ session_t *tls_session =
+ session_get_from_handle (ctx->tls_session_handle);
+ vpp_tls_async_init_events (ctx, openssl_ctx_handshake_rx, tls_session);
+ }
+
while (1)
{
rv = SSL_do_handshake (oc->ssl);
err = SSL_get_error (oc->ssl, rv);
-#ifdef HAVE_OPENSSL_ASYNC
- if (err == SSL_ERROR_WANT_ASYNC)
+ if (openssl_main.async && err == SSL_ERROR_WANT_ASYNC)
{
- openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
- tls_session);
+ openssl_handle_want_async (ctx, SSL_ASYNC_EVT_INIT, NULL, 0);
+
break;
}
-#endif
if (err != SSL_ERROR_WANT_WRITE)
break;
}
@@ -1040,10 +1132,8 @@ openssl_ctx_init_server (tls_ctx_t * ctx)
static int
openssl_transport_close (tls_ctx_t * ctx)
{
-#ifdef HAVE_OPENSSL_ASYNC
- if (vpp_openssl_is_inflight (ctx))
+ if (openssl_main.async && vpp_openssl_is_inflight (ctx))
return 0;
-#endif
if (!(ctx->flags & TLS_CONN_F_HS_DONE))
{
@@ -1224,7 +1314,6 @@ VLIB_INIT_FUNCTION (tls_openssl_init) =
.runs_after = VLIB_INITS("tls_init"),
};
-#ifdef HAVE_OPENSSL_ASYNC
static clib_error_t *
tls_openssl_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
@@ -1302,7 +1391,45 @@ VLIB_CLI_COMMAND (tls_openssl_set_command, static) =
.short_help = "tls openssl set [engine <engine name>] [alg [algorithm] [async]",
.function = tls_openssl_set_command_fn,
};
-#endif
+
+static clib_error_t *
+tls_openssl_set_tls_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ openssl_main_t *om = &openssl_main;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "record-size %U", unformat_memory_size,
+ &om->record_size))
+ {
+ clib_warning ("Using TLS record-size of %d", om->record_size);
+ }
+ else if (unformat (input, "record-split-size %U", unformat_memory_size,
+ &om->record_split_size))
+ {
+ clib_warning ("Using TLS record-split-size of %d",
+ om->record_split_size);
+ }
+ else if (unformat (input, "max-pipelines %U", unformat_memory_size,
+ &om->max_pipelines))
+ {
+ clib_warning ("Using TLS max-pipelines of %d", om->max_pipelines);
+ }
+ else
+ return clib_error_return (0, "failed: unknown input `%U'",
+ format_unformat_error, input);
+ }
+
+ return 0;
+}
+
+VLIB_CLI_COMMAND (tls_openssl_set_tls, static) = {
+ .path = "tls openssl set-tls",
+ .short_help = "tls openssl set-tls [record-size <size>] [record-split-size "
+ "<size>] [max-pipelines <size>]",
+ .function = tls_openssl_set_tls_fn,
+};
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,