+int
+session_listen_cl (stream_session_t * s, session_endpoint_t * sep)
+{
+ transport_connection_t *tc;
+ application_t *server;
+ segment_manager_t *sm;
+ u32 tci;
+
+ /* Transport bind/listen */
+ tci = tp_vfts[sep->transport_proto].bind (s->session_index,
+ session_endpoint_to_transport
+ (sep));
+
+ if (tci == (u32) ~ 0)
+ return -1;
+
+ /* Attach transport to session */
+ s->connection_index = tci;
+ tc = tp_vfts[sep->transport_proto].get_listener (tci);
+
+ /* Weird but handle it ... */
+ if (tc == 0)
+ return -1;
+
+ server = application_get (s->app_index);
+ sm = application_get_listen_segment_manager (server, s);
+ if (session_alloc_fifos (sm, s))
+ return -1;
+
+ /* Add to the main lookup table */
+ session_lookup_add_connection (tc, s->session_index);
+ return 0;
+}
+
+int
+session_listen_app (stream_session_t * s, session_endpoint_t * sep)
+{
+ session_endpoint_extended_t esep;
+ clib_memcpy (&esep, sep, sizeof (*sep));
+ esep.app_index = s->app_index;
+
+ return tp_vfts[sep->transport_proto].bind (s->session_index,
+ (transport_endpoint_t *) & esep);
+}
+
+typedef int (*session_listen_service_fn) (stream_session_t *,
+ session_endpoint_t *);
+
+/* *INDENT-OFF* */
+static session_listen_service_fn
+session_listen_srv_fns[TRANSPORT_N_SERVICES] = {
+ session_listen_vc,
+ session_listen_cl,
+ session_listen_app,
+};
+/* *INDENT-ON* */
+
+/**
+ * Ask transport to listen on local transport endpoint.
+ *
+ * @param s Session for which listen will be called. Note that unlike
+ * established sessions, listen sessions are not associated to a
+ * thread.
+ * @param tep Local endpoint to be listened on.
+ */
+int
+stream_session_listen (stream_session_t * s, session_endpoint_t * sep)
+{
+ transport_service_type_t tst = tp_vfts[sep->transport_proto].service_type;
+ return session_listen_srv_fns[tst] (s, sep);
+}
+