tcp: drop outstanding data when entering closing state

Change-Id: I92a009b9630b0d882ea3c5c99aad88ed6f5109a0
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/session/application_worker.c b/src/vnet/session/application_worker.c
index 3bab356..5423733 100644
--- a/src/vnet/session/application_worker.c
+++ b/src/vnet/session/application_worker.c
@@ -199,6 +199,7 @@
     {
       sm = segment_manager_get (app_wrk->connects_seg_manager);
       sm->app_wrk_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
+      sm->first_is_protected = 0;
       segment_manager_init_del (sm);
     }
 
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 606f717..83c889c 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -462,7 +462,7 @@
 }
 
 u32
-stream_session_dequeue_drop (transport_connection_t * tc, u32 max_bytes)
+session_dequeue_drop (transport_connection_t * tc, u32 max_bytes)
 {
   session_t *s = session_get (tc->s_index, tc->thread_index);
   return svm_fifo_dequeue_drop (s->tx_fifo, max_bytes);
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index 4de7642..f20e0db 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -375,7 +375,7 @@
 				      u8 queue_event);
 int stream_session_peek_bytes (transport_connection_t * tc, u8 * buffer,
 			       u32 offset, u32 max_bytes);
-u32 stream_session_dequeue_drop (transport_connection_t * tc, u32 max_bytes);
+u32 session_dequeue_drop (transport_connection_t * tc, u32 max_bytes);
 
 int session_stream_connect_notify (transport_connection_t * tc, u8 is_fail);
 int session_dgram_connect_notify (transport_connection_t * tc,
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index c5dfb3f..dbe1fc4 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -564,7 +564,7 @@
 	continue;
 
       /* Dequeue the newly ACKed bytes */
-      stream_session_dequeue_drop (&tc->connection, tc->burst_acked);
+      session_dequeue_drop (&tc->connection, tc->burst_acked);
       tc->burst_acked = 0;
       tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
 
@@ -2806,8 +2806,7 @@
 
 	      /* Don't try to deq the FIN acked */
 	      if (tc0->burst_acked > 1)
-		stream_session_dequeue_drop (&tc0->connection,
-					     tc0->burst_acked - 1);
+		session_dequeue_drop (&tc0->connection, tc0->burst_acked - 1);
 	      tc0->burst_acked = 0;
 	    }
 	  break;
@@ -2950,8 +2949,17 @@
 	case TCP_STATE_FIN_WAIT_1:
 	  tc0->rcv_nxt += 1;
 	  tcp_connection_set_state (tc0, TCP_STATE_CLOSING);
-	  tcp_program_ack (wrk, tc0);
-	  /* Wait for ACK but not forever */
+	  if (tc0->flags & TCP_CONN_FINPNDG)
+	    {
+	      /* Drop all outstanding tx data. */
+	      session_dequeue_drop (&tc0->connection,
+				    transport_max_tx_dequeue
+				    (&tc0->connection));
+	      tcp_send_fin (tc0);
+	    }
+	  else
+	    tcp_program_ack (wrk, tc0);
+	  /* Wait for ACK for our FIN but not forever */
 	  tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
 	  break;
 	case TCP_STATE_FIN_WAIT_2: