aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/session/application.c1
-rw-r--r--src/vnet/session/application.h15
-rw-r--r--src/vnet/session/application_interface.c37
-rw-r--r--src/vnet/session/session.h9
-rwxr-xr-xsrc/vnet/session/session_api.c13
-rw-r--r--src/vnet/session/stream_session.h1
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