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 <fcoras@cisco.com> Change-Id: I8a535906d13eb7f8966deb82333839de80f8049f
This commit is contained in:

committed by
Florin Coras

parent
e2272ac27c
commit
ea72764204
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user