+ transport_connection_t *tc;
+ u32 al_index, table_index;
+ session_handle_t lh;
+ session_type_t st;
+ session_t *ls = 0;
+ int rv;
+
+ app_listener = app_listener_alloc (app);
+ al_index = app_listener->al_index;
+ st = session_type_from_proto_and_ip (sep->transport_proto, sep->is_ip4);
+
+ /*
+ * Add session endpoint to local session table. Only binds to "inaddr_any"
+ * (i.e., zero address) are added to local scope table.
+ */
+ if (application_has_local_scope (app)
+ && session_endpoint_is_local ((session_endpoint_t *) sep))
+ {
+ session_type_t local_st;
+
+ local_st = session_type_from_proto_and_ip (TRANSPORT_PROTO_NONE,
+ sep->is_ip4);
+ ls = listen_session_alloc (0, local_st);
+ ls->app_index = app->app_index;
+ ls->app_wrk_index = sep->app_wrk_index;
+ lh = session_handle (ls);
+
+ if ((rv = session_listen (ls, sep)))
+ {
+ ls = session_get_from_handle (lh);
+ session_free (ls);
+ app_listener_free (app, app_listener);
+ return rv;
+ }
+
+ ls = session_get_from_handle (lh);
+ app_listener = app_listener_get (app, al_index);
+ app_listener->local_index = ls->session_index;
+ app_listener->ls_handle = lh;
+ ls->al_index = al_index;
+
+ table_index = application_local_session_table (app);
+ session_lookup_add_session_endpoint (table_index,
+ (session_endpoint_t *) sep, lh);
+ }
+
+ if (application_has_global_scope (app))
+ {
+ /*
+ * Start listening on local endpoint for requested transport and scope.
+ * Creates a stream session with state LISTENING to be used in session
+ * lookups, prior to establishing connection. Requests transport to
+ * build it's own specific listening connection.
+ */
+ ls = listen_session_alloc (0, st);
+ ls->app_index = app->app_index;
+ ls->app_wrk_index = sep->app_wrk_index;
+
+ /* Listen pool can be reallocated if the transport is
+ * recursive (tls) */
+ lh = listen_session_get_handle (ls);
+
+ if ((rv = session_listen (ls, sep)))
+ {
+ ls = listen_session_get_from_handle (lh);
+ session_free (ls);
+ app_listener_free (app, app_listener);
+ return rv;
+ }
+ ls = listen_session_get_from_handle (lh);
+ app_listener = app_listener_get (app, al_index);
+ app_listener->session_index = ls->session_index;
+ app_listener->ls_handle = lh;
+ ls->al_index = al_index;
+
+ /* Add to the global lookup table after transport was initialized.
+ * Lookup table needs to be populated only now because sessions
+ * with cut-through transport are are added to app local tables that
+ * are not related to network fibs, i.e., cannot be added as
+ * connections */
+ tc = session_get_transport (ls);
+ if (!(tc->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP))
+ {
+ fib_protocol_t fib_proto;
+ fib_proto = session_endpoint_fib_proto ((session_endpoint_t *) sep);
+ /* Assume namespace vetted previously so make sure table exists */
+ table_index = session_lookup_get_or_alloc_index_for_fib (
+ fib_proto, sep->fib_index);
+ session_lookup_add_session_endpoint (table_index,
+ (session_endpoint_t *) sep,
+ lh);
+ }
+ }
+
+ if (!ls)
+ {
+ app_listener_free (app, app_listener);
+ return -1;
+ }
+
+ *listener = app_listener;
+ return 0;