0、目录
1、为什么是三次握手
2、Tcp异常断开及RST 报文
3、time_wait存在意义
4、什么是半连接队列?
5、ISN(Initial Sequence Number)是固定的吗?
6、三次握手过程中可以携带数据吗?
7、SYN攻击是什么?
8、粘包发生在那些情况下?
1、为什么是三次握手
单向传输一次信令的可靠性包括: 网络是否允许, 对端是否准备好接收和发送。只有通过ack才能确认这种能力。Tcp保证双向可靠通信,所以两端都做一次发送和接收ack。其中第二三步可以合并一步,增加效率。
2、Tcp异常断开及RST 报文
1、尝试与服务器未监听的端口建立TCP连接,服务器将会直接向客户端发送reset报文
2、接收端收到TCP报文,但是发现该TCP的报文,并不在其已建立的TCP连接列表内,则其直接向对端发送reset报文(断电重启场景)(已关闭的链收到漫游报文时返回)
3、在交互中的某一方长期未收到来自对方的确认报文,则在超出一定的重传次数或时间后,会主动向对端发送Reset报文释放Tcp连接
4、在设计系统时,会利用reset报文快速释放已完成数据交互的TCP连接,以提高业务交互的效率
Reset报文的利用
1、安全设备利用reset报文阻断异常连接
3、time_wait存在意义
存在意义:
①因为被动关闭的可能因为ACK没收到而重新发送FIN,主动端最多等待2msl来接收。
②四元组(2 ip+2 port)确定一个链接,需要保证再次建立该TCP链接时,来自该链接先前化身的重复分组(漫游分节)已经在网络中消逝了
为什么time_wait在主动关闭一端?同意义①
2msl(MSL = IP报文段在网络中存在的最大时间)是为了保证接收重发的FIN。2代表 ack返回 + 重发的Fin
4、什么是半连接队列?
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列
服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除
5、ISN(Initial Sequence Number)是固定的吗?
当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器,每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。
三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。
6、三次握手过程中可以携带数据吗?
其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据
假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据。
7、SYN攻击是什么?
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
netstat -n -p -t | grep SYN_RECV
常见的防御 SYN 攻击的方法有如下几种:
- 缩短超时(SYN Timeout)时间
- 增加最大半连接数
- 过滤网关防护
- SYN cookies技术
8、粘包发生在那些情况下?
TCP是端到端传输的,同时TCP连接是可复用,复用就是一条连接可以供一台主机上的多个进程使用。
1. 由TCP连接复用造成的粘包问题。
如果没有复用一个连接只提供给端到端的两个进程使用,这是数据的传输方和发送方都是约定好了数据的格式的,但是多个进程使用一个TCP连接,此时多种不同结构的数据进到TCP的流式传输,边界分割肯定会出这样或者那样的问题。
如果利用tcp每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题
连接复用的问题
2. 因为TCP默认会使用Nagle算法,此算法会导致粘包问题。
而Nagle算法主要做两件事,1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,在一个确认到来时一起发送。
多个分组拼装为一个数据段发送出去,如果没有好的边界处理,在解包的时候会发生粘包问题。
3. 数据包过大造成的粘包问题。
比如应用进程缓冲区的一条消息的字节的大小超过了发送缓冲区的大小,就有可能产生粘包问题。因为消息已经被分割了,有可能一部分已经被发送出去了,对方已经接受了,但是另外一部分可能刚放入套接口发送缓冲区里准备进一步发送,后半段就有可能是另外一组数据,直接导致了粘包问题的出现。
4. 流量控制,拥塞控制也可能导致粘包。
5. 接收方不及时接收缓冲区的包,造成多个包接收。
Nagle算法、接收方不及时处理两种情况造成的粘包问题主要原因
粘包问题如何处理?
- Nagle算法 问题导致的,需要结合应用场景适当关闭该算法。
2.其他几种情况的处理方法主要:
- 尾部标记序列。通过特殊标识符表示数据包的边界,例如\n\r,\t,或者一些隐藏字符。
- 头部标记分步接收。在TCP报文的头部加上表示数据长度。
- 应用层发送数据时定长发送。