TCP同时打开和自连接预防

dim*_*mba 12 c++ networking tcp

TCP标准具有"同时打开"功能.

当端口来自短暂范围时,客户端尝试连接到本地端口时,该功能的含义可能偶尔会连接到自身(请参阅此处).

所以客户认为它连接到服务器,而它实际上连接到自身.从另一方面来说,服务器无法打开其服务器端口,因为它被客户端占用/窃取.

我正在使用RHEL 5.3,我的客户不断尝试连接到本地服务器.最终客户端连接到自身.

我想防止这种情况发生.我看到了两个可能解决问题的方法:

  1. 不要将临时端口用于服务器端口.同意临时端口范围并在您的机器上进行配置(参见临时范围)
  2. 检查connect(),就像有人在这里提出的那样.

你觉得怎么样?你是如何处理这个问题的?

PS 1

除了我明显寻求的解决方案之外,我希望您能分享您对问题的真实体验.

当我找到问题的原因时,我对我的工作场所感到"惊讶",人们并不熟悉它.通过定期连接轮询服务器是恕我直言的常见做法,所以问题是如何通常不为人所知.

小智 14

当我偶然发现这一点时,我惊呆了.我可以弄清楚传出端口号是否意外地与传入端口号匹配,但不是为什么TCP握手(SYN SYN-ACK ACK)会成功(问自己:如果没有人在进行监听,谁发送ACK)接受()???)

Linux和FreeBSD都显示了这种行为.

无论如何,一种解决方案是远离服务器的高端口号.

我注意到Darwin通过不允许传出端口与目标端口相同来解决此问题.他们一定也被这个咬了......

显示此效果的简单方法如下:

while true
do
    telnet 127.0.0.1 50000 
done
Run Code Online (Sandbox Code Playgroud)

等一会儿左右,你会和自己聊天......

Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hello?
hello?
Run Code Online (Sandbox Code Playgroud)

无论如何,这是一个很好的面试材料.


bla*_*aze 2

对于服务器,您需要将套接字绑定到端口。一旦 addr:port 对绑定了套接字,它将不再用于 connect() 中的隐式绑定。

没问题,没麻烦。

  • 因此,只需在 connect() 之前执行 bind() 并检查分配的临时端口是否等于预期的服务器端口。如果没有,请执行 connect()。 (2认同)