X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fquic%2Fquic.c;h=3dab5eb4d0787428d81966af00d5c1b2f6935aee;hb=24adebad278b88b26bdae5615b6dea94dba7b757;hp=5a57947325af92b84a5539b6ef7046ae378891a5;hpb=94a6df005d9e94f3b836ad3c93d1464b4a840499;p=vpp.git diff --git a/src/plugins/quic/quic.c b/src/plugins/quic/quic.c index 5a57947325a..3dab5eb4d07 100644 --- a/src/plugins/quic/quic.c +++ b/src/plugins/quic/quic.c @@ -388,7 +388,8 @@ quic_ctx_alloc (u32 thread_index) quic_main_t *qm = &quic_main; quic_ctx_t *ctx; - pool_get (qm->ctx_pool[thread_index], ctx); + pool_get_aligned_safe (qm->ctx_pool[thread_index], ctx, + CLIB_CACHE_LINE_BYTES); clib_memset (ctx, 0, sizeof (quic_ctx_t)); ctx->c_thread_index = thread_index; @@ -572,6 +573,12 @@ quic_connection_delete (quic_ctx_t * ctx) clib_bihash_kv_16_8_t kv; quicly_conn_t *conn; + if (ctx->conn == NULL) + { + QUIC_DBG (2, "Skipping redundant delete of connection %u", + ctx->c_c_index); + return; + } QUIC_DBG (2, "Deleting connection %u", ctx->c_c_index); QUIC_ASSERT (!quic_ctx_is_stream (ctx)); @@ -587,8 +594,8 @@ quic_connection_delete (quic_ctx_t * ctx) quic_disconnect_transport (ctx); - if (ctx->conn) - quicly_free (ctx->conn); + if (conn) + quicly_free (conn); session_transport_delete_notify (&ctx->connection); } @@ -669,6 +676,7 @@ quic_send_datagram (session_t *udp_session, struct iovec *packet, hdr.is_ip4 = tc->is_ip4; clib_memcpy (&hdr.lcl_ip, &tc->lcl_ip, sizeof (ip46_address_t)); hdr.lcl_port = tc->lcl_port; + hdr.gso_size = 0; /* Read dest address from quicly-provided sockaddr */ if (hdr.is_ip4) @@ -824,12 +832,13 @@ quic_on_receive (quicly_stream_t * stream, size_t off, const void *src, size_t len) { QUIC_DBG (3, "received data: %lu bytes, offset %lu", len, off); - u32 max_enq, rlen, rv; + u32 max_enq, rv; quic_ctx_t *sctx; session_t *stream_session; app_worker_t *app_wrk; svm_fifo_t *f; quic_stream_data_t *stream_data; + int rlen; if (!len) return; @@ -870,6 +879,14 @@ quic_on_receive (quicly_stream_t * stream, size_t off, const void *src, { /* Streams live on the same thread so (f, stream_data) should stay consistent */ rlen = svm_fifo_enqueue (f, len, (u8 *) src); + if (PREDICT_FALSE (rlen < 0)) + { + /* + * drop, fifo full + * drop, fifo grow + */ + return; + } QUIC_DBG (3, "Session [idx %u, app_wrk %u, ti %u, rx-fifo 0x%llx]: " "Enqueuing %u (rlen %u) at off %u in %u space, ", stream_session->session_index, @@ -892,6 +909,14 @@ quic_on_receive (quicly_stream_t * stream, size_t off, const void *src, rlen = svm_fifo_enqueue_with_offset (f, off - stream_data->app_rx_data_len, len, (u8 *) src); + if (PREDICT_FALSE (rlen < 0)) + { + /* + * drop, fifo full + * drop, fifo grow + */ + return; + } QUIC_ASSERT (rlen == 0); } return; @@ -1008,6 +1033,7 @@ quic_on_stream_open (quicly_stream_open_t * self, quicly_stream_t * stream) sctx->stream = stream; sctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP; sctx->flags |= QUIC_F_IS_STREAM; + sctx->crypto_context_index = qctx->crypto_context_index; if (quicly_stream_is_unidirectional (stream->stream_id)) stream_session->flags |= SESSION_F_UNIDIRECTIONAL; @@ -1142,7 +1168,9 @@ quic_update_timer (quic_ctx_t * ctx) } } - tw = &quic_main.wrk_ctx[vlib_get_thread_index ()].timer_wheel; + ASSERT (vlib_get_thread_index () == ctx->c_thread_index || + vlib_get_thread_index () == 0); + tw = &quic_main.wrk_ctx[ctx->c_thread_index].timer_wheel; QUIC_DBG (4, "Timer set to %ld (int %ld) for ctx %u", next_timeout, next_interval, ctx->c_c_index); @@ -1246,6 +1274,7 @@ quic_connect_stream (session_t * quic_session, session_endpoint_cfg_t * sep) quic_increment_counter (QUIC_ERROR_OPENED_STREAM, 1); sctx->stream = stream; + sctx->crypto_context_index = qctx->crypto_context_index; QUIC_DBG (2, "Opened stream %d, creating session", stream->stream_id); @@ -1298,16 +1327,17 @@ quic_connect_connection (session_endpoint_cfg_t * sep) vnet_connect_args_t _cargs, *cargs = &_cargs; transport_endpt_crypto_cfg_t *ccfg; quic_main_t *qm = &quic_main; + u32 ctx_index, thread_index; quic_ctx_t *ctx; app_worker_t *app_wrk; application_t *app; - u32 ctx_index; - u32 thread_index = vlib_get_thread_index (); int error; if (!sep->ext_cfg) return SESSION_E_NOEXTCFG; + /* Use pool on thread 1 if we have workers because of UDP */ + thread_index = transport_cl_thread (); ccfg = &sep->ext_cfg->crypto; clib_memset (cargs, 0, sizeof (*cargs)); @@ -1430,7 +1460,8 @@ quic_proto_on_close (u32 ctx_index, u32 thread_index) } static u32 -quic_start_listen (u32 quic_listen_session_index, transport_endpoint_t * tep) +quic_start_listen (u32 quic_listen_session_index, + transport_endpoint_cfg_t *tep) { vnet_listen_args_t _bargs, *args = &_bargs; transport_endpt_crypto_cfg_t *ccfg; @@ -1785,11 +1816,15 @@ quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index, app_worker_t *app_wrk; quicly_conn_t *conn; quic_ctx_t *ctx; - u32 thread_index = vlib_get_thread_index (); + u32 thread_index; int ret; quicly_context_t *quicly_ctx; - + /* Allocate session on whatever thread udp used, i.e., probably first + * worker, although this may be main thread. If it is main, it's done + * with a worker barrier */ + thread_index = udp_session->thread_index; + ASSERT (thread_index == 0 || thread_index == 1); ctx = quic_ctx_get (ctx_index, thread_index); if (err) { @@ -1803,9 +1838,6 @@ quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index, return 0; } - ctx->c_thread_index = thread_index; - ctx->c_c_index = ctx_index; - QUIC_DBG (2, "New ctx [%u]%x", thread_index, (ctx) ? ctx_index : ~0); ctx->udp_session_handle = session_handle (udp_session); @@ -1833,11 +1865,7 @@ quic_udp_session_connected_callback (u32 quic_app_index, u32 ctx_index, QUIC_DBG (2, "Registering conn with id %lu %lu", kv.key[0], kv.key[1]); clib_bihash_add_del_16_8 (&quic_main.connection_hash, &kv, 1 /* is_add */ ); - /* UDP stack quirk? preemptively transfer connection if that happens */ - if (udp_session->thread_index != thread_index) - quic_transfer_connection (ctx_index, udp_session->thread_index); - else - quic_send_packets (ctx); + quic_send_packets (ctx); return ret; } @@ -1921,6 +1949,7 @@ quic_udp_session_accepted_callback (session_t * udp_session) ctx->ckpair_index = lctx->ckpair_index; quic_acquire_crypto_context (ctx); udp_session->opaque = ctx_index; + udp_session->session_state = SESSION_STATE_READY; /* TODO timeout to delete these if they never connect */ return 0; @@ -2541,6 +2570,7 @@ quic_init (vlib_main_t * vm) transport_register_protocol (TRANSPORT_PROTO_QUIC, &quic_proto, FIB_PROTOCOL_IP6, ~0); + quic_load_openssl3_legacy_provider (); clib_bitmap_alloc (qm->available_crypto_engines, app_crypto_engine_n_types ()); quic_register_cipher_suite (CRYPTO_ENGINE_PICOTLS, @@ -2554,14 +2584,19 @@ quic_init (vlib_main_t * vm) qm->vnet_crypto_enabled = 1; if (qm->vnet_crypto_enabled == 1) { + u8 empty_key[32] = {}; quic_register_cipher_suite (CRYPTO_ENGINE_VPP, quic_crypto_cipher_suites); qm->default_crypto_engine = CRYPTO_ENGINE_VPP; + vec_validate (qm->per_thread_crypto_key_indices, num_threads); + for (i = 0; i < num_threads; i++) + { + qm->per_thread_crypto_key_indices[i] = vnet_crypto_key_add ( + vm, VNET_CRYPTO_ALG_AES_256_CTR, empty_key, 32); + } } qm->max_packets_per_key = DEFAULT_MAX_PACKETS_PER_KEY; - clib_rwlock_init (&qm->crypto_keys_quic_rw_lock); - qm->default_quic_cc = QUIC_CC_RENO; vec_free (a->name); @@ -2642,7 +2677,6 @@ quic_get_counter_value (u32 event_code) u32 code, i; u64 c, sum = 0; - int index = 0; vm = vlib_get_main (); em = &vm->error_main; @@ -2657,7 +2691,6 @@ quic_get_counter_value (u32 event_code) if (i < vec_len (em->counters_last_clear)) c -= em->counters_last_clear[i]; sum += c; - index++; } return sum; } @@ -2948,7 +2981,7 @@ quic_config_fn (vlib_main_t * vm, unformat_input_t * input) while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (input, "fifo-size %U", unformat_memory_size, &tmp)) + if (unformat (line_input, "fifo-size %U", unformat_memory_size, &tmp)) { if (tmp >= 0x100000000ULL) { @@ -2959,9 +2992,9 @@ quic_config_fn (vlib_main_t * vm, unformat_input_t * input) } qm->udp_fifo_size = tmp; } - else if (unformat (input, "conn-timeout %u", &i)) + else if (unformat (line_input, "conn-timeout %u", &i)) qm->connection_timeout = i; - else if (unformat (input, "fifo-prealloc %u", &i)) + else if (unformat (line_input, "fifo-prealloc %u", &i)) qm->udp_fifo_prealloc = i; else {