标签:number 9.4 返回 div soc 状态 大小 表示 保存
既然是队列,肯定就有大小,那么当这两个队列满了没有空间了怎么办呢? 例如如果我们listen()后不去accept() ,那么全连接队列肯定会满的。 我们下面分别对于这两个队列结合试验进行描述。
试验环境:
CentOS Linux release 7.5.1804 (Core)
Linux version 3.10.0-229.4.2.el7.x86_64
首先说一下 SYN flooding攻击,为了应对SYN flooding(即客户端只发送SYN包发起握手而不回应ACK完成连接建立,快速填满server端的半连接队列,让它无法处理正常的握手请求),Linux实现了一种称为SYNcookie的机制,通过net.ipv4.tcp_syncookies控制,设置为1表示开启。简单说SYNcookie就是将连接信息编码在ISN(initialsequencenumber)中返回给客户端,这时server不需要将半连接保存在队列中,而是利用客户端随后发来的ACK带回的ISN还原连接信息,以完成连接的建立,避免了半连接队列被攻击SYN包填满。 也就是说,如果开启了syncookies的话(通过 TCP参数 net.ipv4.tcp_syncookies配置 ),半连接队列就相当于是无限大的了。在我的环境中就是默认开启的。
如果我们将syncookies关闭的话,半连接队列的长度将为 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog) ,,此时对半连接填满时的处理策略是 server将 丢弃请求连接的SYN,不回复SYN+ACK,这样就会造成client收不到握手响应,始终处在SYN_SENT状态,经过几次重传后,客户端 connect() 调用失败。
当server收到最后一次ACK时,希望将连接从半连接队列中取出放入全连接队列,但是此时全连接队列已满,此时的策略是 将最后接收到的ACK丢弃,并且根据net.ipv4.tcp_synack_retries定义的次数重新向client发送SYN+ACK, client在接收到重传的SYN+ACK后会认为之前的ACK丢失了进而重传ACK,这样在下次重新接收到ACK后,如果全连接队列有空间了,连接就可以正确完成建立。 如果重传了规定次数后全连接队列中依旧没有空间,那么server会简单终止这次连接(这里简单终止的意思是server并没有像client发送RST表明连接无法建立,而是直接丢弃了,这样就会导致在client中的连接处在ESTABLISHED状态,并一直如此,后面的实验会有涉及,我很困惑为什么要这样设计? 还是我没有正确理解 !)。
标签:number 9.4 返回 div soc 状态 大小 表示 保存
原文地址:https://www.cnblogs.com/zh1164/p/10003451.html