quic: fix quicly plugin to use vpp crypto engine. 82/43782/12
authorDave Wallace <[email protected]>
Sat, 27 Sep 2025 02:22:00 +0000 (22:22 -0400)
committerFlorin Coras <[email protected]>
Fri, 3 Oct 2025 21:54:43 +0000 (21:54 +0000)
- Make picotls the default crypto engine
- Improve debug output
- Fix vpp native crypto engine issues introduced
  during quic engine api & quic_quicly plugin
  development
- Convert c++ style comments to c-style
- Refactor 'quic set crypto api' command to
  remove quicly engine specific terminology
  and make it work properly.

Type: fix

Change-Id: I6b60b7b51e8b666fc075373d432b1031b8e5d9e3
Signed-off-by: Dave Wallace <[email protected]>
src/plugins/quic/quic.c
src/plugins/quic/quic.h
src/plugins/quic_quicly/quic_quicly.c
src/plugins/quic_quicly/quic_quicly.h
src/plugins/quic_quicly/quic_quicly_crypto.c
src/plugins/quic_quicly/quic_quicly_crypto.h
test/asf/test_quic.py

index 0ad0389..f0f66fd 100644 (file)
@@ -179,7 +179,8 @@ quic_connect_stream (session_t * quic_session, session_endpoint_cfg_t * sep)
 
   /*  Find base session to which the user want to attach a stream */
   quic_session_handle = session_handle (quic_session);
-  QUIC_DBG (2, "Opening new stream (qsession %u)", quic_session_handle);
+  QUIC_DBG (2, "Connect stream: quic_session_handle 0x%lx",
+           quic_session_handle);
 
   if (session_type_transport_proto (quic_session->session_type) !=
       TRANSPORT_PROTO_QUIC)
@@ -221,10 +222,10 @@ quic_connect_stream (session_t * quic_session, session_endpoint_cfg_t * sep)
   rv = quic_eng_connect_stream (conn, &stream, &stream_data, is_unidir);
   if (rv)
     {
-      QUIC_DBG (2,
-               "quic_eng_connect_stream (c=0x%lx, s=0x%lx, sd=0x%lx, u=%d) "
-               "failed (rv=%d)",
-               conn, &stream, &stream_data, is_unidir, rv);
+      QUIC_DBG (1,
+               "Connect stream: failed %d, conn %p, stream %p, stream_data "
+               "%p, unidir %d",
+               rv, conn, &stream, &stream_data, is_unidir);
       return -1;
     }
   quic_increment_counter (qm, QUIC_ERROR_OPENED_STREAM, 1);
@@ -233,8 +234,9 @@ quic_connect_stream (session_t * quic_session, session_endpoint_cfg_t * sep)
   sctx->crypto_context_index = qctx->crypto_context_index;
 
   stream_session = session_alloc (qctx->c_thread_index);
-  QUIC_DBG (2, "Allocated stream_session 0x%lx ctx %u",
-           session_handle (stream_session), sctx_index);
+  QUIC_DBG (
+    2, "Connect stream: stream_session handle 0x%lx, sctx_index %u, thread %u",
+    session_handle (stream_session), sctx_index, qctx->c_thread_index);
   stream_session->app_wrk_index = app_wrk->wrk_index;
   stream_session->connection_index = sctx_index;
   stream_session->listener_handle = quic_session_handle;
@@ -254,7 +256,7 @@ quic_connect_stream (session_t * quic_session, session_endpoint_cfg_t * sep)
   /* For now we only reset streams. Cleanup will be triggered by timers */
   if ((rv = app_worker_init_connected (app_wrk, stream_session)))
     {
-      QUIC_ERR ("failed to app_worker_init_connected");
+      QUIC_ERR ("Connect stream: failed app_worker_init_connected %d", rv);
       quic_eng_connect_stream_error_reset (stream);
       return app_worker_connect_notify (app_wrk, NULL, rv, sep->opaque);
     }
@@ -268,7 +270,7 @@ quic_connect_stream (session_t * quic_session, session_endpoint_cfg_t * sep)
   if (app_worker_connect_notify (app_wrk, stream_session, SESSION_E_NONE,
                                 sep->opaque))
     {
-      QUIC_ERR ("failed to notify app");
+      QUIC_ERR ("Connect stream: failed to notify app");
       quic_increment_counter (qm, QUIC_ERROR_CLOSED_STREAM, 1);
       quic_eng_connect_stream_error_reset (stream);
       return -1;
@@ -578,7 +580,7 @@ quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index,
   clib_thread_index_t thread_index;
   int ret;
 
-  QUIC_DBG (2, "UDP Session connect callback: session_index %u, thread %u",
+  QUIC_DBG (2, "UDP Session connected: session_index %u, thread %u",
            udp_session->session_index, udp_session->thread_index);
 
   /* Allocate session on whatever thread udp used, i.e., probably first
@@ -601,8 +603,8 @@ quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index,
       return 0;
     }
 
-  QUIC_DBG (2, "New ctx [thread=0x%x] ctx_index=0x%x", thread_index,
-           (ctx) ? ctx_index : ~0);
+  QUIC_DBG (2, "UDP Session connected: quic ctx_index %u, thread %u",
+           (ctx) ? ctx_index : ~0, thread_index);
 
   ctx->udp_session_handle = session_handle (udp_session);
   udp_session->opaque = ctx_index;
@@ -749,17 +751,16 @@ quic_custom_tx_callback (void *s, transport_send_params_t * sp)
                      stream_session->thread_index);
   if (PREDICT_FALSE (!quic_ctx_is_stream (ctx)))
     {
+      QUIC_DBG (1, "NOT a stream: ctx_index %u, thread %u",
+               stream_session->connection_index,
+               stream_session->thread_index);
       goto tx_end; /* Most probably a reschedule */
     }
 
   QUIC_DBG (3, "Stream TX event");
   quic_eng_ack_rx_data (stream_session);
-
   if (PREDICT_FALSE (!quic_eng_stream_tx (ctx, stream_session)))
-    {
-      QUIC_DBG (3, "quic_eng_stream_tx(ctx=0x%lx) failed!", ctx);
-      return 0;
-    }
+    return 0;
 
 tx_end:
   return quic_eng_send_packets (ctx);
@@ -852,11 +853,11 @@ static clib_error_t *
 quic_enable (vlib_main_t *vm, u8 is_en)
 {
   quic_main_t *qm = &quic_main;
-  quic_worker_ctx_t *wrk_ctx;
+  quic_worker_ctx_t *qwc;
   quic_ctx_t *ctx;
   crypto_context_t *crctx;
   vlib_thread_main_t *vtm = vlib_get_thread_main ();
-  int i;
+  u64 i;
 
   qm->engine_type =
     quic_get_engine_type (QUIC_ENGINE_QUICLY, QUIC_ENGINE_OPENSSL);
@@ -886,14 +887,14 @@ quic_enable (vlib_main_t *vm, u8 is_en)
 
   for (i = 0; i < qm->num_threads; i++)
     {
-      wrk_ctx = quic_wrk_ctx_get (qm, i);
-      pool_get_aligned_safe (wrk_ctx->crypto_ctx_pool, crctx,
+      qwc = quic_wrk_ctx_get (qm, i);
+      pool_get_aligned_safe (qwc->crypto_ctx_pool, crctx,
                             CLIB_CACHE_LINE_BYTES);
-      pool_program_safe_realloc ((void **) &wrk_ctx->crypto_ctx_pool,
+      pool_program_safe_realloc ((void **) &qwc->crypto_ctx_pool,
                                 QUIC_CRYPTO_CTX_POOL_PER_THREAD_SIZE,
                                 CLIB_CACHE_LINE_BYTES);
-      pool_get_aligned_safe (wrk_ctx->ctx_pool, ctx, CLIB_CACHE_LINE_BYTES);
-      pool_program_safe_realloc ((void **) &wrk_ctx->ctx_pool,
+      pool_get_aligned_safe (qwc->ctx_pool, ctx, CLIB_CACHE_LINE_BYTES);
+      pool_program_safe_realloc ((void **) &qwc->ctx_pool,
                                 QUIC_CTX_POOL_PER_THREAD_SIZE,
                                 CLIB_CACHE_LINE_BYTES);
     }
@@ -929,7 +930,7 @@ quic_init (vlib_main_t * vm)
   quic_main_t *qm = &quic_main;
   vnet_app_attach_args_t _a, *a = &_a;
   u64 options[APP_OPTIONS_N_OPTIONS];
-  // TODO: Don't use hard-coded values for segment_size and seed[]
+  /* TODO: Don't use hard-coded values for segment_size and seed[] */
   u32 segment_size = 256 << 20;
   u8 seed[32];
 
@@ -987,9 +988,33 @@ quic_plugin_crypto_command_fn (vlib_main_t *vm, unformat_input_t *input,
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
       if (unformat (line_input, "vpp"))
-       qm->default_crypto_engine = CRYPTO_ENGINE_VPP;
-      else if (unformat (line_input, "picotls"))
-       qm->default_crypto_engine = CRYPTO_ENGINE_PICOTLS;
+       {
+         qm->default_crypto_engine = CRYPTO_ENGINE_VPP;
+         qm->vnet_crypto_init = 0;
+       }
+      else if (unformat (line_input, "engine-lib"))
+       {
+         qm->default_crypto_engine =
+           (qm->engine_type == QUIC_ENGINE_QUICLY) ?
+             CRYPTO_ENGINE_PICOTLS :
+             ((qm->engine_type == QUIC_ENGINE_OPENSSL) ?
+                CRYPTO_ENGINE_OPENSSL :
+                CRYPTO_ENGINE_NONE);
+         if (qm->default_crypto_engine != CRYPTO_ENGINE_NONE)
+           {
+             qm->vnet_crypto_init = 0;
+           }
+         else
+           {
+             e = clib_error_return (0,
+                                    "No quic engine available, using default "
+                                    "crypto engine '%U' (%u)",
+                                    format_crypto_engine,
+                                    qm->default_crypto_engine,
+                                    qm->default_crypto_engine);
+             goto done;
+           }
+       }
       else
        {
          e = clib_error_return (0, "unknown input '%U'",
@@ -1201,7 +1226,13 @@ quic_show_connections_command_fn (vlib_main_t *vm, unformat_input_t *input,
       return 0;
     }
 
-  vlib_cli_output (vm, "engine: %s", quic_engine_type_str (qm->engine_type));
+  vlib_cli_output (vm, "quic engine: %s",
+                  quic_engine_type_str (qm->engine_type));
+  vlib_cli_output (
+    vm, "crypto engine: %s",
+    qm->default_crypto_engine == CRYPTO_ENGINE_PICOTLS ?
+      "picotls" :
+      (qm->default_crypto_engine == CRYPTO_ENGINE_VPP ? "vpp" : "none"));
   if (!unformat_user (input, unformat_line_input, line_input))
     {
       quic_show_aggregated_stats (vm);
@@ -1242,9 +1273,13 @@ done:
   return error;
 }
 
+/* TODO: This command should not be engine specific.
+ * Current implementation is for quicly engine!
+ * Fix quicly specific syntax (e.g. picotls) to be generic.
+ */
 VLIB_CLI_COMMAND (quic_plugin_crypto_command, static) = {
   .path = "quic set crypto api",
-  .short_help = "quic set crypto api [picotls|vpp]",
+  .short_help = "quic set crypto api [engine-lib|vpp]",
   .function = quic_plugin_crypto_command_fn,
 };
 VLIB_CLI_COMMAND(quic_plugin_set_fifo_size_command, static)=
@@ -1277,8 +1312,8 @@ VLIB_CLI_COMMAND (quic_set_cc, static) = {
   .function = quic_set_cc_fn,
 };
 VLIB_PLUGIN_REGISTER () = {
-  .version = VPP_BUILD_VER, .description = "Quic transport protocol",
-  // .default_disabled = 1,
+  .version = VPP_BUILD_VER,
+  .description = "Quic transport protocol",
 };
 
 static clib_error_t *
@@ -1313,7 +1348,7 @@ quic_config_fn (vlib_main_t * vm, unformat_input_t * input)
        qm->connection_timeout = i;
       else if (unformat (line_input, "fifo-prealloc %u", &i))
        qm->udp_fifo_prealloc = i;
-      // TODO: add cli selection of quic_eng_<types>
+      /* TODO: add cli selection of quic_eng_<types> */
       else
        {
          error = clib_error_return (0, "unknown input '%U'",
index 5f17a9b..b98310d 100644 (file)
@@ -84,13 +84,13 @@ quic_engine_type_str (quic_engine_type_t engine_type)
   switch (engine_type)
     {
     case QUIC_ENGINE_NONE:
-      return ("QUIC_ENGINE_NONE");
+      return ("none");
     case QUIC_ENGINE_QUICLY:
-      return ("QUIC_ENGINE_QUICLY");
+      return ("quicly");
     case QUIC_ENGINE_OPENSSL:
-      return ("QUIC_ENGINE_OPENSSL");
+      return ("openssl");
     default:
-      return ("UNKNOWN");
+      return ("unknown");
     }
 }
 extern vlib_node_registration_t quic_input_node;
@@ -224,7 +224,7 @@ typedef struct quic_rx_packet_ctx_
 #define _(type, name) type name;
   foreach_quic_rx_pkt_ctx_field
 #undef _
-    u8 padding[1024 * 128]; // FIXME: remove hardcoded size
+    u8 padding[1024 * 128]; /* FIXME: remove hardcoded size */
 } quic_rx_packet_ctx_t;
 
 typedef struct quic_worker_ctx_
@@ -241,7 +241,7 @@ typedef struct quic_main_
   vlib_node_registration_t *quic_input_node;
   u32 app_index;
   quic_worker_ctx_t *wrk_ctx;
-
+  u8 vnet_crypto_init;
   u8 default_crypto_engine; /**< Used if you do connect with CRYPTO_ENGINE_NONE
                               (0) */
   u64 max_packets_per_key;  /**< number of packets that can be sent without a
@@ -359,7 +359,8 @@ typedef enum quic_session_connected_
   QUIC_SESSION_CONNECTED_SERVER,
 } quic_session_connected_t;
 
-// TODO: Define appropriate QUIC return values for quic_engine_vft functions!
+/* TODO: Define appropriate QUIC return values for quic_engine_vft functions!
+ */
 typedef struct quic_engine_vft_
 {
   void (*engine_init) (quic_main_t *qm);
@@ -375,7 +376,7 @@ typedef struct quic_engine_vft_
   void (*connection_get_stats) (void *conn, quic_stats_t *conn_stats);
   int (*udp_session_rx_packets) (session_t *udp_session);
   void (*ack_rx_data) (session_t *stream_session);
-  int (*stream_tx) (quic_ctx_t *ctx, session_t *stream_session);
+  u64 (*stream_tx) (quic_ctx_t *ctx, session_t *stream_session);
   int (*send_packets) (quic_ctx_t *ctx);
   u8 *(*format_connection_stats) (u8 *s, va_list *args);
   u8 *(*format_stream_connection) (u8 *s, va_list *args);
index 3c076ae..f77d863 100644 (file)
@@ -223,21 +223,18 @@ quic_quicly_addr_to_ip46_addr (quicly_address_t *quicly_addr,
 static int
 quic_quicly_send_packets (quic_ctx_t *ctx)
 {
-  // TODO: GET THIS IOVEC OFF OF THE STACK!!!
-  struct iovec
-    packets[QUIC_SEND_PACKET_VEC_SIZE]; // TODO: GET THIS OFF OF THE STACK
-
-  uint8_t buf[QUIC_SEND_PACKET_VEC_SIZE *
-             quic_quicly_get_quicly_ctx_from_ctx (ctx)
-               ->transport_params.max_udp_payload_size]; // TODO: GET THIS OFF
-                                                         // OF THE STACK
+  /* TODO: GET packetsp[], buf[], next_timeout OFF OF THE STACK!!! */
+  struct iovec packets[QUIC_SEND_PACKET_VEC_SIZE];
+  uint64_t max_udp_payload_size = quic_quicly_get_quicly_ctx_from_ctx (ctx)
+                                   ->transport_params.max_udp_payload_size;
+  uint8_t buf[QUIC_SEND_PACKET_VEC_SIZE * max_udp_payload_size];
   session_t *udp_session;
   quicly_conn_t *conn;
   size_t num_packets, i, max_packets;
   u32 n_sent = 0;
   int err = 0;
   quicly_address_t quicly_rmt_ip, quicly_lcl_ip;
-  int64_t next_timeout; // TODO: GET THIS OFF OF THE STACK
+  int64_t next_timeout;
 
   /* We have sctx, get qctx */
   if (quic_ctx_is_stream (ctx))
@@ -270,6 +267,8 @@ quic_quicly_send_packets (quic_ctx_t *ctx)
        }
 
       num_packets = max_packets;
+      QUIC_DBG (3, "num_packets %u, packets %p, buf %p, buf_size %u",
+               num_packets, packets, buf, sizeof (buf));
       if ((err = quicly_send (conn, &quicly_rmt_ip, &quicly_lcl_ip, packets,
                              &num_packets, buf, sizeof (buf))))
        {
@@ -618,7 +617,7 @@ quic_quicly_update_conn_ctx (quicly_conn_t *conn,
 static void
 quic_quicly_connection_migrate (quic_ctx_t *ctx)
 {
-  u32 new_ctx_id, thread_index = vlib_get_thread_index ();
+  u32 new_ctx_index, thread_index = vlib_get_thread_index ();
   quic_ctx_t *new_ctx;
   clib_bihash_kv_16_8_t kv;
   quicly_conn_t *conn;
@@ -626,16 +625,18 @@ quic_quicly_connection_migrate (quic_ctx_t *ctx)
   session_t *udp_session;
   int64_t next_timeout;
 
-  new_ctx_id = quic_ctx_alloc (quic_quicly_main.qm, thread_index);
-  new_ctx = quic_quicly_get_quic_ctx (new_ctx_id, thread_index);
+  new_ctx_index = quic_ctx_alloc (quic_quicly_main.qm, thread_index);
+  new_ctx = quic_quicly_get_quic_ctx (new_ctx_index, thread_index);
 
-  QUIC_DBG (2, "Received conn %u (now %u)", ctx->c_thread_index, new_ctx_id);
+  QUIC_DBG (
+    2, "Migrate conn (ctx_index %u, thread %u) to new_ctx_index %u, thread %u",
+    ctx->c_c_index, ctx->c_thread_index, new_ctx_index, thread_index);
 
   clib_memcpy (new_ctx, ctx, sizeof (quic_ctx_t));
   clib_mem_free (ctx);
 
   new_ctx->c_thread_index = thread_index;
-  new_ctx->c_c_index = new_ctx_id;
+  new_ctx->c_c_index = new_ctx_index;
   quic_quicly_crypto_context_acquire (new_ctx);
 
   conn = new_ctx->conn;
@@ -644,8 +645,10 @@ quic_quicly_connection_migrate (quic_ctx_t *ctx)
 
   quic_quicly_store_conn_ctx (conn, new_ctx);
   quic_quicly_make_connection_key (&kv, quicly_get_master_id (conn));
-  kv.value = ((u64) thread_index) << 32 | (u64) new_ctx_id;
-  QUIC_DBG (2, "Registering conn with id %lu %lu", kv.key[0], kv.key[1]);
+  kv.value = ((u64) thread_index) << 32 | (u64) new_ctx_index;
+  QUIC_DBG (2, "Registering conn: key value 0x%llx, ctx_index %u, thread %u",
+           kv.value, new_ctx_index, thread_index);
+
   clib_bihash_add_del_16_8 (&quic_quicly_main.connection_hash, &kv,
                            1 /* is_add */);
   new_ctx->timer_handle = QUIC_TIMER_HANDLE_INVALID;
@@ -656,7 +659,7 @@ quic_quicly_connection_migrate (quic_ctx_t *ctx)
 
   /*  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->opaque = new_ctx_index;
   udp_session->flags &= ~SESSION_F_IS_MIGRATING;
   if (svm_fifo_max_dequeue (udp_session->tx_fifo))
     {
@@ -807,7 +810,7 @@ quic_quicly_find_packet_ctx (quic_quicly_rx_packet_ctx_t *pctx,
 
   h = &qqm->connection_hash;
   quic_quicly_make_connection_key (&kv, &pctx->packet.cid.dest.plaintext);
-  QUIC_DBG (3, "Searching conn with id %lu %lu", kv.key[0], kv.key[1]);
+  QUIC_DBG (3, "Searching conn with id 0x%llx", *(u64 *) kv.key);
 
   if (clib_bihash_search_16_8 (h, &kv, &kv))
     {
@@ -857,12 +860,17 @@ quic_quicly_accept_connection (quic_quicly_rx_packet_ctx_t *pctx)
   int rv;
   quic_quicly_main_t *qqm = &quic_quicly_main;
 
+  QUIC_DBG (2, "Accept connection: pkt ctx_index %u, thread %u",
+           pctx->ctx_index, pctx->thread_index);
+
   /* new connection, accept and create context if packet is valid
    * TODO: check if socket is actually listening? */
   ctx = quic_quicly_get_quic_ctx (pctx->ctx_index, pctx->thread_index);
   if (ctx->c_s_index != QUIC_SESSION_INVALID)
     {
-      QUIC_DBG (2, "already accepted ctx 0x%x", ctx->c_s_index);
+      QUIC_DBG (
+       2, "Accept connection (already accepted): session_index %u, thread %u",
+       ctx->c_s_index, ctx->c_thread_index);
       return;
     }
 
@@ -873,11 +881,12 @@ quic_quicly_accept_connection (quic_quicly_rx_packet_ctx_t *pctx)
     {
       /* Invalid packet, pass */
       assert (conn == NULL);
-      QUIC_ERR ("Accept failed with %U", quic_quicly_format_err, rv);
+      QUIC_ERR ("Accept connection: failed with %U", quic_quicly_format_err,
+               rv);
       /* TODO: cleanup created quic ctx and UDP session */
       return;
     }
-  assert (conn != NULL); // TODO: why this is in release image???
+  ASSERT (conn != NULL);
 
   ++qqm->next_cid[pctx->thread_index].master_id;
   /* Save ctx handle in quicly connection */
@@ -885,8 +894,11 @@ quic_quicly_accept_connection (quic_quicly_rx_packet_ctx_t *pctx)
   ctx->conn = conn;
 
   quic_session = session_alloc (ctx->c_thread_index);
-  QUIC_DBG (2, "Allocated quic_session, 0x%lx ctx %u",
-           session_handle (quic_session), ctx->c_c_index);
+  QUIC_DBG (2,
+           "Accept connection (new quic_session): session_handle 0x%lx, "
+           "session_index %u, ctx_index %u, thread %u",
+           session_handle (quic_session), quic_session->session_index,
+           ctx->c_c_index, ctx->c_thread_index);
   ctx->c_s_index = quic_session->session_index;
 
   lctx = quic_quicly_get_quic_ctx (ctx->listener_ctx_id, 0);
@@ -901,13 +913,15 @@ quic_quicly_accept_connection (quic_quicly_rx_packet_ctx_t *pctx)
   quic_quicly_make_connection_key (&kv, quicly_get_master_id (conn));
   kv.value = ((u64) pctx->thread_index) << 32 | (u64) pctx->ctx_index;
   clib_bihash_add_del_16_8 (&qqm->connection_hash, &kv, 1 /* is_add */);
-  QUIC_DBG (2, "Registering conn with id %lu %lu", kv.key[0], kv.key[1]);
+  QUIC_DBG (
+    2, "Accept connection: conn key value 0x%llx, ctx_index %u, thread %u",
+    kv.value, pctx->ctx_index, pctx->thread_index);
 
   /* If notify fails, reset connection immediatly */
   rv = app_worker_init_accepted (quic_session);
   if (rv)
     {
-      QUIC_ERR ("failed to allocate fifos");
+      QUIC_ERR ("Accept connection: failed to allocate fifos");
       quic_quicly_proto_on_close (pctx->ctx_index, pctx->thread_index);
       return;
     }
@@ -920,7 +934,7 @@ quic_quicly_accept_connection (quic_quicly_rx_packet_ctx_t *pctx)
   rv = app_worker_accept_notify (app_wrk, quic_session);
   if (rv)
     {
-      QUIC_ERR ("failed to notify accept worker app");
+      QUIC_ERR ("Accept connection: failed to notify accept worker app");
       quic_quicly_proto_on_close (pctx->ctx_index, pctx->thread_index);
       return;
     }
@@ -1024,13 +1038,15 @@ quic_quicly_connect (quic_ctx_t *ctx, u32 ctx_index,
   ++qqm->next_cid[thread_index].master_id;
   /*  save context handle in quicly connection */
   quic_quicly_store_conn_ctx (ctx->conn, ctx);
-  assert (ret == 0); // TODO: why is this in the release image???
+  ASSERT (ret == 0);
 
   /*  Register connection in connections map */
   quic_quicly_make_connection_key (
     &kv, quicly_get_master_id ((quicly_conn_t *) ctx->conn));
   kv.value = ((u64) thread_index) << 32 | (u64) ctx_index;
-  QUIC_DBG (2, "Registering conn with id %lu %lu", kv.key[0], kv.key[1]);
+  QUIC_DBG (
+    2, "UDP Session connected: conn key value 0x%llx, ctx_index %u, thread %u",
+    kv.value, ctx_index, thread_index);
   clib_bihash_add_del_16_8 (&qqm->connection_hash, &kv, 1 /* is_add */);
 
   return (ret);
@@ -1133,8 +1149,9 @@ quic_quicly_receive_a_packet (quic_ctx_t *ctx,
       QUIC_ERR ("quicly_receive return error %U", quic_quicly_format_err, rv);
     }
 
-  // FIXME: Don't return quicly error codes here.
-  // TODO: Define appropriate QUIC return values for QUIC VFT's!
+  /* FIXME: Don't return quicly error codes here.
+   * TODO: Define appropriate QUIC return values for QUIC VFT's!
+   */
   return rv;
 }
 
@@ -1149,14 +1166,18 @@ quic_quicly_connect_stream (void *quic_conn, void **quic_stream,
 
   if (!quicly_connection_is_ready (conn))
     {
-      return -1; // TODO: Define appropriate QUIC return values for QUIC VFT's!
+      /* TODO: Define appropriate QUIC return values for QUIC VFT's!
+       */
+      return -1;
     }
 
   rv = quicly_open_stream (conn, (quicly_stream_t **) quic_stream, is_unidir);
   if (rv)
     {
       QUIC_DBG (2, "quicly_open_stream() failed with %d", rv);
-      return -1; // TODO: Define appropriate QUIC return values for QUIC VFT's!
+      /* TODO: Define appropriate QUIC return values for QUIC VFT's!
+       */
+      return -1;
     }
 
   quicly_stream = *(quicly_stream_t **) quic_stream;
@@ -1174,13 +1195,12 @@ quic_quicly_connect_stream_error_reset (void *quic_stream)
                       QUIC_QUICLY_APP_CONNECT_NOTIFY_ERROR);
 }
 
-static_always_inline int
+static_always_inline u64
 quic_quicly_stream_tx (quic_ctx_t *ctx, session_t *stream_session)
 {
   quic_stream_data_t *stream_data;
   quicly_stream_t *stream;
   u32 max_deq;
-  int rv = 0;
 
   stream = ctx->stream;
   if (!quicly_sendstate_is_open (&stream->sendstate))
@@ -1194,15 +1214,16 @@ quic_quicly_stream_tx (quic_ctx_t *ctx, session_t *stream_session)
   QUIC_ASSERT (max_deq >= stream_data->app_tx_data_len);
   if (max_deq == stream_data->app_tx_data_len)
     {
-      QUIC_DBG (3, "TX but no data %d / %d", max_deq,
-               stream_data->app_tx_data_len);
+      QUIC_DBG (3,
+               "No data: max_deq %d, app_tx_data_len %d, ctx_index "
+               "%u, thread %u",
+               max_deq, stream_data->app_tx_data_len,
+               stream_session->connection_index,
+               stream_session->thread_index);
       return 0;
     }
   stream_data->app_tx_data_len = max_deq;
-  rv = quicly_stream_sync_sendbuf (stream, 1);
-  QUIC_ASSERT (!rv);
-
-  return (rv);
+  return quicly_stream_sync_sendbuf (stream, 1);
 }
 
 static void
@@ -1214,7 +1235,7 @@ quic_quicly_engine_init (quic_main_t *qm)
   tw_timer_wheel_1t_3w_1024sl_ov_t *tw;
   u32 i;
 
-  QUIC_DBG (2, "quic_quicly_engine_init -- start");
+  QUIC_DBG (2, "Quic engine init: quicly");
   qm->default_crypto_engine = CRYPTO_ENGINE_PICOTLS;
   qm->default_quic_cc = QUIC_CC_RENO;
   qm->max_packets_per_key = DEFAULT_MAX_PACKETS_PER_KEY;
@@ -1246,10 +1267,6 @@ quic_quicly_engine_init (quic_main_t *qm)
       next_cid[i].thread_id = i;
       clib_bihash_init_24_8 (&crctx_hash[i], "quic crypto contexts", 64,
                             128 << 10);
-      QUIC_DBG (2,
-               "Initialized crctx_hash[%u] "
-               "(buckets = 0x%lx)",
-               i, crctx_hash[i].buckets);
     }
 }
 
@@ -1329,8 +1346,9 @@ quic_quicly_udp_session_rx_packets (session_t *udp_session)
   int rv = 0;
   clib_thread_index_t thread_index = vlib_get_thread_index ();
   u32 cur_deq, fifo_offset, max_packets, i;
-  // TODO: move packet buffer off of the stack and
-  //       allocate a vector of packet_ct_t.
+  /* TODO: move packet buffer off of the stack and
+   *       allocate a vector of packet_ct_t.
+   */
   quic_quicly_rx_packet_ctx_t packets_ctx[QUIC_RCV_MAX_PACKETS];
 
   if (udp_session->flags & SESSION_F_IS_MIGRATING)
@@ -1392,15 +1410,15 @@ rx_start:
        case QUIC_PACKET_TYPE_RECEIVE:
          ctx =
            quic_quicly_get_quic_ctx (packets_ctx[i].ctx_index, thread_index);
-         // FIXME: Process return value and handle errors.
+         /* FIXME: Process return value and handle errors. */
          quic_quicly_receive_a_packet (ctx, &packets_ctx[i]);
          break;
        case QUIC_PACKET_TYPE_ACCEPT:
-         // FIXME: Process return value and handle errors.
+         /* FIXME: Process return value and handle errors. */
          quic_quicly_accept_connection (&packets_ctx[i]);
          break;
        case QUIC_PACKET_TYPE_RESET:
-         // FIXME: Process return value and handle errors.
+         /* FIXME: Process return value and handle errors. */
          quic_quicly_reset_connection (udp_session_handle, &packets_ctx[i]);
          break;
        }
index 516e542..d5610bf 100644 (file)
@@ -54,8 +54,7 @@ typedef struct quic_quicly_session_cache_
 typedef struct quic_quicly_main_
 {
   quic_main_t *qm;
-  ptls_cipher_suite_t **
-    *quic_ciphers; /**< available ciphers by crypto engine */
+  ptls_cipher_suite_t ***quic_ciphers;
   u32 *per_thread_crypto_key_indices;
   ptls_handshake_properties_t hs_properties;
   clib_bihash_16_8_t connection_hash; /**< quic connection id -> conn handle */
index 12f07c1..dc3a16a 100644 (file)
@@ -72,8 +72,8 @@ quic_quicly_crypto_context_alloc (u8 thread_index)
   clib_memset (crctx, 0, sizeof (*crctx));
   idx = (crctx - wc->crypto_ctx_pool);
   crctx->ctx_index = QUIC_CRCTX_CTX_INDEX_ENCODE (thread_index, idx);
-  QUIC_DBG (2, "Allocated crctx_ndx 0x%08lx (%u) on thread %u",
-           crctx->ctx_index, crctx->ctx_index, thread_index);
+  QUIC_DBG (2, "Allocated crctx: crctx_ndx 0x%08lx, index %u, thread %u",
+           crctx->ctx_index, idx, thread_index);
 
   return crctx;
 }
@@ -250,37 +250,48 @@ quic_quicly_init_crypto_context (crypto_context_t *crctx, quic_ctx_t *ctx)
   application_t *app;
   quic_quicly_crypto_context_data_t *data;
   ptls_context_t *ptls_ctx;
-  u32 i;
 
   ASSERT (QUIC_CRCTX_CTX_INDEX_DECODE_THREAD (crctx->ctx_index) ==
          ctx->c_thread_index);
   ASSERT (QUIC_CRCTX_CTX_INDEX_DECODE_THREAD (crctx->ctx_index) ==
          vlib_get_thread_index ());
-  QUIC_DBG (2, "Init crypto context: crctx_ndx 0x%08lx (%u), thread %d",
-           crctx->ctx_index, crctx->ctx_index, ctx->c_thread_index);
-  quic_quicly_register_cipher_suite (CRYPTO_ENGINE_PICOTLS,
-                                    ptls_openssl_cipher_suites);
-
-  vnet_crypto_main_t *cm = &crypto_main;
-  if (vec_len (cm->engines) > 0)
-    qqm->vnet_crypto_enabled = 0;
-  else
+  QUIC_DBG (2, "Init crctx: crctx_ndx 0x%08lx, thread %d", crctx->ctx_index,
+           ctx->c_thread_index);
+
+  if (PREDICT_FALSE (!qm->vnet_crypto_init))
     {
-      qqm->vnet_crypto_enabled = 1;
-      u8 empty_key[32] = {};
-      quic_quicly_register_cipher_suite (CRYPTO_ENGINE_VPP,
-                                        quic_quicly_crypto_cipher_suites);
-      qm->default_crypto_engine = CRYPTO_ENGINE_VPP;
-      vec_validate (qqm->per_thread_crypto_key_indices, qm->num_threads);
-      for (i = 0; i < qm->num_threads; i++)
+      qm->vnet_crypto_init = 1;
+      if ((vec_len (cm->engines) == 0) ||
+         (qm->default_crypto_engine == CRYPTO_ENGINE_PICOTLS))
        {
-         qqm->per_thread_crypto_key_indices[i] = vnet_crypto_key_add (
-           vlib_get_main (), VNET_CRYPTO_ALG_AES_256_CTR, empty_key, 32);
+         qqm->vnet_crypto_enabled = 0;
+         (void) quic_quicly_register_cipher_suite (
+           CRYPTO_ENGINE_PICOTLS, ptls_openssl_cipher_suites);
+       }
+      else
+       {
+         qqm->vnet_crypto_enabled = 1;
+         if (quic_quicly_register_cipher_suite (
+               CRYPTO_ENGINE_VPP, quic_quicly_crypto_cipher_suites))
+           {
+             u8 empty_key[32] = {};
+             u32 i;
+             qm->default_crypto_engine = ctx->crypto_engine =
+               CRYPTO_ENGINE_VPP;
+             vec_validate (qqm->per_thread_crypto_key_indices,
+                           qm->num_threads);
+             for (i = 0; i < qm->num_threads; i++)
+               {
+                 qqm->per_thread_crypto_key_indices[i] = vnet_crypto_key_add (
+                   vlib_get_main (), VNET_CRYPTO_ALG_AES_256_CTR, empty_key,
+                   32);
+               }
+           }
        }
-    }
 
   /* TODO: Remove this and clean up legacy provider code in quicly */
   quic_quicly_load_openssl3_legacy_provider ();
+    }
 
   data = clib_mem_alloc (sizeof (*data));
   /* picotls depends on data being zeroed */
@@ -293,6 +304,9 @@ quic_quicly_init_crypto_context (crypto_context_t *crctx, quic_ctx_t *ctx)
   ptls_ctx->get_time = &ptls_get_time;
   ptls_ctx->key_exchanges = ptls_openssl_key_exchanges;
   ptls_ctx->cipher_suites = qqm->quic_ciphers[ctx->crypto_engine];
+  QUIC_DBG (2, "Init crctx: engine_type %U (%u), cipher_suites %p",
+           format_crypto_engine, ctx->crypto_engine, ctx->crypto_engine,
+           ptls_ctx->cipher_suites);
   ptls_ctx->certificates.list = NULL;
   ptls_ctx->certificates.count = 0;
   ptls_ctx->on_client_hello = NULL;
@@ -313,11 +327,19 @@ quic_quicly_init_crypto_context (crypto_context_t *crctx, quic_ctx_t *ctx)
   quicly_ctx->now = &quicly_vpp_now_cb;
   quicly_amend_ptls_context (quicly_ctx->tls);
 
-  if (qqm->vnet_crypto_enabled &&
-      qm->default_crypto_engine == CRYPTO_ENGINE_VPP)
-    quicly_ctx->crypto_engine = &quic_quicly_crypto_engine;
+  if (qqm->vnet_crypto_enabled && ctx->crypto_engine == CRYPTO_ENGINE_VPP)
+    {
+  QUIC_DBG (2, "Init crctx: crypto engine vpp, crctx_ndx 0x%08lx, thread %d",
+           crctx->ctx_index, ctx->c_thread_index);
+  quicly_ctx->crypto_engine = &quic_quicly_crypto_engine;
+    }
   else
-    quicly_ctx->crypto_engine = &quicly_default_crypto_engine;
+    {
+  QUIC_DBG (2,
+           "Init crctx: crypto engine quicly, crctx_ndx 0x%08lx, thread %d",
+           crctx->ctx_index, ctx->c_thread_index);
+  quicly_ctx->crypto_engine = &quicly_default_crypto_engine;
+    }
 
   quicly_ctx->transport_params.max_data = QUIC_INT_MAX;
   quicly_ctx->transport_params.max_streams_uni = (uint64_t) 1 << 60;
@@ -369,10 +391,12 @@ quic_quicly_init_crypto_context (crypto_context_t *crctx, quic_ctx_t *ctx)
 }
 
 void
-quic_quicly_crypto_context_release (u32 crypto_context_index, u8 thread_index)
+quic_quicly_crypto_context_release (u32 crctx_ndx, u8 thread_index)
 {
   crypto_context_t *crctx;
-  crctx = quic_quicly_crypto_context_get (crypto_context_index, thread_index);
+  QUIC_DBG (3, "crctx_ndx 0x%x (%u), thread %u", crctx_ndx, crctx_ndx,
+           thread_index);
+  crctx = quic_quicly_crypto_context_get (crctx_ndx, thread_index);
   crctx->n_subscribers--;
   quic_quicly_crypto_context_free_if_needed (crctx, thread_index);
 }
@@ -389,18 +413,9 @@ quic_quicly_crypto_context_acquire (quic_ctx_t *ctx)
   crypto_context_t *crctx;
   clib_bihash_kv_24_8_t kv;
 
-  if (ctx->crypto_engine == CRYPTO_ENGINE_NONE)
-    {
-      QUIC_DBG (2, "No crypto engine specified, using %U",
-               format_crypto_engine, qm->default_crypto_engine);
-      ctx->crypto_engine = qm->default_crypto_engine;
-    }
-  if (!clib_bitmap_get (qqm->available_crypto_engines, ctx->crypto_engine))
-    {
-      QUIC_DBG (1, "Quic does not support crypto engine %U",
-               format_crypto_engine, ctx->crypto_engine);
-      return SESSION_E_NOCRYPTOENG;
-    }
+  ctx->crypto_engine = (ctx->crypto_engine == CRYPTO_ENGINE_NONE) ?
+                        qm->default_crypto_engine :
+                        ctx->crypto_engine;
   /* Check for exisiting crypto ctx */
   quic_quicly_crypto_context_make_key_from_ctx (&kv, ctx);
   if (clib_bihash_search_24_8 (&crctx_hash[ctx->c_thread_index], &kv, &kv) ==
@@ -515,12 +530,13 @@ quic_quicly_crypto_set_key (crypto_key_t *key)
   u32 key_id = qqm->per_thread_crypto_key_indices[thread_index];
   vnet_crypto_key_t *vnet_key = vnet_crypto_get_key (key_id);
   vnet_crypto_engine_t *engine;
-  vnet_crypto_main_t *cm = &crypto_main;
 
   vec_foreach (engine, cm->engines)
     if (engine->key_op_handler)
       engine->key_op_handler (VNET_CRYPTO_KEY_OP_DEL, key_id);
 
+  ASSERT (key->algo);
+  ASSERT (key->key_len);
   vnet_key->alg = key->algo;
   clib_memcpy (vnet_key->data, key->key, key->key_len);
 
@@ -544,7 +560,7 @@ quic_quicly_crypto_encrypt_packet (struct st_quicly_crypto_engine_t *engine,
 
   struct cipher_context_t *hp_ctx =
     (struct cipher_context_t *) header_protect_ctx;
-  struct aead_crypto_context_t *aead_ctx =
+  struct aead_crypto_context_t *aead_crctx =
     (struct aead_crypto_context_t *) packet_protect_ctx;
 
   void *input = datagram.base + payload_from;
@@ -555,20 +571,26 @@ quic_quicly_crypto_encrypt_packet (struct st_quicly_crypto_engine_t *engine,
   size_t aadlen = payload_from - first_byte_at;
 
   /* Build AEAD encrypt crypto operation */
-  vnet_crypto_op_init (&aead_ctx->op, aead_ctx->id);
-  aead_ctx->op.aad = (u8 *) aad;
-  aead_ctx->op.aad_len = aadlen;
-  aead_ctx->op.iv = aead_ctx->iv;
-  ptls_aead__build_iv (aead_ctx->super.algo, aead_ctx->op.iv,
-                      aead_ctx->static_iv, packet_number);
-  aead_ctx->op.key_index = quic_quicly_crypto_set_key (&aead_ctx->key);
-  aead_ctx->op.src = (u8 *) input;
-  aead_ctx->op.dst = output;
-  aead_ctx->op.len = inlen;
-  aead_ctx->op.tag_len = aead_ctx->super.algo->tag_size;
-  aead_ctx->op.tag = aead_ctx->op.src + inlen;
-  vnet_crypto_process_ops (vm, &(aead_ctx->op), 1);
-  assert (aead_ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
+  vnet_crypto_op_init (&aead_crctx->op, aead_crctx->id);
+  aead_crctx->op.aad = (u8 *) aad;
+  aead_crctx->op.aad_len = aadlen;
+  aead_crctx->op.iv = aead_crctx->iv;
+  ptls_aead__build_iv (aead_crctx->super.algo, aead_crctx->op.iv,
+                      aead_crctx->static_iv, packet_number);
+  QUIC_DBG (
+    3, "id %u, key %p, algo %u, key_len %u, key 0x%llx 0x%llx 0x%llx 0x%llx ",
+    aead_crctx->id, &aead_crctx->key, aead_crctx->key.algo,
+    aead_crctx->key.key_len, *(u64 *) &aead_crctx->key.key[0],
+    *(u64 *) &aead_crctx->key.key[8], *(u64 *) &aead_crctx->key.key[16],
+    *(u64 *) &aead_crctx->key.key[24]);
+  aead_crctx->op.key_index = quic_quicly_crypto_set_key (&aead_crctx->key);
+  aead_crctx->op.src = (u8 *) input;
+  aead_crctx->op.dst = output;
+  aead_crctx->op.len = inlen;
+  aead_crctx->op.tag_len = aead_crctx->super.algo->tag_size;
+  aead_crctx->op.tag = aead_crctx->op.src + inlen;
+  vnet_crypto_process_ops (vm, &(aead_crctx->op), 1);
+  assert (aead_crctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
 
   /* Build Header protection crypto operation */
   ptls_aead_supplementary_encryption_t supp = {
@@ -605,24 +627,31 @@ quic_quicly_crypto_aead_decrypt (quic_ctx_t *qctx, ptls_aead_context_t *_ctx,
 {
   vlib_main_t *vm = vlib_get_main ();
 
-  struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *) _ctx;
-
-  vnet_crypto_op_init (&ctx->op, ctx->id);
-  ctx->op.aad = (u8 *) aad;
-  ctx->op.aad_len = aadlen;
-  ctx->op.iv = ctx->iv;
-  ptls_aead__build_iv (ctx->super.algo, ctx->op.iv, ctx->static_iv,
-                      decrypted_pn);
-  ctx->op.src = (u8 *) input;
-  ctx->op.dst = _output;
-  ctx->op.key_index = quic_quicly_crypto_set_key (&ctx->key);
-  ctx->op.len = inlen - ctx->super.algo->tag_size;
-  ctx->op.tag_len = ctx->super.algo->tag_size;
-  ctx->op.tag = ctx->op.src + ctx->op.len;
-
-  vnet_crypto_process_ops (vm, &(ctx->op), 1);
-
-  return ctx->op.len;
+  struct aead_crypto_context_t *aead_crctx =
+    (struct aead_crypto_context_t *) _ctx;
+
+  vnet_crypto_op_init (&aead_crctx->op, aead_crctx->id);
+  aead_crctx->op.aad = (u8 *) aad;
+  aead_crctx->op.aad_len = aadlen;
+  aead_crctx->op.iv = aead_crctx->iv;
+  ptls_aead__build_iv (aead_crctx->super.algo, aead_crctx->op.iv,
+                      aead_crctx->static_iv, decrypted_pn);
+  aead_crctx->op.src = (u8 *) input;
+  aead_crctx->op.dst = _output;
+  QUIC_DBG (
+    3, "id %u, key %p, algo %u, key_len %u, key 0x%llx 0x%llx 0x%llx 0x%llx ",
+    aead_crctx->id, &aead_crctx->key, aead_crctx->key.algo,
+    aead_crctx->key.key_len, *(u64 *) &aead_crctx->key.key[0],
+    *(u64 *) &aead_crctx->key.key[8], *(u64 *) &aead_crctx->key.key[16],
+    *(u64 *) &aead_crctx->key.key[24]);
+  aead_crctx->op.key_index = quic_quicly_crypto_set_key (&aead_crctx->key);
+  aead_crctx->op.len = inlen - aead_crctx->super.algo->tag_size;
+  aead_crctx->op.tag_len = aead_crctx->super.algo->tag_size;
+  aead_crctx->op.tag = aead_crctx->op.src + aead_crctx->op.len;
+
+  vnet_crypto_process_ops (vm, &(aead_crctx->op), 1);
+
+  return aead_crctx->op.len;
 }
 
 void
@@ -630,7 +659,7 @@ quic_quicly_crypto_decrypt_packet (quic_ctx_t *qctx,
                                   quic_quicly_rx_packet_ctx_t *pctx)
 {
   ptls_cipher_context_t *header_protection = NULL;
-  ptls_aead_context_t *aead = NULL;
+  ptls_aead_context_t *ptls_aead_ctx = NULL;
   int pn;
 
   /* Long Header packets are not decrypted by vpp */
@@ -642,10 +671,10 @@ quic_quicly_crypto_decrypt_packet (quic_ctx_t *qctx,
   if (next_expected_packet_number == UINT64_MAX)
     return;
 
-  aead = (ptls_aead_context_t *) qctx->ingress_keys.aead_ctx;
+  ptls_aead_ctx = (ptls_aead_context_t *) qctx->ingress_keys.aead_ctx;
   header_protection = (ptls_cipher_context_t *) qctx->ingress_keys.hp_ctx;
 
-  if (!aead || !header_protection)
+  if (!ptls_aead_ctx || !header_protection)
     return;
 
   size_t encrypted_len = pctx->packet.octets.len - pctx->packet.encrypted_off;
@@ -695,7 +724,7 @@ quic_quicly_crypto_decrypt_packet (quic_ctx_t *qctx,
     }
 
   if ((ptlen = quic_quicly_crypto_aead_decrypt (
-        qctx, aead, pctx->packet.octets.base + aead_off,
+        qctx, ptls_aead_ctx, pctx->packet.octets.base + aead_off,
         pctx->packet.octets.base + aead_off,
         pctx->packet.octets.len - aead_off, pn, pctx->packet.octets.base,
         aead_off)) == SIZE_MAX)
@@ -743,15 +772,17 @@ quic_quicly_crypto_cipher_setup_crypto (ptls_cipher_context_t *_ctx,
 
   if (qqm->vnet_crypto_enabled)
     {
-      // TODO: why is this commented out (from original quic plugin)?
-      //       ctx->key_index =
-      //   quic_quicly_crypto_go_setup_key (algo, key, _ctx->algo->key_size);
       ctx->key.algo = algo;
       ctx->key.key_len = _ctx->algo->key_size;
       assert (ctx->key.key_len <= 32);
       clib_memcpy (&ctx->key.key, key, ctx->key.key_len);
     }
 
+  QUIC_DBG (
+    2, "id %u, key %p, algo %u, key_len %u, key 0x%llx 0x%llx 0x%llx 0x%llx ",
+    ctx->id, &ctx->key, ctx->key.algo, ctx->key.key_len,
+    *(u64 *) &ctx->key.key[0], *(u64 *) &ctx->key.key[8],
+    *(u64 *) &ctx->key.key[16], *(u64 *) &ctx->key.key[24]);
   return 0;
 }
 
@@ -803,15 +834,17 @@ quic_quicly_crypto_aead_setup_crypto (ptls_aead_context_t *_ctx, int is_enc,
   if (qqm->vnet_crypto_enabled)
     {
       clib_memcpy (ctx->static_iv, iv, ctx->super.algo->iv_size);
-      // TODO: why is this commented out (from original quic plugin)?
-      //       ctx->key_index =
-      //   quic_quicly_crypto_go_setup_key (algo, key, _ctx->algo->key_size);
       ctx->key.algo = algo;
       ctx->key.key_len = _ctx->algo->key_size;
       assert (ctx->key.key_len <= 32);
       clib_memcpy (&ctx->key.key, key, ctx->key.key_len);
     }
 
+  QUIC_DBG (
+    3, "id %u, key %p, algo %u, key_len %u, key 0x%llx 0x%llx 0x%llx 0x%llx ",
+    ctx->id, &ctx->key, ctx->key.algo, ctx->key.key_len,
+    *(u64 *) &ctx->key.key[0], *(u64 *) &ctx->key.key[8],
+    *(u64 *) &ctx->key.key[16], *(u64 *) &ctx->key.key[24]);
   return 0;
 }
 
index c4e09bf..75abab2 100644 (file)
@@ -37,8 +37,6 @@ quic_quicly_crypto_context_get (u32 cr_index, u32 thread_index)
 #define quic_quicly_load_openssl3_legacy_provider()
 #endif
 
-extern vnet_crypto_main_t *cm;
-
 typedef struct crypto_key_
 {
   vnet_crypto_alg_t algo;
@@ -73,14 +71,34 @@ typedef struct quic_quicly_crypto_context_data_
   ptls_context_t ptls_ctx;
 } quic_quicly_crypto_context_data_t;
 
-static_always_inline void
+static_always_inline u8
 quic_quicly_register_cipher_suite (crypto_engine_type_t type,
                                   ptls_cipher_suite_t **ciphers)
 {
   quic_quicly_main_t *qqm = &quic_quicly_main;
-  vec_validate (qqm->quic_ciphers, type);
-  clib_bitmap_set (qqm->available_crypto_engines, type, 1);
-  qqm->quic_ciphers[type] = ciphers;
+  u8 rv = 1;
+
+  if (!qqm->quic_ciphers)
+    {
+      vec_validate (qqm->quic_ciphers, type);
+    }
+  if (!qqm->quic_ciphers[type])
+    {
+      QUIC_DBG (3,
+               "Register cipher suite: engine_type %U (%u), cipher_suites %p",
+               format_crypto_engine, type, type, ciphers);
+      clib_bitmap_set (qqm->available_crypto_engines, type, 1);
+      qqm->quic_ciphers[type] = ciphers;
+    }
+  else
+    {
+      QUIC_DBG (3,
+               "Cipher suite already registered: engine_type %U (%u), "
+               "cipher_suites %p",
+               format_crypto_engine, type, type, ciphers);
+      rv = 0;
+    }
+  return rv;
 }
 
 extern quicly_crypto_engine_t quic_quicly_crypto_engine;
index 9f8d75e..c769f97 100644 (file)
@@ -116,8 +116,13 @@ class QUICTestCase(VppAsfTestCase):
         self.ip_t01.add_vpp_config()
         self.ip_t10.add_vpp_config()
         self.logger.debug(self.vapi.cli("show ip fib"))
+        # TODO: refactor test suites to use all crypto cipher suites
+        # self.vapi.cli("quic set crypto api vpp")
+        # self.vapi.cli("quic set crypto api engine-lib")
+        self.logger.debug(self.vapi.cli("show quic"))
 
     def tearDown(self):
+        self.logger.debug(self.vapi.cli("show quic"))
         self.vapi.app_namespace_add_del_v4(
             is_add=0,
             namespace_id=self.server_appns,