What is TCP Self-Connect Issue?

adil
3 min readJul 17, 2022

TCP self-connect issue occurs when `src_ip:src_port == dst_ip:dst_port`

You can try to access a local port to reproduce the self-connect issue.
The application will likely connect to itself.

Photo by Thomas Jensen on Unsplash

This is my local port range:

root@main:~# sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 60999

I randomly picked an even port number (why even number? explained below) between 32768 and 60999 and tried to connect to it:

while true; do nc -v 127.0.0.1 44600; done

I connected to port 44600 after seeing numerous “Connection refused” messages:

Let’s check the network status:

There is only one “ESTABLISHED” connection. No connection in the “LISTEN” state. Because Port 44600 is not listening.

When a program tries to establish a TCP connection, a source port must be created in the local IP port range. Therefore, when you try to access a port in the local port range, you will eventually hit the source port of the program.

This problem is called the “self-connect problem”. The program connects by itself.

The 3-way handshake is successfully done:

Here is an example program to reproduce the self-connect issue:

This is how I run the code. I pick a random port in my local port range:

Result:

The Source port keeps increasing until the source and destination ports are the same.

Why do I always pick an even number?

When I run it with an odd number, the program goes into an infinite loop:

root@main:~# ./tcp_self_connect 37391

It goes to an infinite loop because Linux assigns even source port numbers to connect() and the odd source port numbers to the bind() function (relevant change).

The implementation method has changed over time though (1 and 2). But the rule is still the same.

That’s why the program never ends when it runs with an odd number.

How to avoid this problem?

a) use an odd number
b) don’t run your server in the local port range.
c) you can reserve en ephemeral port so that it cannot be used as a source port:

sysctl -w net.ipv4.ip_local_reserved_ports=44600

Make sure it is set:

cat /proc/sys/net/ipv4/ip_local_reserved_ports

--

--