Linux - TCP connect() 失败,ETIMEDOUT

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8471577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:35:50  来源:igfitidea点击:

Linux - TCP connect() failure with ETIMEDOUT

linuxsocketstcp

提问by Manohar

For a TCP client connect() call to a TCP server..

对于 TCP 客户端 connect() 调用到 TCP 服务器..

UNIX? Network Programming book by Richard Stevens says the following..

UNIX?理查德史蒂文斯的网络编程书说以下..

If the client TCP receives no response to its SYN segment, ETIMEDOUT is returned. 4.4BSD, for example, sends one SYN when connect is called, another 6 seconds later, and another 24 seconds later (p. 828 of TCPv2). If no response is received after a total of 75 seconds, the error is returned.

如果客户端 TCP 没有收到对其 SYN 段的响应,则返回 ETIMEDOUT。例如,4.4BSD 在调用 connect 时发送一个 SYN,6 秒后发送另一个 SYN,24 秒后发送另一个(TCPv2 的第 828 页)。如果在总共 75 秒后没有收到响应,则返回错误。

In Linux I would like know what is the retry mechanism (how many times and how far apart). Asking because for a TCP client connect() call I am getting ETIMEDOUT error. This socket has O_NONBLOCK option and monitored by epoll() for the events.

在 Linux 中,我想知道什么是重试机制(多少次以及相隔多远)。询问是因为对于 TCP 客户端 connect() 调用,我收到 ETIMEDOUT 错误。此套接字具有 O_NONBLOCK 选项并由 epoll() 监视事件。

If someone can point to me where in the code this retry logic is implemented that would be helpful too. I tried following a bit starting with tcp_v4_connect() from net/ipv4/tcp_ipv4.c, but lost my way pretty soon..

如果有人可以指出我在代码中的哪个位置实现了这个重试逻辑,那也会很有帮助。我尝试从 net/ipv4/tcp_ipv4.c 中的 tcp_v4_connect() 开始,但很快就迷失了方向。

采纳答案by sarnold

The timeout is scaled based on the measured round-trip time.

超时根据测量的往返时间进行缩放。

tcp_connect()sets up a timer:

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);

The icsk_rtowill use a per-destination re-transmission timeout; if previous metrics from the destination is available from previous connections, it is re-used. (See the tcp_no_metrics_savediscussion in tcp(7)for details.) If no metrics are saved, then the kernel will fall back to a default RTO value:

icsk_rto将使用每个目的地的重传超时; 如果来自目标的先前指标可从先前的连接中获得,则会重新使用它。(有关详细信息,请参阅 中的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()has some code near the bottom for recalculating the delay:

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()will first perform a linear backoff then an exponential backoff.

retransmits_timed_out()将首先执行线性退避,然后是指数退避。

I think the long and the short of it is that you can reasonably expect roughly 120 seconds before getting ETIMEDOUTerror returns from connect(2)unless the kernel has good reason to suspect that the remote peer should have replied sooner.

我认为它的长短是你可以合理地期望大约 120 秒才能得到ETIMEDOUT错误返回,connect(2)除非内核有充分的理由怀疑远程对等点应该更快地回复。

回答by Aaron Digulla

A typical reason for ETIMEOUT is a firewall which simply swallows the packets instead of replying with ICMP Destination Unreachable.

ETIMEOUT 的一个典型原因是防火墙简单地吞下数据包而不是回复ICMP Destination Unreachable

This is a common setup to prevent hackers from probing a network for hosts.

这是防止黑客探测主机网络的常见设置。