aboutsummaryrefslogtreecommitdiff
path: root/src/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/net_node.inl94
1 files changed, 49 insertions, 45 deletions
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 943061814..9bfe83eed 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -318,7 +318,7 @@ namespace nodetool
}
for (const auto &c: conns)
- zone.second.m_net_server.get_config_object().close(c);
+ zone.second.m_net_server.get_config_object().close(c, false);
conns.clear();
}
@@ -374,7 +374,7 @@ namespace nodetool
return true;
});
for (const auto &c: conns)
- zone.second.m_net_server.get_config_object().close(c);
+ zone.second.m_net_server.get_config_object().close(c, false);
for (int i = 0; i < 2; ++i)
zone.second.m_peerlist.filter(i == 0, [&subnet](const peerlist_entry &pe){
@@ -796,8 +796,14 @@ namespace nodetool
// TODO: at some point add IPv6 support, but that won't be relevant
// for some time yet.
- std::vector<std::vector<std::string>> dns_results;
- dns_results.resize(m_seed_nodes_list.size());
+ struct frame_t
+ {
+ std::vector<std::vector<std::string>> dns_results;
+ boost::mutex sync;
+ };
+
+ const auto frame = std::make_shared<frame_t>();
+ frame->dns_results.resize(m_seed_nodes_list.size());
// some libc implementation provide only a very small stack
// for threads, e.g. musl only gives +- 80kb, which is not
@@ -808,32 +814,22 @@ namespace nodetool
std::list<boost::thread> dns_threads;
uint64_t result_index = 0;
+ const std::weak_ptr<frame_t> frame_weak{frame};
for (const std::string& addr_str : m_seed_nodes_list)
{
- boost::thread th = boost::thread(thread_attributes, [=, &dns_results, &addr_str]
+ boost::thread th = boost::thread(thread_attributes, [frame_weak, addr_str, result_index]
{
MDEBUG("dns_threads[" << result_index << "] created for: " << addr_str);
// TODO: care about dnssec avail/valid
bool avail, valid;
- std::vector<std::string> addr_list;
-
- try
- {
- addr_list = tools::DNSResolver::instance().get_ipv4(addr_str, avail, valid);
- MDEBUG("dns_threads[" << result_index << "] DNS resolve done");
- boost::this_thread::interruption_point();
- }
- catch(const boost::thread_interrupted&)
+ std::vector<std::string> addr_list = tools::DNSResolver::instance().get_ipv4(addr_str, avail, valid);
+ MINFO("dns_threads[" << result_index << "] addr_str: " << addr_str << " number of results: " << addr_list.size());
+ const auto frame = frame_weak.lock();
+ if (frame)
{
- // thread interruption request
- // even if we now have results, finish thread without setting
- // result variables, which are now out of scope in main thread
- MWARNING("dns_threads[" << result_index << "] interrupted");
- return;
+ const boost::lock_guard<boost::mutex> lock{frame->sync};
+ frame->dns_results.at(result_index) = std::move(addr_list);
}
-
- MINFO("dns_threads[" << result_index << "] addr_str: " << addr_str << " number of results: " << addr_list.size());
- dns_results[result_index] = addr_list;
});
dns_threads.push_back(std::move(th));
@@ -847,14 +843,15 @@ namespace nodetool
{
if (! th.try_join_until(deadline))
{
- MWARNING("dns_threads[" << i << "] timed out, sending interrupt");
- th.interrupt();
+ MWARNING("dns_threads[" << i << "] timed out");
+ th.detach();
}
++i;
}
i = 0;
- for (const auto& result : dns_results)
+ const boost::lock_guard<boost::mutex> lock{frame->sync};
+ for (const auto& result : frame->dns_results)
{
MDEBUG("DNS lookup for " << m_seed_nodes_list[i] << ": " << result.size() << " results");
// if no results for node, thread's lookup likely timed out
@@ -1154,19 +1151,26 @@ namespace nodetool
{
MDEBUG("[node] sending stop signal");
for (auto& zone : m_network_zones)
- zone.second.m_net_server.send_stop_signal();
- MDEBUG("[node] Stop signal sent");
-
- for (auto& zone : m_network_zones)
{
- std::list<boost::uuids::uuid> connection_ids;
- zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) {
- connection_ids.push_back(cntxt.m_connection_id);
- return true;
- });
- for (const auto &connection_id: connection_ids)
- zone.second.m_net_server.get_config_object().close(connection_id);
+ const auto close_all_connections = [&, this]()
+ {
+ std::list<boost::uuids::uuid> connection_ids;
+ zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) {
+ connection_ids.push_back(cntxt.m_connection_id);
+ return true;
+ });
+ for (const auto &connection_id: connection_ids)
+ {
+ MDEBUG("Closing connection " << connection_id);
+ // We need to wait for every connection's shutdown sequence to complete before stopping the io_context.
+ zone.second.m_net_server.get_config_object().close(connection_id, true/*wait_for_shutdown*/);
+ MDEBUG("Closed connection " << connection_id);
+ }
+ };
+
+ zone.second.m_net_server.send_stop_signal(close_all_connections);
}
+ MDEBUG("[node] Stop signal sent");
m_payload_handler.stop();
return true;
}
@@ -1253,7 +1257,7 @@ namespace nodetool
{
LOG_WARNING_CC(context_, "COMMAND_HANDSHAKE Failed");
if (!timeout)
- zone.m_net_server.get_config_object().close(context_.m_connection_id);
+ zone.m_net_server.get_config_object().close(context_.m_connection_id, false);
}
else if (!just_take_peerlist)
{
@@ -1287,14 +1291,14 @@ namespace nodetool
if(!handle_remote_peerlist(rsp.local_peerlist_new, context))
{
LOG_WARNING_CC(context, "COMMAND_TIMED_SYNC: failed to handle_remote_peerlist(...), closing connection.");
- m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id );
+ m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id, false);
add_host_fail(context.m_remote_address);
}
if(!context.m_is_income)
m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address, context.m_pruning_seed, context.m_rpc_port, context.m_rpc_credits_per_hash);
if (!m_payload_handler.process_payload_sync_data(rsp.payload_data, context, false))
{
- m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id );
+ m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id, false);
}
});
@@ -1451,7 +1455,7 @@ namespace nodetool
if(just_take_peerlist)
{
- zone.m_net_server.get_config_object().close(con->m_connection_id);
+ zone.m_net_server.get_config_object().close(con->m_connection_id, false);
LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED.");
return true;
}
@@ -1513,7 +1517,7 @@ namespace nodetool
return false;
}
- zone.m_net_server.get_config_object().close(con->m_connection_id);
+ zone.m_net_server.get_config_object().close(con->m_connection_id, false);
LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED.");
@@ -2444,7 +2448,7 @@ namespace nodetool
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::drop_connection(const epee::net_utils::connection_context_base& context)
{
- m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id);
+ m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id, false);
return true;
}
//-----------------------------------------------------------------------------------
@@ -2527,17 +2531,17 @@ namespace nodetool
if(rsp.status != PING_OK_RESPONSE_STATUS_TEXT || pr != rsp.peer_id)
{
LOG_WARNING_CC(ping_context, "back ping invoke wrong response \"" << rsp.status << "\" from" << address.str() << ", hsh_peer_id=" << pr_ << ", rsp.peer_id=" << peerid_to_string(rsp.peer_id));
- zone.m_net_server.get_config_object().close(ping_context.m_connection_id);
+ zone.m_net_server.get_config_object().close(ping_context.m_connection_id, false);
return;
}
- zone.m_net_server.get_config_object().close(ping_context.m_connection_id);
+ zone.m_net_server.get_config_object().close(ping_context.m_connection_id, false);
cb();
});
if(!inv_call_res)
{
LOG_WARNING_CC(ping_context, "back ping invoke failed to " << address.str());
- zone.m_net_server.get_config_object().close(ping_context.m_connection_id);
+ zone.m_net_server.get_config_object().close(ping_context.m_connection_id, false);
return false;
}
return true;