|
你曾经遇到过哪些和时间戳有关的问题?最后是如何解决的?由此可见,一个数据包中,可能同时存在多种时间戳,本文主要探讨的是TCP时间戳。在后续的讨论中,除非另有明确说明,文中提到的“时间戳”一词均默认指的是TCP时间戳。要分析时间戳,需要先了解时间戳的内容和格式。时间戳以TCP选项的形式进行传输,该选项的长度为10字节,格式如下:如图1所示,红、绿、蓝、黄四部分,分别为选项类型、长度、时间戳数值、时间戳回显的原始数据流和解码信息,该选项为SYN包的时间戳,即会话起始,时间戳数值为0xbe48897c;时间戳回显为空,填充为全0。图2展示了该会话SYN/ACK包的时间戳,如下图所示,图2中的时间戳回显为0xbe48897c,与图1中的时间错正好相等。图2的时间戳为0x3c76d71c。
了解了时间戳与回显应答的关系,我们再来看看时间戳是如何增长的。RFC 1323中这样描述时间戳的增长:With the chosen
range of timestamp clock requencies (1 sec to 1 ms), the time to wrap the sign bit
will be between 24.8 days and
24800 days. A TCP connection that is
idle for more than 24 days and
then comes to life is exceedingly unusual.关于时间戳时的钟频率范围(1秒到1ms),包裹符号位的时间将在24.8天至24800天之间。TCP连接空闲超过24天然后恢复正常是非常不寻常的。因此,时间戳的递增单位一般为1ms,也有每10ms、100ms甚至1000ms递增的情况。
ACK包的时间戳为0xbe488985,SYN包时间戳为0xbe48897c,时间戳数值相差7;根据时序图中的相对时间(捕获时间戳)计算,ACK包的时间戳为会话第7ms,时间戳数值差和时间差显示该会话客户端时间戳在7ms内递增了7点,因此推测客户端的时间戳递增单位为1ms。由于不同操作系统默认使用的时间精度和时间戳起始点不同,因此不同主机之间的时间戳数值看起来可能相差很多,如本例中的客户端时间戳0xbe48897c与服务器时间戳0x3c76d71c,数值就相差很远。在一些传输窗口大、重传率高的会话中,精确测量RTT是困难的。引入时间戳后,得到了发送方真实发送数据的时间,能够实现对RTT的精确计算。二、配合PAWS机制,区分序列号回绕前后的数据包,防止TCP会话由于序列号回绕导致的错误。由于TCP的序列号长度为32位,因此一轮序列号最多描述2^32字节数据,即4GB数据,在高速的TCP连接中(每秒传输1GB以上),TCP序列号每4秒即兜一圈回绕一次,在序列号回绕+丢包重传的组合场景下,时间戳能为服务器判断数据包的新旧提供非常好的依据,便于服务器直接忽略时间戳较旧的数据包,防止连接发生错误。在服务器启用了tcp_tw_recycle和tcp_tw_reuse这样的快速端口重用场景下,时间戳可以用于区分数据包是来自新TCP连接或是来自旧TCP连接。故障的成因是由于不同客户端对TCP时间戳的计算精度、起点值不同,所以数值有很大差异(这一点从前文中的时间戳示例也能看出)。不同主机之间的时间戳数值有很大差距。而tcp_tw_recycle参数是基于源IP进行检查的,来自公网的不同客户端被SNAT后,对于服务器来说成为了一个客户端,这就会造成“一个客户端IP的时间戳忽快忽慢”,不巧的是tcp_tw_recycle参数又是丢弃时间戳较旧的数据包的,造成了“部分客户端无法建立TCP连接”的故障现象。对于此类故障的排查,通常是极其耗时的,接下来看看如何从流量分析的角度发现此类问题:
如图所示,图中展示了一些会话,服务器192.168.1.171的443端口运行了HTTPS服务,两台客户端使用相同的SNAT地址访问服务器,一台成功,一台失败,影响了业务,需要分析原因。观察连接建立失败的会话,都卡在了SYN_SENT状态,通过这里可以判断这些连接建立失败的会话连三次握手都没能成功建立,软件将这些会话识别为TCP协议。而那些状态为CLOSED的会话,根据数据包数量可以判断已经正常完成了交互,软件将该会话识别为HTTPS协议。通过时序图也能看出,客户端发送的SYN包,服务器完全没有理会。图6 几乎同时出现的2395端口会话和2396端口会话端口2395和2396的会话是在同一秒开始的,一个成功,一个失败,说明该时段内服务器上的业务是正常的。着重观察一下这两条会话的SYN包有什么区别,使用对比法,对比正常SYN包和异常SYN包的区别图7 2395和2396端口会话SYN包和SYN/ACK包的情况如图6所示,2395端口客户端发送SYN包后,服务器正常返回了SYN/ACK包。随后出现的2396端口会话,服务器似乎没有收到或者忽略了客户端的SYN包。2395端口的客户端SYN包时间戳为be60ada1,服务器正常响应了SYN/ACK;2396端口的客户端SYN包时间戳为be498c98,服务器无响应。对比这两个时间戳的数值,发现第二个客户端的时间戳数值比第一个客户端的时间戳数值小,形成了“后来的数据包反而较旧”的现象。联想到tcp_tw_recycle的PAWS序列号回绕机制,就不难理解服务器为何没有响应这些SYN包了。分析结论为,时间戳的值随时间应为单调递增,但在分析中由于用户服务器是经过NAT后进行互联网的应用访问,而该NAT地址同时存在其他设备访问相同的应用,开启了tcp_tw_recycle选项后,当连接进入TIME_WAIT状态后,会记录对应远端主机最后到达的时间戳。如果同样的主机有新的分节到达,且时间戳小于之前记录的时间戳,即视为无效,相应的数据包会被丢弃本文介绍了TCP的时间戳选项,深入探讨了时间戳选项的分析,和时间戳选项可能导致的故障原因和故障现象,包括了时间戳问题在CSNAS时序图和其它页面中的分析方法,通过深入理解和掌握时间戳的分析技巧,能够提升流量分析工程师在工作中快速分析解决此类故障的能力。还记得开篇的互动问题吗? 你曾经遇到过哪些和时间戳有关的问题?最后是如何解决的?看了这篇文章,你有什么新的想法?欢迎在评论区留言和我们交流~
|