tcp_autocork_rto如何超时

联启 网络工具 18

本文目录导读:

tcp_autocork_rto如何超时-第1张图片-电脑手机工具软件下载 - 免费实用工具合集 | 联启科技

  1. 核心原理与流程
  2. 直接影响因素
  3. 具体代码中的体现

tcp_autocorking (内核参数 tcp_autocorking,通常由 net.ipv4.tcp_autocorking 控制) 本身没有独立的超时时间

它不是一个定时器,而是一个延迟发送的决策机制,它的“超时”是依赖于 TCP 协议栈中已有的其他定时器(主要是 RTO - Retransmission Timeout,重传超时)来触发的。

tcp_autocorking 会阻止小包立即发送,等待更多数据填充,如果一直等不到足够的数据,它必须依靠某种机制“醒过来”把已有的数据发出去,这个“唤醒机制”就是RTO 定时器

核心原理与流程

  1. 触发条件

    • 当应用层调用 send() 写入一个小数据块(通常小于当前 MSS,即最大报文段大小)。
    • 该 socket 启用了 tcp_autocorking(通常默认开启,Linux 3.18+)。
    • 关键前提:该 socket 当前已经有未确认的数据在重传队列中(即前面已经发过包,但还没收到 ACK,正处于“Flight”状态)。
  2. 动作

    • 内核不会立即把这段小数据打包发送。
    • 它会将数据缓存起来,等待应用层下一次 send() 调用,以期凑够一个完整的 MSS 或者打到其他发送条件。
  3. 超时与唤醒

    • 如果应用层再也不发数据了,或者发得极慢,这段缓存的小数据就会一直待在发送缓冲区里。
    • 这时,RTO 定时器登场
      • 前面提到,触发 tcp_autocorking 的前提是重传队列非空,重传队列中的报文本身带有一个 RTO 定时器。
      • 当这个 RTO 定时器超时时,内核会调用 tcp_write_timer_handler()
      • 在这个处理函数中,内核会检查是否因为 autocorking 导致数据被卡住,如果发现是因为 autocorking 正在等待数据,而 RTO 已经超时,内核会强制“解开” corking:
        • 它会将 icsk->icsk_ack.pendingicsk->icsk_ack.pingpong 等状态重置。
        • 然后调用 tcp_write_xmit()__tcp_push_pending_frames()所有累积的数据立即发送出去。
      • 换句话说,autocorking 的“超时”时间就是当前连接重传队列中某个数据包的 RTO 值

直接影响因素

tcp_autocorking 的“延迟时间”(即从数据被 cork 到最终被发送的时长)主要由以下几个因素决定:

  1. RTO 的计算值:RTO 不是固定的,它由 TCP 的 RTT(往返时间)测量和 SRTT(平滑往返时间)算法动态计算,通常初始 RTO 在 1 秒左右,但会随网络状况变化。

    • 如果网络状况好,RTT 小,RTO 也小,autocorking 延迟就短。
    • 如果网络丢包或延迟大,RTO 会指数退避(翻倍增长),autocorking 延迟会急剧增加(可能达到几十秒)。
  2. 是否存在重传队列:如果连接刚建立,还未发送过任何数据(重传队列为空),tcp_autocorking 不会生效,小包会立即发送。只有重传队列非空时,autocorking 才会被触发

  3. 是否 ping-pong 模式tcp_autocorking 的代码逻辑会检查 icsk->icsk_ack.pingpong 标志,如果应用层是交互式、请求-响应模式(如 SSH),autocorking 会被抑制,不会延迟小包。

具体代码中的体现

在 Linux 内核源码 net/ipv4/tcp_output.ctcp_small_queue_check()tcp_sendmsg() 中可以看到逻辑:

// 简化逻辑
bool tcp_autocorking(struct sock *sk)
{
    return (sock_flag(sk, SOCK_CORK) == false) && 
           (sk->sk_route_caps & NETIF_F_SG) &&
           (tcp_sk(sk)->tcp_autocorking) &&
           /* 关键条件:重传队列非空 */
           (tcp_sk(sk)->retransmits < sysctl_tcp_retries1) &&
           (sk_stream_mem_free(sk) > 0) &&
           /* pingpong 模式会跳过 */
           (tcp_sk(sk)->icsk_ack.pingpong == 0);
}

而在 tcp_write_timer() 中:

static void tcp_write_timer(struct sock *sk, ...)
{
    // ... RTO 超时处理 ...
    tcp_write_timer_handler(sk);
}
void tcp_write_timer_handler(struct sock *sk)
{
    // ... 进行重传 ...
    // 如果发现有因 autocorking 而缓存的数据,会强制发送
    if (sk->sk_send_head) {
        tcp_write_xmit(sk, ...);
    }
}
特性 说明
tcp_autocorking 的“超时时间” 不固定,等于当前连接重传队列中最旧数据包的 RTO 值。
如何发生超时 依赖 RTO 定时器,当 RTO 到期,内核在处理重传的同时,会检查并强制发送 autocorking 缓存的报文。
典型延迟范围 初始 RTO 约 1 秒,但在丢包或网络抖动时,RTO 会指数退避(1s -> 2s -> 4s ...),autocorking 延迟可能非常长
如何避免长延迟 对于交互式应用(如 SSH、游戏),pingpong 标志会抑制 autocorking,小包不被延迟,对于需要低延迟的应用,可以关闭 tcp_autocorkingnet.ipv4.tcp_autocorking = 0)。

核心结论tcp_autocorking 没有自己的超时,它借用了RTO 定时器来“唤醒”并发送缓存数据,它的延迟动态取决于网络质量和 RTT。

标签: 动cork 超时

抱歉,评论功能暂时关闭!