更新时间:2025-08-22 GMT+08:00
分享

定制TCP重传策略

背景说明

TCP报文重传遵循指数退避原则,在弱网场景下包到达率较低,时延较高。因此新增通过编程接口定制TCP重传策略的能力,包括定制线性退避次数、最大重传次数、最大重传间隔时间,以优化弱网场景的包到达率和时延。

接口说明

  • 通过sysctl设置TCP重传策略功能

    net.ipv4.tcp_sock_retrans_policy_custom,用于控制定制TCP重传策略功能是否开启。

    0:关闭定制TCP重传策略功能。

    1:开启定制TCP重传策略功能。

    sysctl -w net.ipv4.tcp_sock_retrans_policy_custom=1
  • 调用setsockopt针对指定socket定制TCP重传策略
    • 接口:
      int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
      int getsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

      optname传递枚举,optval传递结构体起始地址。

    • 枚举:
      TCP_SOCK_RETRANS_POLICY_CUSTOM 100
      结构体:
      struct tcp_sock_retrans_policy {
          uint8_t tcp_linear_timeouts_times; /* number of times linear backoff */
          uint8_t tcp_retries_max; /* maximum retransmission times */
          uint8_t tcp_rto_max; /* maximum RTO time, unit:second */
          uint8_t unused;
      };

      其中:

      1. tcp_linear_timeouts_times表示线性退避次数,范围:取值是在0到32之间。

        0:使用默认策略(指数退避)。

        非0:定制线性退避次数。

        • 指数退避:发生报文重传时,RTO值直接翻倍
        • 线性退避:发生报文重传时,RTO值保持不变
      2. tcp_retries_max表示最大重传次数,范围:取值是在0到64之间。

        0:使用系统配置的最大重传次数(默认15次)。

        非0:定制最大重传次数。

        最大重传次数需要大于sysctl选项net.ipv4.tcp_retries1(最小重传次数,默认3次)。

      3. tcp_rto_max表示最大重传间隔时间,单位为秒,不允许设置小数,范围:取值是0或者在20到120之间。

        0:使用默认最大重传间隔时间(120秒)。

        非0:定制最大重传间隔时间。

使用说明

  • 开启TCP重传策略定制能力。通过如下命令,将net.ipv4.tcp_sock_retrans_policy_custom配置为1:
    [root@localhost ~]# sysctl -w net.ipv4.tcp_sock_retrans_policy_custom=1

    设置线性退避4次,最大重传10次,最大重传间隔时间20秒:

    tcp_sock_retrans_policy policy = {0};
    policy.tcp_linear_timeouts_times = 4; 
    policy.tcp_retries_max = 10; 
    policy.tcp_rto_max = 20; 
    setsockopt(sockfd, SOL_TCP, TCP_SOCK_RETRANS_POLICY_CUSTOM, (const void*)&policy, sizeof(struct tcp_sock_retrans_policy));
  • 恢复为默认策略:
    tcp_sock_retrans_policy policy = {0};
    setsockopt(sockfd, SOL_TCP, TCP_SOCK_RETRANS_POLICY_CUSTOM, (const void*)&policy, sizeof(struct tcp_sock_retrans_policy));
  • 关闭TCP重传策略定制能力:
    [root@localhost ~]# sysctl -w net.ipv4.tcp_sock_retrans_policy_custom=0

    定制TCP重传策略功能在HCE2.0版本内核进行修改,在HCE2.0版本glibc中使用该功能,需要在用户态代码中添加TCP_SOCK_RETRANS_POLICY_CUSTOM 宏以及对应的结构体tcp_sock_retrans_policy。

约束限制

  1. 只针对ESTABLISHED状态的TCP链接生效。
  2. 支持IPv4和IPv6,由于历史原因,TCP相关sysctl选项都挂在net.ipv4下,实际以net.ipv4.tcp打头的sysctl选项,对IPv4和IPv6均生效。
  3. 应用级TCP重传策略优先级高于其他全局级TCP重传配置。
  4. 定制TCP重传策略可能会增加系统负载,需要根据系统资源合理定制,建议定制的线性退避次数不超过6次。
  5. 如果定制的最大重传次数小于net.ipv4.tcp_retries1(默认值3),则将无法触发网络探测,可能导致部分网络变更场景报文不通。
  6. 如果定制的最大重传次数非0,则其必须大于等于线性退避次数,否则返回错误。
  7. 如果只定制最大重传间隔时间,不定制最大重传次数,那么实际最大重传次数可能会大于net.ipv4.tcp_retries2(默认值15,描述最大重传次数或时间,下简称R2)。RFC6069规定,如果R2使用次数描述,则必须换算成时间。为避免使能本功能后TCP过早断连,该换算过程使用系统默认TCP_RTO_MAX(120s)而不是定制的最大重传时间,因此对外表现为实际重传次数多于R2。
  8. 由于TCP-TLP算法,未收到ACK的尾包可能会被Loss Probe定时器选中做一次重传,用于后续触发快速重传。该次重传不计入本功能定制的重传次数内。

相关文档