T定时器后丢掉接收到的ACK包。 接下来是对SYN包的处理。前面提到了,如果在TIME_WAIT状态下接收到序列号比上一个连接的结束序列号大的SYN包,可以接受,并建立新的连接,下面这段代码就是来处理这样的情况:
[cpp] view plaincopyprint? 01.if (th->syn && !th->rst && !th->ack && !paws_reject && 02. (after(TCP_SKB_CB(skb)->seq, tcptw->tw_rcv_nxt) || 03. (tmp_opt.saw_tstamp && 04. (s32)(tcptw->tw_ts_recent - tmp_opt.rcv_tsval) < 0))) { 05. u32 isn = tcptw->tw_snd_nxt + 65535 + 2; 06. if (isn == 0) 07. isn++; 08. TCP_SKB_CB(skb)->when = isn; 09. return TCP_TW_SYN; 10.} if (th->syn && !th->rst && !th->ack && !paws_reject && (after(TCP_SKB_CB(skb)->seq, tcptw->tw_rcv_nxt) || (tmp_opt.saw_tstamp && (s32)(tcptw->tw_ts_recent - tmp_opt.rcv_tsval) < 0))) { u32 isn = tcptw->tw_snd_nxt + 65535 + 2; if (isn == 0) isn++; TCP_SKB_CB(skb)->when = isn; return TCP_TW_SYN; } 当返回TCP_TW_SYN时,在tcp_v4_rcv()中会立即释放time_wait控制块,并且开始进行正常的连接建立过程。 如果数据包不是上述几种类型的包,可能的情况有: 1、不是有效的SYN包。不考虑时间戳的话,就是序列号在上一次连接的结束序列号之前 2、ACK包,起始序列号不是下一个要接收的序列号 3、RST包,起始序列号不是下一个要接收的序列号 4、带数据的SKB包 这几种情况由以下代码处理:
[cpp] view plaincopyprint? 01.if (!th->rst) { 02. /* In this case we must reset the TIMEWAIT timer. 03. * 04. * If it is ACKless SYN it may be both old duplicate 05. * and new good SYN with random sequence number <rcv_nxt. 06. * Do not reschedule in the last case. 07. */ 08. if (paws_reject || th->ack) 09. inet_twsk_schedule(tw, &tcp_death_row, TCP_TIMEWAIT_LEN, 10. TCP_TIMEWAIT_LEN); 11. 12. 13. /* Send ACK. Note, we do not put the bucket, 14. * it will be released by caller. 15. */ 16. &nbs 上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >>
|