【问题标题】:Linux - TCP connect() failure with ETIMEDOUTLinux - TCP connect() 失败并出现 ETIMEDOUT
【发布时间】:2011-12-12 08:26:27
【问题描述】:

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

Richard Stevens 的《UNIX® 网络编程》一书说:

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

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

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

【问题讨论】:

    标签: linux sockets tcp


    【解决方案1】:

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

    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(7) 中的 tcp_no_metrics_save 讨论。)如果未保存任何指标,则内核将回退到默认 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() 将首先执行线性退避,然后执行指数退避。

    我认为总而言之,您可以合理地预期大约 120 秒后会从 connect(2) 收到 ETIMEDOUT 错误返回,除非内核有充分的理由怀疑远程对等方应该早点回复。

    【讨论】:

      【解决方案2】:

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

      这是防止黑客探测网络以查找主机的常用设置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-06
        • 2021-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-24
        相关资源
        最近更新 更多