tcp: fix skipping RSTs in SYN_SENT state
[vpp.git] / src / vnet / tcp / tcp_input.c
index bdaa28e..7f32571 100644 (file)
@@ -215,6 +215,7 @@ tcp_rcv_rst (tcp_worker_ctx_t * wrk, tcp_connection_t * tc)
       break;
     case TCP_STATE_SYN_SENT:
       /* Do not program ntf because the connection is half-open */
+      tc->rst_state = tc->state;
       tcp_handle_rst (tc);
       break;
     case TCP_STATE_ESTABLISHED:
@@ -2630,6 +2631,13 @@ tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
       tcp_connection_init_vars (child);
       child->rto = TCP_RTO_MIN;
 
+      /*
+       * This initializes elog track, must be done before synack.
+       * We also do it before possible tcp_connection_cleanup() as it
+       * generates TCP_EVT_DELETE event.
+       */
+      TCP_EVT (TCP_EVT_SYN_RCVD, child, 1);
+
       if (session_stream_accept (&child->connection, lc->c_s_index,
                                 lc->c_thread_index, 0 /* notify */ ))
        {
@@ -2642,8 +2650,6 @@ tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
 
       tcp_send_synack (child);
 
-      TCP_EVT (TCP_EVT_SYN_RCVD, child, 1);
-
     done:
 
       if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
@@ -3224,6 +3230,7 @@ do {                                                              \
   _(CLOSE_WAIT, TCP_FLAG_RST, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
   _(CLOSE_WAIT, TCP_FLAG_RST | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS,
     TCP_ERROR_NONE);
+  _(CLOSE_WAIT, TCP_FLAG_SYN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
   _(LAST_ACK, 0, TCP_INPUT_NEXT_DROP, TCP_ERROR_SEGMENT_INVALID);
   _(LAST_ACK, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
   _(LAST_ACK, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);