vcl: add QUIC support

Type: feature

* Adds the concept of a "connectable listener" : a session that
 can be both connected and accepted on.
* vppcom_session_is_connectable_listener (fd) that tells if the fd
is a connectable listener
* vppcom_session_listener (fd) that gives you the listener's fd
that accepted the session (if any)
* vppcom_session_n_accepted (fd) that gives the number
of sessions a listener accepted.

Change-Id: Id89d67d8339fb15a7cf7e00a9c5448175eca04fc
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index 544b288..d46208c 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -167,6 +167,10 @@
   /* Socket configuration state */
   u8 is_vep;
   u8 is_vep_session;
+  /* VCL session index of the listening session (if any) */
+  u32 listener_index;
+  /* Accepted sessions on this listener */
+  int n_accepted_sessions;
   u8 has_rx_evt;
   u32 attr;
   u64 transport_opts;
@@ -352,6 +356,7 @@
   pool_get (wrk->sessions, s);
   memset (s, 0, sizeof (*s));
   s->session_index = s - wrk->sessions;
+  s->listener_index = VCL_INVALID_SESSION_INDEX;
   return s;
 }
 
@@ -447,6 +452,26 @@
   hash_unset (wrk->session_index_by_vpp_handles, listener_handle);
 }
 
+static inline int
+vcl_session_is_connectable_listener (vcl_worker_t * wrk,
+				     vcl_session_t * session)
+{
+  /* Tell if we session_handle is a QUIC session.
+   * We can be in the following cases :
+   * Listen session <- QUIC session <- Stream session
+   * QUIC session <- Stream session
+   */
+  vcl_session_t *ls;
+  if (session->session_type != VPPCOM_PROTO_QUIC)
+    return 0;
+  if (session->listener_index == VCL_INVALID_SESSION_INDEX)
+    return !(session->session_state & STATE_LISTEN);
+  ls = vcl_session_get_w_handle (wrk, session->listener_index);
+  if (!ls)
+    return VPPCOM_EBADFD;
+  return ls->session_state & STATE_LISTEN;
+}
+
 static inline vcl_session_t *
 vcl_session_table_lookup_listener (vcl_worker_t * wrk, u64 handle)
 {
@@ -467,7 +492,8 @@
       return 0;
     }
 
-  ASSERT (session->session_state & (STATE_LISTEN | STATE_LISTEN_NO_MQ));
+  ASSERT ((session->session_state & (STATE_LISTEN | STATE_LISTEN_NO_MQ)) ||
+	  vcl_session_is_connectable_listener (wrk, session));
   return session;
 }