Type: improvement
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: If5eed7dac4951f0510a4b4b092f66f44d0d3cacd
return pool_elt_at_index (openssl_main.lctx_pool, 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)
{
static int
openssl_read_from_ssl_into_fifo (svm_fifo_t * f, SSL * ssl)
{
/* Return early if we can't read anything */
read = SSL_read (ssl, fs[0].data, fs[0].len);
if (read <= 0)
/* Return early if we can't read anything */
read = SSL_read (ssl, fs[0].data, fs[0].len);
if (read <= 0)
+ {
+ ossl_check_err_is_fatal (ssl, read);
+ return 0;
+ }
for (i = 1; i < n_fs; i++)
{
for (i = 1; i < n_fs; i++)
{
read += rv > 0 ? rv : 0;
if (rv < (int) fs[i].len)
read += rv > 0 ? rv : 0;
if (rv < (int) fs[i].len)
+ {
+ ossl_check_err_is_fatal (ssl, rv);
+ break;
+ }
}
svm_fifo_enqueue_nocopy (f, read);
}
svm_fifo_enqueue_nocopy (f, read);
rv = SSL_write (ssl, fs[i].data, fs[i].len);
wrote += (rv > 0) ? rv : 0;
if (rv < (int) fs[i].len)
rv = SSL_write (ssl, fs[i].data, fs[i].len);
wrote += (rv > 0) ? rv : 0;
if (rv < (int) fs[i].len)
+ {
+ ossl_check_err_is_fatal (ssl, rv);
+ break;
+ }
goto check_tls_fifo;
wrote = openssl_write_from_fifo_into_ssl (f, oc->ssl, deq_max);
goto check_tls_fifo;
wrote = openssl_write_from_fifo_into_ssl (f, oc->ssl, deq_max);
+
+ /* Unrecoverable protocol error. Reset connection */
+ if (PREDICT_FALSE (wrote < 0))
+ {
+ tls_notify_app_io_error (ctx);
+ return 0;
+ }
+
if (!wrote)
goto check_tls_fifo;
if (!wrote)
goto check_tls_fifo;
read = openssl_read_from_ssl_into_fifo (f, oc->ssl);
read = openssl_read_from_ssl_into_fifo (f, oc->ssl);
+ /* Unrecoverable protocol error. Reset connection */
+ if (PREDICT_FALSE (read < 0))
+ {
+ tls_notify_app_io_error (ctx);
+ return 0;
+ }
+
/* If handshake just completed, session may still be in accepting state */
if (read && app_session->session_state >= SESSION_STATE_READY)
tls_notify_app_enqueue (ctx, app_session);
/* If handshake just completed, session may still be in accepting state */
if (read && app_session->session_state >= SESSION_STATE_READY)
tls_notify_app_enqueue (ctx, app_session);
return tls_vfts[ctx->tls_ctx_engine].ctx_handshake_is_over (ctx);
}
return tls_vfts[ctx->tls_ctx_engine].ctx_handshake_is_over (ctx);
}
+void
+tls_notify_app_io_error (tls_ctx_t *ctx)
+{
+ ASSERT (tls_ctx_handshake_is_over (ctx));
+
+ session_transport_reset_notify (&ctx->connection);
+ session_transport_closed_notify (&ctx->connection);
+ tls_disconnect_transport (ctx);
+}
+
void
tls_session_reset_callback (session_t * s)
{
void
tls_session_reset_callback (session_t * s)
{
int tls_notify_app_accept (tls_ctx_t * ctx);
int tls_notify_app_connected (tls_ctx_t * ctx, session_error_t err);
void tls_notify_app_enqueue (tls_ctx_t * ctx, session_t * app_session);
int tls_notify_app_accept (tls_ctx_t * ctx);
int tls_notify_app_connected (tls_ctx_t * ctx, session_error_t err);
void tls_notify_app_enqueue (tls_ctx_t * ctx, session_t * app_session);
+void tls_notify_app_io_error (tls_ctx_t *ctx);
void tls_disconnect_transport (tls_ctx_t * ctx);
#endif /* SRC_VNET_TLS_TLS_H_ */
void tls_disconnect_transport (tls_ctx_t * ctx);
#endif /* SRC_VNET_TLS_TLS_H_ */