diff --git a/ChangeLog b/ChangeLog index c2a30dfba..b512c318a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * add build option to disable share-mode * support validation of HTTPS trackers * deprecate strict super seeding mode * make UPnP port-mapping lease duration configurable diff --git a/Jamfile b/Jamfile index 28a1542e3..0ec171f47 100644 --- a/Jamfile +++ b/Jamfile @@ -442,6 +442,9 @@ feature.compose on : --coverage --coverage ; feature predictive-pieces : on off : composite propagated ; feature.compose off : TORRENT_DISABLE_PREDICTIVE_PIECES ; +feature share-mode : on off : composite propagated ; +feature.compose off : TORRENT_DISABLE_SHARE_MODE ; + feature streaming : on off : composite propagated ; feature.compose off : TORRENT_DISABLE_STREAMING ; diff --git a/docs/building.rst b/docs/building.rst index b7f9e2800..64821a21d 100644 --- a/docs/building.rst +++ b/docs/building.rst @@ -387,6 +387,9 @@ Build features: | ``super-seeding`` | * ``on`` - enable super seeding feature. (default) | | | * ``off`` - disable super seeding feature | +--------------------------+----------------------------------------------------+ +| ``share-mode`` | * ``on`` - enable share-mode feature. (default) | +| | * ``off`` - disable share-mode feature | ++--------------------------+----------------------------------------------------+ | ``predictive-pieces`` | * ``on`` - enable predictive piece announce | | | feature. i.e. | | | settings_pack::predictive_piece_announce | @@ -545,6 +548,10 @@ defines you can use to control the build. | | seeding. The settings will exist, but will not | | | have an effect, when this macro is defined. | +----------------------------------------+-------------------------------------------------+ +| ``TORRENT_DISABLE_SHARE_MODE`` | This macro will disable support for share-mode. | +| | i.e. the mode to maximize upload/download | +| | ratio for a torrent. | ++----------------------------------------+-------------------------------------------------+ | ``TORRENT_DISABLE_MUTABLE_TORRENTS`` | Disables mutable torrent support (`BEP 38`_) | +----------------------------------------+-------------------------------------------------+ | ``TORRENT_DISABLE_STREAMING`` | Disables set_piece_deadline() and associated | diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 25c11afd9..3e46ac423 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -386,8 +386,10 @@ namespace aux { bool is_seed() const; int num_have_pieces() const { return m_num_pieces; } +#ifndef TORRENT_DISABLE_SHARE_MODE void set_share_mode(bool m); bool share_mode() const { return m_share_mode; } +#endif void set_upload_only(bool u); bool upload_only() const { return m_upload_only; } @@ -1105,8 +1107,10 @@ namespace aux { // at a time. bool m_request_large_blocks:1; +#ifndef TORRENT_DISABLE_SHARE_MODE // set to true if this peer is in share mode bool m_share_mode:1; +#endif // set to true when this peer is only uploading bool m_upload_only:1; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index bfa173584..11e946cbf 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -287,8 +287,10 @@ namespace libtorrent { // effectively paused as well. bool m_session_paused:1; +#ifndef TORRENT_DISABLE_SHARE_MODE // this is set when the torrent is in share-mode bool m_share_mode:1; +#endif // this is true if we have all pieces. If it's false, // it means we either don't have any pieces, or, if @@ -411,11 +413,13 @@ namespace libtorrent { void start_announcing(); void stop_announcing(); - void send_share_mode(); void send_upload_only(); +#ifndef TORRENT_DISABLE_SHARE_MODE + void send_share_mode(); void set_share_mode(bool s); bool share_mode() const { return m_share_mode; } +#endif // TODO: make graceful pause also finish all sending blocks // before disconnecting @@ -777,7 +781,9 @@ namespace libtorrent { // -------------------------------------------- // PIECE MANAGEMENT +#ifndef TORRENT_DISABLE_SHARE_MODE void recalc_share_mode(); +#endif #ifndef TORRENT_DISABLE_SUPERSEEDING bool super_seeding() const diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 27ab2b451..fbd37672a 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -298,7 +298,9 @@ namespace { // will send their bitfield when the handshake // is done std::shared_ptr t = associated_torrent().lock(); +#ifndef TORRENT_DISABLE_SHARE_MODE if (!t->share_mode()) +#endif { bool const upload_only_enabled = t->is_upload_only() #ifndef TORRENT_DISABLE_SUPERSEEDING @@ -1608,6 +1610,7 @@ namespace { return; } +#ifndef TORRENT_DISABLE_SHARE_MODE if (extended_id == share_mode_msg) { if (!m_recv_buffer.packet_finished()) return; @@ -1627,6 +1630,7 @@ namespace { set_share_mode(sm); return; } +#endif // TORRENT_DISABLE_SHARE_MODE if (extended_id == holepunch_msg) { @@ -1751,9 +1755,11 @@ namespace { if (root.dict_find_int_value("upload_only", 0)) set_upload_only(true); +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_settings.get_bool(settings_pack::support_share_mode) && root.dict_find_int_value("share_mode", 0)) set_share_mode(true); +#endif auto const myip = root.dict_find_string_value("yourip"); if (!myip.empty()) @@ -1786,7 +1792,10 @@ namespace { // disconnect it if (t->is_finished() && upload_only() && m_settings.get_bool(settings_pack::close_redundant_connections) - && !t->share_mode()) +#ifndef TORRENT_DISABLE_SHARE_MODE + && !t->share_mode() +#endif + ) disconnect(errors::upload_upload_connection, operation_t::bittorrent); stats_counters().inc_stats_counter(counters::num_incoming_ext_handshake); @@ -1888,7 +1897,7 @@ namespace { { INVARIANT_CHECK; -#if TORRENT_USE_ASSERTS +#if TORRENT_USE_ASSERTS && !defined TORRENT_DISABLE_SHARE_MODE std::shared_ptr t = associated_torrent().lock(); TORRENT_ASSERT(!t->share_mode()); #endif @@ -1909,6 +1918,7 @@ namespace { stats_counters().inc_stats_counter(counters::num_outgoing_extended); } +#ifndef TORRENT_DISABLE_SHARE_MODE void bt_peer_connection::write_share_mode() { INVARIANT_CHECK; @@ -1924,6 +1934,7 @@ namespace { stats_counters().inc_stats_counter(counters::num_outgoing_extended); } +#endif void bt_peer_connection::write_keepalive() { @@ -2125,8 +2136,10 @@ namespace { m["upload_only"] = upload_only_msg; m["ut_holepunch"] = holepunch_msg; +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_settings.get_bool(settings_pack::support_share_mode)) m["share_mode"] = share_mode_msg; +#endif m["lt_donthave"] = dont_have_msg; int complete_ago = -1; @@ -2143,7 +2156,9 @@ namespace { // upload-only. If we do, we may be disconnected before we receive the // metadata. if (t->is_upload_only() +#ifndef TORRENT_DISABLE_SHARE_MODE && !t->share_mode() +#endif && t->valid_metadata() #ifndef TORRENT_DISABLE_SUPERSEEDING && !t->super_seeding() @@ -2153,9 +2168,11 @@ namespace { handshake["upload_only"] = 1; } +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_settings.get_bool(settings_pack::support_share_mode) && t->share_mode()) handshake["share_mode"] = 1; +#endif #ifndef TORRENT_DISABLE_EXTENSIONS // loop backwards, to make the first extension be the last diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 2a2446138..6df960463 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -143,7 +143,9 @@ namespace libtorrent { , m_failed(false) , m_connected(pack.tor.expired()) , m_request_large_blocks(false) +#ifndef TORRENT_DISABLE_SHARE_MODE , m_share_mode(false) +#endif , m_upload_only(false) , m_bitfield_received(false) , m_no_download(false) @@ -2260,8 +2262,10 @@ namespace libtorrent { // metadata from us if (!t->valid_metadata() || !has_metadata()) return false; +#ifndef TORRENT_DISABLE_SHARE_MODE // don't close connections in share mode, we don't know if we need them if (t->share_mode()) return false; +#endif if (m_upload_only && t->is_upload_only() && can_disconnect(errors::upload_upload_connection)) @@ -5141,7 +5145,9 @@ namespace libtorrent { INVARIANT_CHECK; #endif +#ifndef TORRENT_DISABLE_SHARE_MODE bool sent_a_piece = false; +#endif std::shared_ptr t = m_torrent.lock(); if (!t || t->is_aborted() || m_requests.empty()) return; @@ -5251,7 +5257,9 @@ namespace libtorrent { , "piece: %d s: %x l: %x", static_cast(r.piece), r.start, r.length); #endif m_reading_bytes += r.length; +#ifndef TORRENT_DISABLE_SHARE_MODE sent_a_piece = true; +#endif // the callback function may be called immediately, instead of being posted @@ -5273,8 +5281,10 @@ namespace libtorrent { --i; } +#ifndef TORRENT_DISABLE_SHARE_MODE if (t->share_mode() && sent_a_piece) t->recalc_share_mode(); +#endif } // this is called when a previously unchecked piece has been @@ -6419,7 +6429,10 @@ namespace libtorrent { // in share mode we don't close redundant connections if (m_settings.get_bool(settings_pack::close_redundant_connections) - && !t->share_mode()) +#ifndef TORRENT_DISABLE_SHARE_MODE + && !t->share_mode() +#endif + ) { bool const ok_to_disconnect = can_disconnect(errors::upload_upload_connection) @@ -6590,6 +6603,7 @@ namespace libtorrent { && m_num_pieces > 0 && t && t->valid_metadata(); } +#ifndef TORRENT_DISABLE_SHARE_MODE void peer_connection::set_share_mode(bool u) { TORRENT_ASSERT(is_single_thread()); @@ -6598,6 +6612,7 @@ namespace libtorrent { m_share_mode = u; } +#endif void peer_connection::set_upload_only(bool u) { diff --git a/src/torrent.cpp b/src/torrent.cpp index cdb3e59de..088482911 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -158,7 +158,9 @@ bool is_downloading_state(int const st) , m_abort(false) , m_paused(p.flags & torrent_flags::paused) , m_session_paused(session_paused) +#ifndef TORRENT_DISABLE_SHARE_MODE , m_share_mode(p.flags & torrent_flags::share_mode) +#endif , m_have_all(false) , m_graceful_pause_mode(false) , m_state_subscription(p.flags & torrent_flags::update_subscribe) @@ -689,7 +691,11 @@ bool is_downloading_state(int const st) , download_limit() , m_seed_mode ? "seed-mode " : "" , m_upload_mode ? "upload-mode " : "" +#ifndef TORRENT_DISABLE_SHARE_MODE , m_share_mode ? "share-mode " : "" +#else + , "" +#endif , m_apply_ip_filter ? "apply-ip-filter " : "" , m_paused ? "paused " : "" , m_auto_managed ? "auto-managed " : "" @@ -920,6 +926,7 @@ bool is_downloading_state(int const st) m_ses.disk_thread().submit_jobs(); } +#ifndef TORRENT_DISABLE_SHARE_MODE void torrent::send_share_mode() { #ifndef TORRENT_DISABLE_EXTENSIONS @@ -932,11 +939,15 @@ bool is_downloading_state(int const st) } #endif } +#endif // TORRENT_DISABLE_SHARE_MODE void torrent::send_upload_only() { #ifndef TORRENT_DISABLE_EXTENSIONS + +#ifndef TORRENT_DISABLE_SHARE_MODE if (share_mode()) return; +#endif #ifndef TORRENT_DISABLE_SUPERSEEDING if (super_seeding()) return; #endif @@ -964,7 +975,7 @@ bool is_downloading_state(int const st) p->send_not_interested(); p->send_upload_only(upload_only_enabled); } -#endif +#endif // TORRENT_DISABLE_EXTENSIONS } torrent_flags_t torrent::flags() const @@ -974,8 +985,10 @@ bool is_downloading_state(int const st) ret |= torrent_flags::seed_mode; if (m_upload_mode) ret |= torrent_flags::upload_mode; +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_share_mode) ret |= torrent_flags::share_mode; +#endif if (m_apply_ip_filter) ret |= torrent_flags::apply_ip_filter; if (is_torrent_paused()) @@ -1009,8 +1022,10 @@ bool is_downloading_state(int const st) } if (mask & torrent_flags::upload_mode) set_upload_mode(bool(flags & torrent_flags::upload_mode)); +#ifndef TORRENT_DISABLE_SHARE_MODE if (mask & torrent_flags::share_mode) set_share_mode(bool(flags & torrent_flags::share_mode)); +#endif if (mask & torrent_flags::apply_ip_filter) set_apply_ip_filter(bool(flags & torrent_flags::apply_ip_filter)); if (mask & torrent_flags::paused) @@ -1038,6 +1053,7 @@ bool is_downloading_state(int const st) m_enable_pex = !bool(flags & torrent_flags::disable_pex); } +#ifndef TORRENT_DISABLE_SHARE_MODE void torrent::set_share_mode(bool s) { if (s == m_share_mode) return; @@ -1056,6 +1072,7 @@ bool is_downloading_state(int const st) prioritize_files(aux::vector(num_files, dont_download)); } } +#endif // TORRENT_DISABLE_SHARE_MODE void torrent::set_upload_mode(bool b) { @@ -1819,12 +1836,14 @@ bool is_downloading_state(int const st) construct_storage(); +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_share_mode && valid_metadata()) { // in share mode, all pieces have their priorities initialized to 0 m_file_priority.clear(); m_file_priority.resize(m_torrent_file->num_files(), dont_download); } +#endif // it's important to initialize the peers early, because this is what will // fix up their have-bitmasks to have the correct size @@ -3973,8 +3992,10 @@ bool is_downloading_state(int const st) m_last_download = aux::time_now32(); +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_share_mode) recalc_share_mode(); +#endif } } @@ -5072,8 +5093,10 @@ bool is_downloading_state(int const st) if (m_file_priority != prios) { m_file_priority = std::move(prios); +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_share_mode) recalc_share_mode(); +#endif } if (err) @@ -6813,8 +6836,10 @@ bool is_downloading_state(int const st) return false; } +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_share_mode) recalc_share_mode(); +#endif return peerinfo->connection != nullptr; } @@ -7137,8 +7162,10 @@ bool is_downloading_state(int const st) if (m_peer_list) m_peer_list->check_invariant(); #endif +#ifndef TORRENT_DISABLE_SHARE_MODE if (m_share_mode) recalc_share_mode(); +#endif // once we add the peer to our m_connections list, we can't throw an // exception. That will end up violating an invariant between the session, @@ -9339,6 +9366,7 @@ bool is_downloading_state(int const st) } } +#ifndef TORRENT_DISABLE_SHARE_MODE void torrent::recalc_share_mode() { TORRENT_ASSERT(share_mode()); @@ -9475,6 +9503,7 @@ bool is_downloading_state(int const st) update_peer_interest(was_finished); update_want_peers(); } +#endif // TORRENT_DISABLE_SHARE_MODE void torrent::sent_bytes(int const bytes_payload, int const bytes_protocol) { @@ -10720,7 +10749,11 @@ bool is_downloading_state(int const st) #endif #if TORRENT_ABI_VERSION == 1 +#ifndef TORRENT_DISABLE_SHARE_MODE st->share_mode = m_share_mode; +#else + st->share_mode = false; +#endif st->upload_mode = m_upload_mode; #endif st->up_bandwidth_queue = 0; diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index 0c36006b0..dfb166478 100644 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -310,7 +310,12 @@ namespace libtorrent { { async_call(&torrent::set_upload_mode, b); } void torrent_handle::set_share_mode(bool b) const - { async_call(&torrent::set_share_mode, b); } + { + TORRENT_UNUSED(b); +#ifndef TORRENT_DISABLE_SHARE_MODE + async_call(&torrent::set_share_mode, b); +#endif + } void torrent_handle::apply_ip_filter(bool b) const { async_call(&torrent::set_apply_ip_filter, b); } diff --git a/test/test_fast_extension.cpp b/test/test_fast_extension.cpp index cddc50882..3735d9748 100644 --- a/test/test_fast_extension.cpp +++ b/test/test_fast_extension.cpp @@ -926,7 +926,9 @@ TORRENT_TEST(extension_handshake) // these extensions are built-in TEST_CHECK(extensions["m"]["lt_donthave"].integer() != 0); +#ifndef TORRENT_DISABLE_SHARE_MODE TEST_CHECK(extensions["m"]["share_mode"].integer() != 0); +#endif TEST_CHECK(extensions["m"]["upload_only"].integer() != 0); TEST_CHECK(extensions["m"]["ut_holepunch"].integer() != 0); diff --git a/test/test_flags.cpp b/test/test_flags.cpp index d7498655c..829fc8baf 100644 --- a/test/test_flags.cpp +++ b/test/test_flags.cpp @@ -115,6 +115,7 @@ TORRENT_TEST(flag_upload_mode) test_unset_after_add(torrent_flags::upload_mode); } +#ifndef TORRENT_DISABLE_SHARE_MODE TORRENT_TEST(flag_share_mode) { // share-mode @@ -122,6 +123,7 @@ TORRENT_TEST(flag_share_mode) test_set_after_add(torrent_flags::share_mode); test_unset_after_add(torrent_flags::share_mode); } +#endif TORRENT_TEST(flag_apply_ip_filter) { diff --git a/test/test_resume.cpp b/test/test_resume.cpp index 9a7847d3d..23367357e 100644 --- a/test/test_resume.cpp +++ b/test/test_resume.cpp @@ -602,6 +602,7 @@ TORRENT_TEST(file_priorities_override_resume_deprecated) TEST_EQUAL(file_priorities[2], 3); } +#ifndef TORRENT_DISABLE_SHARE_MODE TORRENT_TEST(file_priorities_resume_share_mode_deprecated) { // in share mode file priorities should always be 0 @@ -627,6 +628,7 @@ TORRENT_TEST(file_priorities_share_mode_deprecated) TEST_EQUAL(file_priorities[1], 0); TEST_EQUAL(file_priorities[2], 0); } +#endif TORRENT_TEST(resume_save_load_deprecated) { @@ -815,6 +817,7 @@ TORRENT_TEST(upload_mode_deprecated) TEST_EQUAL(s.uploads_limit, 1346); } +#ifndef TORRENT_DISABLE_SHARE_MODE TORRENT_TEST(share_mode_deprecated) { lt::session ses(settings()); @@ -831,6 +834,7 @@ TORRENT_TEST(share_mode_deprecated) TEST_EQUAL(s.connections_limit, 2); TEST_EQUAL(s.uploads_limit, 1); } +#endif TORRENT_TEST(auto_managed_deprecated) { @@ -924,6 +928,7 @@ TORRENT_TEST(file_priorities_default) TEST_EQUAL(file_priorities[2], 4_pri); } +#ifndef TORRENT_DISABLE_SHARE_MODE TORRENT_TEST(file_priorities_resume_share_mode) { // in share mode file priorities should always be 0 @@ -949,6 +954,7 @@ TORRENT_TEST(file_priorities_share_mode) TEST_EQUAL(file_priorities[1], 0_pri); TEST_EQUAL(file_priorities[2], 0_pri); } +#endif namespace { @@ -1418,6 +1424,7 @@ TORRENT_TEST(upload_mode) TEST_EQUAL(s.uploads_limit, 1346); } +#ifndef TORRENT_DISABLE_SHARE_MODE TORRENT_TEST(share_mode) { lt::session ses(settings()); @@ -1433,6 +1440,7 @@ TORRENT_TEST(share_mode) TEST_EQUAL(s.connections_limit, 1345); TEST_EQUAL(s.uploads_limit, 1346); } +#endif TORRENT_TEST(auto_managed) {