diff --git a/ChangeLog b/ChangeLog index fff739d60..413a7066e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,7 @@ * fix uTP edge case where udp socket buffer fills up * fix nagle implementation in uTP + * prevent tracker exchange for magnet links before metadata is received * fix crash in make_magnet_uri when generating links longer than 1024 characters * fix hanging issue when closing files on windows (completing a download) * fix piece picking edge case that could cause torrents to get stuck at hash failure diff --git a/src/lt_trackers.cpp b/src/lt_trackers.cpp index 767898183..90adb8fd4 100644 --- a/src/lt_trackers.cpp +++ b/src/lt_trackers.cpp @@ -245,8 +245,8 @@ namespace libtorrent { namespace if (m_full_list) { - send_full_tex_list(); - m_full_list = false; + if (send_full_tex_list()) + m_full_list = false; } else { @@ -261,6 +261,9 @@ namespace libtorrent { namespace // if there's no change in out tracker set, don't send anything if (m_tp.num_updates() == 0) return; + if (!m_torrent.valid_metadata() || m_torrent.torrent_file().priv()) + return; + std::vector const& tex_msg = m_tp.get_lt_tex_msg(); char msg[6]; @@ -274,9 +277,12 @@ namespace libtorrent { namespace m_pc.setup_send(); } - void send_full_tex_list() const + bool send_full_tex_list() const { - if (m_tp.trackers().empty()) return; + if (m_tp.trackers().empty()) return false; + + if (!m_torrent.valid_metadata() || m_torrent.torrent_file().priv()) + return false; #ifdef TORRENT_VERBOSE_LOGGING std::stringstream log_line; @@ -311,6 +317,8 @@ namespace libtorrent { namespace m_pc.send_buffer(msg, sizeof(msg)); m_pc.send_buffer(&tex_msg[0], tex_msg.size()); m_pc.setup_send(); + + return true; } // this is the message index the remote peer uses @@ -331,6 +339,9 @@ namespace libtorrent { namespace if (pc->type() != peer_connection::bittorrent_connection) return boost::shared_ptr(); + if (m_torrent.valid_metadata() && m_torrent.torrent_file().priv()) + return boost::shared_ptr(); + bt_peer_connection* c = static_cast(pc); return boost::shared_ptr(new lt_tracker_peer_plugin(m_torrent, *c, *this)); } diff --git a/test/test_trackers_extension.cpp b/test/test_trackers_extension.cpp index ecfd9b27c..22c0ccf7f 100644 --- a/test/test_trackers_extension.cpp +++ b/test/test_trackers_extension.cpp @@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/extensions/metadata_transfer.hpp" #include "libtorrent/extensions/ut_metadata.hpp" #include "libtorrent/extensions/lt_trackers.hpp" +#include "libtorrent/bencode.hpp" using boost::tuples::ignore; @@ -61,7 +62,48 @@ int test_main() torrent_handle tor2 = ses2.add_torrent(atp, ec); tor2.connect_peer(tcp::endpoint(address_v4::from_string("127.0.0.1"), ses1.listen_port())); - for (int i = 0; i < 130; ++i) + // trackers are NOT supposed to be exchanged for torrents that we + // don't have metadata for, since they might be private + for (int i = 0; i < 10; ++i) + { + // make sure this function can be called on + // torrents without metadata + print_alerts(ses1, "ses1", false, true); + print_alerts(ses2, "ses2", false, true); + + if (tor1.trackers().size() != 0) break; + test_sleep(1000); + } + + TEST_CHECK(tor1.trackers().size() == 0); + + entry info; + info["pieces"] = "aaaaaaaaaaaaaaaaaaaa"; + info["name"] = "slightly shorter name, it's kind of sad that people started the trend of incorrectly encoding the regular name field and then adding another one with correct encoding"; + info["name.utf-8"] = "this is a long ass name in order to try to make make_magnet_uri overflow and hopefully crash. Although, by the time you read this that particular bug should have been fixed"; + info["piece length"] = 16 * 1024; + info["length"] = 3245; + entry torrent; + torrent["info"] = info; + + std::vector buf; + bencode(std::back_inserter(buf), torrent); + boost::intrusive_ptr ti(new torrent_info(&buf[0], buf.size(), ec)); + TEST_CHECK(!ec); + + atp.ti = ti; + atp.info_hash.clear(); + atp.save_path = "./"; + atp.trackers.clear(); + + tor1 = ses1.add_torrent(atp, ec); + atp.trackers.push_back("http://test.non-existent.com/announce"); + tor2 = ses2.add_torrent(atp, ec); + tor2.connect_peer(tcp::endpoint(address_v4::from_string("127.0.0.1"), ses1.listen_port())); + + TEST_CHECK(tor1.trackers().size() == 0); + + for (int i = 0; i < 60; ++i) { // make sure this function can be called on // torrents without metadata @@ -73,6 +115,7 @@ int test_main() } TEST_CHECK(tor1.trackers().size() == 1); + return 0; }