tls svm: prealloc tcp fifo chunks before ssl write

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I7c47b55ec6f0c83f2d13e0e737d0559a32f7c837
diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c
index dd0f96a..7a840f1 100644
--- a/src/plugins/tlsopenssl/tls_openssl.c
+++ b/src/plugins/tlsopenssl/tls_openssl.c
@@ -382,6 +382,13 @@
 
   deq_max = clib_min (deq_max, sp->max_burst_size);
 
+  /* Make sure tcp's tx fifo can actually buffer all bytes to be dequeued.
+   * If under memory pressure, tls's fifo segment might not be able to
+   * allocate the chunks needed. This also avoids errors from the underlying
+   * custom bio to the ssl infra which at times can get stuck. */
+  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);
   if (!wrote)
     goto check_tls_fifo;
diff --git a/src/svm/svm_fifo.c b/src/svm/svm_fifo.c
index 14eeb1c..2150694 100644
--- a/src/svm/svm_fifo.c
+++ b/src/svm/svm_fifo.c
@@ -1257,6 +1257,9 @@
   if (n_avail < len && f_try_chunk_alloc (f, head, tail, len))
     return SVM_FIFO_EGROW;
 
+  if (!fs || !n_segs)
+    return 0;
+
   c = f_tail_cptr (f);
   head_pos = (tail - c->start_byte);
   fs[0].data = c->data + head_pos;
diff --git a/src/vnet/tls/tls.c b/src/vnet/tls/tls.c
index 6a61df1..1ab885e 100644
--- a/src/vnet/tls/tls.c
+++ b/src/vnet/tls/tls.c
@@ -226,7 +226,8 @@
       /* Free app session pre-allocated when transport was established */
       if (ctx->tls_type == TRANSPORT_PROTO_TLS)
 	session_free (session_get (ctx->c_s_index, ctx->c_thread_index));
-      goto failed;
+      ctx->no_app_session = 1;
+      goto send_reply;
     }
 
   /* For DTLS the app session is not preallocated because the underlying udp
@@ -271,6 +272,7 @@
 failed:
   ctx->no_app_session = 1;
   tls_disconnect (ctx->tls_ctx_handle, vlib_get_thread_index ());
+send_reply:
   return app_worker_connect_notify (app_wrk, 0, err,
 				    ctx->parent_app_api_context);
 }