session/tcp: postpone cleanup on reset

Change-Id: I45fd7538853f84c6c8bf804cc20acbc9601db3ba
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/session-apps/echo_client.c b/src/vnet/session-apps/echo_client.c
index 51a85c0..d100aae 100644
--- a/src/vnet/session-apps/echo_client.c
+++ b/src/vnet/session-apps/echo_client.c
@@ -424,9 +424,15 @@
 static void
 echo_clients_session_reset_callback (stream_session_t * s)
 {
+  echo_client_main_t *ecm = &echo_client_main;
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
+
   if (s->session_state == SESSION_STATE_READY)
     clib_warning ("Reset active connection %U", format_stream_session, s, 2);
-  stream_session_cleanup (s);
+
+  a->handle = session_handle (s);
+  a->app_index = ecm->app_index;
+  vnet_disconnect_session (a);
   return;
 }
 
@@ -440,7 +446,7 @@
 echo_clients_session_disconnect_callback (stream_session_t * s)
 {
   echo_client_main_t *ecm = &echo_client_main;
-  vnet_disconnect_args_t _a, *a = &_a;
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
   a->handle = session_handle (s);
   a->app_index = ecm->app_index;
   vnet_disconnect_session (a);
@@ -451,7 +457,7 @@
 echo_clients_session_disconnect (stream_session_t * s)
 {
   echo_client_main_t *ecm = &echo_client_main;
-  vnet_disconnect_args_t _a, *a = &_a;
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
   a->handle = session_handle (s);
   a->app_index = ecm->app_index;
   vnet_disconnect_session (a);
@@ -552,6 +558,7 @@
   int rv;
 
   da->app_index = ecm->app_index;
+  da->api_client_index = ~0;
   rv = vnet_application_detach (da);
   ecm->test_client_attached = 0;
   ecm->app_index = ~0;
diff --git a/src/vnet/session-apps/echo_server.c b/src/vnet/session-apps/echo_server.c
index e79e838..c0fdb13 100644
--- a/src/vnet/session-apps/echo_server.c
+++ b/src/vnet/session-apps/echo_server.c
@@ -73,7 +73,7 @@
 echo_server_session_disconnect_callback (stream_session_t * s)
 {
   echo_server_main_t *esm = &echo_server_main;
-  vnet_disconnect_args_t _a, *a = &_a;
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
 
   a->handle = session_handle (s);
   a->app_index = esm->app_index;
@@ -83,8 +83,12 @@
 void
 echo_server_session_reset_callback (stream_session_t * s)
 {
+  echo_server_main_t *esm = &echo_server_main;
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
   clib_warning ("Reset session %U", format_stream_session, s, 2);
-  stream_session_cleanup (s);
+  a->handle = session_handle (s);
+  a->app_index = esm->app_index;
+  vnet_disconnect_session (a);
 }
 
 int
diff --git a/src/vnet/session-apps/http_server.c b/src/vnet/session-apps/http_server.c
index 37441bb..d5e0ed9 100644
--- a/src/vnet/session-apps/http_server.c
+++ b/src/vnet/session-apps/http_server.c
@@ -435,7 +435,7 @@
 http_server_session_disconnect_callback (stream_session_t * s)
 {
   http_server_main_t *bsm = &http_server_main;
-  vnet_disconnect_args_t _a, *a = &_a;
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
 
   a->handle = session_handle (s);
   a->app_index = bsm->app_index;
@@ -445,8 +445,11 @@
 static void
 http_server_session_reset_callback (stream_session_t * s)
 {
-  clib_warning ("called.. ");
-  stream_session_cleanup (s);
+  http_server_main_t *htm = &http_server_main;
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
+  a->handle = session_handle (s);
+  a->app_index = htm->app_index;
+  vnet_disconnect_session (a);
 }
 
 static int
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index b944f5a..6533303 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -835,7 +835,7 @@
   app_worker_t *app_wrk;
   application_t *app;
   s = session_get (tc->s_index, tc->thread_index);
-  s->session_state = SESSION_STATE_CLOSED;
+  svm_fifo_dequeue_drop_all (s->server_tx_fifo);
   app_wrk = app_worker_get (s->app_wrk_index);
   app = application_get (app_wrk->app_index);
   app->cb_fns.session_reset_callback (s);
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 31139c3..40fc416 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -1063,6 +1063,7 @@
 static void
 vl_api_reset_session_reply_t_handler (vl_api_reset_session_reply_t * mp)
 {
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
   app_worker_t *app_wrk;
   application_t *app;
   stream_session_t *s;
@@ -1097,7 +1098,9 @@
 
   /* This comes as a response to a reset, transport only waiting for
    * confirmation to remove connection state, no need to disconnect */
-  stream_session_cleanup (s);
+  a->handle = mp->handle;
+  a->app_index = app->app_index;
+  vnet_disconnect_session (a);
 }
 
 static void
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index cf2d576..1457668 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -84,6 +84,7 @@
 static void
 session_mq_reset_reply_handler (void *data)
 {
+  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
   session_reset_reply_msg_t *mp;
   app_worker_t *app_wrk;
   stream_session_t *s;
@@ -119,7 +120,9 @@
 
   /* This comes as a response to a reset, transport only waiting for
    * confirmation to remove connection state, no need to disconnect */
-  stream_session_cleanup (s);
+  a->handle = mp->handle;
+  a->app_index = app->app_index;
+  vnet_disconnect_session (a);
 }
 
 static void
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index 04613cd..f703d63 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -296,6 +296,7 @@
     case TCP_STATE_CLOSED:
       return;
     }
+  tc->state = TCP_STATE_CLOSED;
 }
 
 /**
@@ -349,6 +350,9 @@
     case TCP_STATE_FIN_WAIT_1:
       tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
       break;
+    case TCP_STATE_CLOSED:
+      tcp_connection_timers_reset (tc);
+      break;
     default:
       TCP_DBG ("state: %u", tc->state);
     }
@@ -553,6 +557,7 @@
   tc->snd_una = tc->iss;
   tc->snd_nxt = tc->iss + 1;
   tc->snd_una_max = tc->snd_nxt;
+  tc->srtt = 0;
 }
 
 void
@@ -1052,7 +1057,8 @@
 {
   int snd_space, snt_limited;
 
-  if (PREDICT_FALSE (tcp_in_fastrecovery (tc)))
+  if (PREDICT_FALSE (tcp_in_fastrecovery (tc)
+		     || tc->state == TCP_STATE_CLOSED))
     return 0;
 
   snd_space = tcp_available_output_snd_space (tc);
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index 6809a91..e15ad73 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -501,8 +501,8 @@
   else
     {
       mrtt = tcp_time_now_w_thread (thread_index) - tc->rcv_opts.tsecr;
+      mrtt = clib_max (mrtt, 1);
       tc->mrtt_us = (f64) mrtt *TCP_TICK;
-
     }
 
   if (mrtt > 0 && mrtt < TCP_RTT_MAX)