diff --git a/Jamfile b/Jamfile index cd491dba1..e31ec3643 100644 --- a/Jamfile +++ b/Jamfile @@ -441,6 +441,9 @@ feature.compose off : TORRENT_DISABLE_PREDICTIVE_PIEC feature streaming : on off : composite propagated ; feature.compose off : TORRENT_DISABLE_STREAMING ; +feature super-seeding : on off : composite propagated ; +feature.compose off : TORRENT_DISABLE_SUPERSEEDING ; + feature i2p : on off : composite propagated ; feature.compose on : TORRENT_USE_I2P=1 ; feature.compose off : TORRENT_USE_I2P=0 ; diff --git a/docs/building.rst b/docs/building.rst index 2fd1433c1..79e4d0838 100644 --- a/docs/building.rst +++ b/docs/building.rst @@ -384,6 +384,9 @@ Build features: | | ``set_piece_deadline()``. | | | * ``off`` - disable streaming functionality. | +--------------------------+----------------------------------------------------+ +| ``super-seeding`` | * ``on`` - enable super seeding feature | +| | * ``off`` - disable super seeding feature | ++--------------------------+----------------------------------------------------+ | ``predictive-pieces`` | * ``on`` - enable predictive piece announce | | | feature. i.e. | | | settings_pack::predictive_piece_announce | @@ -537,6 +540,10 @@ defines you can use to control the build. | | peer_log_alert. With this build flag, you | | | cannot enable those alerts. | +----------------------------------------+-------------------------------------------------+ +| ``TORRENT_DISABLE_SUPERSEEDING`` | This macro will disable support for super | +| | seeding. The settings will exist, but will not | +| | have an effect, when this macro is defined. | ++----------------------------------------+-------------------------------------------------+ | ``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 5bd324de5..25c11afd9 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -367,6 +367,7 @@ namespace aux { // it will let the peer know that we have the given piece void announce_piece(piece_index_t index); +#ifndef TORRENT_DISABLE_SUPERSEEDING // this will tell the peer to announce the given piece // and only allow it to request that piece void superseed_piece(piece_index_t replace_piece, piece_index_t new_piece); @@ -375,6 +376,7 @@ namespace aux { return m_superseed_piece[0] == index || m_superseed_piece[1] == index; } +#endif // tells if this connection has data it want to send // and has enough upload bandwidth quota left to send it. @@ -1016,12 +1018,14 @@ namespace aux { // by sending choke, unchoke. int m_num_invalid_requests = 0; +#ifndef TORRENT_DISABLE_SUPERSEEDING // if [0] is -1, super-seeding is not active. If it is >= 0 // this is the piece that is available to this peer. Only // these two pieces can be downloaded from us by this peer. // This will remain the current piece for this peer until // another peer sends us a have message for this piece std::array m_superseed_piece = {{piece_index_t(-1), piece_index_t(-1)}}; +#endif // the number of bytes send to the disk-io // thread that hasn't yet been completely written. diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 624e0fc4d..7b664a735 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -779,6 +779,7 @@ namespace libtorrent { void recalc_share_mode(); +#ifndef TORRENT_DISABLE_SUPERSEEDING bool super_seeding() const { // we're not super seeding if we're not a seed @@ -787,6 +788,7 @@ namespace libtorrent { void set_super_seeding(bool on); piece_index_t get_piece_to_super_seed(typed_bitfield const&); +#endif // returns true if we have downloaded the given piece bool have_piece(piece_index_t index) const @@ -1573,9 +1575,11 @@ namespace libtorrent { // haven't bool m_seed_mode:1; +#ifndef TORRENT_DISABLE_SUPERSEEDING // if this is true, we're currently super seeding this // torrent. bool m_super_seeding:1; +#endif // if this is set, whenever transitioning into a downloading/seeding state // from a non-downloading/seeding state, the torrent is paused. diff --git a/simulation/test_super_seeding.cpp b/simulation/test_super_seeding.cpp index 9f8c5a100..c173550a6 100644 --- a/simulation/test_super_seeding.cpp +++ b/simulation/test_super_seeding.cpp @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. using namespace lt; +#ifndef TORRENT_DISABLE_SUPERSEEDING TORRENT_TEST(super_seeding) { setup_swarm(5, swarm_test::upload @@ -70,4 +71,4 @@ TORRENT_TEST(strict_super_seeding) , [](int, lt::session&) -> bool { return true; }); } - +#endif diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index f94d7bebf..27ab2b451 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -300,7 +300,11 @@ namespace { std::shared_ptr t = associated_torrent().lock(); if (!t->share_mode()) { - bool const upload_only_enabled = t->is_upload_only() && !t->super_seeding(); + bool const upload_only_enabled = t->is_upload_only() +#ifndef TORRENT_DISABLE_SUPERSEEDING + && !t->super_seeding() +#endif + ; send_upload_only(upload_only_enabled); } @@ -1968,6 +1972,7 @@ namespace { TORRENT_ASSERT(m_sent_handshake); TORRENT_ASSERT(t->valid_metadata()); +#ifndef TORRENT_DISABLE_SUPERSEEDING if (t->super_seeding()) { #ifndef TORRENT_DISABLE_LOGGING @@ -1986,7 +1991,9 @@ namespace { if (piece >= piece_index_t(0)) superseed_piece(piece_index_t(-1), piece); return; } - else if (m_supports_fast && t->is_seed()) + else +#endif + if (m_supports_fast && t->is_seed()) { write_have_all(); return; @@ -2138,7 +2145,10 @@ namespace { if (t->is_upload_only() && !t->share_mode() && t->valid_metadata() - && !t->super_seeding()) +#ifndef TORRENT_DISABLE_SUPERSEEDING + && !t->super_seeding() +#endif + ) { handshake["upload_only"] = 1; } diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index d5723104f..ac7ee7520 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -632,6 +632,7 @@ namespace libtorrent { return; } +#ifndef TORRENT_DISABLE_SUPERSEEDING if (t->super_seeding()) { #ifndef TORRENT_DISABLE_LOGGING @@ -639,6 +640,7 @@ namespace libtorrent { #endif return; } +#endif if (upload_only()) { @@ -1941,6 +1943,7 @@ namespace libtorrent { return; } +#ifndef TORRENT_DISABLE_SUPERSEEDING if (t->super_seeding() && !m_settings.get_bool(settings_pack::strict_super_seeding)) { // if we're super-seeding and the peer just told @@ -1954,6 +1957,7 @@ namespace libtorrent { superseed_piece(index, t->get_piece_to_super_seed(m_have_piece)); } } +#endif if (m_have_piece[index]) { @@ -2016,6 +2020,7 @@ namespace libtorrent { disconnect_if_redundant(); if (is_disconnecting()) return; +#ifndef TORRENT_DISABLE_SUPERSEEDING // if we're super seeding, this might mean that somebody // forwarded this piece. In which case we need to give // a new piece to that peer @@ -2030,6 +2035,7 @@ namespace libtorrent { p->superseed_piece(index, t->get_piece_to_super_seed(p->get_bitfield())); } } +#endif } // ----------------------------- @@ -2315,6 +2321,7 @@ namespace libtorrent { , "piece: %d s: %x l: %x", static_cast(r.piece), r.start, r.length); #endif +#ifndef TORRENT_DISABLE_SUPERSEEDING if (t->super_seeding() && !super_seeded_piece(r.piece)) { @@ -2348,6 +2355,7 @@ namespace libtorrent { } return; } +#endif // TORRENT_DISABLE_SUPERSEEDING // if we haven't received a bitfield, it was // probably omitted, which is the same as 'have_none' @@ -4606,6 +4614,7 @@ namespace libtorrent { p.local_endpoint = get_socket()->local_endpoint(ec); } +#ifndef TORRENT_DISABLE_SUPERSEEDING // TODO: 3 new_piece should be an optional. piece index -1 // should not be allowed void peer_connection::superseed_piece(piece_index_t const replace_piece @@ -4654,6 +4663,7 @@ namespace libtorrent { m_superseed_piece[1] = m_superseed_piece[0]; m_superseed_piece[0] = new_piece; } +#endif // TORRENT_DISABLE_SUPERSEEDING void peer_connection::max_out_request_queue(int s) { @@ -4789,6 +4799,7 @@ namespace libtorrent { send_block_requests(); } +#ifndef TORRENT_DISABLE_SUPERSEEDING if (t->super_seeding() && t->ready_for_connections() && !m_peer_interested @@ -4798,6 +4809,7 @@ namespace libtorrent { // become interested in us then superseed_piece(piece_index_t(-1), t->get_piece_to_super_seed(m_have_piece)); } +#endif on_tick(); if (is_disconnecting()) return; diff --git a/src/torrent.cpp b/src/torrent.cpp index 0f8cbb347..49d8de5e1 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -200,7 +200,9 @@ bool is_downloading_state(int const st) , m_sequential_download(p.flags & torrent_flags::sequential_download) , m_auto_sequential(false) , m_seed_mode(false) +#ifndef TORRENT_DISABLE_SUPERSEEDING , m_super_seeding(p.flags & torrent_flags::super_seeding) +#endif , m_stop_when_ready(p.flags & torrent_flags::stop_when_ready) , m_need_save_resume_data(p.flags & torrent_flags::need_save_resume) , m_enable_dht(!bool(p.flags & torrent_flags::disable_dht)) @@ -692,7 +694,11 @@ bool is_downloading_state(int const st) , m_paused ? "paused " : "" , m_auto_managed ? "auto-managed " : "" , m_state_subscription ? "update-subscribe " : "" +#ifndef TORRENT_DISABLE_SUPERSEEDING , m_super_seeding ? "super-seeding " : "" +#else + , "" +#endif , m_sequential_download ? "sequential-download " : "" , (m_add_torrent_params && m_add_torrent_params->flags & torrent_flags::override_trackers) ? "override-trackers " : "" @@ -931,7 +937,9 @@ bool is_downloading_state(int const st) { #ifndef TORRENT_DISABLE_EXTENSIONS if (share_mode()) return; +#ifndef TORRENT_DISABLE_SUPERSEEDING if (super_seeding()) return; +#endif // if we send upload-only, the other end is very likely to disconnect // us, at least if it's a seed. If we don't want to close redundant @@ -943,7 +951,11 @@ bool is_downloading_state(int const st) // only, since they might disconnect immediately when // they have downloaded a single piece, although we'll // make another piece available - bool const upload_only_enabled = is_upload_only() && !super_seeding(); + bool const upload_only_enabled = is_upload_only() +#ifndef TORRENT_DISABLE_SUPERSEEDING + && !super_seeding() +#endif + ; for (auto p : m_connections) { @@ -970,8 +982,10 @@ bool is_downloading_state(int const st) ret |= torrent_flags::paused; if (m_auto_managed) ret |= torrent_flags::auto_managed; +#ifndef TORRENT_DISABLE_SUPERSEEDING if (m_super_seeding) ret |= torrent_flags::super_seeding; +#endif if (m_sequential_download) ret |= torrent_flags::sequential_download; if (m_stop_when_ready) @@ -1008,8 +1022,10 @@ bool is_downloading_state(int const st) } if (mask & torrent_flags::auto_managed) auto_managed(bool(flags & torrent_flags::auto_managed)); +#ifndef TORRENT_DISABLE_SUPERSEEDING if (mask & torrent_flags::super_seeding) set_super_seeding(bool(flags & torrent_flags::super_seeding)); +#endif if (mask & torrent_flags::sequential_download) set_sequential_download(bool(flags & torrent_flags::sequential_download)); if (mask & torrent_flags::stop_when_ready) @@ -4484,6 +4500,7 @@ bool is_downloading_state(int const st) m_num_connecting_seeds = 0; } +#ifndef TORRENT_DISABLE_SUPERSEEDING void torrent::set_super_seeding(bool on) { if (on == m_super_seeding) return; @@ -4545,6 +4562,7 @@ bool is_downloading_state(int const st) if (avail_vec.empty()) return piece_index_t(-1); return avail_vec[random(std::uint32_t(avail_vec.size() - 1))]; } +#endif void torrent::on_files_deleted(storage_error const& error) try { @@ -6246,7 +6264,9 @@ bool is_downloading_state(int const st) ret.flags = torrent_flags_t{}; if (m_sequential_download) ret.flags |= torrent_flags::sequential_download; if (m_seed_mode ) ret.flags |= torrent_flags::seed_mode; +#ifndef TORRENT_DISABLE_SUPERSEEDING if (m_super_seeding ) ret.flags |= torrent_flags::super_seeding; +#endif if (is_torrent_paused()) ret.flags |= torrent_flags::paused; if (m_auto_managed ) ret.flags |= torrent_flags::auto_managed; if (m_stop_when_ready) ret.flags |= torrent_flags::stop_when_ready; @@ -7590,6 +7610,7 @@ bool is_downloading_state(int const st) if (!is_seed()) { +#ifndef TORRENT_DISABLE_SUPERSEEDING // turn off super seeding if we're not a seed if (m_super_seeding) { @@ -7597,6 +7618,7 @@ bool is_downloading_state(int const st) set_need_save_resume(); state_updated(); } +#endif if (m_state != torrent_status::finished && is_finished()) finished(); diff --git a/test/test_flags.cpp b/test/test_flags.cpp index da70524c5..d7498655c 100644 --- a/test/test_flags.cpp +++ b/test/test_flags.cpp @@ -148,6 +148,7 @@ TORRENT_TEST(flag_auto_managed) test_unset_after_add(torrent_flags::auto_managed); } +#ifndef TORRENT_DISABLE_SUPERSEEDING TORRENT_TEST(flag_super_seeding) { // super-seeding @@ -155,6 +156,7 @@ TORRENT_TEST(flag_super_seeding) test_set_after_add(torrent_flags::super_seeding); test_unset_after_add(torrent_flags::super_seeding); } +#endif TORRENT_TEST(flag_sequential_download) {