tcp: do not delete session on establish pop
Also:
- force reset if wait close pops in fin-wait-1 with unsent data
- adds more event logging.
Change-Id: I4ddada046214fa71e17514cdec57b3026f84a283
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index f637d62..9dc3523 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -174,9 +174,15 @@
void
session_free (session_t * s)
{
- pool_put (session_main.wrk[s->thread_index].sessions, s);
if (CLIB_DEBUG)
- clib_memset (s, 0xFA, sizeof (*s));
+ {
+ u8 thread_index = s->thread_index;
+ clib_memset (s, 0xFA, sizeof (*s));
+ pool_put (session_main.wrk[thread_index].sessions, s);
+ return;
+ }
+ SESSION_EVT_DBG (SESSION_EVT_FREE, s);
+ pool_put (session_main.wrk[s->thread_index].sessions, s);
}
void
diff --git a/src/vnet/session/session_debug.h b/src/vnet/session/session_debug.h
index 2912ae3..a26cd7f 100644
--- a/src/vnet/session/session_debug.h
+++ b/src/vnet/session/session_debug.h
@@ -25,6 +25,7 @@
_(POLL_GAP_TRACK, "poll gap track") \
_(POLL_DISPATCH_TIME, "dispatch time")\
_(DISPATCH_END, "dispatch end") \
+ _(FREE, "session free") \
typedef enum _session_evt_dbg
{
@@ -36,6 +37,7 @@
#define SESSION_DEBUG 0 * (TRANSPORT_DEBUG > 0)
#define SESSION_DEQ_NODE_EVTS (0)
#define SESSION_EVT_POLL_DBG (0)
+#define SESSION_SM (0)
#if SESSION_DEBUG
@@ -57,6 +59,21 @@
} * ed; \
ed = ELOG_DATA (&vlib_global_main.elog_main, _e)
+#if SESSION_SM
+#define SESSION_EVT_FREE_HANDLER(_s) \
+{ \
+ ELOG_TYPE_DECLARE (_e) = \
+ { \
+ .format = "free: idx %u", \
+ .format_args = "i4", \
+ }; \
+ DEC_SESSION_ETD(_s, _e, 1); \
+ ed->data[0] = _s->session_index; \
+}
+#else
+#define SESSION_EVT_FREE_HANDLER(_s)
+#endif
+
#if SESSION_DEQ_NODE_EVTS && SESSION_DEBUG > 1
#define SESSION_EVT_DEQ_HANDLER(_s, _body) \
{ \
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index 78ada2b..b6884f5 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -266,9 +266,14 @@
tcp_connection_free (tcp_connection_t * tc)
{
tcp_main_t *tm = &tcp_main;
+ if (CLIB_DEBUG)
+ {
+ u8 thread_index = tc->c_thread_index;
+ clib_memset (tc, 0xFA, sizeof (*tc));
+ pool_put (tm->connections[thread_index], tc);
+ return;
+ }
pool_put (tm->connections[tc->c_thread_index], tc);
- if (CLIB_DEBUG > 0)
- clib_memset (tc, 0xFA, sizeof (*tc));
}
/** Notify session that connection has been reset.
@@ -1255,10 +1260,10 @@
ASSERT (tc->state == TCP_STATE_SYN_RCVD);
tc->timers[TCP_TIMER_ESTABLISH] = TCP_TIMER_HANDLE_INVALID;
tcp_connection_set_state (tc, TCP_STATE_CLOSED);
- /* Start cleanup. App wasn't notified yet so use delete notify as
- * opposed to delete to cleanup session layer state. */
tcp_connection_timers_reset (tc);
- session_transport_delete_notify (&tc->connection);
+ /* Start cleanup. Do NOT delete the session until we do the connection
+ * cleanup. Otherwise, we end up with a dangling session index in the
+ * tcp connection. */
tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, TCP_CLEANUP_TIME);
}
@@ -1283,7 +1288,7 @@
static void
tcp_timer_waitclose_handler (u32 conn_index)
{
- u32 thread_index = vlib_get_thread_index (), rto;
+ u32 thread_index = vlib_get_thread_index ();
tcp_connection_t *tc;
tc = tcp_connection_get (conn_index, thread_index);
@@ -1321,15 +1326,12 @@
tcp_connection_timers_reset (tc);
if (tc->flags & TCP_CONN_FINPNDG)
{
- /* If FIN pending send it before closing and wait as long as
- * the rto timeout would wait. Notify session layer that transport
- * is closed. We haven't sent everything but we did try. */
- tcp_cong_recovery_off (tc);
- tcp_send_fin (tc);
- rto = clib_max ((tc->rto >> tc->rto_boff) * TCP_TO_TIMER_TICK, 1);
- tcp_timer_set (tc, TCP_TIMER_WAITCLOSE,
- clib_min (rto, TCP_2MSL_TIME));
+ /* If FIN pending, we haven't sent everything, but we did try.
+ * Notify session layer that transport is closed. */
+ tcp_connection_set_state (tc, TCP_STATE_CLOSED);
session_transport_closed_notify (&tc->connection);
+ tcp_send_reset (tc);
+ tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, TCP_CLEANUP_TIME);
}
else
{
diff --git a/src/vnet/tcp/tcp_debug.h b/src/vnet/tcp/tcp_debug.h
index 23ad391..262d3fa 100755
--- a/src/vnet/tcp/tcp_debug.h
+++ b/src/vnet/tcp/tcp_debug.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -177,7 +177,7 @@
{ \
ELOG_TYPE_DECLARE (_e) = \
{ \
- .format = "close: %d", \
+ .format = "close: cidx %d", \
.format_args = "i4", \
}; \
DECLARE_ETD(_tc, _e, 1); \
@@ -201,12 +201,13 @@
TCP_EVT_INIT_HANDLER(_tc, 0); \
ELOG_TYPE_DECLARE (_e) = \
{ \
- .format = "syn-rx: idx %u irs %u", \
- .format_args = "i4i4", \
+ .format = "syn-rx: cidx %u sidx %u irs %u", \
+ .format_args = "i4i4i4", \
}; \
- DECLARE_ETD(_tc, _e, 2); \
+ DECLARE_ETD(_tc, _e, 3); \
ed->data[0] = _tc->c_c_index; \
- ed->data[1] = _tc->irs; \
+ ed->data[1] = _tc->c_s_index; \
+ ed->data[2] = _tc->irs; \
TCP_EVT_STATE_CHANGE_HANDLER(_tc); \
}
@@ -226,11 +227,12 @@
{ \
ELOG_TYPE_DECLARE (_e) = \
{ \
- .format = "delete: %d", \
- .format_args = "i4", \
+ .format = "delete: cidx %d sidx %d", \
+ .format_args = "i4i4", \
}; \
- DECLARE_ETD(_tc, _e, 1); \
+ DECLARE_ETD(_tc, _e, 2); \
ed->data[0] = _tc->c_c_index; \
+ ed->data[1] = _tc->c_s_index; \
TCP_EVT_DEALLOC_HANDLER(_tc); \
}
@@ -379,7 +381,7 @@
.n_enum_strings = 2, \
.enum_strings = { \
"syn", \
- "syn-ack", \
+ "synack", \
}, \
}; \
DECLARE_ETD(_tc, _e, 5); \
@@ -405,8 +407,8 @@
} \
ELOG_TYPE_DECLARE (_e) = \
{ \
- .format = "timer-pop: %s (%d)", \
- .format_args = "t4i4", \
+ .format = "timer-pop: %s cidx %u sidx %u", \
+ .format_args = "t4i4i4", \
.n_enum_strings = 8, \
.enum_strings = { \
"retransmit", \
@@ -421,9 +423,10 @@
}; \
if (_tc) \
{ \
- DECLARE_ETD(_tc, _e, 2); \
+ DECLARE_ETD(_tc, _e, 3); \
ed->data[0] = _timer_id; \
- ed->data[1] = _timer_id; \
+ ed->data[1] = _tc->c_c_index; \
+ ed->data[2] = _tc->c_s_index; \
} \
else \
{ \
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index e0139a4..f838bc5 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -3185,7 +3185,6 @@
tcp_connection_init_vars (child0);
child0->rto = TCP_RTO_MIN;
- TCP_EVT_DBG (TCP_EVT_SYN_RCVD, child0, 1);
if (session_stream_accept (&child0->connection, lc0->c_s_index,
0 /* notify */ ))
@@ -3195,6 +3194,7 @@
goto drop;
}
+ TCP_EVT_DBG (TCP_EVT_SYN_RCVD, child0, 1);
child0->tx_fifo_size = transport_tx_fifo_size (&child0->connection);
tcp_send_synack (child0);
tcp_timer_set (child0, TCP_TIMER_ESTABLISH, TCP_SYN_RCVD_TIME);