session tls: support tls descheduling 83/26083/9
authorFlorin Coras <fcoras@cisco.com>
Mon, 23 Mar 2020 15:34:22 +0000 (15:34 +0000)
committerDave Barach <openvpp@barachs.net>
Sat, 4 Apr 2020 17:34:13 +0000 (17:34 +0000)
Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ieb8bb9c6deb92479fdd3e045778fe5ae4782d1ea

src/plugins/quic/quic.c
src/plugins/tlsmbedtls/tls_mbedtls.c
src/plugins/tlsopenssl/tls_openssl.c
src/plugins/tlspicotls/tls_picotls.c
src/vnet/session/application_local.c
src/vnet/session/session_node.c
src/vnet/session/transport.h
src/vnet/tcp/tcp.h
src/vnet/tcp/tcp_output.c
src/vnet/tls/tls.c
src/vnet/tls/tls.h

index 4d80944..de0e4e4 100644 (file)
@@ -1928,7 +1928,7 @@ quic_custom_app_rx_callback (transport_connection_t * tc)
 }
 
 static int
-quic_custom_tx_callback (void *s, u32 max_burst_size)
+quic_custom_tx_callback (void *s, transport_send_params_t * sp)
 {
   session_t *stream_session = (session_t *) s;
   quic_stream_data_t *stream_data;
index 8ac736a..3fccba2 100644 (file)
@@ -431,7 +431,8 @@ mbedtls_ctx_handshake_rx (tls_ctx_t * ctx)
 }
 
 static int
-mbedtls_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_write)
+mbedtls_ctx_write (tls_ctx_t * ctx, session_t * app_session,
+                  transport_send_params_t * sp)
 {
   mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
   u8 thread_index = ctx->c_thread_index;
@@ -446,7 +447,7 @@ mbedtls_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_write)
   if (!deq_max)
     return 0;
 
-  deq_max = clib_min (deq_max, max_write);
+  deq_max = clib_min (deq_max, sp->max_burst_size);
   tls_session = session_get_from_handle (ctx->tls_session_handle);
   enq_max = svm_fifo_max_enqueue_prod (tls_session->tx_fifo);
   deq_now = clib_min (deq_max, TLS_CHUNK_SIZE);
index 935e014..669a503 100644 (file)
@@ -110,15 +110,11 @@ openssl_lctx_get (u32 lctx_index)
 }
 
 static int
-openssl_read_from_bio_into_fifo (svm_fifo_t * f, BIO * bio)
+openssl_read_from_bio_into_fifo (svm_fifo_t * f, BIO * bio, u32 enq_max)
 {
-  u32 enq_now, enq_max;
   svm_fifo_chunk_t *c;
   int read, rv;
-
-  enq_max = svm_fifo_max_enqueue_prod (f);
-  if (!enq_max)
-    return 0;
+  u32 enq_now;
 
   svm_fifo_fill_chunk_list (f);
 
@@ -256,12 +252,17 @@ openssl_try_handshake_read (openssl_ctx_t * oc, session_t * tls_session)
 static int
 openssl_try_handshake_write (openssl_ctx_t * oc, session_t * tls_session)
 {
-  u32 read;
+  u32 read, enq_max;
 
   if (BIO_ctrl_pending (oc->rbio) <= 0)
     return 0;
 
-  read = openssl_read_from_bio_into_fifo (tls_session->tx_fifo, oc->rbio);
+  enq_max = svm_fifo_max_enqueue_prod (tls_session->tx_fifo);
+  if (!enq_max)
+    return 0;
+
+  read = openssl_read_from_bio_into_fifo (tls_session->tx_fifo, oc->rbio,
+                                         enq_max);
   if (read)
     tls_add_vpp_q_tx_evt (tls_session);
 
@@ -413,11 +414,12 @@ openssl_confirm_app_close (tls_ctx_t * ctx)
 }
 
 static inline int
-openssl_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_write)
+openssl_ctx_write (tls_ctx_t * ctx, session_t * app_session,
+                  transport_send_params_t * sp)
 {
   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
-  int wrote = 0, read, max_buf = 4 * TLS_CHUNK_SIZE, max_space;
-  u32 deq_max, to_write;
+  int wrote = 0, read, max_buf = 4 * TLS_CHUNK_SIZE, max_space, n_pending;
+  u32 deq_max, to_write, enq_max;
   session_t *tls_session;
   svm_fifo_t *f;
 
@@ -427,7 +429,7 @@ openssl_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_write)
   if (!deq_max)
     goto check_tls_fifo;
 
-  deq_max = clib_min (deq_max, max_write);
+  deq_max = clib_min (deq_max, sp->max_burst_size);
 
   /* Figure out how much data to write */
   max_space = max_buf - BIO_ctrl_pending (oc->rbio);
@@ -443,26 +445,38 @@ openssl_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_write)
 
 check_tls_fifo:
 
-  if (BIO_ctrl_pending (oc->rbio) <= 0)
+  if ((n_pending = BIO_ctrl_pending (oc->rbio)) <= 0)
     return wrote;
 
   tls_session = session_get_from_handle (ctx->tls_session_handle);
 
-  read = openssl_read_from_bio_into_fifo (tls_session->tx_fifo, oc->rbio);
+  enq_max = svm_fifo_max_enqueue_prod (tls_session->tx_fifo);
+  if (!enq_max)
+    goto maybe_reschedule;
+
+  read = openssl_read_from_bio_into_fifo (tls_session->tx_fifo, oc->rbio,
+                                         enq_max);
   if (!read)
-    {
-      /* Request tx reschedule of the app session */
-      app_session->flags |= SESSION_F_CUSTOM_TX;
-      return wrote;
-    }
+    goto maybe_reschedule;
 
   tls_add_vpp_q_tx_evt (tls_session);
 
-  if (BIO_ctrl_pending (oc->rbio) > 0)
-    app_session->flags |= SESSION_F_CUSTOM_TX;
-  else if (ctx->app_closed)
+  if (PREDICT_FALSE (ctx->app_closed && !BIO_ctrl_pending (oc->rbio)))
     openssl_confirm_app_close (ctx);
 
+maybe_reschedule:
+
+  if (!svm_fifo_max_enqueue_prod (tls_session->tx_fifo))
+    {
+      svm_fifo_add_want_deq_ntf (tls_session->tx_fifo,
+                                SVM_FIFO_WANT_DEQ_NOTIF);
+      transport_connection_deschedule (&ctx->connection);
+      sp->flags |= TRANSPORT_SND_F_DESCHED;
+    }
+  else
+    /* Request tx reschedule of the app session */
+    app_session->flags |= SESSION_F_CUSTOM_TX;
+
   return wrote;
 }
 
index a9eea33..a8944bc 100644 (file)
@@ -410,7 +410,8 @@ picotls_content_process (picotls_ctx_t * ptls_ctx, svm_fifo_t * src_fifo,
 }
 
 static inline int
-picotls_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_write)
+picotls_ctx_write (tls_ctx_t * ctx, session_t * app_session,
+                  transport_send_params_t * sp)
 {
   picotls_ctx_t *ptls_ctx = (picotls_ctx_t *) ctx;
   u32 deq_max, deq_now;
@@ -458,7 +459,7 @@ picotls_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_write)
   if (!deq_max)
     return deq_max;
 
-  deq_max = clib_min (deq_max, max_write);
+  deq_max = clib_min (deq_max, sp->max_burst_size);
   deq_now = clib_min (deq_max, svm_fifo_max_read_chunk (app_tx_fifo));
 
   enq_max = svm_fifo_max_enqueue_prod (tls_tx_fifo);
index d54d111..0e1f6db 100644 (file)
@@ -470,7 +470,7 @@ format_ct_connection_id (u8 * s, va_list * args)
 }
 
 static int
-ct_custom_tx (void *session, u32 max_burst_size)
+ct_custom_tx (void *session, transport_send_params_t * sp)
 {
   session_t *s = (session_t *) session;
   if (session_has_transport (s))
index 30eca1e..f023a95 100644 (file)
@@ -872,7 +872,8 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
     {
       u32 n_custom_tx;
       ctx->s->flags &= ~SESSION_F_CUSTOM_TX;
-      n_custom_tx = ctx->transport_vft->custom_tx (ctx->tc, max_burst);
+      ctx->sp.max_burst_size = max_burst;
+      n_custom_tx = ctx->transport_vft->custom_tx (ctx->tc, &ctx->sp);
       *n_tx_packets += n_custom_tx;
       if (PREDICT_FALSE
          (ctx->s->session_state >= SESSION_STATE_TRANSPORT_CLOSED))
@@ -1068,8 +1069,9 @@ session_tx_fifo_dequeue_internal (session_worker_t * wrk,
                                  vlib_node_runtime_t * node,
                                  session_evt_elt_t * elt, int *n_tx_packets)
 {
+  transport_send_params_t *sp = &wrk->ctx.sp;
   session_t *s = wrk->ctx.s;
-  u32 n_packets, max_pkts;
+  u32 n_packets;
 
   if (PREDICT_FALSE (s->session_state >= SESSION_STATE_TRANSPORT_CLOSED))
     return 0;
@@ -1077,18 +1079,17 @@ session_tx_fifo_dequeue_internal (session_worker_t * wrk,
   /* Clear custom-tx flag used to request reschedule for tx */
   s->flags &= ~SESSION_F_CUSTOM_TX;
 
-  max_pkts = clib_min (VLIB_FRAME_SIZE - *n_tx_packets,
-                      TRANSPORT_PACER_MAX_BURST_PKTS);
-  n_packets = transport_custom_tx (session_get_transport_proto (s), s,
-                                  max_pkts);
-  *n_tx_packets -= n_packets;
+  sp->max_burst_size = clib_min (VLIB_FRAME_SIZE - *n_tx_packets,
+                                TRANSPORT_PACER_MAX_BURST_PKTS);
 
-  if (svm_fifo_max_dequeue_cons (s->tx_fifo)
-      || (s->flags & SESSION_F_CUSTOM_TX))
+  n_packets = transport_custom_tx (session_get_transport_proto (s), s, sp);
+  *n_tx_packets += n_packets;
+
+  if (s->flags & SESSION_F_CUSTOM_TX)
     {
       session_evt_add_old (wrk, elt);
     }
-  else
+  else if (!(sp->flags & TRANSPORT_SND_F_DESCHED))
     {
       svm_fifo_unset_event (s->tx_fifo);
       if (svm_fifo_max_dequeue_cons (s->tx_fifo))
index 6dc6984..eb98032 100644 (file)
@@ -44,9 +44,21 @@ typedef enum transport_snd_flags_
 
 typedef struct transport_send_params_
 {
-  u32 snd_space;
-  u32 tx_offset;
-  u16 snd_mss;
+  union
+  {
+    /* Used to retrieve snd params from transports */
+    struct
+    {
+      u32 snd_space;
+      u32 tx_offset;
+      u16 snd_mss;
+    };
+    /* Used by custom tx functions */
+    struct
+    {
+      u32 max_burst_size;
+    };
+  };
   transport_snd_flags_t flags;
 } transport_send_params_t;
 
@@ -76,7 +88,7 @@ typedef struct _transport_proto_vft
                      transport_send_params_t *sp);
   void (*update_time) (f64 time_now, u8 thread_index);
   void (*flush_data) (transport_connection_t *tconn);
-  int (*custom_tx) (void *session, u32 max_burst_size);
+  int (*custom_tx) (void *session, transport_send_params_t *sp);
   int (*app_rx_evt) (transport_connection_t *tconn);
 
   /*
@@ -152,9 +164,10 @@ transport_get_half_open (transport_proto_t tp, u32 conn_index)
 }
 
 static inline int
-transport_custom_tx (transport_proto_t tp, void *s, u32 max_burst_size)
+transport_custom_tx (transport_proto_t tp, void *s,
+                    transport_send_params_t * sp)
 {
-  return tp_vfts[tp].custom_tx (s, max_burst_size);
+  return tp_vfts[tp].custom_tx (s, sp);
 }
 
 static inline int
index f8c8cb3..f4cc2c8 100644 (file)
@@ -325,7 +325,7 @@ void tcp_reschedule (tcp_connection_t * tc);
 fib_node_index_t tcp_lookup_rmt_in_fib (tcp_connection_t * tc);
 u32 tcp_session_push_header (transport_connection_t * tconn,
                             vlib_buffer_t * b);
-int tcp_session_custom_tx (void *conn, u32 max_burst_size);
+int tcp_session_custom_tx (void *conn, transport_send_params_t * sp);
 
 void tcp_connection_timers_init (tcp_connection_t * tc);
 void tcp_connection_timers_reset (tcp_connection_t * tc);
index 095f360..b1af535 100644 (file)
@@ -2010,7 +2010,7 @@ tcp_do_retransmit (tcp_connection_t * tc, u32 max_burst_size)
 }
 
 int
-tcp_session_custom_tx (void *conn, u32 max_burst_size)
+tcp_session_custom_tx (void *conn, transport_send_params_t * sp)
 {
   tcp_connection_t *tc = (tcp_connection_t *) conn;
   u32 n_segs = 0;
@@ -2018,8 +2018,7 @@ tcp_session_custom_tx (void *conn, u32 max_burst_size)
   if (tcp_in_cong_recovery (tc) && (tc->flags & TCP_CONN_RXT_PENDING))
     {
       tc->flags &= ~TCP_CONN_RXT_PENDING;
-      n_segs = tcp_do_retransmit (tc, max_burst_size);
-      max_burst_size -= n_segs;
+      n_segs = tcp_do_retransmit (tc, sp->max_burst_size);
     }
 
   if (!(tc->flags & TCP_CONN_SNDACK))
@@ -2031,13 +2030,13 @@ tcp_session_custom_tx (void *conn, u32 max_burst_size)
   if (n_segs && !tc->pending_dupacks)
     return n_segs;
 
-  if (!max_burst_size)
+  if (sp->max_burst_size <= n_segs)
     {
       tcp_program_ack (tc);
-      return max_burst_size;
+      return n_segs;
     }
 
-  n_segs += tcp_send_acks (tc, max_burst_size);
+  n_segs += tcp_send_acks (tc, sp->max_burst_size - n_segs);
 
   return n_segs;
 }
index d0552dc..89dbd36 100644 (file)
@@ -307,13 +307,13 @@ tls_ctx_init_client (tls_ctx_t * ctx)
 }
 
 static inline int
-tls_ctx_write (tls_ctx_t * ctx, session_t * app_session, u32 max_burst_size)
+tls_ctx_write (tls_ctx_t * ctx, session_t * app_session,
+              transport_send_params_t * sp)
 {
-  u32 max_write, n_wrote;
+  u32 n_wrote;
 
-  max_write = max_burst_size * TRANSPORT_PACER_MIN_MSS;
-  n_wrote = tls_vfts[ctx->tls_ctx_engine].ctx_write (ctx, app_session,
-                                                    max_write);
+  sp->max_burst_size = sp->max_burst_size * TRANSPORT_PACER_MIN_MSS;
+  n_wrote = tls_vfts[ctx->tls_ctx_engine].ctx_write (ctx, app_session, sp);
   return n_wrote > 0 ? clib_max (n_wrote / TRANSPORT_PACER_MIN_MSS, 1) : 0;
 }
 
@@ -447,6 +447,17 @@ tls_app_rx_callback (session_t * tls_session)
   return 0;
 }
 
+int
+tls_app_tx_callback (session_t * tls_session)
+{
+  tls_ctx_t *ctx;
+
+  ctx = tls_ctx_get (tls_session->opaque);
+  transport_connection_reschedule (&ctx->connection);
+
+  return 0;
+}
+
 int
 tls_session_connected_callback (u32 tls_app_index, u32 ho_ctx_index,
                                session_t * tls_session, session_error_t err)
@@ -524,6 +535,7 @@ static session_cb_vft_t tls_app_cb_vft = {
   .add_segment_callback = tls_add_segment_callback,
   .del_segment_callback = tls_del_segment_callback,
   .builtin_app_rx_callback = tls_app_rx_callback,
+  .builtin_app_tx_callback = tls_app_tx_callback,
   .session_cleanup_callback = tls_app_session_cleanup,
 };
 /* *INDENT-ON* */
@@ -712,7 +724,7 @@ tls_listener_get (u32 listener_index)
 }
 
 int
-tls_custom_tx_callback (void *session, u32 max_burst_size)
+tls_custom_tx_callback (void *session, transport_send_params_t * sp)
 {
   session_t *app_session = (session_t *) session;
   tls_ctx_t *ctx;
@@ -722,8 +734,7 @@ tls_custom_tx_callback (void *session, u32 max_burst_size)
     return 0;
 
   ctx = tls_ctx_get (app_session->connection_index);
-  tls_ctx_write (ctx, app_session, max_burst_size);
-  return 0;
+  return tls_ctx_write (ctx, app_session, sp);
 }
 
 u8 *
index 2d09b29..d950fe8 100644 (file)
@@ -110,7 +110,8 @@ typedef struct tls_engine_vft_
   int (*ctx_init_client) (tls_ctx_t * ctx);
   int (*ctx_init_server) (tls_ctx_t * ctx);
   int (*ctx_read) (tls_ctx_t * ctx, session_t * tls_session);
-  int (*ctx_write) (tls_ctx_t * ctx, session_t * app_session, u32 max_write);
+  int (*ctx_write) (tls_ctx_t * ctx, session_t * app_session,
+                   transport_send_params_t * sp);
     u8 (*ctx_handshake_is_over) (tls_ctx_t * ctx);
   int (*ctx_start_listen) (tls_ctx_t * ctx);
   int (*ctx_stop_listen) (tls_ctx_t * ctx);