Skip to content

Commit dc0f901

Browse files
committed
fixup: close connection only if the send queue is empty
Fixes #84
1 parent daf7082 commit dc0f901

File tree

2 files changed

+11
-13
lines changed

2 files changed

+11
-13
lines changed

src/sv2/connman.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Sv2Connman::~Sv2Connman()
1919
for (const auto& client : m_sv2_clients) {
2020
LogTrace(BCLog::SV2, "Disconnecting client id=%zu\n",
2121
client.first);
22-
CloseConnection(client.second->m_id);
2322
client.second->m_disconnect_flag = true;
2423
}
2524
DisconnectFlagged();
@@ -64,7 +63,8 @@ void Sv2Connman::DisconnectFlagged()
6463
// Remove clients that are flagged for disconnection.
6564
auto it = m_sv2_clients.begin();
6665
while(it != m_sv2_clients.end()) {
67-
if (it->second->m_disconnect_flag) {
66+
if (it->second->m_send_messages.empty() && it->second->m_disconnect_flag) {
67+
CloseConnection(it->second->m_id);
6868
it = m_sv2_clients.erase(it);
6969
} else {
7070
it++;
@@ -203,7 +203,6 @@ void Sv2Connman::EventGotData(Id id, std::span<const uint8_t> data)
203203
// Serious transport problem
204204
LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Transport problem, disconnecting client id=%zu\n",
205205
client->m_id);
206-
CloseConnection(id);
207206
// TODO: should we even bother with this?
208207
client->m_disconnect_flag = true;
209208
break;
@@ -217,7 +216,6 @@ void Sv2Connman::EventGotData(Id id, std::span<const uint8_t> data)
217216
}
218217
} catch (const std::exception& e) {
219218
LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received error when processing client id=%zu message: %s\n", client->m_id, e.what());
220-
CloseConnection(id);
221219
client->m_disconnect_flag = true;
222220
}
223221

@@ -227,15 +225,13 @@ void Sv2Connman::EventGotEOF(NodeId node_id)
227225
{
228226
auto client{WITH_LOCK(m_clients_mutex, return GetClientById(node_id);)};
229227
if (client == nullptr) return;
230-
CloseConnection(node_id);
231228
client->m_disconnect_flag = true;
232229
}
233230

234231
void Sv2Connman::EventGotPermanentReadError(NodeId node_id, const std::string& errmsg)
235232
{
236233
auto client{WITH_LOCK(m_clients_mutex, return GetClientById(node_id);)};
237234
if (client == nullptr) return;
238-
CloseConnection(node_id);
239235
client->m_disconnect_flag = true;
240236
}
241237

@@ -250,6 +246,13 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
250246

251247
DataStream ss (sv2_net_msg.m_msg);
252248

249+
if (client.m_disconnect_flag) {
250+
// Don't bother processing new messages if we are about to disconnect when the
251+
// send queue empties. This also prevents us from appending to the send queue
252+
// when m_disconnect_flag is set.
253+
return;
254+
}
255+
253256
switch (sv2_net_msg.m_msg_type)
254257
{
255258
case Sv2MsgType::SETUP_CONNECTION:
@@ -266,7 +269,6 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
266269
} catch (const std::exception& e) {
267270
LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received invalid SetupConnection message from client id=%zu: %s\n",
268271
client.m_id, e.what());
269-
CloseConnection(client.m_id);
270272
client.m_disconnect_flag = true;
271273
return;
272274
}
@@ -279,7 +281,6 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
279281
client.m_id);
280282
client.m_send_messages.emplace_back(setup_conn_err);
281283

282-
CloseConnection(client.m_id);
283284
client.m_disconnect_flag = true;
284285
return;
285286
}
@@ -293,7 +294,6 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
293294

294295
LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received a connection from client id=%zu with incompatible protocol_versions: min_version: %d, max_version: %d\n",
295296
client.m_id, setup_conn.m_min_version, setup_conn.m_max_version);
296-
CloseConnection(client.m_id);
297297
client.m_disconnect_flag = true;
298298
return;
299299
}
@@ -310,7 +310,6 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
310310
case Sv2MsgType::COINBASE_OUTPUT_CONSTRAINTS:
311311
{
312312
if (!client.m_setup_connection_confirmed) {
313-
CloseConnection(client.m_id);
314313
client.m_disconnect_flag = true;
315314
return;
316315
}
@@ -322,7 +321,6 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
322321
} catch (const std::exception& e) {
323322
LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received invalid CoinbaseOutputConstraints message from client id=%zu: %s\n",
324323
client.m_id, e.what());
325-
CloseConnection(client.m_id);
326324
client.m_disconnect_flag = true;
327325
return;
328326
}
@@ -333,7 +331,6 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
333331
if (max_additional_size > MAX_BLOCK_WEIGHT) {
334332
LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received impossible CoinbaseOutputConstraints from client id=%zu: %d\n",
335333
client.m_id, max_additional_size);
336-
CloseConnection(client.m_id);
337334
client.m_disconnect_flag = true;
338335
return;
339336
}

src/sv2/connman.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ struct Sv2Client
3737
bool m_setup_connection_confirmed = false;
3838

3939
/**
40-
* Whether the client is a candidate for disconnection.
40+
* Whether the client is a candidate for disconnection. The client's socket will be
41+
* closed after all queued messages have been sent.
4142
*/
4243
bool m_disconnect_flag = false;
4344

0 commit comments

Comments
 (0)