From ac4dd411ccc33d1104334a7f3c984512fb225e29 Mon Sep 17 00:00:00 2001 From: arvidn Date: Thu, 16 Apr 2020 14:27:04 +0200 Subject: [PATCH] fix peer connection timeout --- ChangeLog | 1 + simulation/test_fast_extensions.cpp | 97 ++++++++++++++++++++++++++ simulation/test_optimistic_unchoke.cpp | 1 + src/peer_connection.cpp | 2 +- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 093002e1f..7bd9002f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * fix peer timeout logic * simplify proxy handling. A proxy now overrides listen_interfaces * fix issues when configured to use a non-default choking algorithm * fix issue in reading resume data diff --git a/simulation/test_fast_extensions.cpp b/simulation/test_fast_extensions.cpp index c2baccb40..56a43aad6 100644 --- a/simulation/test_fast_extensions.cpp +++ b/simulation/test_fast_extensions.cpp @@ -91,6 +91,103 @@ void run_fake_peer_test( sim.run(); } + +struct idle_peer +{ + idle_peer(simulation& sim, char const* ip) + : m_ios(sim, asio::ip::address::from_string(ip)) + { + boost::system::error_code ec; + m_acceptor.open(asio::ip::tcp::v4(), ec); + TEST_CHECK(!ec); + m_acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v4::any(), 6881), ec); + TEST_CHECK(!ec); + m_acceptor.listen(10, ec); + TEST_CHECK(!ec); + + m_acceptor.async_accept(m_socket, [&] (boost::system::error_code const& ec) + { m_accepted = true; }); + } + + void close() + { + m_acceptor.close(); + m_socket.close(); + } + + + bool accepted() const { return m_accepted; } + + asio::io_service m_ios; + asio::ip::tcp::acceptor m_acceptor{m_ios}; + asio::ip::tcp::socket m_socket{m_ios}; + + bool m_accepted = false; +}; + +TORRENT_TEST(peer_timeout) +{ + sim::default_config cfg; + sim::simulation sim{cfg}; + + sim::asio::io_service ios(sim, lt::address_v4::from_string("50.0.0.1")); + lt::session_proxy zombie; + + // setup settings pack to use for the session (customization point) + lt::settings_pack pack = settings(); + pack.set_str(lt::settings_pack::listen_interfaces, "0.0.0.0:6881"); + pack.set_bool(lt::settings_pack::enable_outgoing_utp, false); + pack.set_bool(lt::settings_pack::enable_incoming_utp, false); + pack.set_int(lt::settings_pack::alert_mask, lt::alert_category::error + | lt::alert_category::connect + | lt::alert_category::peer_log); + + // create session + std::shared_ptr ses = std::make_shared(pack, ios); + + // just a listen socket that accepts connections, but never responds + idle_peer peer(sim, "60.0.0.0"); + + int const num_pieces = 5; + lt::add_torrent_params params = create_torrent(0, false, num_pieces); + params.flags &= ~lt::torrent_flags::auto_managed; + params.flags &= ~lt::torrent_flags::paused; + ses->async_add_torrent(params); + + lt::time_point peer_timeout_timestamp{}; + + // the alert notification function is called from within libtorrent's + // context. It's not OK to talk to libtorrent in there, post it back out and + // then ask for alerts. + print_alerts(*ses, [&](lt::session& ses, lt::alert const* a) { + + if (auto at = lt::alert_cast(a)) + { + lt::torrent_handle h = at->handle; + h.connect_peer(ep("60.0.0.0", 6881)); + } + else if (auto pe = lt::alert_cast(a)) + { + if (peer_timeout_timestamp == lt::time_point{}) + peer_timeout_timestamp = pe->timestamp(); + } + + }); + + sim::timer t(sim, lt::seconds(300) + , [&](boost::system::error_code const&) + { + // shut down + zombie = ses->abort(); + ses.reset(); + }); + + sim.run(); + + TEST_CHECK(peer_timeout_timestamp != lt::time_point{}); + TEST_CHECK(peer_timeout_timestamp < lt::time_point(lt::seconds(122))); +} + #ifndef TORRENT_DISABLE_LOGGING // make sure we consistently send the same allow-fast pieces, regardless // of which pieces the peer has. diff --git a/simulation/test_optimistic_unchoke.cpp b/simulation/test_optimistic_unchoke.cpp index 9b37383be..c623d35c7 100644 --- a/simulation/test_optimistic_unchoke.cpp +++ b/simulation/test_optimistic_unchoke.cpp @@ -79,6 +79,7 @@ TORRENT_TEST(optimistic_unchoke) // only allow an optimistic unchoke slot pack.set_int(settings_pack::unchoke_slots_limit, 1); pack.set_int(settings_pack::num_optimistic_unchoke_slots, 1); + pack.set_int(settings_pack::peer_timeout, 9999); std::vector peer_choke_state(num_nodes); diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 6df960463..fdd30b000 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -4834,7 +4834,7 @@ namespace libtorrent { // if the peer hasn't said a thing for a certain // time, it is considered to have timed out - time_duration d = std::min(now - m_last_receive, now - m_last_sent); + time_duration d = now - m_last_receive; if (m_connecting) {