tcp: fast retransmit improvements

Patch is too large to be ported to 18.10 just days before release.

- handle fast retransmits outside of established node and limit the
retransmit burst size to avoid tx losses and worsening congestion.
- in the absance of a tx pacer, use slow start after fast retransmit
exists
- add fast retransmit heuristic that re-retries sending the first
segment if everything else fails
- fine tuning

Change-Id: I84a2ab8fbba8b97f1d2b26584dc11a1e2c33c8d2
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index e32b5c4..cb05b8c 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -950,7 +950,8 @@
 
   hole = scoreboard_first_hole (sb);
   if (hole)
-    s = format (s, "\n head %u tail %u holes:\n", sb->head, sb->tail);
+    s = format (s, "\n head %u tail %u %u holes:\n", sb->head, sb->tail,
+		pool_elts (sb->holes));
 
   while (hole)
     {
@@ -1027,7 +1028,7 @@
 {
   int snd_space, snt_limited;
 
-  if (PREDICT_TRUE (tcp_in_cong_recovery (tc) == 0))
+  if (PREDICT_TRUE (!tcp_in_fastrecovery (tc)))
     {
       snd_space = tcp_available_output_snd_space (tc);
 
@@ -1047,16 +1048,6 @@
       return tcp_round_snd_space (tc, snd_space);
     }
 
-  if (tcp_in_recovery (tc))
-    {
-      tc->snd_nxt = tc->snd_una_max;
-      snd_space = tcp_available_snd_wnd (tc) - tc->snd_rxt_bytes
-	- (tc->snd_una_max - tc->snd_congestion);
-      if (snd_space <= 0 || (tc->snd_una_max - tc->snd_una) >= tc->snd_wnd)
-	return 0;
-      return tcp_round_snd_space (tc, snd_space);
-    }
-
   /* RFC 5681: When previously unsent data is available and the new value of
    * cwnd and the receiver's advertised window allow, a TCP SHOULD send 1*SMSS
    * bytes of previously unsent data. */
@@ -1103,6 +1094,7 @@
   tw_timer_expire_timers_16t_2w_512sl (&tcp_main.
 				       wrk_ctx[thread_index].timer_wheel,
 				       now);
+  tcp_do_fastretransmits (thread_index);
   tcp_flush_frames_to_output (thread_index);
 }