+int
+session_open_vc (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque)
+{
+ transport_connection_t *tc;
+ transport_endpoint_t *tep;
+ u64 handle;
+ int rv;
+
+ tep = session_endpoint_to_transport (rmt);
+ rv = tp_vfts[rmt->transport_proto].open (tep);
+ if (rv < 0)
+ {
+ SESSION_DBG ("Transport failed to open connection.");
+ return VNET_API_ERROR_SESSION_CONNECT;
+ }
+
+ tc = tp_vfts[rmt->transport_proto].get_half_open ((u32) rv);
+
+ /* If transport offers a stream service, only allocate session once the
+ * connection has been established.
+ * Add connection to half-open table and save app and tc index. The
+ * latter is needed to help establish the connection while the former
+ * is needed when the connect notify comes and we have to notify the
+ * external app
+ */
+ handle = (((u64) app_wrk_index) << 32) | (u64) tc->c_index;
+ session_lookup_add_half_open (tc, handle);
+
+ /* Store api_context (opaque) for when the reply comes. Not the nicest
+ * thing but better than allocating a separate half-open pool.
+ */
+ tc->s_index = opaque;
+ return 0;
+}
+
+int
+session_open_app (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque)
+{
+ session_endpoint_extended_t *sep = (session_endpoint_extended_t *) rmt;
+ sep->app_wrk_index = app_wrk_index;
+ sep->opaque = opaque;
+
+ return tp_vfts[rmt->transport_proto].open ((transport_endpoint_t *) sep);
+}
+
+typedef int (*session_open_service_fn) (u32, session_endpoint_t *, u32);
+
+/* *INDENT-OFF* */
+static session_open_service_fn session_open_srv_fns[TRANSPORT_N_SERVICES] = {
+ session_open_vc,
+ session_open_cl,
+ session_open_app,
+};
+/* *INDENT-ON* */
+
+/**
+ * Ask transport to open connection to remote transport endpoint.
+ *
+ * Stores handle for matching request with reply since the call can be
+ * asynchronous. For instance, for TCP the 3-way handshake must complete
+ * before reply comes. Session is only created once connection is established.
+ *
+ * @param app_index Index of the application requesting the connect
+ * @param st Session type requested.
+ * @param tep Remote transport endpoint
+ * @param opaque Opaque data (typically, api_context) the application expects
+ * on open completion.
+ */
+int
+session_open (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque)
+{
+ transport_service_type_t tst = tp_vfts[rmt->transport_proto].service_type;
+ return session_open_srv_fns[tst] (app_wrk_index, rmt, opaque);
+}
+