From d22c44c057835269023b683739ffef3970a8fb2a Mon Sep 17 00:00:00 2001 From: arvidn Date: Thu, 21 Sep 2017 09:57:34 -0700 Subject: [PATCH] fix kludge and down-cast to send upload_only. Promote upload-only to a top-level peer feature --- include/libtorrent/bt_peer_connection.hpp | 2 +- include/libtorrent/peer_connection.hpp | 2 ++ include/libtorrent/web_connection_base.hpp | 1 + src/bt_peer_connection.cpp | 36 ++++++++++------------ src/peer_connection.cpp | 21 ++++++++++++- src/torrent.cpp | 25 ++++++++------- 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/include/libtorrent/bt_peer_connection.hpp b/include/libtorrent/bt_peer_connection.hpp index b1767daef..c10501c97 100644 --- a/include/libtorrent/bt_peer_connection.hpp +++ b/include/libtorrent/bt_peer_connection.hpp @@ -242,9 +242,9 @@ namespace libtorrent { void write_piece(peer_request const& r, disk_buffer_holder buffer) override; void write_keepalive() override; void write_handshake(); + void write_upload_only(bool enabled) override; #ifndef TORRENT_DISABLE_EXTENSIONS void write_extensions(); - void write_upload_only(); void write_share_mode(); void write_holepunch_msg(int type, tcp::endpoint const& ep, int error); #endif diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 50e89fba3..b860962e2 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -576,6 +576,7 @@ namespace aux { void send_interested(); void send_not_interested(); void send_suggest(piece_index_t piece); + void send_upload_only(bool enabled); void snub_peer(); // reject any request in the request @@ -706,6 +707,7 @@ namespace aux { virtual void write_reject_request(peer_request const& r) = 0; virtual void write_allow_fast(piece_index_t piece) = 0; + virtual void write_upload_only(bool enabled) = 0; virtual void on_connected() = 0; virtual void on_tick() {} diff --git a/include/libtorrent/web_connection_base.hpp b/include/libtorrent/web_connection_base.hpp index ff3f966dc..ac53a65f5 100644 --- a/include/libtorrent/web_connection_base.hpp +++ b/include/libtorrent/web_connection_base.hpp @@ -93,6 +93,7 @@ namespace libtorrent { void write_allow_fast(piece_index_t) override {} void write_suggest(piece_index_t) override {} void write_bitfield() override {} + void write_upload_only(bool) override {} #if TORRENT_USE_INVARIANT_CHECKS void check_invariant() const; diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index db0ba031c..fdeb653d1 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -313,13 +313,17 @@ namespace { // connections that are still in the handshake // will send their bitfield when the handshake // is done + std::shared_ptr t = associated_torrent().lock(); #ifndef TORRENT_DISABLE_EXTENSIONS - write_upload_only(); + if (!t->share_mode()) + { + bool const upload_only_enabled = t->is_upload_only() && !t->super_seeding(); + send_upload_only(upload_only_enabled); + } #endif if (m_sent_bitfield) return; - std::shared_ptr t = associated_torrent().lock(); TORRENT_ASSERT(t); write_bitfield(); TORRENT_ASSERT(m_sent_bitfield); @@ -1902,42 +1906,36 @@ namespace { return finished; } -#ifndef TORRENT_DISABLE_EXTENSIONS - void bt_peer_connection::write_upload_only() + void bt_peer_connection::write_upload_only(bool const enabled) { +#ifndef TORRENT_DISABLE_EXTENSIONS INVARIANT_CHECK; +#if TORRENT_USE_ASSERTS std::shared_ptr t = associated_torrent().lock(); + TORRENT_ASSERT(!t->share_mode()); +#endif + if (m_upload_only_id == 0) return; - if (t->share_mode()) return; // 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 // connections, don't sent upload-only if (!m_settings.get_bool(settings_pack::close_redundant_connections)) return; -#ifndef TORRENT_DISABLE_LOGGING - if (should_log(peer_log_alert::outgoing_message)) - { - peer_log(peer_log_alert::outgoing_message, "UPLOAD_ONLY", "%d" - , int(t->is_upload_only() && !t->super_seeding())); - } -#endif - char msg[7] = {0, 0, 0, 3, msg_extended}; char* ptr = msg + 5; detail::write_uint8(m_upload_only_id, ptr); - // if we're super seeding, we don't want to make peers - // think that we only have a single piece and is upload - // only, since they might disconnect immediately when - // they have downloaded a single piece, although we'll - // make another piece available - detail::write_uint8(t->is_upload_only() && !t->super_seeding(), ptr); + detail::write_uint8(enabled, ptr); send_buffer(msg); stats_counters().inc_stats_counter(counters::num_outgoing_extended); +#else + TORRENT_UNUSED(enabled); +#endif } +#ifndef TORRENT_DISABLE_EXTENSIONS void bt_peer_connection::write_share_mode() { INVARIANT_CHECK; diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 7a815dc2a..5c5f5402e 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -3764,10 +3764,29 @@ namespace libtorrent { m_became_uninteresting = aux::time_now(); #ifndef TORRENT_DISABLE_LOGGING - peer_log(peer_log_alert::outgoing_message, "NOT_INTERESTED"); + if (should_log(peer_log_alert::outgoing_message)) + { + peer_log(peer_log_alert::outgoing_message, "NOT_INTERESTED"); + } #endif } + void peer_connection::send_upload_only(bool const enabled) + { + TORRENT_ASSERT(is_single_thread()); + if (m_connecting || in_handshake()) return; + +#ifndef TORRENT_DISABLE_LOGGING + if (should_log(peer_log_alert::outgoing_message)) + { + peer_log(peer_log_alert::outgoing_message, "UPLOAD_ONLY", "%d" + , int(enabled)); + } +#endif + + write_upload_only(enabled); + } + void peer_connection::send_piece_suggestions(int const num) { std::shared_ptr t = m_torrent.lock(); diff --git a/src/torrent.cpp b/src/torrent.cpp index a49377947..ebe3610b7 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -879,21 +879,24 @@ namespace libtorrent { if (share_mode()) return; if (super_seeding()) return; + // 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 + // connections, don't sent upload-only + if (!settings().get_bool(settings_pack::close_redundant_connections)) return; + + // if we're super seeding, we don't want to make peers + // think that we only have a single piece and is upload + // 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(); + for (auto p : m_connections) { TORRENT_INCREMENT(m_iterating_connections); - if (p->type() != connection_type::bittorrent) - continue; - // TODO: 3 the general peer interface should have a hook to be notified - // of upload only mode to avoid this downcast - bt_peer_connection* btp = static_cast(p); - std::shared_ptr me(btp->self()); - if (!btp->is_disconnecting()) - { - btp->send_not_interested(); - btp->write_upload_only(); - } + p->send_not_interested(); + p->send_upload_only(upload_only_enabled); } #endif }