From 95575cda6eb107d06a713a7f3b3b1234b0d8409b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 Dec 2020 14:14:09 +0000 Subject: [PATCH] epee: fix some issues using connections after shutdown --- .../epee/include/net/abstract_tcp_server2.inl | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index cbacd118c..44a7899f9 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -334,6 +334,9 @@ PRAGMA_WARNING_DISABLE_VS(4355) TRY_ENTRY(); //_info("[sock " << socket().native_handle() << "] Async read calledback."); + if (m_was_shutdown) + return; + if (!e) { double current_speed_down; @@ -360,6 +363,9 @@ PRAGMA_WARNING_DISABLE_VS(4355) CRITICAL_REGION_LOCAL( epee::net_utils::network_throttle_manager::m_lock_get_global_throttle_in ); delay = epee::net_utils::network_throttle_manager::get_global_throttle_in().get_sleep_time_after_tick( bytes_transferred ); } + + if (m_was_shutdown) + return; delay *= 0.5; long int ms = (long int)(delay * 100); @@ -431,6 +437,9 @@ PRAGMA_WARNING_DISABLE_VS(4355) std::size_t bytes_transferred) { TRY_ENTRY(); + + if (m_was_shutdown) return; + if (e) { // offload the error case @@ -438,12 +447,15 @@ PRAGMA_WARNING_DISABLE_VS(4355) return; } - reset_timer(get_timeout_from_bytes_read(bytes_transferred), false); - - buffer_ssl_init_fill += bytes_transferred; - if (buffer_ssl_init_fill <= get_ssl_magic_size()) + buffer_ssl_init_fill = bytes_transferred; + MTRACE("we now have " << buffer_ssl_init_fill << "/" << get_ssl_magic_size() << " bytes needed to detect SSL"); + if (buffer_ssl_init_fill < get_ssl_magic_size()) { - socket().async_receive(boost::asio::buffer(buffer_.data() + buffer_ssl_init_fill, buffer_.size() - buffer_ssl_init_fill), + // don't busy loop on this, ideally we'd want to queue a "async_receive_if_new_data" but there doesn't + // seem to be something like that in boost if we want to just peek at the data, so we'd need to copy and + // have a bit more code just for this. Though I'm just seeing async_read_until which might just work. + epee::misc_utils::sleep_no_w(100); + socket().async_receive(boost::asio::buffer(buffer_.data(), buffer_.size()), boost::asio::socket_base::message_peek, strand_.wrap( boost::bind(&connection::handle_receive, connection::shared_from_this(), @@ -651,6 +663,8 @@ PRAGMA_WARNING_DISABLE_VS(4355) boost::this_thread::sleep(boost::posix_time::milliseconds( ms ) ); m_send_que_lock.lock(); _dbg1("sleep for queue: " << ms); + if (m_was_shutdown) + return false; if (retry > retry_limit) { MWARNING("send que size is more than ABSTRACT_SERVER_SEND_QUE_MAX_COUNT(" << ABSTRACT_SERVER_SEND_QUE_MAX_COUNT << "), shutting down connection"); @@ -748,7 +762,8 @@ PRAGMA_WARNING_DISABLE_VS(4355) template void connection::reset_timer(boost::posix_time::milliseconds ms, bool add) { - if (ms.total_milliseconds() < 0) + const auto tms = ms.total_milliseconds(); + if (tms < 0 || (add && tms == 0)) { MWARNING("Ignoring negative timeout " << ms); return;