linux内核中修改TCP MSS值

本文介绍了如何在Linux内核中修改TCPMSS,包括MSS概念、MTU与MSS的关系,以及协商过程。重点讲解了通过iptables设置TCPMSS以适应不同网络环境,提升数据传输性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在linux内核中修改TCP MSS值

0. 前言

  最近在解决一些网络相关的问题的时候,我发现许多客户的需求可以不用费劲周折在代码中找到修改的位置,可以直接修改内核中一些网络相关的参数,在大部分情况下即可满足需求,减少时间和精力的消耗(俗称偷懒)。

1. MSS相关概念

  MTU: Maxitum Transmission Unit 最大传输单元
  MSS: Maxitum Segment Size 最大分段大小

  MSS最大传输大小的缩写,是TCP协议里面的一个概念。
  MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes),通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。

  而一般以太网MTU都为1500,所以在以太网中,往往TCP MSS为1460。

2. 协商TCP MSS过程

  对于涉及PPPOE+NAT、IPsec、L2TP、GRE等组网,通常由于报文太大需要分片,这样会降低传输速率; 所以选择一个合适的MSS对传输数据来说比较重要。 Linux中一般可以通过netfilter iptables设置TCP MSS来解决。

iptables -A FORWARD -p tcp- -tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
这条规则的目的就是改变TCP MSS以适应PMTU(Path MTU)

iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN- j TCPMSS --set-mss 128
设置MSS为固定数值128

同理Ipv6只需改为ip6tables,即:

ip6tables -A FORWARD -p tcp- -tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

ip6tables -A FORWARD -p tcp --tcp-flags SYN,RST SYN- j TCPMSS --set-mss 128

<think>嗯,用户这次的问题非常聚焦于Linux内核TCP实现的一个具体字段:tp->delivered。从提问的精准度来看,用户应该是有网络协议栈开发或性能调优需求的工程师,至少是熟悉TCP协议基本概念的研究者。用户能直接提到tp结构体成员,说明已经看过部分内核源码。 注意到用户引用了三个站内技术文档片段,其中引用[1]和[2]都涉及TCP发送队列管理机制,尤其引用[2]提到的tcp_fragment函数和TCPWQUEUETOOBIG计数器,与tp->delivered存在潜在关联——因为分片行为会影响实际交付的报文计数。不过用户核心诉求明确指向delivered字段的语义,需要重点解析这个字段的计量逻辑。 tp->delivered字段的官方定义在include/net/tcp.h里其实比较简略,需要结合tcp_input.c和tcp_output.c的上下文理解。它的核心价在于实时追踪原始数据字节的传输进展,注意三个关键点: 1. 计量单位是字节而非报文段,这从tcp_ack()中tp->delivered += acked的累加方式可验证 2. 包含重传数据,因为网络丢包时该计数仍会累积(参考RFC6298的重传计时器机制) 3. 与TCPTSO机制有隐含互动,当GSO分片发生时,实际delivered增量可能大于MSS 用户可能真正关心的是如何利用这个字段做带宽评估。比如BBR算法正是通过delivered/delivered_mstamp计算即时带宽。但需要提醒用户注意delivered_mstamp的更新时机问题——它只在ACK到达时更新,可能导致采样间隙内的带宽估算偏差。 考虑到用户的技术深度,后续问题可以延伸到具体应用场景。比如如何基于/proc/net/tcp获取该(需要修改内核暴露接口),或者解释delivered与RFC4898定义的DeliveredData的区别(后者是TCP选项需要额外计算)。</think>在 Linux 内核TCP 协议栈实现中,`tp->delivered` 是 `struct tcp_sock` 结构体的一个关键成员变量,主要用于**精确追踪实际交付给接收端应用层的数据量**。其核心作用与运作机制如下: --- ### **核心作用** 1. **计量已确认交付的数据量 (字节单位)** `tp->delivered` 记录的是**已被接收端成功接收并确认 (ACKed)** 且**对端应用层已消费**的数据总量(单位:字节)。它反映的是真正“有效交付”的数据,而非单纯发送出去的数据。 2. **支撑拥塞控制算法** 该字段是 BBR (Bottleneck Bandwidth and Round-trip propagation time) 等现代拥塞控制算法的核心输入: - **计算实时带宽**:通过采样周期内 `tp->delivered` 的增长量 Δdelivered 与时间间隔 Δt,计算瞬时带宽:$Bandwidth = \frac{\Delta delivered}{\Delta t}$。 - **判断网络瓶颈**:结合 RTT 测量,识别网络路径的带宽与延迟特性[^1]。 3. **启用 RACK (Recent ACK) 丢包检测** 在 RACK 机制中,`tp->delivered` 用作数据包的“发送序列号”,通过比较不同数据包的 `(tp->delivered, 发送时间戳)` 二元组,推断丢包事件的发生时机[^2]。 --- ### **运作机制详解** 1. **初始化** 连接建立时(如 SYN-ACK 到达),`tp->delivered` 初始化为 0: ```c tp->delivered = 0; // 初始无交付数据 ``` 2. **数据交付确认时的更新** 当收到接收端的 ACK 确认新数据时,内核在 `tcp_ack()` 函数中更新: ```c delivered = tp->delivered; // 记录更新前的 (用于带宽计算) tp->delivered += newly_acked_bytes; // 增加本次确认的字节数 ``` 3. **记录数据包元信息** 数据包发送时(如调用 `tcp_transmit_skb()`),其当时的 `tp->delivered` 会被记录到该包的 TCP 控制块中(`struct tcp_skb_cb->delivered`): ```c tcb->delivered = tp->delivered; // 标记该包发送时的全局交付量 ``` 此代表“该包发送时,连接上已交付的总字节数”,用于后续计算该包本身的交付量。 4. **计算单包交付量** 当某个数据包被确认时,其**实际交付量** = `当前 tp->delivered - 该包记录的 tcb->delivered`。 例如: - 包 A 发送时:`tcb->delivered = 100` - 包 A 被确认时:`tp->delivered = 120` - 则包 A 的交付量 = $120 - 100 = 20$ 字节 --- ### **技术意义** - **精准拥塞控制**:BBR 依赖 `tp->delivered` 计算真实带宽,替代传统基于丢包或延迟的启发式方法,显著提升高带宽、高延迟网络下的性能[^1]。 - **丢包诊断优化**:RACK 通过比较数据包的 `(delivered, 发送时间)` 而非序列号,能更早、更准确地检测乱序和丢包[^2]。 - **性能监控基础**:该字段是计算吞吐量、传输效率的核心指标,可通过 `ss -t -i` 命令查看(输出中的 `delivery_rate` 和 `busy` 相关字段)。 ```bash $ ss -t -i ESTAB 0 0 192.168.1.2:443 192.168.1.3:55678 cubic wscale:7,7 rto:204 rtt:1.234/0.75 mss:1448 delivered:105600 // 连接累计交付量 (字节) delivery_rate:2.5Gbps // 基于delivered计算的瞬时带宽 ``` --- ### **与相关字段的对比** | 字段 | 含义 | 与 `tp->delivered` 的关系 | |------|------|---------------------------| | `tp->bytes_sent` | 累计发送字节数(含重传) | 始终 ≥ `tp->delivered` | | `tp->bytes_acked` | 累计确认字节数(含重传数据的确认) | 可能 > `tp->delivered`(存在乱序确认) | | `tp->snd_una` | 最早未确认序列号 | 用于计算 `newly_acked_bytes` 以更新 `delivered` | ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ʚ兔子的先森ɞ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值