diff options
Diffstat (limited to 'src/vnet/session')
-rw-r--r-- | src/vnet/session/application.c | 1 | ||||
-rw-r--r-- | src/vnet/session/application.h | 15 | ||||
-rw-r--r-- | src/vnet/session/application_interface.c | 37 | ||||
-rw-r--r-- | src/vnet/session/session.h | 9 | ||||
-rwxr-xr-x | src/vnet/session/session_api.c | 13 | ||||
-rw-r--r-- | src/vnet/session/stream_session.h | 1 |
6 files changed, 63 insertions, 13 deletions
diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 9020d1c2864..b80aa3391a6 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -831,6 +831,7 @@ application_start_local_listen (application_t * server, /* Store the original session type for the unbind */ ll->listener_session_type = session_type_from_proto_and_ip (sep->transport_proto, sep->is_ip4); + ll->transport_listener_index = ~0; *handle = application_local_session_handle (ll); session_lookup_add_session_endpoint (table_index, sep, *handle); diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h index 4938bef08bd..6fb0f066ad3 100644 --- a/src/vnet/session/application.h +++ b/src/vnet/session/application.h @@ -209,7 +209,7 @@ local_session_parse_handle (session_handle_t handle, u32 * server_index, u32 * session_index) { u32 bottom; - ASSERT ((handle >> 32) == SESSION_LOCAL_TABLE_PREFIX); + ASSERT ((handle >> 32) == SESSION_LOCAL_HANDLE_PREFIX); bottom = (handle & 0xFFFFFFFF); local_session_parse_id (bottom, server_index, session_index); } @@ -217,7 +217,8 @@ local_session_parse_handle (session_handle_t handle, u32 * server_index, always_inline session_handle_t application_local_session_handle (local_session_t * ls) { - return ((u64) SESSION_LOCAL_TABLE_PREFIX << 32) | local_session_id (ls); + return ((u64) SESSION_LOCAL_HANDLE_PREFIX << 32) + | (u64) local_session_id (ls); } always_inline local_session_t * @@ -226,6 +227,16 @@ application_get_local_listen_session (application_t * app, u32 session_index) return pool_elt_at_index (app->local_listen_sessions, session_index); } +always_inline local_session_t * +application_get_local_listener_w_handle (session_handle_t handle) +{ + u32 server_index, session_index; + application_t *app; + local_session_parse_handle (handle, &server_index, &session_index); + app = application_get (server_index); + return application_get_local_listen_session (app, session_index); +} + always_inline u8 application_local_session_listener_has_transport (local_session_t * ls) { diff --git a/src/vnet/session/application_interface.c b/src/vnet/session/application_interface.c index 1023c8c9a62..fd079b5147b 100644 --- a/src/vnet/session/application_interface.c +++ b/src/vnet/session/application_interface.c @@ -91,10 +91,10 @@ session_endpoint_update_for_app (session_endpoint_t * sep, static int vnet_bind_i (u32 app_index, session_endpoint_t * sep, u64 * handle) { + u64 lh, ll_handle = SESSION_INVALID_HANDLE; application_t *app; u32 table_index; - u64 listener; - int rv, have_local = 0; + int rv; app = application_get_if_valid (app_index); if (!app) @@ -109,8 +109,8 @@ vnet_bind_i (u32 app_index, session_endpoint_t * sep, u64 * handle) table_index = application_session_table (app, session_endpoint_fib_proto (sep)); - listener = session_lookup_endpoint_listener (table_index, sep, 1); - if (listener != SESSION_INVALID_HANDLE) + lh = session_lookup_endpoint_listener (table_index, sep, 1); + if (lh != SESSION_INVALID_HANDLE) return VNET_API_ERROR_ADDRESS_IN_USE; /* @@ -121,11 +121,11 @@ vnet_bind_i (u32 app_index, session_endpoint_t * sep, u64 * handle) { if ((rv = application_start_local_listen (app, sep, handle))) return rv; - have_local = 1; + ll_handle = *handle; } if (!application_has_global_scope (app)) - return (have_local - 1); + return (ll_handle == SESSION_INVALID_HANDLE ? -1 : 0); /* * Add session endpoint to global session table @@ -133,8 +133,22 @@ vnet_bind_i (u32 app_index, session_endpoint_t * sep, u64 * handle) /* Setup listen path down to transport */ rv = application_start_listen (app, sep, handle); - if (rv && have_local) + if (rv && ll_handle != SESSION_INVALID_HANDLE) session_lookup_del_session_endpoint (table_index, sep); + + /* + * Store in local table listener the index of the transport layer + * listener. We'll need local listeners are hit and we need to + * return global handle + */ + if (ll_handle != SESSION_INVALID_HANDLE) + { + local_session_t *ll; + stream_session_t *tl; + ll = application_get_local_listener_w_handle (ll_handle); + tl = listen_session_get_from_handle (*handle); + ll->transport_listener_index = tl->session_index; + } return rv; } @@ -192,6 +206,9 @@ vnet_connect_i (u32 client_index, u32 api_context, session_endpoint_t * sep, if (lh == SESSION_DROP_HANDLE) return VNET_API_ERROR_APP_CONNECT_FILTERED; + if (lh == SESSION_INVALID_HANDLE) + goto global_scope; + local_session_parse_handle (lh, &server_index, &li); /* @@ -199,9 +216,9 @@ vnet_connect_i (u32 client_index, u32 api_context, session_endpoint_t * sep, * can happen if client is a generic proxy. Route connect through * global table instead. */ - if (server_index != client_index - && (server = application_get_if_valid (server_index))) + if (server_index != client_index) { + server = application_get (server_index); ll = application_get_local_listen_session (server, li); return application_local_session_connect (table_index, client, server, ll, api_context); @@ -212,6 +229,8 @@ vnet_connect_i (u32 client_index, u32 api_context, session_endpoint_t * sep, * If nothing found, check the global scope for locally attached * destinations. Make sure first that we're allowed to. */ + +global_scope: if (session_endpoint_is_local (sep)) return VNET_API_ERROR_SESSION_CONNECT; diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h index 108e5fe259a..364c6462dec 100644 --- a/src/vnet/session/session.h +++ b/src/vnet/session/session.h @@ -25,6 +25,7 @@ #define HALF_OPEN_LOOKUP_INVALID_VALUE ((u64)~0) #define INVALID_INDEX ((u32)~0) #define SESSION_PROXY_LISTENER_INDEX ((u32)~0 - 1) +#define SESSION_LOCAL_HANDLE_PREFIX 0x7FFFFFFF /* TODO decide how much since we have pre-data as well */ #define MAX_HDRS_LEN 100 /* Max number of bytes for headers */ @@ -299,7 +300,7 @@ session_get_from_handle_if_valid (session_handle_t handle) always_inline u8 session_handle_is_local (session_handle_t handle) { - if ((handle >> 32) == SESSION_LOCAL_TABLE_PREFIX) + if ((handle >> 32) == SESSION_LOCAL_HANDLE_PREFIX) return 1; return 0; } @@ -310,6 +311,12 @@ session_type_transport_proto (session_type_t st) return (st >> 1); } +always_inline u8 +session_type_is_ip4 (session_type_t st) +{ + return (st & 1); +} + always_inline transport_proto_t session_get_transport_proto (stream_session_t * s) { diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 11fa0faa738..f21701c3896 100755 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -200,12 +200,23 @@ send_session_accept_callback (stream_session_t * s) listener = listen_session_get (ls->listener_session_type, ls->listener_index); mp->listener_handle = listen_session_get_handle (listener); + mp->is_ip4 = session_type_is_ip4 (listener->session_type); } else { ll = application_get_local_listen_session (server, ls->listener_index); - mp->listener_handle = application_local_session_handle (ll); + if (ll->transport_listener_index != ~0) + { + listener = listen_session_get (ll->listener_session_type, + ll->transport_listener_index); + mp->listener_handle = listen_session_get_handle (listener); + } + else + { + mp->listener_handle = application_local_session_handle (ll); + } + mp->is_ip4 = session_type_is_ip4 (ll->listener_session_type); } mp->handle = application_local_session_handle (ls); mp->port = ls->port; diff --git a/src/vnet/session/stream_session.h b/src/vnet/session/stream_session.h index 57d256cdbc6..5c4601daa31 100644 --- a/src/vnet/session/stream_session.h +++ b/src/vnet/session/stream_session.h @@ -119,6 +119,7 @@ typedef struct local_session_ /** Has transport embedded when listener not purely local */ session_type_t listener_session_type; + u32 transport_listener_index; /** * Client data |