The timeout is scaled based on the measured round trip time.
tcp_connect() sets the timer:
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
icsk_rto will use the redirect timeout; if previous metrics from the destination are available from previous connections, it is reused. (For details, see the tcp_no_metrics_save discussion in tcp(7) .) If the metrics are not saved, the kernel will revert to the standard RTO values:
#define TCP_RTO_MAX ((unsigned)(120*HZ)) #define TCP_RTO_MIN ((unsigned)(HZ/5)) #define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) #define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ))
tcp_retransmit_timer() has some code at the bottom for recalculating the delay:
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0, 0)) __sk_dst_reset(sk);
retransmits_timed_out() will do a linear delay first and then an exponential trip.
I think it’s long and short that you can reasonably expect about 120 seconds before getting an ETIMEDOUT error from connect(2) if the kernel has no reason to suspect that the remote peer should have answered earlier.
source share