[erlang-questions] Socket connects to itself

Per Hedeland per@REDACTED
Tue Oct 13 00:12:05 CEST 2009


Rob Charlton <rob@REDACTED> wrote:
>
>I noticed in the logs one night that this process P which had tried for
>several hours to connect to a non-existent server on 127.0.0.1:2920 had
>actually succeeded! Even more exciting than that, it had connected to
>itself, so when it started trying to communicate with its peer it was
>very surprised to receive its own communications back again. Needless to
>say P crashed at this point. I was very curious to know how this could
>happen and to try and fix it! You could argue this isn't a bug because
>the system configuration was incorrectly specified. In this particular
>case though, the misconfiguration can happen easily and I would like P
>not to crash but instead to keep trying.
>
>I tried Googling for this and did find a couple of non-erlang sources
>suggesting it had happened to them in similar circumstances. It could be
>that this is a very timing sensitive 'feature' of TCP/IP. Can anyone
>enlighten me?

That's a nice one!:-) Whenever you call gen_tcp:connect(), the
underlying OS connect() system call will first bind the socket to a
local address and port, and then send the initial SYN packet using that
address/port as source. It is quite possible that at some point it may
happen to choose the unused port 2920 for that, and hence attempt a
connect from 127.0.0.1:2920 to 127.0.0.1:2920.

This is where the "feature" comes into play - you might think that this
connection should fail, since there is no process listening on port
2920, but the TCP spec explicitly prescribes that "simultaneous
initiation" should be handled - e.g. from section 2.7 of RFC 793:

                     Two processes which issue active OPENs to each
  other at the same time will be correctly connected.  This flexibility
  is critical for the support of distributed computing in which
  components act asynchronously with respect to each other.

You can also see it in the famous state diagram in Figure 6 of RFC 793,
as the "rcv SYN" transition from SYN_SENT to SYN_RCVD. Though of course
it's a pretty safe bet that no protocol in serious use actually requires
this "critical" functionality.

--Per Hedeland


More information about the erlang-questions mailing list