SYN很频繁地收到RST,ACK

Hi Socket编程专家,

我在Windows上运行SQL Server 2005/2008的Linux上编写代理服务器。 该代理使用bsd套接字编码,并在C中,它工作正常与下面描述的问题。

当我使用数据库客户机(用JAVA编写,并在Linux机器上运行)直接向数据库服务器发出查询(并发数为100或更多)时,不会遇到连接重置。 但通过我的代理,我正在经历许多连接重置。

深入挖掘我知道从“DB客户端”到“代理服务器”的连接总是成功的,但是当“代理服务器”试图连接到数据库服务器时,连接失败,因为SYN数据包获得了RST,ACK。

这是给一些背景。 问题是:为什么有时SYN会收到RST,ACK?

DB client(linux) to Server(windows) ----> Works fine DB client(linux) to Proxy(Linux) to Server(windows) -----> problematic 

我知道这可能发生在“连接被拒绝”的情况下,但这绝对不是那个。 SYN洪泛可能是另一种情况,但这并不能解释直接向服务器发起攻击时的良好行为。

我怀疑一些套接字选项设置可能是必需的,客户端连接之前,我的代理不。 请把这个点亮一下。 任何帮助(链接或指针)最受赞赏。

附加信息:

写一个并发连接的C客户端,它将并发作为参数。 这里是我的观察: – > 5000并发和以上,一些连接失败,连接被拒绝。 – > 2000年以下,它工作正常。

但是,即使在100个或更多的并发情况下,也会观察到实际的问题。 注意:问题是依赖于时间的,有时它永远不会出现,有时非常频繁,DB客户端(直接到服务器)在任何时候都可以正常工作。

SQL server需要工作线程来接受传入的连接。 如果你的服务器是工人饿死的(这可以通过sys.dm_os_tasks中的PENDING状态中的大量条目来诊断),那么尝试打开新的连接将会失败。 所以我怀疑发生这种情况的可能性是,您正在向服务器推送更多可处理的工作负载。 您需要优化工作量或者获得更强大的服务器。

像Java客户端这样的客户端可以有效地使用连接池 ,即使在高负载的情况下,也不需要打开新的连接,因此您不会看到这个问题,而只会看到请求完成的延迟。

监听套接字在建立过程中保持已建立的连接和连接的队列(例如,SYN获得,SYNACK答复,但是还没有来自客户端的ACK)。 如果已建立的队列溢出,则OS栈上的IP堆栈响应会有所不同。 最传统的方法是忽略新来的SYN,等待用户接受()并释放队列中的一个插槽。 在90年代中期发生SYN洪泛攻击的情况下,发明了一种名为“SYN cookies”的新方法,完全降低了建立队列的需求,需要支持特殊的TCP选项。 OTOH我听说Windows堆栈改变了他们的行为 – 在某些情况下,对队列溢出的反应是RST响应。 在较早的堆栈(例如Win95)中,这是主要的响应,客户端相应地被改变为忽略对SYN的RST响应:(这就是为什么我猜测某些代理主机功能会触发Windows堆栈中的RST。

另一种猜测是,数据库服务器在某些情况下(例如检测到的过载峰值)完全关闭了监听套接字,而这个状态只出现在代理服务器上。

当SYN收到RST响应时,不应该是SQL-SERVER的问题。

因为应用程序只能在tcp握手完成后才能accept套接字。

代理和SQL-server机器之间是否有任何设备?

尽量确保RST响应来自sql-server机器。

你认为连接数量远不是SYN-FLOOD。