From ea72764204dac0a1ab6412bc27b758faead2ca10 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Fri, 7 May 2021 19:39:43 -0700 Subject: session: use half-open sessions for vc establishment Use half-open sessions to track virtual circuit connection establishment. These sesssions can only be allocated and freed by the thread that allocates half-open connections (main). Consequently, they can only be freed on half-open cleanup notifications from transports. Goal is to simplify state tracking within the session layer but it's also a first step towards allowing builtin apps to track and cleanup outstanding connects. Type: improvement Signed-off-by: Florin Coras Change-Id: I8a535906d13eb7f8966deb82333839de80f8049f --- src/vnet/session/session.c | 96 +++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'src/vnet/session/session.c') diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index 7fe35c233c8..1fac5ed2bb9 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -251,6 +251,10 @@ session_is_valid (u32 si, u8 thread_index) || s->session_state <= SESSION_STATE_LISTENING) return 1; + if (s->session_state == SESSION_STATE_CONNECTING && + (s->flags & SESSION_F_HALF_OPEN)) + return 1; + tc = session_get_transport (s); if (s->connection_index != tc->c_index || s->thread_index != tc->thread_index || tc->s_index != si) @@ -296,17 +300,23 @@ session_delete (session_t * s) } void -session_cleanup_half_open (transport_proto_t tp, session_handle_t ho_handle) +session_cleanup_half_open (session_handle_t ho_handle) { - transport_cleanup_half_open (tp, session_handle_index (ho_handle)); + session_t *s = session_get_from_handle (ho_handle); + transport_cleanup_half_open (session_get_transport_proto (s), + s->connection_index); } void -session_half_open_delete_notify (transport_proto_t tp, - session_handle_t ho_handle) +session_half_open_delete_notify (transport_connection_t *tc) { - app_worker_t *app_wrk = app_worker_get (session_handle_data (ho_handle)); - app_worker_del_half_open (app_wrk, tp, ho_handle); + app_worker_t *app_wrk; + session_t *s; + + s = session_get (tc->s_index, tc->thread_index); + app_wrk = app_worker_get (s->app_wrk_index); + app_worker_del_half_open (app_wrk, s->ho_index); + session_free (s); } session_t * @@ -328,6 +338,18 @@ session_alloc_for_connection (transport_connection_t * tc) return s; } +static session_t * +session_alloc_for_half_open (transport_connection_t *tc) +{ + session_t *s; + + s = ho_session_alloc (); + s->session_type = session_type_from_proto_and_ip (tc->proto, tc->is_ip4); + s->connection_index = tc->c_index; + tc->s_index = s->session_index; + return s; +} + /** * Discards bytes from buffer chain * @@ -797,39 +819,21 @@ int session_stream_connect_notify (transport_connection_t * tc, session_error_t err) { - session_handle_t ho_handle, wrk_handle; u32 opaque = 0, new_ti, new_si; app_worker_t *app_wrk; - session_t *s = 0; + session_t *s = 0, *ho; /* - * Find connection handle and cleanup half-open table + * Cleanup half-open table */ - ho_handle = session_lookup_half_open_handle (tc); - if (ho_handle == HALF_OPEN_LOOKUP_INVALID_VALUE) - { - SESSION_DBG ("half-open was removed!"); - return -1; - } session_lookup_del_half_open (tc); - /* Get the app's index from the handle we stored when opening connection - * and the opaque (api_context for external apps) from transport session - * index */ - app_wrk = app_worker_get_if_valid (session_handle_data (ho_handle)); + ho = ho_session_get (tc->s_index); + opaque = ho->opaque; + app_wrk = app_worker_get_if_valid (ho->app_wrk_index); if (!app_wrk) return -1; - wrk_handle = app_worker_lookup_half_open (app_wrk, tc->proto, ho_handle); - if (wrk_handle == SESSION_INVALID_HANDLE) - return -1; - - /* Make sure this is the same half-open index */ - if (session_handle_index (wrk_handle) != session_handle_index (ho_handle)) - return -1; - - opaque = session_handle_data (wrk_handle); - if (err) return app_worker_connect_notify (app_wrk, s, err, opaque); @@ -1258,7 +1262,8 @@ session_open_vc (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque) { transport_connection_t *tc; transport_endpoint_cfg_t *tep; - u64 handle, wrk_handle; + app_worker_t *app_wrk; + session_t *s; int rv; tep = session_endpoint_to_transport_cfg (rmt); @@ -1271,27 +1276,22 @@ session_open_vc (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque) tc = transport_get_half_open (rmt->transport_proto, (u32) rv); - /* If transport offers a stream service, only allocate session once the - * connection has been established. - * Add connection to half-open table and save app and tc index. The - * latter is needed to help establish the connection while the former - * is needed when the connect notify comes and we have to notify the - * external app - */ - handle = session_make_handle (tc->c_index, app_wrk_index); - session_lookup_add_half_open (tc, handle); + app_wrk = app_worker_get (app_wrk_index); - /* Store the half-open handle in the connection. Transport will use it - * when cleaning up @ref session_half_open_delete_notify + /* If transport offers a vc service, only allocate established + * session once the connection has been established. + * In the meantime allocate half-open session for tracking purposes + * associate half-open connection to it and add session to app-worker + * half-open table. These are needed to allocate the established + * session on transport notification, and to cleanup the half-open + * session if the app detaches before connection establishment. */ - tc->s_ho_handle = handle; + s = session_alloc_for_half_open (tc); + s->app_wrk_index = app_wrk->wrk_index; + s->ho_index = app_worker_add_half_open (app_wrk, session_handle (s)); + s->opaque = opaque; - /* Track the half-open connections in case we want to forcefully - * clean them up @ref session_cleanup_half_open - */ - wrk_handle = session_make_handle (tc->c_index, opaque); - app_worker_add_half_open (app_worker_get (app_wrk_index), - rmt->transport_proto, handle, wrk_handle); + session_lookup_add_half_open (tc, tc->c_index); return 0; } -- cgit 1.2.3-korg