段按顺序处理,首先抛弃重复的段,对于以后的处理要根据SEG.SEQ的大小进行。如果有的段内的新老内容重叠在一起,那只用处理新的那一部分。下面是对接收到的数据的可接受性测试中的四种情况:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果RCV.WND = 0,除了合法的ACK,URG和RST段外拒绝其它的数据段。如果接收到的数据段不可接受,应该返回一个应答,格式如下:<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>。在发送完应答后,抛弃不可接受的数据段,然后返回。
第二步检查RST位。
如果处于SYN-RECEIVED 状态时,而且处于设置了RST的情况下,如果连接以被动OPEN开始,将连接返回到LISTEN状态,不需要通知用户;如果连接以主动OPEN打开,拒绝连接,并通知用户"connection refused"。在上面任何一种情况下,所有在重发队列中的数据都要删除。在主动OPEN的那种情况下,进入CLOSED状态,删除TCB然后返回。
如果处于ESTABLISHED,FIN-WAIT-1,FIN-WAIT-2或CLOSE-WAIT状态时,而且RST已经设置,那么任何存在的RECEIVE和SEND都会收到"reset"。所有队列中的数据段都应该立即发送。用户也会收到"connection reset"。进入CLOSED状态,删除TCB并返回。
如果处于CLOSING状态,LAST-ACK状态或TIME-WAIT状态,而且RST已经设置,进入CLOSED状态,删除TCB并返回。
检查安全和优先级
在SYN-RECEIVED状态下
如果段中的security/compartment和优先级和TCB中的不匹配,发送RST并返回。
在ESTABLISHED状态下
如果段中的security/compartment和优先级和TCB中的不匹配,发送RST ,所有存在的RECEIVE和SEND接收到"reset",立即发送所有队列中的数据段,用户接收到"connection reset"。进入CLOSED状态,删除TCB并返回。
第四步检查SYN位,如果连接处于以下状态
SYN-RECEIVED
ESTABLISHED状态
FIN-WAIT STATE-1
FIN-WAIT STATE-2
CLOSE-WAIT状态
CLOSING状态
LAST-ACK状态
TIME-WAIT状态
如果SYN在窗口中就是错误,发送RST,任何存在的RECEIVE和SEND收到"reset",所有在队列中的数据段立即发送,用户也接收到"connection reset",进入CLOSED状态,删除TCB并返回。如果SYN未在窗口中,这一步不会发生。
第五步检查ACK域
如果ACK位关闭,抛弃数据段返回。如果ACK域打开的情况下,如果连接处于
SYN-RECEIVED状态时
如果SND.UNA =< SEG.ACK =< SND.NXT,进入ESTABLISHED状态。如果段的确认消息不可接受,形成如下形式的RST并发送:
<SEQ=SEG.ACK><CTL=RST>
ESTABLISHED状态时
如果SND.UNA < SEG.ACK =< SND.NXT,设置SND.UNA <- SEG.ACK。因此而对重新传送队列中数据段的确认也带来了对这些数据段的删除。用户应该接收对缓冲区的主动确认,如果ACK是重复的(SEG.ACK < SND.UNA)可以忽略这个ACK。如果ACK确认了还未发送的东西(SEG.ACK > SND.NXT),那么可以发送ACK,抛弃数据段并返回。
如果SND.UNA < SEG.ACK =< SND.NXT,应该更新发送窗口。如果(SND.WL1 < SEG.SEQ)或(SND.WL1 = SEG.SEQ且SND.WL2 =< SEG.ACK),设置SND.WND <- SEG.WND,SND.WL1 <- SEG.SEQ和SND.WL2 <- SEG.ACK。
FIN-WAIT-1状态
除了对于ESTABLISHED状态的处理外,如果确定了FIN,则进入FIN-WAIT-2状态并在这个状态下继续处理。
FIN-WAIT-2状态时
除了对于ESTABLISHED状态的处理外,如果重新发送队列为空,确认用户的CLOSE,但不删除TCB。
CLOSE-WAIT状态时
同ESTABLISHED状态的处理。
CLOSING状态时
除了对于ESTABLISHED状态的处理外,如果确定了FIN,则进入TIME-WAIT状态,如果未确认,则忽略这个段。
LAST-ACK状态时
在此状态下唯一可能发生的就是重要发送远程FIN。如果确认了FIN,则删除TCB,进入CLOSED状态并返回。
TIME-WAIT状态时
在此状态下唯一可能发生的就是重要发送远程FIN。确认它,并重新开始2 MSL超时。
第六步检查URG位,如果连接处于ESTABLISHED状态,FIN-WAIT-1状态或FIN-WAIT-2 状态,而且URG位被设置,那么RCV.UP <- max(RCV.UP,SEG.UP),通知用户远方有紧急数据,如果用户已经处于紧急状态,不用再多嘴了。连接在此时不会处于CLOSE-WAIT状态,CLOSING状态,LAST-ACK状态或TIME-WAIT状态,因为还没有从远方获得FIN。
第七步处理段数据
处于ESTABLISHED状态,FIN-WAIT-1 状态或FIN-WAIT-2 状态时,在进入ESTABLISHED状态后才可能向用户接收缓冲区传送数据。段中的数据可以移向缓冲区,直到缓冲区满或段为空为止。如果段为空并带有标记PUSH,在返回缓冲区数据后要通知用户接收到PUSH。TCP传送数据时必须对接收到的数据也发给确认。前面已经说过对RCV.NXT和RCV.WND的处理,这里不再多说了。发送的确认有如下格式:<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>。
而CLOSE-WAIT状态,CLOSING状态,LAST-ACK状态或TIME-WAIT 状态根本不会发生,因为还未从远程TCP接收到FIN。
第八步检查FIN位。如果状态是CLOSED,LISTEN或SYN-SENT,不要处理FIN,因为此时的SEG.SEQ不会的意义,应该直接抛弃数据段返回。如果设置了FIN位,通知用户"connection closing"中止所有正在进行的RECEIVE,增加RCV.NXT超过FIN,对FIN发送确认。
如果此时处于:SYN-RECEIVED状态或ESTABLISHED状态进入CLOSE-WAIT状态。
如果此时处于FIN-WAIT-1 状态
如果确定了FIN段,那么进入TIME-WAIT状态,打开time-wait计数器,关闭其它计数器,如果没有确认,进入CLOSING状态。
如果此时处于FIN-WAIT-2状态
进入TIME-WAIT状态,关闭其它计数器,打开time-wait计数器。
如果此时处于CLOSE-WAIT状态或CLOSING状态或LAST-ACK状态,保留各自原来的状态。
如果此时处于TIME-WAIT状态,保持在TIME-WAIT状态。重新开始2 MSL time-wait超时。
用户超时
对于任何一种状态,用户超时的情况下,发送队列中的数据,返回"error: connection aborted due to user timeout",删除TCB,进行CLOSED状态并返回。
重发超时
在任何状态下,如果重发队列中的数据段发送超时,将它再次放到队列首部重新发送。
TIME-WAIT超时
如果time-wait超时,删除TCB,进行CLOSE状态并返回。