Linux 中异常缓慢的 TCP 连接

     2023-04-14     178

关键词:

【中文标题】Linux 中异常缓慢的 TCP 连接【英文标题】:Unusually slow TCP-connection in Linux 【发布时间】:2020-05-03 14:30:55 【问题描述】:

我编写了基于 Berkeley 套接字的用户模式客户端-服务器 c 应用程序,该套接字通过某些专用网络进行交互。 情况肯定很奇怪。在某些模糊的情况下,连接有时会变得非常慢。在我的例子中,正常的 TCP 数据交换是每段大约 10-25 KB 的有效负载,但有时它会变成每段大约 200-500 字节。

经过一些故障排除后,我意识到其他网络服务无法重现此问题,因此看来是我的服务有问题。但我想不通,怎么了。它在 3.10 Linux 内核上运行良好,但在 4.4 上有这种奇怪的行为。会不会是一些内部内核更改导致了这样的问题?

我尝试使用 Linux sysctl 设置:

net.ipv4.tcp_congestion_control
net.ipv4.tcp_sack
net.ipv4.route.flush

但这并没有帮助。

似乎问题出现在监听套接字端。在 tcpdump 中,握手时 TCP 窗口大小正常。但是在第一个传入数据包窗口大小减小后(在侦听器方面)。

UPD 这是我的服务器端代码 sn-p:

 serv_fd = socket(AF_INET, SOCK_STREAM, 0); 
 if (serv_fd == -1) 
      perror("socket");
      return;
    

 server.sin_family = AF_INET;
 server.sin_port = htons(LISTEN_PORT);
 server.sin_addr.s_addr = htonl(INADDR_ANY);

 #ifdef SET_BUF
 if (setsockopt(serv_fd, SOL_SOCKET, SO_RCVBUF, &buflen, sizeof(int)) == -1) 
      perror ("setsockopt");
      return;
    
 if (setsockopt(serv_fd, SOL_SOCKET, SO_SNDBUF, &buflen, sizeof(int)) == -1) 
      perror ("setsockopt");
      return;
    
 #endif // SET_BUF

 if (bind(serv_fd, (struct sockaddr *) &server, sizeof(server)) == -1) 
      perror("bind");
      return;
    

 if (listen(serv_fd, 3)) 
      perror("listen");
      return;
    

 printf("Server is listening on %u\n", LISTEN_PORT);

有人能解释一下我的问题吗?我将不胜感激! 它可能与最近的一些 Linux 内核修改有关吗?我是否需要调整一些 Linux 内核设置或检查一些用户模式设置(例如套接字选项或其他)?

附:问题不稳定。

更新:

tcpdump 的输出:

IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [S], seq 426261790, win 43690, options [mss 65495,sackOK,TS val 799180610 ecr 0,nop,wscale 7], length 0
IP 10.0.0.99.12345 > 10.0.0.34.31334: Flags [S.], seq 803872704, ack 426261791, win 65483, options [mss 65495,sackOK,TS val 799180567 ecr 799180610,nop,wscale 0], length 0
IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 799180610 ecr 799180567], length 0
IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [P.], seq 1:1301, ack 1, win 342, options [nop,nop,TS val 799180610 ecr 799180567], length 1300
IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [P.], seq 1301:1804, ack 1, win 342, options [nop,nop,TS val 799181412 ecr 799180610], length 503
IP 10.0.0.99.12345 > 10.0.0.34.31334: Flags [.], ack 1804, win 512, options [nop,nop,TS val 799181412 ecr 799181412], length 0

10.0.0.34.31334 是客户端,10.0.0.99.12345 是服务器。注意最后一行意外的win 512

UPD2: 我在 dmesg 中看到了几条关于 SYN-cookie 的消息,例如:

possible SYN flooding on port 12345. Sending cookies.

但它们与慢速传输的时间关系不大。

【问题讨论】:

很奇怪的情况。如果“问题不稳定”,你怎么能确定问题没有出现在 3.10 内核上。看看dmesg 输出。传输慢的时候有什么不寻常的地方吗? 请注意,Cloudflare 博客条目 SYN packet handling in the wild 指出“在 4.3 之前的内核中,SYN 队列长度的计算方式不同。”我没有仔细看它,但我认为你的积压 3 在 4.3 之前被四舍五入到 16。这也表明将您的 backlog 增加到至少 16 可能会使您的性能类似于您在 3.10 中看到的性能。更改链接到博客here。 您还应该检查是否在 3.10 部署中启用了 SYN cookie。如果不是,SYN 将被丢弃,客户端将重新传输。 Here 是其他人在启用时间戳时观察到窗口大小和同步 cookie 的类似问题。 (如果您看不懂中文,请在 Chrome 中加载,右键单击并选择翻译,这会做得不错)。根据 cloudflare 博客,他们禁用了时间戳(这是存储 wscale 的位置),因此看不到这个问题。 @z0lupka 查看this change,它消除了nr_table_entries,它曾经具有最小值8+1,向上取整为2 的幂=16。我实际上并没有尝试从listen() 遵循backlog 的值。要真正证明基于 backlog 值为 3 的 SYN 队列长度是 16 需要更多调查。 @z0lupka 有人通过here 完成了这项工作 【参考方案1】:

我不确定这是否正是您的情况,但看起来很相似。似乎是known problem。

原因

许多情况都可能导致这种 Linux 内核行为:

SYN-cookies 上下文中内核连接处理的特殊性,连接具有零窗口比例(或者如果 WS 以其他方式修改)。 零窗口比例setsockopt()SO_RCVBUF 引起的(请参阅tcp_select_initial_window()) 非常backlog

说明

关于“慢”传输:Windows Scaling option 由两个主机在 [SYN - SYN+ACK] 阶段计算。粗略地说,主机 A 说“在未来交换期间暗示我在 N 上的 TCP 窗口大小”(SYN)然后主机 B 说“在未来交换期间暗示我在 M 上的 TCP 窗口大小”(SYN+ACK) - 这里 N 和 M 可能相同.因此,在正常情况下,这些系数会被存储并最终在数据交换时使用。 但是TCP SYN-cookies 技术意味着忘记了连接的 [SYN - SYN+ACK] 阶段(包括 WS 在内的一些声明的选项将在 SYN+ACK 之后丢失)。在这种情况下,Linux 内核重新计算 WS当 ACK 到达时(如果 ACK 已经到达,则需要创建常规连接)。但是第二次重新计算可能会有点不同,因为setsockopt() 不会影响它(出于某些客观原因)。在这里您面临的情况是,当您的服务器使用 SYN+ACK 发送零窗口比例选项,然后忘记它,然后重新生成连接(当 ACK 到达时),就像使用一些默认窗口比例(例如 7)并使用小窗口暗示客户端会将其乘以 128。但客户端不会忘记 WS 为 0 并将小窗口大小视为真实 - 因此它发送一小部分数据 - 因此您的“慢”连接占据了舞台。

关于 SYN-flood: 当你有这么少的积压时,一个简单的 3 次 SYN 重传可以引发 SYN-cookies(即会填充你的积压队列)。顺便说一句,您在 tcpdump 中看到重传吗? 来自ip-sysctl.txt:

Note, that syncookies is fallback facility.
It MUST NOT be used to help highly loaded servers to stand
against legal connection rate. If you see SYN flood warnings
in your logs, but investigation shows that they occur
because of overload with legal connections, you should tune
another parameters until this warning disappear.
See: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.

syncookies seriously violate TCP protocol, do not allow
to use TCP extensions, can result in serious degradation
of some services (f.e. SMTP relaying), visible not by you,
but your clients and relays, contacting you. While you see
SYN flood warnings in logs not being really flooded, your server
is seriously misconfigured.

因此,如果您的 LAN 中没有 SYN-flood 攻击 - 您的服务器配置严重错误。 SYN-cookies 应该只在 SYN-flood 攻击存在时才能发挥作用。


解决方案

总之,可以通过一些活动来消除这个问题:

    如果您的网络中存在真正的 SYN-flood - 部分 SYN-cookie 解决这个信息安全问题。有了真正的攻击,有 没有时间考虑慢速连接。这是紧急情况。 如果不是,即某些 SYN 重传会引发 SYN cookie: thoughtfully increase backlog 消除此类情况; 不要在监听套接字上使用setsockopt()SO_RCVBUF。这没有多大意义。在不执行setsockopt() 的情况下,您可以在上述场景中降低内核进行不同 WS 计算的概率。顺便说一句,如果需要,您可以在接受的套接字上设置 SO_RCVBUF

复制

我在近似条件下使用hping3 用简单的客户端和服务器重现了您的问题。因此,您可以使用以下内容填充服务器的 backlog 队列:

hping3 -c 3 -S -p 12345 --fast 10.0.0.99

然后从客户端启动连接 - 至少在 4.4 内核上,连接将在所谓的 “SYN-cookies 上下文” 中打开。您也可以在 3.10 内核上检查它,将 -c3 增加到 X 直到成功复制。

【讨论】:

好的,但是 3.10 内核呢?这是我的生产代码,所以我必须注意可能出现的不良行为。 是的,我的 LAN 中没有 SYN-flood,但是有几次 syn 重传 @z0lupka 您可以通过hping3 实用程序模拟此类 SYN 重新传输并检查 3.10 内核的行为。 hping3 -d 120 -S -p 12345 10.0.0.99 --fast 之类的东西会立即从客户端发起连接。 非常感谢!积压增加有所帮助。

在linux操作系统中怎么评估tcp连接数

参考技术A1.首先,客户端和服务器建立的每个TCP连接都会占用服务器内存,所以最大TCP连接数和内存成正比。简单估算为最大内存除以单TCP连接占用的最小内存2.Linux操作系统中,一切都是文件。所以每个TCP连接,都会打开一个... 查看详情

在 Linux 上的 C++ 中获取活动的 TCP/UDP 连接

】在Linux上的C++中获取活动的TCP/UDP连接【英文标题】:GettingactiveTCP/UDPconnectionsinc++onlinux【发布时间】:2014-11-1013:47:26【问题描述】:我正在制作需要在c++中获得活动TCP/UDP连接的程序?.我知道我可以通过使用IPHelperAPI在Windows上做... 查看详情

linux系统支持的最大tcp连接是多少?

1.首先,客户端和服务器建立的每个TCP连接都会占用服务器内存,所以最大TCP连接数和内存成正比。简单估算为最大内存除以单TCP连接占用的最小内存2.Linux操作系统中,一切都是文件。所以每个TCP连接,都会打开一个文件。为此... 查看详情

linux下ssh连接缓慢详解

...tps://blog.csdn.net/asd2479745295/article/details/83006379linux下ssh连接缓慢详解原创皮的开心最后发布于2018-10-1109:13:37阅读数1824收藏展开  最近发现公司新linux控制器使用ssh连接特别慢,大概要10秒钟左右,scp也是需要10秒左右,但是pi... 查看详情

论tcp状态监控在异常侦测业务告警中有多重要

 很多同学在做监控告警、异常侦测时专注于软件本身的数据,而忽略了TCP连接状态的监控,其实TCP连接真实的反应了服务器和服务本身的队列情况,是最灵敏的服务阴晴表。   现在的服务之间都是通过网络进行通... 查看详情

每个 TCP/IP 网络连接的 Linux 内核消耗多少内存?

】每个TCP/IP网络连接的Linux内核消耗多少内存?【英文标题】:HowmuchmemoryisconsumedbytheLinuxkernelperTCP/IPnetworkconnection?【发布时间】:2012-01-2814:12:57【问题描述】:每个TCP/IP网络连接平均由Linux内核(在内核地址空间中)消耗多少内... 查看详情

linux中tcp通信中send函数如何判断何时断开连接了

...有回复心跳就应认为此链路已经坏掉了,需要关闭,重新连接!2至于发送数据,应该检查对应的api的返回值,是否已经成功发送或者接受定长数据!没有完成应该重新发送或者接受3网络数据问题,可以用抓包工具直接抓包看数... 查看详情

ideagit无法使用或者git工具栏操作异常缓慢

参考技术A一、idea内git无法识别,gitbash等报错 ANOMALY:useofREX.wismeaningless(defaultoperandsizeis64)1、问题原因:电脑安装了360天擎的监控软件(与系统建立了TCP连接)。在报错中:[0x7FFCA4D1E0A4]ANOMALY:useofREX.wismeaningless(defaultoperandsizeis64)... 查看详情

SocketPolicy 异常 int TCP Unity 与 C# 服务器之间的连接

】SocketPolicy异常intTCPUnity与C#服务器之间的连接【英文标题】:SocketPolicyexceptionintTCPConnectionbetweenunityandC#server【发布时间】:2017-05-1308:26:31【问题描述】:我正在开发简单的多人游戏,我正在自己的编码服务器上工作(在C#中)。... 查看详情

计算机网络复习总结3

1.23说一说TCP里的reset状态。TCP异常终止(reset报文)TCP的异常终止是相对于正常释放TCP连接的过程而言的,我们都知道,TCP连接的建立是通过三次握手完成的,而TCP正常释放连接是通过四次挥手来完成,但... 查看详情

如何使用 Amphp 捕获 php websocket 断开的 TCP 连接异常?

】如何使用Amphp捕获phpwebsocket断开的TCP连接异常?【英文标题】:HowtocatchaphpwebsocketbrokenTCPconnectionexceptionwithAmphp?【发布时间】:2019-11-2618:01:06【问题描述】:这是我在连接仍然存在时正在运行的当前WebSocket循环。但是连续连接11... 查看详情

linux系统如何通过netstat命令查看连接数判断攻击

...遇到服务器遭受cc或syn等攻击,如果发现自己的网站访问异常缓慢且流量异常。可以使用系统内置netstat命令简单判断一下服务器是否被攻击。常用的netstat命令该命令将显示所有活动的网络连接。查看同时连接到哪个服务器IP比较... 查看详情

linux中怎么检测tcp网络连接是不是正常

...式同“ifconfig-e”。-n以网络IP地址代替名称,显示出网络连接情形。-r显示核心路由表,格式同“route-e”。-t显示TCP协议的连接情况。-u显示UDP协议的连接情况。-v显示正在进行的工作。1.netstat-an|grepLISTEN0.0.0.0的就是每个IP都有的... 查看详情

如何在linux cent OS中查找每个进程允许的TCP连接总数和TIME_WAIT值[重复]

】如何在linuxcentOS中查找每个进程允许的TCP连接总数和TIME_WAIT值[重复]【英文标题】:HowtofindtotalnumberofallowedTCPconnectionperprocessandTIME_WAITvalueinlinuxcentOS[duplicate]【发布时间】:2017-10-0307:59:59【问题描述】:我在清漆端看到很多503,... 查看详情

tcp连接断连问题剖析

...TCP连接断连的原因,并在此基础上,以AIX系统上TCP连接的异常断连为例,借助相应的网络分析工具,逐步揭开AIX上TCP断连的原因,并给出两种可行的解决方案。引言在官方的正式文档中,TCP/IP协议簇也称为国际互联网协议簇。TCP... 查看详情

哪些常见的网络情况会造成tcp同步包与tcp同步确认包异常

参考技术A传输控制协议(TransmissionControlProtocol,TCP)TCP协议主为了在主机间实现高可靠性的包交换传输协议。本文将描述协议标准和实现的一些方法。因为计算机网络在现代社会中已经是不可缺少的了,TCP协议主要在网络不可靠... 查看详情

tcp异常连接(代码片段)

...队列和半队列查询全连接队列半连接队列        TCP异常连接分为connect,第一次握手,第三次握手源码逻辑介绍,给出优化方案以及查看全连接与半连接的方法。connect在连接失败后,大量的端口范围查找,... 查看详情

SQLServer异常;与主机 localhost、端口 1433 的 TCP/IP 连接失败

】SQLServer异常;与主机localhost、端口1433的TCP/IP连接失败【英文标题】:SQLServerException;TheTCP/IPconnectiontothehostlocalhost,port1433hasfailed【发布时间】:2016-08-0920:20:17【问题描述】:使用这个连接字符串jdbc:sqlserver://localhost\\\\SQLEXPRESS:1433... 查看详情