quic: fifo size is u32
[vpp.git] / src / plugins / quic / quic.c
index 96416a7..d9d5844 100644 (file)
@@ -60,7 +60,7 @@ quic_ctx_alloc (u32 thread_index)
 static void
 quic_ctx_free (quic_ctx_t * ctx)
 {
-  QUIC_DBG (2, "Free ctx %u", ctx->c_c_index);
+  QUIC_DBG (2, "Free ctx %u %x", ctx->c_thread_index, ctx->c_c_index);
   u32 thread_index = ctx->c_thread_index;
   if (CLIB_DEBUG)
     clib_memset (ctx, 0xfb, sizeof (*ctx));
@@ -139,23 +139,16 @@ quic_sendable_packet_count (session_t * udp_session)
 static quicly_context_t *
 quic_get_quicly_ctx_from_ctx (quic_ctx_t * ctx)
 {
-  app_worker_t *app_wrk;
-  application_t *app;
-  app_wrk = app_worker_get_if_valid (ctx->parent_app_wrk_id);
-  if (!app_wrk)
-    return 0;
-  app = application_get (app_wrk->app_index);
-  return (quicly_context_t *) app->quicly_ctx;
+  return ctx->quicly_ctx;
 }
 
 static quicly_context_t *
 quic_get_quicly_ctx_from_udp (u64 udp_session_handle)
 {
-  session_t *udp_session;
-  application_t *app;
-  udp_session = session_get_from_handle (udp_session_handle);
-  app = application_get (udp_session->opaque);
-  return (quicly_context_t *) app->quicly_ctx;
+  session_t *udp_session = session_get_from_handle (udp_session_handle);
+  quic_ctx_t *ctx =
+    quic_ctx_get (udp_session->opaque, udp_session->thread_index);
+  return ctx->quicly_ctx;
 }
 
 static inline void
@@ -294,7 +287,7 @@ quic_connection_closed (quic_ctx_t * ctx)
       quic_connection_delete (ctx);
       break;
     default:
-      QUIC_DBG (0, "BUG");
+      QUIC_DBG (0, "BUG %d", ctx->conn_state);
       break;
     }
 }
@@ -862,11 +855,13 @@ quic_encrypt_ticket_cb (ptls_encrypt_ticket_t * _self, ptls_t * tls,
 }
 
 static void
-quic_store_quicly_ctx (application_t * app, u8 is_client)
+quic_store_quicly_ctx (application_t * app, u32 cert_key_index)
 {
   quic_main_t *qm = &quic_main;
   quicly_context_t *quicly_ctx;
   ptls_iovec_t key_vec;
+  app_cert_key_pair_t *ckpair;
+  u64 max_enq;
   if (app->quicly_ctx)
     return;
 
@@ -905,8 +900,12 @@ quic_store_quicly_ctx (application_t * app, u8 is_client)
   quicly_ctx->transport_params.max_data = QUIC_INT_MAX;
   quicly_ctx->transport_params.max_streams_uni = (uint64_t) 1 << 60;
   quicly_ctx->transport_params.max_streams_bidi = (uint64_t) 1 << 60;
-  quicly_ctx->transport_params.max_stream_data.bidi_local = (qm->udp_fifo_size - 1);   /* max_enq is SIZE - 1 */
-  quicly_ctx->transport_params.max_stream_data.bidi_remote = (qm->udp_fifo_size - 1);  /* max_enq is SIZE - 1 */
+
+  /* max_enq is FIFO_SIZE - 1 */
+  max_enq = app->sm_properties.rx_fifo_size - 1;
+  quicly_ctx->transport_params.max_stream_data.bidi_local = max_enq;
+  max_enq = app->sm_properties.tx_fifo_size - 1;
+  quicly_ctx->transport_params.max_stream_data.bidi_remote = max_enq;
   quicly_ctx->transport_params.max_stream_data.uni = QUIC_INT_MAX;
 
   quicly_ctx->tls->random_bytes (quicly_ctx_data->cid_key, 16);
@@ -917,16 +916,15 @@ quic_store_quicly_ctx (application_t * app, u8 is_client)
     quicly_new_default_cid_encryptor (&ptls_openssl_bfecb,
                                      &ptls_openssl_aes128ecb,
                                      &ptls_openssl_sha256, key_vec);
-  if (is_client)
-    return;
-  if (app->tls_key != NULL && app->tls_cert != NULL)
+
+  ckpair = app_cert_key_pair_get_if_valid (cert_key_index);
+  if (ckpair && ckpair->key != NULL && ckpair->cert != NULL)
     {
-      if (load_bio_private_key (quicly_ctx->tls, (char *) app->tls_key))
+      if (load_bio_private_key (quicly_ctx->tls, (char *) ckpair->key))
        {
          QUIC_DBG (1, "failed to read private key from app configuration\n");
        }
-      if (load_bio_certificate_chain (quicly_ctx->tls,
-                                     (char *) app->tls_cert))
+      if (load_bio_certificate_chain (quicly_ctx->tls, (char *) ckpair->cert))
        {
          QUIC_DBG (1, "failed to load certificate\n");
        }
@@ -1078,7 +1076,10 @@ quic_connect_connection (session_endpoint_cfg_t * sep)
   ctx->parent_app_id = app_wrk->app_index;
   cargs->sep_ext.ns_index = app->ns_index;
 
-  quic_store_quicly_ctx (app, 1 /* is client */ );
+  quic_store_quicly_ctx (app, ctx->ckpair_index);
+  /* Also store it in ctx for convenience
+   * Waiting for crypto_ctx logic */
+  ctx->quicly_ctx = (quicly_context_t *) app->quicly_ctx;
 
   if ((error = vnet_connect (cargs)))
     return error;
@@ -1167,7 +1168,7 @@ quic_start_listen (u32 quic_listen_session_index, transport_endpoint_t * tep)
   app = application_get (app_wrk->app_index);
   QUIC_DBG (2, "Called quic_start_listen for app %d", app_wrk->app_index);
 
-  quic_store_quicly_ctx (app, 0 /* is_client */ );
+  quic_store_quicly_ctx (app, sep->ckpair_index);
 
   sep->transport_proto = TRANSPORT_PROTO_UDPC;
   clib_memset (args, 0, sizeof (*args));
@@ -1185,6 +1186,9 @@ quic_start_listen (u32 quic_listen_session_index, transport_endpoint_t * tep)
 
   lctx = quic_ctx_get (lctx_index, 0);
   lctx->flags |= QUIC_F_IS_LISTENER;
+  /* Also store it in ctx for convenience
+   * Waiting for crypto_ctx logic */
+  lctx->quicly_ctx = (quicly_context_t *) app->quicly_ctx;
 
   clib_memcpy (&lctx->c_rmt_ip, &args->sep.peer.ip, sizeof (ip46_address_t));
   clib_memcpy (&lctx->c_lcl_ip, &args->sep.ip, sizeof (ip46_address_t));
@@ -1437,6 +1441,8 @@ quic_receive_connection (void *arg)
 
   /*  Trigger write on this connection if necessary */
   udp_session = session_get_from_handle (new_ctx->udp_session_handle);
+  udp_session->opaque = new_ctx_id;
+  udp_session->flags &= ~SESSION_F_IS_MIGRATING;
   if (svm_fifo_max_dequeue (udp_session->tx_fifo))
     quic_set_udp_tx_evt (udp_session);
 }
@@ -1510,7 +1516,7 @@ quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index,
            is_fail, thread_index, (ctx) ? ctx_index : ~0);
 
   ctx->udp_session_handle = session_handle (udp_session);
-  udp_session->opaque = ctx->parent_app_id;
+  udp_session->opaque = ctx_index;
 
   /* Init QUIC lib connection
    * Generate required sockaddr & salen */
@@ -1558,31 +1564,19 @@ quic_udp_session_reset_callback (session_t * s)
 static void
 quic_udp_session_migrate_callback (session_t * s, session_handle_t new_sh)
 {
-  /*
-   * TODO we need better way to get the connection from the session
-   * This will become possible once we stop storing the app id in the UDP
-   * session opaque
-   */
-  u32 thread_index = vlib_get_thread_index ();
-  u64 old_session_handle = session_handle (s);
   u32 new_thread = session_thread_from_handle (new_sh);
   quic_ctx_t *ctx;
 
   QUIC_DBG (1, "Session %x migrated to %lx", s->session_index, new_sh);
-  /* *INDENT-OFF* */
-  pool_foreach (ctx, quic_main.ctx_pool[thread_index],
-    ({
-      if (ctx->udp_session_handle == old_session_handle)
-        {
-          /*  Right ctx found, move associated conn */
-          QUIC_DBG (5, "Found right ctx: %x", ctx->c_c_index);
-          ctx->udp_session_handle = new_sh;
-          quic_transfer_connection (ctx->c_c_index, new_thread);
-          return;
-        }
-    }));
-  /* *INDENT-ON* */
-  QUIC_DBG (0, "BUG: Connection to migrate not found");
+  ASSERT (vlib_get_thread_index () == s->thread_index);
+  ctx = quic_ctx_get (s->opaque, s->thread_index);
+  ASSERT (ctx->udp_session_handle == session_handle (s));
+
+  ctx->udp_session_handle = new_sh;
+#if QUIC_DEBUG >= 1
+  s->opaque = 0xfeedface;
+#endif
+  quic_transfer_connection (ctx->c_c_index, new_thread);
 }
 
 int
@@ -1615,7 +1609,11 @@ quic_udp_session_accepted_callback (session_t * udp_session)
   ctx->conn_state = QUIC_CONN_STATE_OPENED;
   ctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
 
-  udp_session->opaque = ctx->parent_app_id;
+  /* Also store it in ctx for convenience
+   * Waiting for crypto_ctx logic */
+  ctx->quicly_ctx = lctx->quicly_ctx;
+
+  udp_session->opaque = ctx_index;
 
   /* Put this ctx in the "opening" pool */
   pool_get (quic_main.wrk_ctx[ctx->c_thread_index].opening_ctx_pool,
@@ -1847,8 +1845,7 @@ quic_reset_connection (u64 udp_session_handle,
 }
 
 static int
-quic_process_one_rx_packet (u64 udp_session_handle,
-                           quicly_context_t * quicly_ctx, svm_fifo_t * f,
+quic_process_one_rx_packet (u64 udp_session_handle, svm_fifo_t * f,
                            u32 * fifo_offset, u32 * max_packet, u32 packet_n,
                            quic_rx_packet_ctx_t * packet_ctx)
 {
@@ -1865,6 +1862,7 @@ quic_process_one_rx_packet (u64 udp_session_handle,
   u32 thread_index = vlib_get_thread_index ();
   u32 *opening_ctx_pool, *ctx_index_ptr;
   u32 cur_deq = svm_fifo_max_dequeue (f) - *fifo_offset;
+  quicly_context_t *quicly_ctx;
 
   if (cur_deq == 0)
     {
@@ -1968,22 +1966,19 @@ static int
 quic_udp_session_rx_callback (session_t * udp_session)
 {
   /*  Read data from UDP rx_fifo and pass it to the quicly conn. */
-  application_t *app;
   quic_ctx_t *ctx = NULL;
   svm_fifo_t *f;
   u32 max_deq;
-  u32 app_index = udp_session->opaque;
   u64 udp_session_handle = session_handle (udp_session);
   int rv = 0;
   u32 thread_index = vlib_get_thread_index ();
   quic_rx_packet_ctx_t packets_ctx[16];
   u32 i, fifo_offset, max_packets;
 
-  if (!(app = application_get_if_valid (app_index)))
+  if (udp_session->flags & SESSION_F_IS_MIGRATING)
     {
-      QUIC_DBG (1, "Got RX on detached app");
-      /*  TODO: close this session, cleanup state? */
-      return 1;
+      QUIC_DBG (3, "RX on migrating udp session");
+      return 0;
     }
 
   while (1)
@@ -1997,10 +1992,8 @@ quic_udp_session_rx_callback (session_t * udp_session)
       fifo_offset = 0;
       max_packets = 16;
       for (i = 0; i < max_packets; i++)
-       quic_process_one_rx_packet (udp_session_handle,
-                                   (quicly_context_t *) app->quicly_ctx, f,
-                                   &fifo_offset, &max_packets, i,
-                                   &packets_ctx[i]);
+       quic_process_one_rx_packet (udp_session_handle, f, &fifo_offset,
+                                   &max_packets, i, &packets_ctx[i]);
 
       for (i = 0; i < max_packets; i++)
        {
@@ -2091,7 +2084,7 @@ static const transport_proto_vft_t quic_proto = {
 /* *INDENT-ON* */
 
 static void
-quic_register_cipher_suite (quic_crypto_engine_t type,
+quic_register_cipher_suite (crypto_engine_type_t type,
                            ptls_cipher_suite_t ** ciphers)
 {
   quic_main_t *qm = &quic_main;
@@ -2106,7 +2099,7 @@ quic_update_fifo_size ()
   segment_manager_props_t *seg_mgr_props =
     application_get_segment_manager_properties (qm->app_index);
 
-  if (seg_mgr_props)
+  if (!seg_mgr_props)
     {
       clib_warning
        ("error while getting segment_manager_props_t, can't update fifo-size");
@@ -2212,15 +2205,25 @@ quic_plugin_set_fifo_size_command_fn (vlib_main_t * vm,
                                      unformat_input_t * input,
                                      vlib_cli_command_t * cmd)
 {
+  quic_main_t *qm = &quic_main;
   unformat_input_t _line_input, *line_input = &_line_input;
+  uword tmp;
+
   if (!unformat_user (input, unformat_line_input, line_input))
     return 0;
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat
-         (line_input, "%U", unformat_data_size, &quic_main.udp_fifo_size))
-       quic_update_fifo_size ();
+      if (unformat (line_input, "%U", unformat_memory_size, &tmp))
+       {
+         if (tmp >= 0x100000000ULL)
+           {
+             return clib_error_return
+               (0, "fifo-size %llu (0x%llx) too large", tmp, tmp);
+           }
+         qm->udp_fifo_size = tmp;
+         quic_update_fifo_size ();
+       }
       else
        return clib_error_return (0, "unknown input '%U'",
                                  format_unformat_error, line_input);
@@ -2280,7 +2283,7 @@ VLIB_CLI_COMMAND (quic_plugin_crypto_command, static) =
 VLIB_CLI_COMMAND(quic_plugin_set_fifo_size_command, static)=
 {
   .path = "quic set fifo-size",
-  .short_help = "quic set fifo-size N[Kb|Mb|GB] (default 64K)",
+  .short_help = "quic set fifo-size N[K|M|G] (default 64K)",
   .function = quic_plugin_set_fifo_size_command_fn,
 };
 VLIB_CLI_COMMAND(quic_plugin_stats_command, static)=
@@ -2300,15 +2303,22 @@ VLIB_PLUGIN_REGISTER () =
 static clib_error_t *
 quic_config_fn (vlib_main_t * vm, unformat_input_t * input)
 {
-  quic_main.udp_fifo_size = QUIC_DEFAULT_FIFO_SIZE;
-  quic_main.udp_fifo_prealloc = 0;
+  quic_main_t *qm = &quic_main;
+  uword tmp;
 
+  qm->udp_fifo_size = QUIC_DEFAULT_FIFO_SIZE;
+  qm->udp_fifo_prealloc = 0;
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat
-         (input, "fifo-size %U", unformat_data_size,
-          &quic_main.udp_fifo_size))
-       ;
+      if (unformat (input, "fifo-size %U", unformat_memory_size, &tmp))
+       {
+         if (tmp >= 0x100000000ULL)
+           {
+             return clib_error_return
+               (0, "fifo-size %llu (0x%llx) too large", tmp, tmp);
+           }
+         qm->udp_fifo_size = tmp;
+       }
       else
        if (unformat
            (input, "fifo-prealloc %u", &quic_main.udp_fifo_prealloc))