From 252e08a88922c0ffe6f6fdd752cf16917d3f3824 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 4 Sep 2014 08:55:24 +0000 Subject: [PATCH] merged fixes from RC_1_0 --- ChangeLog | 1 + src/bt_peer_connection.cpp | 2 +- test/test.hpp | 10 ++-- test/test_fast_extension.cpp | 101 ++++++++++++++++++++++++++++++++++- test/test_piece_picker.cpp | 27 ++++++++++ 5 files changed, 134 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd88f8922..5015f027c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -103,6 +103,7 @@ * fix uTP edge case where udp socket buffer fills up * fix nagle implementation in uTP + * fix bug in lt_donthave extension * expose i2p_alert to python. cleaning up of i2p connection code * fixed overflow and download performance issue when downloading at high rates * fixed bug in add_torrent_alert::message for magnet links diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index d6e7c90ea..b963ca10a 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -1751,7 +1751,7 @@ namespace libtorrent #endif return; } - int piece = detail::read_uint32(recv_buffer.begin) != 0; + int piece = detail::read_uint32(recv_buffer.begin); incoming_dont_have(piece); return; } diff --git a/test/test.hpp b/test/test.hpp index 817ca97c9..509c80003 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -74,9 +74,9 @@ int EXPORT print_failures(); if (!(x)) \ TEST_REPORT_AUX("TEST_CHECK failed: \"" #x "\"", __FILE__, __LINE__); #define TEST_EQUAL(x, y) \ - if (x != y) { \ + if ((x) != (y)) { \ std::stringstream s__; \ - s__ << "TEST_EQUAL_ERROR:\n" #x ": " << x << "\nexpected: " << y; \ + s__ << "TEST_EQUAL_ERROR:\n" #x ": " << (x) << "\nexpected: " << (y); \ TEST_REPORT_AUX(s__.str().c_str(), __FILE__, __LINE__); \ } #else @@ -97,9 +97,9 @@ int EXPORT print_failures(); #define TEST_EQUAL(x, y) \ try { \ - if (x != y) { \ + if ((x) != (y)) { \ std::stringstream s__; \ - s__ << "TEST_EQUAL_ERROR: " #x ": " << x << " expected: " << y; \ + s__ << "TEST_EQUAL_ERROR: " #x ": " << (x) << " expected: " << (y); \ TEST_REPORT_AUX(s__.str().c_str(), __FILE__, __LINE__); \ } \ } \ @@ -114,7 +114,7 @@ int EXPORT print_failures(); #endif #define TEST_ERROR(x) \ - TEST_REPORT_AUX((std::string("ERROR: \"") + x + "\"").c_str(), __FILE__, __LINE__) + TEST_REPORT_AUX((std::string("ERROR: \"") + (x) + "\"").c_str(), __FILE__, __LINE__) #define TEST_NOTHROW(x) \ try \ diff --git a/test/test_fast_extension.cpp b/test/test_fast_extension.cpp index 657dfc276..97d5eeb17 100644 --- a/test/test_fast_extension.cpp +++ b/test/test_fast_extension.cpp @@ -36,6 +36,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/io.hpp" #include "libtorrent/alloca.hpp" #include "libtorrent/time.hpp" +#include "libtorrent/peer_info.hpp" +#include "libtorrent/lazy_entry.hpp" #include #include #include @@ -87,6 +89,8 @@ void print_message(char const* buffer, int len) int msg = buffer[0]; if (msg >= 0 && msg < int(sizeof(message_name)/sizeof(message_name[0]))) strcpy(message, message_name[msg]); + else if (msg == 20) + snprintf(message, sizeof(message), "extension msg [%d]", buffer[1]); else snprintf(message, sizeof(message), "unknown[%d]", msg); @@ -193,7 +197,7 @@ void send_bitfield(stream_socket& s, char const* bits) void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer) { - char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04" + char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\x10\0\x04" " " // space for info-hash "aaaaaaaaaaaaaaaaaaaa"; // peer-id std::cout << time_now_string() << " ==> handshake" << std::endl; @@ -418,12 +422,107 @@ void test_multiple_have_all() test_sleep(500); } +// makes sure that pieces that are lost are not requested +void test_dont_have() +{ + using namespace libtorrent::detail; + + std::cerr << " === test dont_have ===" << std::endl; + + boost::shared_ptr t = ::create_torrent(); + sha1_hash ih = t->info_hash(); + lt::session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48950, 49050), "0.0.0.0", 0); + error_code ec; + add_torrent_params p; + p.flags &= ~add_torrent_params::flag_paused; + p.flags &= ~add_torrent_params::flag_auto_managed; + p.ti = t; + p.save_path = "./tmp1_dont_have"; + + remove("./tmp1_dont_have/temporary", ec); + if (ec) fprintf(stderr, "remove(): %s\n", ec.message().c_str()); + ec.clear(); + torrent_handle th = ses1.add_torrent(p, ec); + + test_sleep(300); + + io_service ios; + stream_socket s(ios); + s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec); + + char recv_buffer[1000]; + do_handshake(s, ih, recv_buffer); + send_have_all(s); + + test_sleep(300); + + std::vector pi; + th.get_peer_info(pi); + + TEST_EQUAL(pi.size(), 1); + if (pi.size() != 1) return; + + // at this point, the peer should be considered a seed + TEST_CHECK(pi[0].flags & peer_info::seed); + + int lt_dont_have = 0; + while (lt_dont_have == 0) + { + int len = read_message(s, recv_buffer); + print_message(recv_buffer, len); + if (len == 0) continue; + int msg = recv_buffer[0]; + if (msg != 20) continue; + int ext_msg = recv_buffer[1]; + if (ext_msg != 0) continue; + + lazy_entry e; + error_code ec; + lazy_bdecode(recv_buffer + 2, recv_buffer + len - 2, e, ec); + + printf("extension handshake: %s\n", print_entry(e).c_str()); + lazy_entry const* m = e.dict_find_dict("m"); + TEST_CHECK(m); + if (!m) return; + lazy_entry const* dont_have = m->dict_find_int("lt_donthave"); + TEST_CHECK(dont_have); + if (!dont_have) return; + + lt_dont_have = dont_have->int_value(); + } + + char* ptr = recv_buffer; + write_uint32(6, ptr); + write_uint8(20, ptr); + write_uint8(lt_dont_have, ptr); + write_uint32(3, ptr); + + libtorrent::asio::write(s, libtorrent::asio::buffer(recv_buffer, 10) + , libtorrent::asio::transfer_all(), ec); + + test_sleep(1000); + + th.get_peer_info(pi); + + TEST_EQUAL(pi.size(), 1); + if (pi.size() != 1) return; + + TEST_EQUAL(pi[0].flags & peer_info::seed, 0); + TEST_EQUAL(pi[0].pieces.count(), pi[0].pieces.size() - 1); + TEST_EQUAL(pi[0].pieces[3], false); + TEST_EQUAL(pi[0].pieces[2], true); + TEST_EQUAL(pi[0].pieces[1], true); + TEST_EQUAL(pi[0].pieces[0], true); +} + int test_main() { test_reject_fast(); test_respect_suggest(); test_multiple_bitfields(); test_multiple_have_all(); + test_dont_have(); + return 0; } diff --git a/test/test_piece_picker.cpp b/test/test_piece_picker.cpp index 3d9dce41b..0cf58a023 100644 --- a/test/test_piece_picker.cpp +++ b/test/test_piece_picker.cpp @@ -510,6 +510,33 @@ int test_main() TEST_CHECK(int(picked.size()) > 0); TEST_CHECK(picked.front().piece_index == 1); +// ======================================================== + + // make sure we can split m_seed when removing a refcount + print_title("test dec_refcount split seed"); + p = setup_picker("0000000", " ", "0000000", ""); + p->inc_refcount_all(0); + + std::vector avail; + p->get_availability(avail); + TEST_EQUAL(avail.size(), 7); + TEST_CHECK(avail[0] != 0); + TEST_CHECK(avail[1] != 0); + TEST_CHECK(avail[2] != 0); + TEST_CHECK(avail[3] != 0); + TEST_CHECK(avail[4] != 0); + + p->dec_refcount(3, 0); + + p->get_availability(avail); + TEST_EQUAL(avail.size(), 7); + + TEST_CHECK(avail[0] != 0); + TEST_CHECK(avail[1] != 0); + TEST_CHECK(avail[2] != 0); + TEST_CHECK(avail[3] == 0); + TEST_CHECK(avail[4] != 0); + // ======================================================== // make sure init preserves priorities