tcp_max_syn_backlog和somaxconn有什么区别?它们都与TCP连接相关,但具体有什么不同呢?

13

我一直在阅读关于Linux上TCP实现的文章,有些搞不清楚,net.ipv4.tcp_max_syn_backlognet.core.somaxconn以及作为listen()系统调用参数的backlog之间有什么区别,它们之间的联系是什么。

注:我想要针对内核版本4.15的解释,因为我发现在这个主题上较老和较新的内核之间存在一些差异。

1个回答

23

sysctl是一个API。因此,您可以阅读适当版本的Linux内核文档

tcp_max_syn_backlog - INTEGER
    Maximal number of remembered connection requests, which have not
    received an acknowledgment from connecting client.
    The minimal value is 128 for low memory machines, and it will
    increase in proportion to the memory of machine.
    If server suffers from overload, try increasing this number.

somaxconn - INTEGER
    Limit of socket listen() backlog, known in userspace as SOMAXCONN.
    Defaults to 128.  See also tcp_max_syn_backlog for additional tuning
    for TCP sockets.

让我们考虑一下TCP握手tcp_max_syn_backlog代表SYN_RECV队列中连接的最大数量。也就是说,当您的服务器收到SYN并发送SYN-ACK但尚未收到ACK时。这是一种称为“请求套接字”的单独队列,在代码中称为reqsk(即不完全的套接字,“请求套接字”占用更少的内存)。在此状态下,我们可以节省一些内存,并且如果ACK不到达,则不需要分配完整的套接字。该队列的值受到影响(请参见此帖子)通过listen()backlog参数并由内核中的tcp_max_syn_backlog限制。 somaxconn代表ESTABLISHED队列的最大大小。这是另一个队列。回想一下先前提到的SYN_RECV队列-您的服务器正在等待来自客户端的ACK。当ACK到达时,内核会从“请求套接字”中大致地创建完整的套接字,并将其移动到已建立队列中。然后,您可以在此套接字上执行accept()。该队列也受listen()backlog参数的影响,并由内核中的somaxconn限制。
有用的链接:12

1
在你提到的链接中,我发现了这样一段话:“TCP套接字上backlog参数的行为在Linux 2.2中发生了变化。现在它指定了等待被接受的完全建立的套接字队列长度,而不是不完整连接请求的数量。不完整套接字队列的最大长度可以使用/proc/sys/net/ipv4/tcp_max_syn_backlog进行设置。”但是你说backlog影响两个队列,能否解释一下? - Random
1
@Random 在4.15内核中也是一样的:sk_acceptq_is_fullinet_csk_reqsk_queue_is_full将与通过listen()调用设置的sk->sk_max_ack_backlog进行比较。 - red0ct
1
@Random 是的。*"在listen()系统调用中,backlog参数被截断为somaxconn值。因此,somaxconn值不应超过65535(USHRT_MAX)"*. 添加了链接。如果我的回答有帮助,请标记为已接受。 - red0ct
1
@Random 不客气 :) Linux内核变化非常迅速,因此很难跟上最新版本的书籍。通常来说,理解某个经过详细描述的Linux内核版本上的网络堆栈的基础知识就足够了,然后只需检查源代码(查看差异,分析通过检查git Linux内核存储库添加的新功能)以了解您需要理解的特定版本即可。 - red0ct
4
考虑到一个同步排队连接所占用的内存非常少(我看到是80字节),把这个值增加到非常大的数值,比如从512增加到5万,会有什么不利影响呢?这样做只需要4MB的内存,且可以更好地防止Syn欺骗攻击。但是是否存在缺陷呢? - l008com
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接