How can you have a TCP connection back to the same

2019-01-13 08:37发布

Machine is RHEL 5.3 (kernel 2.6.18).

Some times I notice in netstat that my application has connection, established TCP connection when Local Address and Foreign Address are same.

Here same problem reported by someone else too.

The symptoms are same as described in link - client connects to port X port of server running locally. After some time netstat shows that client has connection from 127.0.0.1:X to 127.0.0.1:X

How it's possible?

Edit 01

Simultaneous open is causing the problem (thanks a lot to Hasturkun). You can see it on classical TCP state diagram in transition from SYN_SENT state to SYNC_RECEIVED

2条回答
我命由我不由天
2楼-- · 2019-01-13 09:14

This may be caused by TCP simultaneous connect (mentioned on this post to LKML, see also here).

It's possible for a program looping on trying to connect to a port within the dynamic local port range (which can be seen in /proc/sys/net/ipv4/ip_local_port_range),to succeed while the server is not listening on that port.

On a large enough number of attempts, the socket being used to connect may be bound to the same port being connected to, which succeeds due to previously mentioned simultaneous connect. You now magically have a client connected to itself

查看更多
霸刀☆藐视天下
3楼-- · 2019-01-13 09:16

A TCP connection is uniquely identified by this tuple (local address, local port #, foreign address, foreign port #). There is no requirement that local address and foreign address, or even that the port numbers be different (though that would be exceedingly strange). But there is at most 1 TCP connection that has the same values for a given tuple.

When a computer connects to itself, it's local address and foreign address are almost always the same. After all, the 'local' side and 'foreign' side are actually the same computer. In fact, when this happens your computer should be showing two connections that have the same 'local' and 'foreign' addresses, but reversed port numbers. For example:

$ ssh localhost

will result in two connections that look something like this:

$ netstat -nA inet | fgrep :22
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address        Foreign Address        State      
tcp        0      0 127.0.0.1:56039      127.0.0.1:22           ESTABLISHED 
tcp        0      0 127.0.0.1:22         127.0.0.1:56039        ESTABLISHED 

As you can see, the local address and foreign addresses are the same, but the port numbers are reversed. The unique tuple for this TCP connection is (127.0.0.1, 56039, 127.0.0.1, 22). There will be no other TCP connection that has these same four fields.

The fact you see two is because your computer is both ends of the connection. Each end has its own view of which one is 'foreign' and which is 'local'.

You can even connect to yourself on the same port, and while this is not a common occurrence, it is not forbidden by the spec. Here is a sample program in Python which will do this:

import socket
import time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 56443))
s.connect(('127.0.0.1', 56443))
time.sleep(30)

This code works because one way in which it's possible to open a TCP connection is to have the other side of the connection try to open one with you simultaneously. This is known as simultaneous SYN exchange, and the linked to StackOverflow answer describes what that's about.

I also have a paper on using simultaneous SYN exchange to get through NAT, though in that case the source and foreign would be completely different.

查看更多
登录 后发表回答