mirror of
https://github.com/transmission/transmission
synced 2025-03-13 07:33:02 +00:00
fix: use message id to check for pex and metadata xfer support (#7177)
* refactor: use metadata id to check for ut metadata support * refactor: use pex id to check for ut pex support * refactor: start pex timer after ltep handshake * refactor: harden metadata xfer sanity checks * code review: constexpr * code review: don't save peer ut_pex_id and ut_metadata_id if on private torrent
This commit is contained in:
parent
0518a2269e
commit
8c18cf4245
1 changed files with 25 additions and 24 deletions
|
@ -308,12 +308,6 @@ public:
|
||||||
, callback_{ callback }
|
, callback_{ callback }
|
||||||
, callback_data_{ callback_data }
|
, callback_data_{ callback_data }
|
||||||
{
|
{
|
||||||
if (tor_.allows_pex())
|
|
||||||
{
|
|
||||||
pex_timer_ = session->timerMaker().create([this]() { send_ut_pex(); });
|
|
||||||
pex_timer_->start_repeating(SendPexInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io_->supports_ltep())
|
if (io_->supports_ltep())
|
||||||
{
|
{
|
||||||
send_ltep_handshake();
|
send_ltep_handshake();
|
||||||
|
@ -591,6 +585,11 @@ private:
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool can_xfer_metadata() const noexcept
|
||||||
|
{
|
||||||
|
return tor_.is_public() && ut_metadata_id_ != 0U;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::optional<int64_t> pop_next_metadata_request()
|
[[nodiscard]] std::optional<int64_t> pop_next_metadata_request()
|
||||||
{
|
{
|
||||||
auto& reqs = peer_requested_metadata_pieces_;
|
auto& reqs = peer_requested_metadata_pieces_;
|
||||||
|
@ -618,6 +617,12 @@ private:
|
||||||
void parse_ut_pex(MessageReader& payload);
|
void parse_ut_pex(MessageReader& payload);
|
||||||
void parse_ltep(MessageReader& payload);
|
void parse_ltep(MessageReader& payload);
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool can_send_ut_pex() const noexcept
|
||||||
|
{
|
||||||
|
// only send pex if both the torrent and peer support it
|
||||||
|
return tor_.allows_pex() && ut_pex_id_ != 0U;
|
||||||
|
}
|
||||||
|
|
||||||
void send_ut_pex();
|
void send_ut_pex();
|
||||||
|
|
||||||
int client_got_block(std::unique_ptr<Cache::BlockData> block_data, tr_block_index_t block);
|
int client_got_block(std::unique_ptr<Cache::BlockData> block_data, tr_block_index_t block);
|
||||||
|
@ -689,8 +694,6 @@ private:
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
bool peer_supports_pex_ = false;
|
|
||||||
bool peer_supports_metadata_xfer_ = false;
|
|
||||||
bool client_sent_ltep_handshake_ = false;
|
bool client_sent_ltep_handshake_ = false;
|
||||||
|
|
||||||
size_t desired_request_count_ = 0;
|
size_t desired_request_count_ = 0;
|
||||||
|
@ -933,19 +936,19 @@ void tr_peerMsgsImpl::parse_ltep(MessageReader& payload)
|
||||||
// in the reserved bytes of the BT handshake.
|
// in the reserved bytes of the BT handshake.
|
||||||
send_ltep_handshake();
|
send_ltep_handshake();
|
||||||
|
|
||||||
if (io_->supports_ltep())
|
if (can_send_ut_pex())
|
||||||
{
|
{
|
||||||
|
pex_timer_ = session->timerMaker().create([this]() { send_ut_pex(); });
|
||||||
|
pex_timer_->start_repeating(SendPexInterval);
|
||||||
send_ut_pex();
|
send_ut_pex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ltep_msgid == UT_PEX_ID)
|
else if (ltep_msgid == UT_PEX_ID)
|
||||||
{
|
{
|
||||||
peer_supports_pex_ = true;
|
|
||||||
parse_ut_pex(payload);
|
parse_ut_pex(payload);
|
||||||
}
|
}
|
||||||
else if (ltep_msgid == UT_METADATA_ID)
|
else if (ltep_msgid == UT_METADATA_ID)
|
||||||
{
|
{
|
||||||
peer_supports_metadata_xfer_ = true;
|
|
||||||
parse_ut_metadata(payload);
|
parse_ut_metadata(payload);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1005,8 +1008,7 @@ void tr_peerMsgsImpl::parse_ut_pex(MessageReader& payload)
|
||||||
|
|
||||||
void tr_peerMsgsImpl::send_ut_pex()
|
void tr_peerMsgsImpl::send_ut_pex()
|
||||||
{
|
{
|
||||||
// only send pex if both the torrent and peer support it
|
if (!can_send_ut_pex())
|
||||||
if (!peer_supports_pex_ || !tor_.allows_pex())
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1232,22 +1234,20 @@ void tr_peerMsgsImpl::parse_ltep_handshake(MessageReader& payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check supported messages for utorrent pex
|
// check supported messages for utorrent pex
|
||||||
peer_supports_pex_ = false;
|
|
||||||
peer_supports_metadata_xfer_ = false;
|
|
||||||
auto holepunch_supported = false;
|
auto holepunch_supported = false;
|
||||||
|
|
||||||
if (tr_variant* sub = nullptr; tr_variantDictFindDict(&*var, TR_KEY_m, &sub))
|
if (tr_variant* sub = nullptr; tr_variantDictFindDict(&*var, TR_KEY_m, &sub))
|
||||||
{
|
{
|
||||||
if (auto ut_pex = int64_t{}; tr_variantDictFindInt(sub, TR_KEY_ut_pex, &ut_pex))
|
auto const tor_is_public = tor_.is_public();
|
||||||
|
|
||||||
|
if (auto ut_pex = int64_t{}; tor_is_public && tr_variantDictFindInt(sub, TR_KEY_ut_pex, &ut_pex))
|
||||||
{
|
{
|
||||||
peer_supports_pex_ = ut_pex != 0;
|
|
||||||
ut_pex_id_ = static_cast<uint8_t>(ut_pex);
|
ut_pex_id_ = static_cast<uint8_t>(ut_pex);
|
||||||
logtrace(this, fmt::format("msgs->ut_pex is {:d}", ut_pex_id_));
|
logtrace(this, fmt::format("msgs->ut_pex is {:d}", ut_pex_id_));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto ut_metadata = int64_t{}; tr_variantDictFindInt(sub, TR_KEY_ut_metadata, &ut_metadata))
|
if (auto ut_metadata = int64_t{}; tor_is_public && tr_variantDictFindInt(sub, TR_KEY_ut_metadata, &ut_metadata))
|
||||||
{
|
{
|
||||||
peer_supports_metadata_xfer_ = ut_metadata != 0;
|
|
||||||
ut_metadata_id_ = static_cast<uint8_t>(ut_metadata);
|
ut_metadata_id_ = static_cast<uint8_t>(ut_metadata);
|
||||||
logtrace(this, fmt::format("msgs->ut_metadata_id_ is {:d}", ut_metadata_id_));
|
logtrace(this, fmt::format("msgs->ut_metadata_id_ is {:d}", ut_metadata_id_));
|
||||||
}
|
}
|
||||||
|
@ -1271,11 +1271,11 @@ void tr_peerMsgsImpl::parse_ltep_handshake(MessageReader& payload)
|
||||||
|
|
||||||
// look for metainfo size (BEP 9)
|
// look for metainfo size (BEP 9)
|
||||||
if (auto metadata_size = int64_t{};
|
if (auto metadata_size = int64_t{};
|
||||||
peer_supports_metadata_xfer_ && tr_variantDictFindInt(&*var, TR_KEY_metadata_size, &metadata_size))
|
can_xfer_metadata() && tr_variantDictFindInt(&*var, TR_KEY_metadata_size, &metadata_size))
|
||||||
{
|
{
|
||||||
if (!tr_metadata_download::is_valid_metadata_size(metadata_size))
|
if (!tr_metadata_download::is_valid_metadata_size(metadata_size))
|
||||||
{
|
{
|
||||||
peer_supports_metadata_xfer_ = false;
|
ut_metadata_id_ = 0U;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1366,9 +1366,10 @@ void tr_peerMsgsImpl::parse_ut_metadata(MessageReader& payload_in)
|
||||||
|
|
||||||
if (msg_type == MetadataMsgType::Request)
|
if (msg_type == MetadataMsgType::Request)
|
||||||
{
|
{
|
||||||
if (piece >= 0 && tor_.has_metainfo() && tor_.is_public() && std::size(peer_requested_metadata_pieces_) < MetadataReqQ)
|
auto& reqs = peer_requested_metadata_pieces_;
|
||||||
|
if (piece >= 0 && tor_.has_metainfo() && can_xfer_metadata() && std::size(reqs) < MetadataReqQ)
|
||||||
{
|
{
|
||||||
peer_requested_metadata_pieces_.push(piece);
|
reqs.push(piece);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1845,7 +1846,7 @@ void tr_peerMsgsImpl::pulse()
|
||||||
|
|
||||||
void tr_peerMsgsImpl::maybe_send_metadata_requests(time_t now) const
|
void tr_peerMsgsImpl::maybe_send_metadata_requests(time_t now) const
|
||||||
{
|
{
|
||||||
if (!peer_supports_metadata_xfer_)
|
if (!can_xfer_metadata())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue