diff --git a/simulation/test_fast_extensions.cpp b/simulation/test_fast_extensions.cpp index 56a43aad6..b7ab3a3b5 100644 --- a/simulation/test_fast_extensions.cpp +++ b/simulation/test_fast_extensions.cpp @@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "setup_transfer.hpp" // for ep() #include "simulator/utils.hpp" #include "libtorrent/string_view.hpp" +#include "libtorrent/random.hpp" using namespace lt::literals; @@ -91,7 +92,6 @@ void run_fake_peer_test( sim.run(); } - struct idle_peer { idle_peer(simulation& sim, char const* ip) @@ -106,9 +106,33 @@ struct idle_peer TEST_CHECK(!ec); m_acceptor.async_accept(m_socket, [&] (boost::system::error_code const& ec) - { m_accepted = true; }); + { + m_accepted = true; + + if (!m_handshake) return; + + static char handshake_buffer[68]; + + asio::async_read(m_socket, asio::buffer(handshake_buffer, 68) + , [&](boost::system::error_code const& ec, std::size_t) + { + if (memcmp(handshake_buffer, "\x13" "BitTorrent protocol", 20) != 0) + { + std::printf(" invalid protocol specifier\n"); + m_socket.close(); + return; + } + + // change the peer ID and echo back the handshake + lt::aux::random_bytes({handshake_buffer + 48, 20}); + asio::async_write(m_socket, asio::buffer(handshake_buffer, 68) + , [](boost::system::error_code const& ec, size_t) { }); + }); + }); } + void enable_handshake() { m_handshake = true; } + void close() { m_acceptor.close(); @@ -123,13 +147,11 @@ struct idle_peer asio::ip::tcp::socket m_socket{m_ios}; bool m_accepted = false; + bool m_handshake = false; }; -TORRENT_TEST(peer_timeout) +lt::time_duration run_timeout_sim(sim::simulation& sim) { - 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; @@ -145,9 +167,6 @@ TORRENT_TEST(peer_timeout) // 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; @@ -155,6 +174,7 @@ TORRENT_TEST(peer_timeout) ses->async_add_torrent(params); lt::time_point peer_timeout_timestamp{}; + lt::time_point const start = lt::clock_type::now(); // 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 @@ -185,7 +205,41 @@ TORRENT_TEST(peer_timeout) sim.run(); TEST_CHECK(peer_timeout_timestamp != lt::time_point{}); - TEST_CHECK(peer_timeout_timestamp < lt::time_point(lt::seconds(122))); + return peer_timeout_timestamp - start; +} + +TORRENT_TEST(peer_idle_timeout) +{ + sim::default_config cfg; + sim::simulation sim{cfg}; + + // just a listen socket that accepts connections, and just respond with a + // bittorrent handshake, but nothing more + idle_peer peer(sim, "60.0.0.0"); + peer.enable_handshake(); + + auto peer_timeout_timestamp = run_timeout_sim(sim); + + // the peer timeout defaults to 120 seconds + // settings_pack::peer_timeout + TEST_CHECK(peer_timeout_timestamp < lt::seconds(122)); + TEST_CHECK(peer_timeout_timestamp > lt::seconds(120)); +} + +TORRENT_TEST(handshake_timeout) +{ + sim::default_config cfg; + sim::simulation sim{cfg}; + + // just a listen socket that accepts connections, but never responds + idle_peer peer(sim, "60.0.0.0"); + + auto peer_timeout_timestamp = run_timeout_sim(sim); + + // the handshake timeout defaults to 10 seconds + // settings_pack::handshake_timeout + TEST_CHECK(peer_timeout_timestamp < lt::seconds(15)); + TEST_CHECK(peer_timeout_timestamp > lt::seconds(9)); } #ifndef TORRENT_DISABLE_LOGGING diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index fbd37672a..927594a89 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -466,7 +466,9 @@ namespace { bool bt_peer_connection::in_handshake() const { - return !m_sent_handshake; + // this returns true until we have received a handshake + // and until we have send our handshake + return !m_sent_handshake || m_state < state_t::read_packet_size; } #if !defined TORRENT_DISABLE_ENCRYPTION diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index fdd30b000..07779ab7c 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -2895,8 +2895,7 @@ namespace libtorrent { // we received a request within the timeout, make sure this peer is // not snubbed anymore - if (total_seconds(now - m_requested) - < request_timeout() + if (total_seconds(now - m_requested) < request_timeout() && m_snubbed) { m_snubbed = false;