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_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())
|
||||
{
|
||||
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()
|
||||
{
|
||||
auto& reqs = peer_requested_metadata_pieces_;
|
||||
|
@ -618,6 +617,12 @@ private:
|
|||
void parse_ut_pex(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();
|
||||
|
||||
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;
|
||||
|
||||
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.
|
||||
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();
|
||||
}
|
||||
}
|
||||
else if (ltep_msgid == UT_PEX_ID)
|
||||
{
|
||||
peer_supports_pex_ = true;
|
||||
parse_ut_pex(payload);
|
||||
}
|
||||
else if (ltep_msgid == UT_METADATA_ID)
|
||||
{
|
||||
peer_supports_metadata_xfer_ = true;
|
||||
parse_ut_metadata(payload);
|
||||
}
|
||||
else
|
||||
|
@ -1005,8 +1008,7 @@ void tr_peerMsgsImpl::parse_ut_pex(MessageReader& payload)
|
|||
|
||||
void tr_peerMsgsImpl::send_ut_pex()
|
||||
{
|
||||
// only send pex if both the torrent and peer support it
|
||||
if (!peer_supports_pex_ || !tor_.allows_pex())
|
||||
if (!can_send_ut_pex())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1232,22 +1234,20 @@ void tr_peerMsgsImpl::parse_ltep_handshake(MessageReader& payload)
|
|||
}
|
||||
|
||||
// check supported messages for utorrent pex
|
||||
peer_supports_pex_ = false;
|
||||
peer_supports_metadata_xfer_ = false;
|
||||
auto holepunch_supported = false;
|
||||
|
||||
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);
|
||||
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);
|
||||
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)
|
||||
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))
|
||||
{
|
||||
peer_supports_metadata_xfer_ = false;
|
||||
ut_metadata_id_ = 0U;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1366,9 +1366,10 @@ void tr_peerMsgsImpl::parse_ut_metadata(MessageReader& payload_in)
|
|||
|
||||
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
|
||||
{
|
||||
|
@ -1845,7 +1846,7 @@ void tr_peerMsgsImpl::pulse()
|
|||
|
||||
void tr_peerMsgsImpl::maybe_send_metadata_requests(time_t now) const
|
||||
{
|
||||
if (!peer_supports_metadata_xfer_)
|
||||
if (!can_xfer_metadata())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue