我们有一个互联网服务器在TCP端口上侦听,用户必须连接并保持连接。一旦60秒过去,服务器自动关闭连接而没有收到任何数据包,并且客户每隔30秒就会发送一个小的保持活动数据包。这个数据包是一个非常小的普通TCP流数据,总共大约10个字节。
我们特意让一些用户在连接后系统地快速断开连接。服务器端原因是我们实施的60年代“超时”。我使用tcpdump过滤来自特定受影响用户的通信,我发现的内容相当奇怪。
连接正常打开,流量按预期发生。并且预计客户会在更有意义的流量结束后不久进入“保持活跃”模式。
在01:21:58,客户端打开了与服务器的连接,并进行了正常的握手和登录过程。
在01:22:03,客户端发送了服务器收到的最后一个数据包。 30秒后,在01:22:33,客户端发送一个保持活动包,服务器用RST包回复它!
现在,这很奇怪,但仔细检查表明故障不在服务器上。客户端发送的下一个TCP数据包形成得非常好,这显然是流的一部分。但数据包来自客户端的不同端口!服务器tcp堆栈看到该意外数据包并自动使用RST数据包进行回复。
现在,作为一个猜测我会说问题是用户的互联网路由器做了非常奇怪的事情,它的连接跟踪和错误的原始的一个。问题是,有没有人见过类似的东西,有什么我可以做的,以防止它发生?如果需要,不能重写整个协议以处理重新连接到服务器。我们尝试大大增加保持活动频率,以防路由器以某种方式延迟连接跟踪,但即使每隔5秒保持活动似乎也会发生。
用户路由器是TRENDNET TEW-432BRP。没有要求他将自己的固件刷新到最近的版本(2年左右出来),我不知道该怎么做。
这是相应连接的过滤tcpdump跟踪。这里有点难以理解,所以我把它放在这里:http://pastebin.com/eUnjUJTk
问题发生在最后三行。来自客户端的数据包正好是有效负载中预期的保持活动数据包,并且序列信息完全匹配,只有数据包源端口发生了变化。接下来,服务器拒绝此数据包,最后一个是服务器通过客户端超时主动关闭连接。