session: avoid session handle conflict with vcl 43/10543/3
authorFlorin Coras <fcoras@cisco.com>
Wed, 14 Feb 2018 16:04:31 +0000 (08:04 -0800)
committerDamjan Marion <dmarion.lists@gmail.com>
Thu, 15 Feb 2018 10:53:33 +0000 (10:53 +0000)
Change-Id: I7f5a3b8d92ef07d60315bab6e560eba49ea07249
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/session/application.c
src/vnet/session/application.h
src/vnet/session/application_interface.c
src/vnet/session/session.h
src/vnet/session/session_api.c
src/vnet/session/stream_session.h

index 9020d1c..b80aa33 100644 (file)
@@ -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);
index 4938bef..6fb0f06 100644 (file)
@@ -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)
 {
index 1023c8c..fd079b5 100644 (file)
@@ -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;
 
index 108e5fe..364c646 100644 (file)
@@ -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)
 {
index 11fa0fa..f21701c 100755 (executable)
@@ -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;
index 57d256c..5c4601d 100644 (file)
@@ -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