TCPIP协议栈中的TimeStamp选项
TCP应该是以太⽹协议族中被应⽤最为⼴泛的协议之⼀,这⾥就聊⼀聊TCP协议中的TimeStamp选项。这个选项是由RFC 1323引⼊的,该C建议提交于1992年,到今天已经⾜⾜有20个年头。不过相信⼤部分程序猿对这个建议还是相当陌⽣。
要理解为啥需要⽤TimeStamp选项,还需要从TCP协议的⼏个基本设计说起。
TCP协议的⼏个设计初衷,以及引发的问题:
1. 协议规定收端不需要响应每⼀个收到的数据报⽂,只需要收到N个报⽂后,向发端回复⼀个ack报⽂即可。
这样的规定是为了提⾼通讯的效率,但是也引⼊了⼏个问题:
A. 发端发出报⽂后,到底多久能够收到ack是不确定的。
B. 万⼀ack报⽂丢失了,判断需要重发的timeout时间也很难确定。
2. TCP报⽂中,标⽰Sequence号的地址长度为32位。
这就限制了发端最多⼀次发送2^30长度的数据,就必须等待ack信号。为啥呢?在这个⾥有⼀些详细的讨论。
然⽽对于超⾼速以太⽹(1000M以⾄于10G),这样会影响TCP连接的转发效率。
为解决上⾯提到的问题,TimeStamp选项主要有两个⽤途:
1. 测量TCP连接两端通讯的延迟(Round Trip Time Measurement)
有了RTTM机制,TCP的两端可以很容易的判断出线路上报⽂的延迟情况,从⽽制定出⼀个优化的发包间隔和报⽂TimeOut时间,从⽽解决了第⼀个问题。
2. 处理Sequence号反转的问题(Protect Against Wrapped Sequence Numbers)。
TCP收端收到⼀个数据报⽂后,会先⽐较本次收到报⽂的TimeStamp和上次收到报⽂的TimeStamp。如果本次的⽐较新,那么可以直接判断本次收到的报⽂是新的报⽂,不需要进⾏复杂的Sequence Number Window Scale计算,从⽽解决了第⼆个问题。
然⽽,RFC1323建议还存在⼀些隐患。
建议中定义TimeStamp增加的间隔可以使1ms-1s。如果设备按照1ms的速度增加TimeStamp,那么只要⼀个TCP连接连续24.8天
(1ms*2^31)没有通讯,再发送报⽂,收端⽐较本次报⽂和上次报⽂TimeStamp的动作就会出错。(问题1)
(注:TCP协议中并没有定义KeepAlive。如果应⽤层代码不定义超时机制,TCP连接就永远不会中断,所以连续24.8天不通讯的情况是却有可能发⽣的。)
引⽤Linux相关代码:((s32)(tp->v_tsval - tp->rx_opt.ts_recent) < 0)
⽐如 tp->v_tsval = 0x80000020,      tp->rx_opt.ts_recent = 0x10
((s32)(tp->v_tsval - tp->rx_opt.ts_recent) = (s32)0x80000010,是⼀个负数,必然⼩于0。
如果解决问题1呢?
已知按照RFC1323的规定,按照最快TimeStamp增加的速度,也需要24.8天TImeStamp才有可能发⽣反转。
如果((s32)(tp->v_tsval - tp->rx_opt.ts_recent) < 0)判断成⽴,还可以再⽤本地收到报⽂的本地TimeStamp减去上⼀次收到报⽂的本地TimeStamp。如果时间⼤于24.8天,那么就是TimeStamp发⽣了反转;否则就不是反转的情况。这样做是不是就万⽆⼀失了呢?不⼀定!
别忘了本地TimeStamp的计数器也是个32位,也可能会翻转的。(问题2)
举个极端的例⼦:假设TCP两端设备的TimeStamp增加间隔不⼀致,A为1ms,B为10ms。TCP连接连续248天没有通讯;这个时候B向A发送了⼀个数据报⽂。
此时B发送给A的TCP报⽂中的TimeStamp,正好发⽣了翻转。然⽽由于A的计数器是每1ms加⼀的,248天时间,A的计数器已经归零过5次了。这时候再⽤本地TimeStamp做判断还是错的。
⽐较保险的做法是:
如果TCP连接的速度不那么快(2^32/s),本地TimeStamp⽤最⼤间隔时间1S。从⽽规避了(问题2)。
如果TCP连接速度⾮常快,1S的TimeStamp间隔就有些不合时宜了,可以选⼩⼀级,如100ms。如果这时候还会发⽣连续24800天(为啥是24800天呢)不通讯的情况,除了骂娘以外,我也没办法了。
Description
Protocol suite: TCP/IP.tcpip协议pdf
Protocol type: Transport layer protocol.
Option length: 10 bytes.
The TCP Timestamp option obsoletes the TCP Echo request and Echo reply options.
RFC 1323:
The timestamps are used for two distinct mechanisms: RTTM (Round Trip Time Measurement)
and PAWS (Protected Against Wrapped Squences).
结构图
Kind. 8 bits. Set to 8.
Length. 8 bits. Set to 10.
Timestamp Value (TSval). 32 bits.
This field contains the current value of the timestamp clock of the TCP sending the option. TImestamp Echo Reply (TSecr). 32 bits.
This field only valid if the ACK bit is set in the TCP header. If it is valid, it echos a timestamp value that was sent by the remote TCP in the TSval field of a Timestamps option. When TSecr is not valid, its value must be zero. The TSecr value will generally be from the most recent Timestamp option that was received; however, there are exceptions that are explained below. A TCP may send the Timestamp option in an initial SYN , segment containing a SYN bit and no ACK bit), and may send a TSopt in other segments only if it received a TSopt in the initial SYN segment for the connection.
Linux内核中的使⽤
如果⽀持Timestamp选项,那么可以⽤此选项来计算RTT。
[java]
1. static void tcp_ack_saw_tstamp(struct sock *sk , int flag)
2. {
3.        /* RTTM Rule: A TSecr value received in a segment is used to
4.          * update the averaged RTT measurement only if the segment
5.          * acknowledges some new data, i.e., only if it advances the
6.          * left edge of the send window.
7.          *
8.          * Changed: reset backoff as soon as we see the first valid
9.          * sample. If we do not, we get strongly overestimated rto.
10.          * With timestamps samples are accepted even from very
11.          * old segments: f.e., when rtt=1 increases to 8, we retransmit
12.          * 5 times and after 8 seconds delayed answer arrives rto
13.          * becomes 120 seconds!
14.          */
15.          struct tcp_sock *tp = tcp_sk(sk);
16.          tcp_valid_rtt_meas(sk, tcp_time_stamp - tp->v_tsecr);
17. }
rtt即等于现在的时间tcp_time_stamp减去Timestamp Echo Reply,即tp->v_tsecr。
TCP timestamp option的作⽤:
1)allow more accurate round-trip time measurements for deriving the retransmission
timeout estimator.
2)protect against old segments from the previous incarnations of the TCP connection.
3)allow detection of unnecessary retransmissions.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。