Connection crossing can block programs indefinitely
The comments in the code explain how crossing connections are resolved.
This solution, unfortunately, does not account for the possibility of connection failures.
It can be that A has a severed connection to B, but A still thinks the connection is healthy. Now, B is aware that the connection has failed, and it tries to reconnect. The result is that A will respond with ConnectionRequestCrossed, and B will wait forever an incoming connection from A.
This seems reasonable to me.
Here is a solution with probing and tagging connections. Probing a connection with a dummy message is necessary to detect if it is still healthy.
When a request for an incoming TCP connection arrives:
If the node has a connection in init state to the remote peer and it has the highest address
then it sends ack
probes the old connection (needed only if connection is in valid state)
responds with a crossed message
tags the old connection (which is in either valid or init state)
If a probe is responded, then the tag is removed from the connection. If instead a tagged connection fails, then another attempt to establish a TCP connection is initiated.
On behalf of Alexander Vershilov:
After discussion with Facundo we ended with the following idea:
> if connection is in `Valid` state (i.e. it's got accepted by another side) then we use new connection
> if connection is in `Init` state (i.e. was not accepted by another side) then we are waiting until our connection resolves
> either with accept or network failure.