tcp: fix window probes in fin-wait-1 88/18088/4
authorFlorin Coras <fcoras@cisco.com>
Thu, 7 Mar 2019 00:51:58 +0000 (16:51 -0800)
committerDave Barach <openvpp@barachs.net>
Fri, 8 Mar 2019 20:03:22 +0000 (20:03 +0000)
Change-Id: Idf060f385f4d9b2f42fdab6a1d372727beb8b19e
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/tcp/tcp_input.c
src/vnet/tcp/tcp_output.c

index b7838e2..c03c5db 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;
 
index 66651e8..94f96b6 100644 (file)
@@ -1096,18 +1096,14 @@ tcp_make_state_flags (tcp_connection_t * tc, tcp_state_t next_state)
     case TCP_STATE_CLOSE_WAIT:
     case TCP_STATE_TIME_WAIT:
     case TCP_STATE_FIN_WAIT_2:
+    case TCP_STATE_CLOSING:
+    case TCP_STATE_LAST_ACK:
+    case TCP_STATE_FIN_WAIT_1:
       return TCP_FLAG_ACK;
     case TCP_STATE_SYN_RCVD:
       return TCP_FLAG_SYN | TCP_FLAG_ACK;
     case TCP_STATE_SYN_SENT:
       return TCP_FLAG_SYN;
-    case TCP_STATE_LAST_ACK:
-    case TCP_STATE_FIN_WAIT_1:
-    case TCP_STATE_CLOSING:
-      if (tc->snd_nxt + 1 < tc->snd_una_max)
-       return TCP_FLAG_ACK;
-      else
-       return TCP_FLAG_FIN;
     default:
       clib_warning ("Shouldn't be here!");
     }
@@ -1709,7 +1705,6 @@ tcp_timer_persist_handler (u32 index)
   u8 *data;
 
   tc = tcp_connection_get_if_valid (index, thread_index);
-
   if (!tc)
     return;
 
@@ -1717,8 +1712,8 @@ tcp_timer_persist_handler (u32 index)
   tc->timers[TCP_TIMER_PERSIST] = TCP_TIMER_HANDLE_INVALID;
 
   /* Problem already solved or worse */
-  if (tc->state == TCP_STATE_CLOSED || tc->state > TCP_STATE_ESTABLISHED
-      || tc->snd_wnd > tc->snd_mss)
+  if (tc->state == TCP_STATE_CLOSED || tc->snd_wnd > tc->snd_mss
+      || (tc->flags & TCP_CONN_FINSNT))
     return;
 
   available_bytes = transport_max_tx_dequeue (&tc->connection);
@@ -1755,10 +1750,10 @@ tcp_timer_persist_handler (u32 index)
 
   tcp_validate_txf_size (tc, offset);
   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
-  max_snd_bytes =
-    clib_min (tc->snd_mss, tm->bytes_per_buffer - TRANSPORT_MAX_HDRS_LEN);
-  n_bytes =
-    session_tx_fifo_peek_bytes (&tc->connection, data, offset, max_snd_bytes);
+  max_snd_bytes = clib_min (tc->snd_mss,
+                           tm->bytes_per_buffer - TRANSPORT_MAX_HDRS_LEN);
+  n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
+                                       max_snd_bytes);
   b->current_length = n_bytes;
   ASSERT (n_bytes != 0 && (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)
                           || tc->snd_nxt == tc->snd_una_max