ECN 想解决什么问题
传统拥塞控制靠丢包来感知链路拥塞,代价是丢包本身造成重传与延迟。显式拥塞通知(ECN)让路由器在队列变满之前把报文标记出来,接收方把这个信号回告给发送方,发送方主动降速,从而在不丢包的情况下完成拥塞响应。它在抓包里体现为握手阶段的协商,以及后续报文里被标记的位。
基本信息
| 抓包字段 | tcp.flags.ecn 表示两个标记位,tcp.flags.ece 与 tcp.flags.cwr 为回告与确认位 |
|---|---|
| 取值含义 | 0 表示未启用、1 与 2 分别表示两种可标记形态、3 表示已标记拥塞 |
| 协商过程 | 发起方在 SYN 中同时置位两个标志位,接收方在 SYN-ACK 中置位其中一个表示同意 |
| 确认流程 | 发送方在首个数据段中置位相应标志,确认对方已同意使用 |
| 协商失败 | 不支持时自然回落为普通连接,属正常现象 |
| 收益前提 | 需要路径上的设备愿意做标记,否则机制不会真正生效 |
典型使用场景
- 机制核查:确认双方确实完成了协商,而不是只在某一端打开了开关
- 拥塞分析:看被标记报文的出现频率,判断链路是否接近拥塞
- 吞吐波动解释:机制生效后发送速率会主动下降,吞吐曲线出现台阶属预期
- 设备能力评估:路径设备是否支持标记,直接影响机制收益
- 协议教学:用抓包逐帧展示协商与回告过程
过滤与观察
过滤与观察
# 握手阶段协商: SYN 中同时置位 ECE 与 CWR
tshark -r a.pcap -Y 'tcp.flags.syn == 1 && tcp.flags.ece == 1 && tcp.flags.cwr == 1' -T fields -e frame.number -e ip.src
# 接收方同意: SYN-ACK 中置位 ECE
tshark -r a.pcap -Y 'tcp.flags.syn == 1 && tcp.flags.ack == 1 && tcp.flags.ece == 1' -T fields -e frame.number -e ip.src
# 被标记为拥塞经历的报文
tshark -r a.pcap -Y 'tcp.flags.ecn == 3' -T fields -e frame.number -e ip.src | head -20
# 发送方回告确认
tshark -r a.pcap -Y 'tcp.flags.cwr == 1 && tcp.flags.syn == 0' -T fields -e frame.number -e ip.src | head标志位与含义
| 字段 | 含义 | 出现位置 |
|---|---|---|
| tcp.flags.ecn == 0 | 未启用该机制 | 普通报文 |
| tcp.flags.ecn == 1 或 2 | 声明可被标记的两种形态 | 数据报文 |
| tcp.flags.ecn == 3 | 已被标记为经历拥塞 | 由路径设备设置 |
| tcp.flags.ece == 1 | 回告拥塞信号 | 接收方发出的确认报文 |
| tcp.flags.cwr == 1 | 确认已收到回告 | 发送方的数据报文 |
| SYN 中两者同时置位 | 请求启用该机制 | 握手阶段 |
协商失败会自动回落,抓包里看到没有该机制的正常连接不需要处理;只有确认双方与路径都支持时,未生效才值得跟进。
相关问题常表现为吞吐波动而不是连接失败:需要拉长时间窗口统计标记报文的比例,用单次抓包很难得出结论。