Как рассчитать время тайм-аута повторной передачи (RTO, Retransmission timeout) для TCP соединений и на кой это нам нужно? Когда начинается разговор про RTO - это постоянно разрывает мне мозг, потому в первую очередь для самого себя любимого сей пост как руководство на будущее, но может и ещё кому сгодится.
Что определяет tcp_retries1 и tcp_retries1
Значение RTO в совокупности со значениями в параметрах ядра Linux net.ipv4.tcp_retries1 и net.ipv4.tcp_retries2 используется для определения числа попыток, а также тайм-аута повторной передачи неподтверждённых TCP-пакетов по уже установленному TCP-соединению, после истечения которого передача сбрасывается.
В документации сказано:
$ man tcp
...
tcp_retries1 (integer; default: 3; since Linux 2.2)
The number of times TCP will attempt to retransmit a packet on an established connection normally, without the extra effort of getting the network layers involved. Once we exceed this number of retransmits, we first have the network layer update the route if possible before each new retransmit. The default is the RFC specified minimum of 3.tcp_retries2 (integer; default: 15; since Linux 2.2)
The maximum number of times a TCP packet is retransmitted in established state before giving up. The default value is 15, which corresponds to a duration of approximately between 13 to 30 minutes, depending on the retransmission timeout. The RFC 1122 specified minimum limit of 100 seconds is typically deemed too short.
tcp_retries1 и tcp_retries2 определяет число попыток повторной передачи.
В первом случае (tcp_retries1), после 3 (по умолчанию) попыток повторной передачи будет обновлён сетевой маршрут прежде чем сделать последующие попытки.
Во втором случае (tcp_retries2), после последующих 15 (по умолчанию) неудачных попыток передача TCP-пакетов прекращается. В описании TCP-параметра tcp_retries2 также сказано, что: "The default value is 15, which corresponds to a duration of approximately between 13 to 30 minutes, depending on the retransmission timeout." - число 15 соответствует длительности приблизительно от 13 до 30 минут, в зависимости от тайм-аута повторной передачи, того самого RTO.
...А как рассчитывается такой таймаут "от 13 до 30 минут", - в документации умалчивается...
В документации ядра Linux, в описании этих же TCP-параметров говорится, что: "This value influences the timeout of an alive TCP connection, when RTO retransmissions remain unacknowledged. Given a value of N, a hypothetical TCP connection following exponential backoff with an initial RTO of TCP_RTO_MIN would retransmit N times before killing the connection at the (N+1)th RTO.", - с начальным тайм-аутом "RTO of TCP_RTO_MIN" экспоненциально увеличенного между каждой попыткой, неподтверждённые (unacknowledged) TCP-пакеты будут повторно отправлены "N+1" раз.
Ок, а как определить начальную величину RTO?
Как рассчитать RTO (Retransmission timeout)
RTO является не статическим, а динамическим значением, которое определяется в начале установки TCP-соединения исходя из значения RTT, - информация обработалась, всё поняли?:)
RFC 1122 - Requirements for Internet Hosts - Communication Layers
4.2.3.1 Retransmission Timeout Calculation
A host TCP MUST implement Karn's algorithm and Jacobson's algorithm for computing the retransmission timeout ("RTO").
o Jacobson's algorithm for computing the smoothed round-trip ("RTT") time incorporates a simple measure of the variance [TCP:7].
o Karn's algorithm for selecting RTT measurements ensures that ambiguous round-trip times will not corrupt the calculation of the smoothed round-trip time [TCP:6].
This implementation also MUST include "exponential backoff" for successive RTO values for the same segment. Retransmission of SYN segments SHOULD use the same algorithm as data segments.
RTT - это так называемое "Round Trip Time" (Время в пути), и чтобы не томить, определяется оно по временному промежутку от момента получения хостом/сервером TCP-пакета с флагом SYN и последующего получения от него SYN-ACK подтверждения клиентом.

Однако несмотря на значение RTT и прочие факторы, например RTT при пинге может быть "rtt min/avg/max/mdev = 77.108/78.227/80.600/1.414 ms", начальное RTO из определённых соображений самого разработчика ОС ограничено определёнными минимальным и максимальным значениями.
Например для ОС систем на базе ядра Linux минимальное и максимальное значения RTO зашиты в константах "TCP_RTO_MIN" и "TCP_RTO_MAX":
# less /usr/src/linux-headers-4.9.0-7-common/include/net/tcp.h #define TCP_RTO_MAX ((unsigned)(120*HZ)) #define TCP_RTO_MIN ((unsigned)(HZ/5))
HZ равно 1000 мс или 1 сек, таким образом TCP_RTO_MIN = 200 мс и TCP_RTO_MAX = 120 сек.
Для ОС Windows минимальное-максимальное RTO составляет 300-65535 мс.
Более же полная формула калькуляции RTO описана в RFC 793:
RFC 793 - Transmission Control Protocol
Retransmission Timeout
Because of the variability of the networks that compose an internetwork system and the wide range of uses of TCP connections the retransmission timeout must be dynamically determined. One procedure for determining a retransmission time out is given here as an illustration.
An Example Retransmission Timeout Procedure
Measure the elapsed time between sending a data octet with a particular sequence number and receiving an acknowledgment that covers that sequence number (segments sent do not have to match segments received). This measured elapsed time is the Round Trip Time (RTT). Next compute a Smoothed Round Trip Time (SRTT) as:
SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT)and based on this, compute the retransmission timeout (RTO) as:
RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]]where UBOUND is an upper bound on the timeout (e.g., 1 minute), LBOUND is a lower bound on the timeout (e.g., 1 second), ALPHA is a smoothing factor (e.g., .8 to .9), and BETA is a delay variance factor (e.g., 1.3 to 2.0).
Как видим RTO является значением динамическим и для каждого TCP соединения в рамках текущей сессии, - например, при открытии веб-страницы в браузер Firefox/IE устанавливает 8-16 соединений для каждого из которых будет разное RTO
Отталкиваясь от вышеизложенного, если сумма значений параметров tcp_retries1 и tcp_retries2 будет равна 15, то взяв в качестве начального RTO минимальное значение в 200 мс увеличение таймаута между каждой попыткой повторной передачи будет выглядеть следующим образом:

Как узнать RTO для TCP соединений
# ss -i|less State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 13522 93.170.128.114:webcache 66.249.91.84:51058 cubic rto:406 rtt:203.5/13.75 ato:40 cwnd:3 ssthresh:2 bytes_acked:761961 bytes_received:46044 segs_out:662 segs_in:607 send 162.8Kbps unacked:3 retrans:0/57 rcv_rtt:24911 rcv_space:33874
Начальное RTO для большинства TCP-соединений как правило составляет 300-400 мс.
Ссылки по теме RTO
- How to modify the TCP/IP maximum retransmission time-out - support.microsoft.com
- Understanding RTT Impact on TCP Retransmission | Catchpoint (на примере захваченных TCP-пакетов снифером Wireshark)
- ipv4 Variables Linux Kernel - kernel.org

