tls: limit openssl engine max read burst
[vpp.git] / src / plugins / tlsopenssl / tls_openssl.c
index 1e35f9d..a3e93e1 100644 (file)
@@ -40,7 +40,8 @@ openssl_ctx_alloc_w_thread (u32 thread_index)
   openssl_main_t *om = &openssl_main;
   openssl_ctx_t **ctx;
 
-  pool_get (om->ctx_pool[thread_index], ctx);
+  pool_get_aligned_safe (om->ctx_pool[thread_index], ctx, 0);
+
   if (!(*ctx))
     *ctx = clib_mem_alloc (sizeof (openssl_ctx_t));
 
@@ -99,7 +100,7 @@ openssl_ctx_attach (u32 thread_index, void *ctx_ptr)
   session_handle_t sh;
   openssl_ctx_t **oc;
 
-  pool_get (om->ctx_pool[thread_index], oc);
+  pool_get_aligned_safe (om->ctx_pool[thread_index], oc, 0);
   /* Free the old instance instead of looking for an empty spot */
   if (*oc)
     clib_mem_free (*oc);
@@ -162,7 +163,7 @@ openssl_lctx_get (u32 lctx_index)
     return -1;
 
 static int
-openssl_read_from_ssl_into_fifo (svm_fifo_t * f, SSL * ssl)
+openssl_read_from_ssl_into_fifo (svm_fifo_t *f, SSL *ssl, u32 max_len)
 {
   int read, rv, n_fs, i;
   const int n_segs = 2;
@@ -173,6 +174,7 @@ openssl_read_from_ssl_into_fifo (svm_fifo_t * f, SSL * ssl)
   if (!max_enq)
     return 0;
 
+  max_enq = clib_min (max_len, max_enq);
   n_fs = svm_fifo_provision_chunks (f, fs, n_segs, max_enq);
   if (n_fs < 0)
     return 0;
@@ -185,18 +187,20 @@ openssl_read_from_ssl_into_fifo (svm_fifo_t * f, SSL * ssl)
       return 0;
     }
 
-  for (i = 1; i < n_fs; i++)
+  if (read == (int) fs[0].len)
     {
-      rv = SSL_read (ssl, fs[i].data, fs[i].len);
-      read += rv > 0 ? rv : 0;
-
-      if (rv < (int) fs[i].len)
+      for (i = 1; i < n_fs; i++)
        {
-         ossl_check_err_is_fatal (ssl, rv);
-         break;
+         rv = SSL_read (ssl, fs[i].data, 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);
 
   return read;
@@ -270,10 +274,10 @@ openssl_handle_handshake_failure (tls_ctx_t * ctx)
       if (app_session)
        {
          session_free (app_session);
-         ctx->no_app_session = 1;
          ctx->c_s_index = SESSION_INVALID_INDEX;
          tls_disconnect_transport (ctx);
        }
+      ctx->no_app_session = 1;
     }
   else
     {
@@ -530,9 +534,10 @@ static inline int
 openssl_ctx_read_tls (tls_ctx_t *ctx, session_t *tls_session)
 {
   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
+  const u32 max_len = 128 << 10;
   session_t *app_session;
-  int read;
   svm_fifo_t *f;
+  int read;
 
   if (PREDICT_FALSE (SSL_in_init (oc->ssl)))
     {
@@ -546,7 +551,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);
+  read = openssl_read_from_ssl_into_fifo (f, oc->ssl, max_len);
 
   /* Unrecoverable protocol error. Reset connection */
   if (PREDICT_FALSE (read < 0))