tcp: drop anything but fins in TIME_WAIT
[vpp.git] / src / vnet / tcp / tcp_input.c
index b7838e2..5235c20 100644 (file)
@@ -349,7 +349,7 @@ tcp_segment_validate (tcp_worker_ctx_t * wrk, tcp_connection_t * tc0,
 
       /* If our window is 0 and the packet is in sequence, let it pass
        * through for ack processing. It should be dropped later. */
-      if (tc0->rcv_wnd == 0
+      if (tc0->rcv_wnd < tc0->snd_mss
          && tc0->rcv_nxt == vnet_buffer (b0)->tcp.seq_number)
        goto check_reset;
 
@@ -1317,18 +1317,20 @@ tcp_do_fastretransmits (tcp_worker_ctx_t * wrk)
 
   for (i = 0; i < vec_len (ongoing_fast_rxt); i++)
     {
+      tc = tcp_connection_get (ongoing_fast_rxt[i], thread_index);
+      if (!tcp_in_fastrecovery (tc))
+       {
+         tc->flags &= ~TCP_CONN_FRXT_PENDING;
+         continue;
+       }
+
       if (n_segs >= VLIB_FRAME_SIZE)
        {
          vec_add1 (wrk->postponed_fast_rxt, ongoing_fast_rxt[i]);
          continue;
        }
 
-      tc = tcp_connection_get (ongoing_fast_rxt[i], thread_index);
       tc->flags &= ~TCP_CONN_FRXT_PENDING;
-
-      if (!tcp_in_fastrecovery (tc))
-       continue;
-
       burst_size = clib_min (max_burst_size, VLIB_FRAME_SIZE - n_segs);
       burst_bytes = transport_connection_tx_pacer_burst (&tc->connection,
                                                         last_cpu_time);
@@ -2890,6 +2892,9 @@ tcp46_rcv_process_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          if (tcp_rcv_ack (wrk, tc0, b0, tcp0, &error0))
            goto drop;
 
+         if (!is_fin0)
+           goto drop;
+
          tcp_program_ack (wrk, tc0);
          tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_TIMEWAIT_TIME);
          goto drop;
@@ -2959,6 +2964,15 @@ tcp46_rcv_process_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
              session_tx_fifo_dequeue_drop (&tc0->connection,
                                            transport_max_tx_dequeue
                                            (&tc0->connection));
+             /* Make it look as if we've recovered, if needed */
+             if (tcp_in_cong_recovery (tc0))
+               {
+                 scoreboard_clear (&tc0->sack_sb);
+                 tcp_fastrecovery_off (tc0);
+                 tcp_recovery_off (tc0);
+                 tcp_connection_timers_reset (tc0);
+                 tc0->snd_nxt = tc0->snd_una_max = tc0->snd_una;
+               }
              tcp_send_fin (tc0);
            }
          else