From caa7acf5c55a78ef4f7addfb94da0ad788f59a75 Mon Sep 17 00:00:00 2001 From: Nathan Skrzypczak Date: Wed, 2 Oct 2019 10:02:05 +0200 Subject: [PATCH] session: add is_migrating flag Type: fix Add SESSION_F_IS_MIGRATING flag for session. It is set by the session layer before poking the transport for migration. It's the transport responsibility to unset the flag & act apropriatly if RX happens on a migrating session. Change-Id: Ie722917f1cf9344d8f041cad4ed8b064fb5853b6 Signed-off-by: Nathan Skrzypczak --- src/plugins/quic/quic.c | 86 +++++++++++++++++----------------------- src/plugins/quic/quic.h | 1 + src/vnet/session/session.c | 1 + src/vnet/session/session_types.h | 1 + 4 files changed, 40 insertions(+), 49 deletions(-) diff --git a/src/plugins/quic/quic.c b/src/plugins/quic/quic.c index 4b2bbefb5f1..291f54608cd 100644 --- a/src/plugins/quic/quic.c +++ b/src/plugins/quic/quic.c @@ -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; } } @@ -1079,6 +1072,9 @@ quic_connect_connection (session_endpoint_cfg_t * sep) cargs->sep_ext.ns_index = app->ns_index; quic_store_quicly_ctx (app, 1 /* is client */ ); + /* 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; @@ -1185,6 +1181,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 +1436,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 +1511,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 +1559,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 +1604,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 +1840,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 +1857,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 +1961,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 +1987,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++) { diff --git a/src/plugins/quic/quic.h b/src/plugins/quic/quic.h index d26ad37a01b..dacf07a14ad 100644 --- a/src/plugins/quic/quic.h +++ b/src/plugins/quic/quic.h @@ -122,6 +122,7 @@ typedef struct quic_ctx_ u32 parent_app_wrk_id; u32 parent_app_id; u8 flags; + quicly_context_t *quicly_ctx; } quic_ctx_t; /* Make sure our custom fields don't overlap with the fields we use in diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index be62d929363..f1360226152 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -799,6 +799,7 @@ session_dgram_connect_notify (transport_connection_t * tc, new_s->rx_fifo->master_session_index = new_s->session_index; new_s->rx_fifo->master_thread_index = new_s->thread_index; new_s->session_state = SESSION_STATE_READY; + new_s->flags |= SESSION_F_IS_MIGRATING; session_lookup_add_connection (tc, session_handle (new_s)); /* diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index bf45855e264..03f7096c4b8 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -148,6 +148,7 @@ typedef enum session_flags_ SESSION_F_RX_EVT = 1, SESSION_F_PROXY = (1 << 1), SESSION_F_CUSTOM_TX = (1 << 2), + SESSION_F_IS_MIGRATING = (1 << 3), } session_flags_t; typedef struct session_ -- 2.16.6