From 4e0a4db9b4a7786367c8b3c03e054643f86db8da Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 12 Jun 2016 20:36:05 -0400 Subject: [PATCH] fixed inverted priority of incoming piece suggestions (#809) --- ChangeLog | 1 + src/peer_connection.cpp | 8 +++-- test/test_fast_extension.cpp | 62 +++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 14a6db264..5bed298dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 1.1.1 release + * fixed inverted priority of incoming piece suggestions * optimize allow-fast logic * fix issue where FAST extension messages were not used during handshake * fixed crash on invalid input in http_parser diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index ffb399a7c..e77bd43d1 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -1580,10 +1580,14 @@ namespace libtorrent return; } + // the piece picker will prioritize the pieces from the beginning to end. + // the later the suggestion is received, the higher priority we should + // ascribe to it, so we need to insert suggestions at the front of the + // queue. if (int(m_suggested_pieces.size()) > m_settings.get_int(settings_pack::max_suggest_pieces)) - m_suggested_pieces.erase(m_suggested_pieces.begin()); + m_suggested_pieces.resize(m_settings.get_int(settings_pack::max_suggest_pieces) - 1); - m_suggested_pieces.push_back(index); + m_suggested_pieces.insert(m_suggested_pieces.begin(), index); #ifndef TORRENT_DISABLE_LOGGING peer_log(peer_log_alert::info, "SUGGEST_PIECE", "piece: %d added to set: %d" diff --git a/test/test_fast_extension.cpp b/test/test_fast_extension.cpp index bd99207dd..61e8ceeb2 100644 --- a/test/test_fast_extension.cpp +++ b/test/test_fast_extension.cpp @@ -626,7 +626,7 @@ TORRENT_TEST(reject_suggest) using namespace libtorrent::detail; char* ptr = recv_buffer + 1; - int piece = read_int32(ptr); + int const piece = read_int32(ptr); std::vector::iterator i = std::find(suggested.begin() , suggested.end(), piece); @@ -660,6 +660,66 @@ TORRENT_TEST(reject_suggest) print_session_log(*ses); } +TORRENT_TEST(suggest_order) +{ + std::cerr << "\n === test suggest ===\n" << std::endl; + + sha1_hash ih; + boost::shared_ptr ses; + io_service ios; + tcp::socket s(ios); + setup_peer(s, ih, ses); + + char recv_buffer[1000]; + do_handshake(s, ih, recv_buffer); + print_session_log(*ses); + send_have_all(s); + print_session_log(*ses); + + std::vector suggested; + suggested.push_back(0); + suggested.push_back(1); + suggested.push_back(2); + suggested.push_back(3); + + std::for_each(suggested.begin(), suggested.end() + , boost::bind(&send_suggest_piece, boost::ref(s), _1)); + print_session_log(*ses); + + send_unchoke(s); + print_session_log(*ses); + + int fail_counter = 100; + while (!suggested.empty() && fail_counter > 0) + { + print_session_log(*ses); + int len = read_message(s, recv_buffer, sizeof(recv_buffer)); + if (len == -1) break; + print_message(recv_buffer, len); + int msg = recv_buffer[0]; + fail_counter--; + + // we're just interested in requests + if (msg != 0x6) continue; + + using namespace libtorrent::detail; + char* ptr = recv_buffer + 1; + int const piece = read_int32(ptr); + + // make sure we receive the requests inverse order of sending the suggest + // messages. The last suggest should be the highest priority + int const expected_piece = suggested.back(); + suggested.pop_back(); + TEST_EQUAL(piece, expected_piece); + } + print_session_log(*ses); + TEST_CHECK(fail_counter > 0); + + s.close(); + test_sleep(500); + print_session_log(*ses); +} + TORRENT_TEST(multiple_bitfields) { std::cerr << "\n === test multiple bitfields ===\n" << std::endl;