net: fix race condition in self-connect detection

Initiating an outbound network connection currently involves the
following steps after the socket connection is established (see
 `CConnman::OpenNetworkConnection` method):
    1. set up node state
    2. queue VERSION message
    3. add new node to vector `m_nodes`

If we connect to ourself, it can happen that the sent VERSION message
(step 2) is received and processed locally *before* the node object
is added to the connection manager's `m_nodes` vector (step 3). In this
case, the self-connect remains undiscovered, as the detection doesn't
find the outbound peer in `m_nodes` yet (see `CConnman::CheckIncomingNonce`).

Fix this by swapping the order of 2. and 3., by taking the `PushNodeVersion`
call out of `InitializeNode` and doing that in the `SendMessages` method
instead, which is only called for `CNode` instances in `m_nodes`.

Thanks go to vasild, mzumsande, dergoegge and sipa for suggestions on
how to fix this.
This commit is contained in:
Sebastian Falbesoner
2024-07-04 20:12:13 +02:00
parent 1c11089c7f
commit 66673f1c13
3 changed files with 16 additions and 5 deletions

View File

@@ -991,7 +991,7 @@ public:
/** Mutex for anything that is only accessed via the msg processing thread */
static Mutex g_msgproc_mutex;
/** Initialize a peer (setup state, queue any initial messages) */
/** Initialize a peer (setup state) */
virtual void InitializeNode(CNode& node, ServiceFlags our_services) = 0;
/** Handle removal of a peer (clear state) */