diff --git a/include/libtorrent/web_peer_connection.hpp b/include/libtorrent/web_peer_connection.hpp index 8871ad8ec..742d823f0 100755 --- a/include/libtorrent/web_peer_connection.hpp +++ b/include/libtorrent/web_peer_connection.hpp @@ -120,7 +120,8 @@ namespace libtorrent void write_interested() {} void write_not_interested() {} void write_request(peer_request const& r); - void write_cancel(peer_request const& r) {} + void write_cancel(peer_request const& r) + { incoming_reject_request(r); } void write_have(int index) {} void write_piece(peer_request const& r, char* buffer) { TORRENT_ASSERT(false); } void write_keepalive() {} diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 2148ada2c..f1bf8d706 100755 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -295,6 +295,8 @@ namespace libtorrent { INVARIANT_CHECK; + if (!m_supports_fast) return; + TORRENT_ASSERT(m_sent_handshake && m_sent_bitfield); TORRENT_ASSERT(associated_torrent().lock()->valid_metadata()); @@ -312,6 +314,7 @@ namespace libtorrent TORRENT_ASSERT(m_sent_handshake && m_sent_bitfield); TORRENT_ASSERT(associated_torrent().lock()->valid_metadata()); + TORRENT_ASSERT(m_supports_fast); char msg[] = {0,0,0,5, msg_allowed_fast, 0, 0, 0, 0}; char* ptr = msg + 5; @@ -1297,6 +1300,9 @@ namespace libtorrent detail::write_int32(r.start, ptr); // begin detail::write_int32(r.length, ptr); // length send_buffer(msg, sizeof(msg)); + + if (!m_supports_fast) + incoming_reject_request(r); } void bt_peer_connection::write_request(peer_request const& r) diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index a57982702..71c4d6cec 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -770,7 +770,7 @@ namespace libtorrent } // ----------------------------- - // -------- REJECT PIECE ------- + // ------- SUGGEST PIECE ------- // ----------------------------- void peer_connection::incoming_suggest(int index) @@ -1136,6 +1136,12 @@ namespace libtorrent "i: " << m_peer_interested << " | " "t: " << (int)t->torrent_file().piece_size(r.piece) << " | " "n: " << t->torrent_file().num_pieces() << " ]\n"; + + (*m_logger) << time_now_string() + << " ==> REJECT_PIECE [ " + "piece: " << r.piece << " | " + "s: " << r.start << " | " + "l: " << r.length << " ]\n"; #endif write_reject_request(r); return; @@ -1156,6 +1162,12 @@ namespace libtorrent "i: " << m_peer_interested << " | " "t: " << (int)t->torrent_file().piece_size(r.piece) << " | " "n: " << t->torrent_file().num_pieces() << " ]\n"; + + (*m_logger) << time_now_string() + << " ==> REJECT_PIECE [ " + "piece: " << r.piece << " | " + "s: " << r.start << " | " + "l: " << r.length << " ]\n"; #endif write_reject_request(r); return; @@ -1184,8 +1196,13 @@ namespace libtorrent { write_reject_request(r); #ifdef TORRENT_VERBOSE_LOGGING - (*m_logger) << time_now_string() - << " *** REJECTING REQUEST [ peer choked and piece not in allowed fast set ]\n"; + (*m_logger) << time_now_string() + << " *** REJECTING REQUEST [ peer choked and piece not in allowed fast set ]\n"; + (*m_logger) << time_now_string() + << " ==> REJECT_PIECE [ " + "piece: " << r.piece << " | " + "s: " << r.start << " | " + "l: " << r.length << " ]\n"; #endif } else @@ -1208,6 +1225,12 @@ namespace libtorrent "n: " << t->torrent_file().num_pieces() << " | " "h: " << t->have_piece(r.piece) << " | " "block_limit: " << t->block_size() << " ]\n"; + + (*m_logger) << time_now_string() + << " ==> REJECT_PIECE [ " + "piece: " << r.piece << " | " + "s: " << r.start << " | " + "l: " << r.length << " ]\n"; #endif write_reject_request(r); @@ -1394,6 +1417,9 @@ namespace libtorrent m_outstanding_writing_bytes += p.length; TORRENT_ASSERT(!m_reading); picker.mark_as_writing(block_finished, peer_info_struct()); +#ifndef NDEBUG + t->check_invariant(); +#endif } void peer_connection::on_disk_write_complete(int ret, disk_io_job const& j @@ -1508,6 +1534,14 @@ namespace libtorrent if (i != m_requests.end()) { m_requests.erase(i); +#ifdef TORRENT_VERBOSE_LOGGING + (*m_logger) << time_now_string() + << " ==> REJECT_PIECE [ " + "piece: " << r.piece << " | " + "s: " << r.start << " | " + "l: " << r.length << " ]\n"; +#endif + write_reject_request(r); } else { @@ -1764,11 +1798,6 @@ namespace libtorrent // sent yet, so we don't have to send a cancel. return; } - else - { - m_download_queue.erase(it); - t->picker().abort_download(block); - } int block_offset = block.block_index * t->block_size(); int block_size @@ -1782,13 +1811,12 @@ namespace libtorrent r.start = block_offset; r.length = block_size; - write_cancel(r); - #ifdef TORRENT_VERBOSE_LOGGING (*m_logger) << time_now_string() << " ==> CANCEL [ piece: " << block.piece_index << " | s: " << block_offset << " | l: " << block_size << " | " << block.block_index << " ]\n"; #endif + write_cancel(r); } void peer_connection::send_choke() @@ -1812,6 +1840,19 @@ namespace libtorrent // reject the requests we have in the queue std::for_each(m_requests.begin(), m_requests.end() , bind(&peer_connection::write_reject_request, this, _1)); + +#ifdef TORRENT_VERBOSE_LOGGING + for (std::deque::iterator i = m_requests.begin() + , end(m_requests.end()); i != end; ++i) + { + peer_request const& r = *i; + (*m_logger) << time_now_string() + << " ==> REJECT_PIECE [ " + "piece: " << r.piece << " | " + "s: " << r.start << " | " + "l: " << r.length << " ]\n"; + } +#endif m_requests.clear(); } @@ -2235,18 +2276,24 @@ namespace libtorrent else { piece_picker& picker = t->picker(); - while (!m_download_queue.empty()) + + std::deque dl(m_download_queue); + for (std::deque::iterator i = dl.begin() + , end(dl.end()); i != end; ++i) { piece_block const& r = m_download_queue.back(); - picker.abort_download(r); +#ifdef TORRENT_VERBOSE_LOGGING + (*m_logger) << time_now_string() + << " ==> CANCEL [ piece: " << r.piece_index + << " | block: " << r.block_index + << " ]\n"; +#endif write_cancel(t->to_req(r)); - m_download_queue.pop_back(); } while (!m_request_queue.empty()) { piece_block const& r = m_request_queue.back(); picker.abort_download(r); - write_cancel(t->to_req(r)); m_request_queue.pop_back(); } @@ -2923,6 +2970,10 @@ namespace libtorrent == m_ses.m_bandwidth_manager[i]->is_in_history(this) || m_bandwidth_limit[i].throttle() == bandwidth_limit::inf); } + std::set unique; + std::copy(m_download_queue.begin(), m_download_queue.end(), std::inserter(unique, unique.begin())); + std::copy(m_request_queue.begin(), m_request_queue.end(), std::inserter(unique, unique.begin())); + TORRENT_ASSERT(unique.size() == m_download_queue.size() + m_request_queue.size()); if (m_peer_info) { TORRENT_ASSERT(m_peer_info->connection == this diff --git a/src/torrent.cpp b/src/torrent.cpp index bae5187d6..2100fe5e3 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2667,7 +2667,8 @@ namespace libtorrent for (std::map::iterator i = num_requests.begin() , end(num_requests.end()); i != end; ++i) { - TORRENT_ASSERT(m_picker->num_peers(i->first) == i->second); + if (!m_picker->is_downloaded(i->first)) + TORRENT_ASSERT(m_picker->num_peers(i->first) == i->second); } TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered()); } diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index 58c25f184..098f26dc4 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -11,9 +11,32 @@ #include "test.hpp" #include "libtorrent/assert.hpp" +#include "libtorrent/alert_types.hpp" using boost::filesystem::remove_all; using boost::filesystem::create_directory; +using namespace libtorrent; + +void print_alerts(libtorrent::session& ses, char const* name, bool allow_disconnects, bool allow_no_torrents) +{ + std::vector handles = ses.get_torrents(); + TEST_CHECK(!handles.empty() || allow_no_torrents); + torrent_handle h; + if (!handles.empty()) h = handles[0]; + std::auto_ptr a; + a = ses.pop_alert(); + while (a.get()) + { + std::cerr << name << ": " << a->msg() << "\n"; + TEST_CHECK(dynamic_cast(a.get()) == 0 + || (!handles.empty() && h.is_seed()) + || a->msg() == "connecting to peer" + || a->msg() == "closing connection to ourself" + || a->msg() == "duplicate connection" + || (allow_disconnects && a->msg() == "End of file.")); + a = ses.pop_alert(); + } +} void test_sleep(int millisec) { @@ -167,15 +190,21 @@ setup_transfer(session* ses1, session* ses2, session* ses3 // use the same files sha1_hash info_hash = t->info_hash(); torrent_handle tor1 = ses1->add_torrent(clone_ptr(t), "./tmp1" + suffix); + TEST_CHECK(!ses1->get_torrents().empty()); torrent_handle tor2; torrent_handle tor3; - if (ses3) tor3 = ses3->add_torrent(clone_ptr(t), "./tmp3" + suffix); + if (ses3) + { + tor3 = ses3->add_torrent(clone_ptr(t), "./tmp3" + suffix); + TEST_CHECK(!ses3->get_torrents().empty()); + } if (use_metadata_transfer) tor2 = ses2->add_torrent("http://non-existent-name.com/announce" , t->info_hash(), 0, "./tmp2" + suffix); else tor2 = ses2->add_torrent(clone_ptr(t), "./tmp2" + suffix); + TEST_CHECK(!ses2->get_torrents().empty()); assert(ses1->get_torrents().size() == 1); assert(ses2->get_torrents().size() == 1); diff --git a/test/setup_transfer.hpp b/test/setup_transfer.hpp index 5e5cd3b21..3d9e9d2fe 100644 --- a/test/setup_transfer.hpp +++ b/test/setup_transfer.hpp @@ -5,6 +5,9 @@ #include +void print_alerts(libtorrent::session& ses, char const* name + , bool allow_disconnects = false + , bool allow_no_torrents = false); void test_sleep(int millisec); boost::intrusive_ptr create_torrent(std::ostream* file = 0); diff --git a/test/test_lsd.cpp b/test/test_lsd.cpp index 03168655c..c3316d859 100644 --- a/test/test_lsd.cpp +++ b/test/test_lsd.cpp @@ -56,27 +56,9 @@ void test_lsd() for (int i = 0; i < 30; ++i) { - std::auto_ptr a; - a = ses1.pop_alert(); - while(a.get()) - { - std::cerr << "ses1: " << a->msg() << "\n"; - a = ses1.pop_alert(); - } - - a = ses2.pop_alert(); - while (a.get()) - { - std::cerr << "ses2: " << a->msg() << "\n"; - a = ses2.pop_alert(); - } - - a = ses3.pop_alert(); - while (a.get()) - { - std::cerr << "ses3: " << a->msg() << "\n"; - a = ses3.pop_alert(); - } + print_alerts(ses1, "ses1", true); + print_alerts(ses2, "ses2", true); + print_alerts(ses3, "ses3", true); torrent_status st1 = tor1.status(); torrent_status st2 = tor2.status(); diff --git a/test/test_metadata_extension.cpp b/test/test_metadata_extension.cpp index 6ce68487a..36294d784 100644 --- a/test/test_metadata_extension.cpp +++ b/test/test_metadata_extension.cpp @@ -39,20 +39,8 @@ void test_transfer(bool clear_files, bool disconnect // make sure this function can be called on // torrents without metadata if (!disconnect) tor2.status(); - std::auto_ptr a; - a = ses1.pop_alert(); - while(a.get()) - { - std::cerr << "ses1: " << a->msg() << "\n"; - a = ses1.pop_alert(); - } - - a = ses2.pop_alert(); - while (a.get()) - { - std::cerr << "ses2: " << a->msg() << "\n"; - a = ses2.pop_alert(); - } + print_alerts(ses1, "ses1", false, true); + print_alerts(ses2, "ses2", false, true); if (disconnect && tor2.is_valid()) ses2.remove_torrent(tor2); if (!disconnect && tor2.has_metadata()) break; diff --git a/test/test_pe_crypto.cpp b/test/test_pe_crypto.cpp index 09c72d22f..2188aaef9 100644 --- a/test/test_pe_crypto.cpp +++ b/test/test_pe_crypto.cpp @@ -114,20 +114,8 @@ void test_transfer(libtorrent::pe_settings::enc_policy policy, for (int i = 0; i < 50; ++i) { tor2.status(); - std::auto_ptr a; - a = ses1.pop_alert(); - while(a.get()) - { - std::cerr << "ses1: " << a->msg() << "\n"; - a = ses1.pop_alert(); - } - - a = ses2.pop_alert(); - while (a.get()) - { - std::cerr << "ses2: " << a->msg() << "\n"; - a = ses2.pop_alert(); - } + print_alerts(ses1, "ses1"); + print_alerts(ses2, "ses2"); if (tor2.is_seed()) break; test_sleep(100); diff --git a/test/test_pex.cpp b/test/test_pex.cpp index 43108d14f..0ac05ad7f 100644 --- a/test/test_pex.cpp +++ b/test/test_pex.cpp @@ -63,27 +63,9 @@ void test_pex() for (int i = 0; i < 40; ++i) { - std::auto_ptr a; - a = ses1.pop_alert(); - while(a.get()) - { - std::cerr << "ses1: " << a->msg() << "\n"; - a = ses1.pop_alert(); - } - - a = ses2.pop_alert(); - while (a.get()) - { - std::cerr << "ses2: " << a->msg() << "\n"; - a = ses2.pop_alert(); - } - - a = ses3.pop_alert(); - while (a.get()) - { - std::cerr << "ses3: " << a->msg() << "\n"; - a = ses3.pop_alert(); - } + print_alerts(ses1, "ses1"); + print_alerts(ses2, "ses2"); + print_alerts(ses3, "ses3"); torrent_status st1 = tor1.status(); torrent_status st2 = tor2.status(); diff --git a/test/test_swarm.cpp b/test/test_swarm.cpp index 2b74ffb91..e5aef1b8d 100644 --- a/test/test_swarm.cpp +++ b/test/test_swarm.cpp @@ -63,27 +63,9 @@ void test_swarm() for (int i = 0; i < 26; ++i) { - std::auto_ptr a; - a = ses1.pop_alert(); - while(a.get()) - { - std::cerr << "ses1: " << a->msg() << "\n"; - a = ses1.pop_alert(); - } - - a = ses2.pop_alert(); - while (a.get()) - { - std::cerr << "ses2: " << a->msg() << "\n"; - a = ses2.pop_alert(); - } - - a = ses3.pop_alert(); - while (a.get()) - { - std::cerr << "ses3: " << a->msg() << "\n"; - a = ses3.pop_alert(); - } + print_alerts(ses1, "ses1"); + print_alerts(ses2, "ses2"); + print_alerts(ses3, "ses3"); torrent_status st1 = tor1.status(); torrent_status st2 = tor2.status();