aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/tcp/tcp.h1
-rw-r--r--src/vnet/tcp/tcp_output.c13
2 files changed, 14 insertions, 0 deletions
diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h
index 48bbb3eb02f..98808c1368b 100644
--- a/src/vnet/tcp/tcp.h
+++ b/src/vnet/tcp/tcp.h
@@ -112,6 +112,7 @@ extern timer_expiration_handler tcp_timer_retransmit_syn_handler;
#define TCP_RTT_MAX 30 * THZ /* 30s (probably too much) */
#define TCP_RTO_SYN_RETRIES 3 /* SYN retries without doubling RTO */
#define TCP_RTO_INIT 1 * THZ /* Initial retransmit timer */
+#define TCP_RTO_BOFF_MAX 8 /* Max number of retries before reset */
/** TCP connection flags */
#define foreach_tcp_connection_flag \
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index 03caa075a41..c9ffd00d016 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -1517,6 +1517,19 @@ tcp_timer_retransmit_handler_i (u32 index, u8 is_syn)
tcp_update_rto (tc);
}
+ /* Peer is dead or network connectivity is lost. Close connection.
+ * RFC 1122 section 4.2.3.5 recommends a value of at least 100s. For
+ * a min rto of 0.2s we need to retry about 8 times. */
+ if (tc->rto_boff >= TCP_RTO_BOFF_MAX)
+ {
+ tcp_send_reset (tc);
+ tcp_connection_set_state (tc, TCP_STATE_CLOSED);
+ session_transport_closing_notify (&tc->connection);
+ tcp_connection_timers_reset (tc);
+ tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, TCP_CLOSEWAIT_TIME);
+ return;
+ }
+
/* Increment RTO backoff (also equal to number of retries) and go back
* to first un-acked byte */
tc->rto_boff += 1;