TCP standard has "simultaneous open" feature.
The implication of the feature, client trying to connect to local port, when the port is from ephemeral range, can occasionally connect to itself (see here).
So client think it's connected to server, while it actually connected to itself. From other side, server can not open its server port, since it's occupied/stolen by client.
I'm using RHEL 5.3 and my clients constantly tries to connect to local server. Eventually client connects to itself.
I want to prevent the situation. I see two possible solutions to the problem:
What do you thinks? How do you handle the issue?
P.S. 1
Except of the solution, which I obviously looking for, I'd like you to share your real life experience with the problem.
When I found the cause of the problem, I was "astonished" on my work place people are not familiar with it. Polling server by connecting it periodically is IMHO common practice, so how it's that the problem is not commonly known.
The session can be closed by a double FIN, by a mix of FIN + RST, or only by RST packets.
On the TCP level the tuple (source ip, source port, destination ip, destination port) must be unique for each simultaneous connection. That means a single client cannot open more than 65535 simultaneous connections to a single server. But a server can (theoretically) serve 65535 simultaneous connections per client.
The TCP multiplexing engine monitors each incoming and outgoing packet to manage sessions and determine when a connection can be used for another client. The server no longer has to expend its processing power setting up and tearing down sessions for each user request.
What is the maximum number of concurrent TCP connections that a server can handle, in theory ? A single listening port can accept more than one connection simultaneously. There is a '64K' limit that is often cited, but that is per client per server port, and needs clarifying.
When I stumbled into this I was flabbergasted. I could figure out that the outgoing port number accidentally matches the incoming port number, but not why the TCP handshake (SYN SYN-ACK ACK) would succeed (ask yourself: who is sending the ACK if there is nobody doing a listen() and accept()???)
Both Linux and FreeBSD show this behavior.
Anyway, one solution is to stay out of the high range of port numbers for servers.
I noticed that Darwin side-steps this issue by not allowing the outgoing port to be the same as the destination port. They must have been bitten by this as well...
An easy way to show this effect is as follows:
while true
do
telnet 127.0.0.1 50000
done
And wait for a minute or so and you will be chatting with yourself...
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?
Anyway, it makes good job interview material.
Bind the client socket to port 0 (system assigns), check the system assigned port, if it matches the local server port you already know the server is down and and can skip connect().
For server you need to bind() socket to port. Once addr:port pair had socket bound, it will no longer be used for implicit binding in connect().
No problem, no trouble.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With