linux TCP未完成队列和完成队列

来源:互联网 发布:唯彼穷途哭,知余行路难 编辑:程序博客网 时间:2024/05/12 02:09
已完成连接队列(completed connection queue)
(1)三次握手已经完成,但还未被应用层接收(accept),但也处于ESTABLISHED状态.
(2)队列长度由listen的backlog参数和内核的 net.core.somaxconn 参数共同决定.
(3)当这个队列满了之后,不管未完成连接队列是否已满,是否启用syncookie,都不在接收新的SYN请求.(该特性跟内核版本有关)
(4)如果client端向已完成连接队列的socket发送包,内核将保存数据到socket的接收缓冲区,等应用层accept之后,传给应用层.

未完成连接队列(incomplete connection queue)
(1)半连接状态,处于SYN_RCVD状态.
(2)由内核参数 net.ipv4.tcp_max_syn_backlog 设置.
(3)如果启用了syncookie,在未完成连接队列满了之后,新的SYN请求将使用syncookie机制.
服务器会重发SYN-ACK,重试次数为:/proc/sys/net/ipv4/tcp_synack_retries

关于syn flood 攻击转载至:http://coolshell.cn/articles/11564.html
试想一下,如果server端接到了clien发的SYN后回了SYN-ACK后client掉线了,server端没有收到client回来的ACK,那么,这个连接处于一个中间状态,即没成功,也没失败。于是,server端如果在一定时间内没有收到的TCP会重发SYN-ACK。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻售,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才会把断开这个连接。
一些恶意的人就为此制造了SYN Flood攻击——给服务器发了一个SYN后,就下线了,于是服务器需要默认等63s才会断开连接,这样,攻击者就可以把服务器的syn连接的队列耗尽,让正常的连接请求不能处理。于是,Linux下给了一个叫tcp_syncookies的参数来应对这个事,由net.ipv4.tcp_syncookies控制:
当SYN队列满了后,TCP会通过源地址端口、目标地址端口和时间戳打造出一个特别的Sequence Number发回去(又叫cookie),这时server不需要将半连接保存在队列中。如果是攻击者则不会有响应,如果是正常连接,则会把这个 SYN Cookie发回来,然后服务端可以通过cookie建连接(即使你不在SYN队列中)。请注意,请先千万别用tcp_syncookies来处理正常的大负载的连接的情况。因为,synccookies是妥协版的TCP协议,并不严谨。
对于正常的请求,你应该调整三个TCP参数可供你选择,第一个是:tcp_synack_retries 可以用他来减少重试次数;第二个是:tcp_max_syn_backlog,可以增大SYN连接数;第三个是:tcp_abort_on_overflow 处理不过来干脆就直接拒绝连接了。
http://m.blog.csdn.net/blog/yuzegao/42393203

0 0