session: track app session closes

Make sure applications, especially builtin ones, cannot close a session
multiple times.

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I960a1ae89a48eb359e7e1873a59d47c298c37ef1
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index eaba80f..b0dbb9d 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -1526,9 +1526,15 @@
 void
 session_close (session_t * s)
 {
-  if (!s)
+  if (!s || (s->flags & SESSION_F_APP_CLOSED))
     return;
 
+  /* Transports can close and delete their state independent of app closes
+   * and transport initiated state transitions can hide app closes. Instead
+   * of extending the state machine to support separate tracking of app and
+   * transport initiated closes, use a flag. */
+  s->flags |= SESSION_F_APP_CLOSED;
+
   if (s->session_state >= SESSION_STATE_CLOSING)
     {
       /* Session will only be removed once both app and transport
diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h
index dcbbd72..513929a 100644
--- a/src/vnet/session/session_types.h
+++ b/src/vnet/session/session_types.h
@@ -173,7 +173,8 @@
   _ (IS_MIGRATING, "migrating")                                               \
   _ (UNIDIRECTIONAL, "unidirectional")                                        \
   _ (CUSTOM_FIFO_TUNING, "custom-fifo-tuning")                                \
-  _ (HALF_OPEN, "half-open")
+  _ (HALF_OPEN, "half-open")                                                  \
+  _ (APP_CLOSED, "app-closed")
 
 typedef enum session_flags_bits_
 {