两端握手参数为什么要对比
TCP 的能力协商全在握手的选项里完成:最大报文段长度、窗口缩放、选择确认、时间戳。如果这些选项在中间被防火墙、负载均衡或隧道设备改写甚至剥离,连接仍然能建立,但后续行为会变得低效——大包被分片、窗口放大失效、重传恢复变慢。只在链路一端抓包看不到这个过程,需要两端各抓一份逐项对照。
基本信息
| 对比对象 | 客户端发出的 SYN 与服务端收到的 SYN;以及两侧的 SYN-ACK |
|---|---|
| 对比项 | MSS、窗口缩放、选择确认许可、时间戳 |
| 判据 | 两端同一报文的选项不一致,说明路径上有设备改写或剥离 |
| 合理改写 | 隧道出口做 MSS 收敛是常见且合理的做法 |
| 危险缺失 | 窗口缩放被剥离会让大窗口协商失效,长肥管道吞吐骤降 |
| 前提条件 | 两端需有可对齐的时间基准,或能按五元组定位同一连接 |
典型使用场景
- 跨隧道性能排查:确认出口是否把 MSS 收敛到合理值,避免大包被丢弃
- 窗口放大失效:长延迟链路上吞吐上不去,检查窗口缩放是否在路径中被剥离
- 防火墙策略评估:核实设备对选项的处理方式是否符合预期
- 负载均衡行为核对:确认转发过程中是否保留客户端的原始选项
- 上线前验证:新链路接入后对比握手选项,观察是否引入了新的改写行为
两端对照命令
两端对照命令
# 客户端侧: 看自己发出去的 SYN 选项
tshark -r client.pcap -Y 'tcp.flags.syn == 1 && tcp.flags.ack == 0' -V | grep -A6 Options
tshark -r client.pcap -Y 'tcp.options.wscale' -T fields -e ip.src -e tcp.options.wscale.shift
# 服务端侧: 看收到的 SYN 选项, 同样的条件再跑一遍
tshark -r server.pcap -Y 'tcp.flags.syn == 1 && tcp.flags.ack == 0' -V | grep -A6 Options
# 逐项列出 MSS 便于对照
tshark -r client.pcap -Y 'tcp.options.mss' -T fields -e ip.src -e tcp.options.mss_val选项与改写后的表现
| 选项 | 作用 | 被改写后的常见表现 |
|---|---|---|
| MSS | 声明可接收的最大报文段 | 数值被调小属常见优化, 突然变大则可能超过路径 MTU |
| 窗口缩放 | 放大 16 位窗口字段 | 被剥离后窗口无法放大, 吞吐受限 |
| 选择确认许可 | 允许选择性重传 | 被剥离后丢包恢复效率下降 |
| 时间戳 | 提高往返估算精度 | 被剥离后重传超时估算变粗 |
| 选项顺序与个数 | 本身不影响功能 | 顺序异常可作为路径改写的线索 |
对比时逐项列出,不要只盯 MSS 一项;很多时候 MSS 被正确收敛,出问题的却是窗口缩放被剥离,而这一项在折起的选项树里很容易被忽略。
隧道与虚拟化封装会额外占用字节,收敛后的 MSS 需要按封装开销留出余量;具体数值按现场封装方式核算,不要直接照搬网上示例。