Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TCP simultaneous open and self connect prevention

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:

  1. Don't use ephemeral ports for server ports. Agree ephemeral port range and configure it on your machines (see ephemeral range)
  2. Check connect() as somebody propose here.

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.

like image 735
dimba Avatar asked Feb 28 '11 08:02

dimba


People also ask

What two ways can a TCP session be closed?

The session can be closed by a double FIN, by a mix of FIN + RST, or only by RST packets.

How many simultaneous TCP connections are there?

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.

How does TCP manage multiple sessions?

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.

Can you have multiple TCP connections on same port?

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.


3 Answers

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.

like image 120
Marcel van Kervinck Avatar answered Oct 16 '22 22:10

Marcel van Kervinck


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().

like image 36
Erik Avatar answered Oct 16 '22 22:10

Erik


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.

like image 30
blaze Avatar answered Oct 16 '22 23:10

blaze