/* 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)
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);
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;
/* 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);
}
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;
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
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;
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);
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);
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);
}
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];
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'",
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);
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)=
.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 *
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'",
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;
#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_
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
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);
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);
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))
}
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))))
{
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;
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;
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;
/* 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))
{
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))
{
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;
}
{
/* 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 */
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);
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;
}
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;
}
++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);
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;
}
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;
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))
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
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;
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);
}
}
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)
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;
}
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 */
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;
}
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 */
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;
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;
}
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);
}
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) ==
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);
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;
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 = {
{
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
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 */
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;
}
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)
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;
}
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;
}
#define quic_quicly_load_openssl3_legacy_provider()
#endif
-extern vnet_crypto_main_t *cm;
-
typedef struct crypto_key_
{
vnet_crypto_alg_t algo;
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;
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,