TCP 时间戳选项一箭双雕:让发送方在重传存在时仍能放心测 RTT,又让接收方能挡掉绕了一圈回来的旧包(PAWS)。这篇在 macOS 上抓包看它的格式、开销、时钟,用 TSecr 配对测 RTT,在丢包里验证 ACK 回显的是哪一次发送。PAWS 的注入验证做不到,只给计算。
lo0:SYN 里 TSval=True(TSecr = 0),SYN+ACK 里 TS=True;SYN 的 MSS = 16344;数据段里最大载荷 = 16332 字节;数据段 TCP 头长 32 字节(20 基本 + 12 时间戳选项) 所以 lo0 上 MSS 16344 − 12 字节时间戳选项 = 16332 字节有效载荷 example.com:本机 SYN 里 TS=True,服务器 SYN+ACK 里 TS=True(两边都有才会启用);SYN+ACK 的 MSS = 1400
kind 8、10 字节加两个 NOP 共 12 字节,两端 SYN 都带才启用;lo0 上有效载荷从 MSS 16344 变成 16332。
net.inet.tcp.randomize_timestamps: 1(1 = 每条连接的 TSval 起点加一个随机偏移,所以 TSval 的绝对值没有意义,只有差值有意义) lo0:客户端发出的 keepalive 探测 9 个,其中带时间戳选项的 0 个(TCP 头长 [20] 字节);服务端回的 ACK 9 个,带时间戳选项的 9 个(头长 [32] 字节) 服务端 ACK 里的 TSecr(回显客户端最近一个带时间戳的包的 TSval):[949424606]——只有一个值,因为探测没有带时间戳,服务端没有新的可回显 服务端 TSval 的变化(相邻差值):[1001, 1000, 1000, 1000, 1001, 1001, 1001, 1001] 本机的时间戳钟:1000.0 次/秒(Hz);每个刻度 1.00 ms;32 位 TSval 绕一圈要 49.7 天(计算) example.com:握手之后、关闭之前(第 1~7.5 秒)本机发出的纯 ACK(keepalive 探测)6 个,带时间戳的 0 个;服务器发来的带时间戳的包 9 个 服务器 TSval 随时间变化的速率 1000.1 Hz(每个刻度 1.00 ms)
回 ACK 的一端 TSval 每秒增加约 1000;每条连接起点有随机偏移。keepalive 探测不带时间戳。
凭 TSecr 配对成功 20 个数据段(共发 20 条)。dummynet 让同一个包在 lo0 上被抓到不止一次(延迟前后各一份),所以“RTT”有两种读法: 数据段第一次被抓到 → 对应 ACK 第一次被抓到:中位 50.0 ms(最小 49.5 / 最大 51.1)——只包含一个方向的延迟 数据段第一次被抓到 → 对应 ACK 最后一次被抓到(= 真正送达):中位 50.0 ms(最小 49.5 / 最大 51.1)——两个方向都包含 内核 tcp_info:rttcur = 100 ms,srtt = 93 ms,rttvar = 13 ms
TSecr 配对 20/20 成功,但单个抓包点读到的差值不是真正 RTT(50 对 100 ms)。
发了 150 个不同的数据段;其中被重传(同一序号出现不同 TSval)的 36 个
序号 24194:发送过 2 次,TSval = [3326993437, 3326993503],间隔(ms)= [66]
序号 24294:发送过 2 次,TSval = [3326993483, 3326993573],间隔(ms)= [90]
序号 24344:发送过 2 次,TSval = [3326993508, 3326993573],间隔(ms)= [65]
在被重传的 36 个段里:有 ACK 回显了某次重传的 TSval 的 34 个,有 ACK 回显了最初那次的 TSval 的 0 个36 个被重传的段中,34 个 ACK 回显重传的 TSval,发送方因此分得清 ACK 对应哪次发送。
100 Mbit/s 的链路上,2^32 字节的序号空间 343.6 秒回绕一次(计算)
1000 Mbit/s 的链路上,2^32 字节的序号空间 34.4 秒回绕一次(计算)
10000 Mbit/s 的链路上,2^32 字节的序号空间 3.4 秒回绕一次(计算)
100000 Mbit/s 的链路上,2^32 字节的序号空间 0.3 秒回绕一次(计算)
时间戳钟 1000 Hz:TSval 32 位回绕要 49.7 天,PAWS 的比较窗口(2^31)是 24.9 天;规范要求时间戳钟的刻度在 1 ms~1 s 之间,保证一个包在网络里的寿命(MSL)远小于绕一圈的时间(计算)序号 32 位回绕:10 Gbit/s 下 3.4 秒。TSval 49.7 天才回绕,可以挡掉旧包。没有实测。