对于TCP客户端connect()调用TCP服务器..
理查德史蒂文斯的UNIX®网络编程书籍如下......如果客户端TCP未收到对其SYN段的响应,则返回ETIMEDOUT。 4.4BSD, 例如,在调用connect时发送一个SYN,在另一个6秒后发送另一个SYN 24秒后(TCPv2的第828页)。如果在总共75秒后没有收到响应,那么 错误被返回。
在Linux中我想知道什么是重试机制(多少次和多远)。要求因为TCP客户端connect()调用我得到ETIMEDOUT错误。此套接字具有O_NONBLOCK选项,并由epoll()监视事件。
如果有人可以指出我在代码中的哪个位置实现了这种重试逻辑,那么它也会有所帮助。我尝试从net / ipv4 / tcp_ipv4.c开始使用tcp_v4_connect(),但很快就迷失了方向..
答案 0 :(得分:8)
根据测量的往返时间缩放超时。
tcp_connect()
设置了一个计时器:
/* Timer for repeating the SYN until an answer. */
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
icsk_rto
将使用每个目的地re-transmission timeout;如果来自目的地的先前度量标准可从先前的连接获得,则重新使用它。 (有关详细信息,请参阅tcp_no_metrics_save
中的tcp(7)
讨论。)如果未保存任何指标,则内核将回退到默认的RTO值:
#define TCP_RTO_MAX ((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))
#define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC2988bis initial RTO value */
#define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now
* used as a fallback RTO for the
* initial data transmission if no
* valid RTT sample has been acquired,
* most likely due to retrans in 3WHS.
*/
tcp_retransmit_timer()
底部附近有一些代码用于重新计算延迟:
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()
将首先执行线性退避,然后执行指数退避。
我认为,除非内核有充分的理由怀疑远程对等方应该有ETIMEDOUT
错误,否早点回答。
答案 1 :(得分:4)
ETIMEOUT的典型原因是防火墙只是吞下数据包而不是回复ICMP Destination Unreachable。
这是防止黑客为主机探测网络的常见设置。