From 793290f940a9af18d4f0292a263d976a066dff65 Mon Sep 17 00:00:00 2001 From: lmanners Date: Thu, 10 May 2018 18:23:22 +0200 Subject: [PATCH] Net: Fixed a race condition when disabling the network. This change addresses a race condition where setnetworkactive=false wouldn't always disconnect all peers. Before this change, the following could happen: 1. Thread A -- Begins connecting to a node. 2. Thread B -- Sets kNetworkActive=false and disconnects connected nodes. 3. Thread A -- Finishes connecting and adds node to list of connected nodes. The node that was connected from Thread A remains connected and active, even though kNetworkActive=false. To fix the race, disconnections when kNetworkActive=false are now handled in the main network loop. fixes #13038 --- src/net.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 55043ffe30c..b384cb70f68 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1163,6 +1163,17 @@ void CConnman::ThreadSocketHandler() // { LOCK(cs_vNodes); + + if (!fNetworkActive) { + // Disconnect any connected nodes + for (CNode* pnode : vNodes) { + if (!pnode->fDisconnect) { + LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId()); + pnode->fDisconnect = true; + } + } + } + // Disconnect unused nodes std::vector vNodesCopy = vNodes; for (CNode* pnode : vNodesCopy) @@ -2198,14 +2209,6 @@ void CConnman::SetNetworkActive(bool active) fNetworkActive = active; - if (!fNetworkActive) { - LOCK(cs_vNodes); - // Close sockets to all nodes - for (CNode* pnode : vNodes) { - pnode->CloseSocketDisconnect(); - } - } - uiInterface.NotifyNetworkActiveChanged(fNetworkActive); }