fix kludge and down-cast to send upload_only. Promote upload-only to a top-level peer feature

This commit is contained in:
arvidn 2017-09-21 09:57:34 -07:00 committed by Arvid Norberg
parent 1d9b10a32b
commit d22c44c057
6 changed files with 55 additions and 32 deletions

View File

@ -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

View File

@ -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() {}

View File

@ -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;

View File

@ -313,13 +313,17 @@ namespace {
// connections that are still in the handshake
// will send their bitfield when the handshake
// is done
std::shared_ptr<torrent> 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<torrent> 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<torrent> 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;

View File

@ -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<torrent> t = m_torrent.lock();

View File

@ -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<bt_peer_connection*>(p);
std::shared_ptr<peer_connection> 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
}