summaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp/tcp_output.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-05-03 21:09:42 -0700
committerDave Barach <openvpp@barachs.net>2017-05-07 12:38:12 +0000
commit3af90fceb61d0c236709c25df936bbbf304cbff5 (patch)
tree19b9166a401fd23fb9e58a9ceba48ca8452c50a4 /src/vnet/tcp/tcp_output.c
parent1989bce006a28781156a61ced693775a6f5aba95 (diff)
Fix TCP loss recovery, VPP-745
Allows pure loss recovery retransmits only on timeout. Change-Id: I563cdbf9e7b890a6569350bdbda4f746ace0544e Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/tcp/tcp_output.c')
-rw-r--r--src/vnet/tcp/tcp_output.c44
1 files changed, 17 insertions, 27 deletions
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index a85d30daddb..7ee930c61af 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -73,7 +73,7 @@ tcp_set_snd_mss (tcp_connection_t * tc)
snd_mss = dummy_mtu;
/* TODO cache mss and consider PMTU discovery */
- snd_mss = tc->opt.mss < snd_mss ? tc->opt.mss : snd_mss;
+ snd_mss = clib_min (tc->opt.mss, snd_mss);
tc->snd_mss = snd_mss;
@@ -923,6 +923,12 @@ tcp_push_hdr_i (tcp_connection_t * tc, vlib_buffer_t * b,
/* TODO this is updated in output as well ... */
if (tc->snd_nxt > tc->snd_una_max)
tc->snd_una_max = tc->snd_nxt;
+
+ if (tc->rtt_ts == 0)
+ {
+ tc->rtt_ts = tcp_time_now ();
+ tc->rtt_seq = tc->snd_nxt;
+ }
TCP_EVT_DBG (TCP_EVT_PKTIZE, tc);
}
@@ -1019,9 +1025,10 @@ tcp_rtx_timeout_cc (tcp_connection_t * tc)
}
/* Start again from the beginning */
- tcp_recovery_on (tc);
+
tc->cwnd = tcp_loss_wnd (tc);
tc->snd_congestion = tc->snd_una_max;
+ tcp_recovery_on (tc);
}
static void
@@ -1032,7 +1039,7 @@ tcp_timer_retransmit_handler_i (u32 index, u8 is_syn)
u32 thread_index = vlib_get_thread_index ();
tcp_connection_t *tc;
vlib_buffer_t *b;
- u32 bi, snd_space, n_bytes;
+ u32 bi, n_bytes;
if (is_syn)
{
@@ -1065,33 +1072,16 @@ tcp_timer_retransmit_handler_i (u32 index, u8 is_syn)
/* Exponential backoff */
tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
- /* Figure out what and how many bytes we can send */
- snd_space = tcp_available_snd_space (tc);
-
TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 1);
- if (snd_space == 0)
- {
- clib_warning ("no wnd to retransmit");
- tcp_return_buffer (tm);
-
- /* Force one segment */
- tcp_retransmit_first_unacked (tc);
+ /* Send one segment. No fancy recovery for now! */
+ n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, tc->snd_mss);
+ scoreboard_clear (&tc->sack_sb);
- /* Re-enable retransmit timer. Output may be unwilling
- * to do it for us */
- tcp_retransmit_timer_set (tc);
-
- return;
- }
- else
+ if (n_bytes == 0)
{
- /* No fancy recovery for now! */
- n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, snd_space);
- scoreboard_clear (&tc->sack_sb);
-
- if (n_bytes == 0)
- return;
+ clib_warning ("could not retransmit");
+ return;
}
}
else
@@ -1400,7 +1390,7 @@ tcp46_output_inline (vlib_main_t * vm,
}
/* If not retransmitting
- * 1) update snd_una_max (SYN, SYNACK, new data, FIN)
+ * 1) update snd_una_max (SYN, SYNACK, FIN)
* 2) If we're not tracking an ACK, start tracking */
if (seq_lt (tc0->snd_una_max, tc0->snd_nxt))
{