标签:
本想通过学习将此文完成的,由于老板又给新的任务,估计要好久不能碰LINUX了,呜。。。。。。。只有先贴原理的一部分了。
希望高手能帮我指正错误并给出实现部分
TCP PAWS处理
PAWS(Protect Against Wrapped Sequence numbers)是一个简单的防止重复报文的机制。PAWS使用和RTTM同样的时间戳机制进行操作。
时间戳选项在RFC1323有详细的描述:
+--------+---------+------------------------+------------------+
|Kind=8 | 10 | TS Value (TSval) |TS Echo Reply (TSecr)|
+--------+---------+----------------- --+-------------------+
1 1 4 4
时间戳选项类型是8,通常,我们将发送的时间戳和应答的时间戳集合在一起,形成了以上的形式,总长度是10bytes。根据RFC1323的建议,发送方在时间戳选项的首部添上0x0101080a,第一个和第二个字节都等于一,为NOP,在添上两个32bit的NOP后,紧接着的时间戳和数据就可以按照32bit对齐。
时间戳选向是两个4bytes的时间戳构成的,TSval是tcp发送此选项时的时钟值。TSecr仅出现在ACK被置位的情况下,它显示一个由远端tcp发送的时间域TSval的值。
有三种情况需要考虑:
1. 延迟的ACKs
(根据RFC1122中的规定,tcp不需要对每一个数据包都做出响应,可以对连续的数据包做出一个响应,这被称为延迟的ACKs,当然,也不能过分的延迟,通常,延迟应该小于0.5秒,在一个完整的数据流中,最少每两个数据报一个响应)
此时,数据发送段必须将延迟的ACKs占用的额外的时间包括到计算正确的RTT时间中去,否则会引起不必要的重传。因此,当延迟的ACK被使用,接收者必须回应以最初的未响应段的Tsval值。
2. 序列空间中有空洞(部分包丢失)
发送端将持续发送直到窗口被填满,同时,接受端将产生ACKs直到这些丢失的报到达。丢包可能是一个网络拥塞的信号,在这种情况下,发送端应该处于保守的重传状态。此外,高估RTT也优于低估。因此这个丢失包的ACK必须包含最新的增大窗口的数据段的时间戳。同样的情况出现在数据包顺序被网络重排的情况下。
3. 序列空间的填充的洞:
填补漏洞的数据包反映了网络特性的最新度量情况。从另一个角度说,从最初的数据段中获取的RTT值可能包含着发送者的超时重传,影响了发送方平均RTT值的正确性。因此,最新的数据包(填补漏洞的数据包)的时间戳应该回显。
涵盖了以上三种情况的运算法则将在下面描述。
1. 连接状态由两个32bits的接口描述:
TS.Recent保存一个用以发送数据段时填充TSecr时间戳的值(即对端发送的最新的有效时间戳),Last.ACK.sent保存最后一个数据段发送后的ACK值,当ACKs没有被延迟时,Last.ACK.sent将等于RCV.NXT。
2. 如果Last.ACK.sent落在了接收到的数据段的序列空间中:
SEG.SEQ<=Last.ACK.sent<seg.seq+seg.len <br="">那么,数据段的TSval被拷贝到TS.Recent;否则,这个TSval被忽略。
3. 当TSopt被发送,它的TSecr域被填充到当前的TS.Recent值中。
以下是个例子:
*数据包按顺序到达,但是,部分包的ACKs延迟了,从最早的未响应包的时间戳被回显。
TS.Recent
(A, TSval=1) ------------------->
1
(B, TSval=2) ------------------->
1
(C, TSval=3) ------------------->
1
<---- (ACK(C), TSecr=1)
(etc)
*数据包不按顺序到达,每个包都得到了响应。
在这种情况下,最新的使窗口的左边缘增长的数据包的时间戳被回显。直到丢失的包到达。在B的过程中,使得窗口的左缘增长的时间戳被回显。直到丢失的报文到达,
TS.Recent
(A, TSval=1) ------------------->
1
<----(ACK(A), TSecr=1)
1
(C, TSval=3)------------------->
1
<----(ACK(A), TSecr=1)
1
(B, TSval=2)------------------->
2
<---- (ACK(C), TSecr=2)
2
(E, TSval=5)------------------->
2
<----(ACK(C), TSecr=2)
2
(D, TSval=4) ------------------->
4
<---- (ACK(E), TSecr=4)
(etc)
根据以上的情况,PAWS假设每一个接收到的TCP报文包含一个单调不减的时间戳SEG.Tsval,最基本的观点就是如果收到比当前连接的时间戳更小的SEG.Tsval,那么就认为接收到了重复的报文。
随SYN或{SYN、ACK}报文发送的TSval时间戳用来初始化PAWS。在同步连接中,PAWS拒绝老的重复的非SYN报文和重复的SYN报文。在非连接状态,重复的SYN和{SYN、ACK}报文将被TCP三次建链操作进行的检查丢弃。
推荐在RST报文中不使用时间戳,忽略时间戳的RST报文可以被接收。老的重复的RST报文是极端不可靠的,因此,清除程序的优先权将高于时间戳。
以下描述基本的PAWS算法。
PAWS算法要求对同步连接中的所有报文进行如下操作:
1. 如果一个报文到达,其时间戳符合如下要求:SEG.Tsval<ts.recent,同时ts.recent是正确的,那么,认为此报文不可接受 <br="">发送一个ACK(在RFC-793中69页描述)并丢弃报文。注意:发送一个ACK是有必要的,这将保留TCP侦测、修复半开连接的机制。例子在RFC-793种描述
2. 假如报文超出了窗口范围,拒收(普通的TCP机制)
3. 假如到达的报文满足:SEG.SEQ<=Last.ACK.sent,那么将其时间戳填入TS.Recent。
4. 假如接收的报文是按序的(例如,在窗口值的左边缘),接受。
5. 否则,将此报文当作窗口内的乱序的tcp报文段(将报文加入队列,以后递交给用户)
其中,2、4、5是普通的tcp操作(在RFC-793中定义)
以上是RFC1323给出的算法,在Richard Stevens的TCP/IP详解(卷二:实现)中给出了新的回显算法。
标签:
原文地址:http://www.cnblogs.com/lutianba/p/4225037.html