三次握手状态图:
简述三次握手:
(seq、ack具体看上图)
1.三次握手:
(1)client首先创建传输控制模块TCB,向server发出请求报文段,该报文段首部中SYN=1,ACK=0(SYN=1的报文段不能携带数据,且要消耗一个序号(为什么要消耗序号?可以认为是为了确认,具体可看tcp中SYN、FIN为什么要消耗一个序号))。
这时,client进入SYN_SENT(同步已发送)状态
(2)server接收到后,如果同意建立连接,则向client发送SYN=1,ACK=1的报文段(SYN同样不能携带数据,且要消耗序号)。这时,server进入SYN_RCVD(同步收到)状态
(3)client接收后,向server发送ACK=1的报文段(ACK可以携带数据,不携带数据的时候不需要消耗序号)。此时,client进入ESTABLISHED(已建立连接)状态。可以看出第三次握手客户端已经可以发送携带数据的报文段了。
2.两个队列:
server端维护两个队列:syn queue(半连接队列)、accept queue(全连接队列)
client第一次发送时,server就将相关信息放到syn queue中;
client第二次发送时,server就将相关信息放到accept queue中;
比如syn floods攻击就是针对半连接队列的:攻击方不停地建立连接,server不停的回复SYN+ACK报文段,而攻击方收到后就扔掉,导致server上半连接队列syn queue满而影响了正常的请求。
当client第二次发送时,若server的全连接队列accept queue没满,则将相关信息从半连接队列放到全连接队列里;若满了,会将此报文段丢弃,不将其相关信息加入accept queue中,此时tcp_abort_on_overflow为0(表示丢弃,不加入),过一段时间再发送SYN+ACK给client(即连接的第二步),如果client等待时间比较短,则容易发生异常。