mirror of
https://github.com/transmission/transmission.git
synced 2025-12-19 18:08:31 +00:00
fix: check if piece is wanted upon receiving block (#7866)
* fix: check if piece is wanted upon receiving block * test: block_last_loc
This commit is contained in:
@@ -97,6 +97,12 @@ public:
|
||||
return byte_loc(uint64_t{ block } * BlockSize);
|
||||
}
|
||||
|
||||
// Location of the last byte in `block`.
|
||||
[[nodiscard]] constexpr auto block_last_loc(tr_block_index_t const block) const noexcept
|
||||
{
|
||||
return byte_loc((uint64_t{ block } * BlockSize) + block_size(block) - 1U);
|
||||
}
|
||||
|
||||
// Location of the first byte (+ optional offset and length) in `piece`
|
||||
[[nodiscard]] constexpr auto piece_loc(tr_piece_index_t piece, uint32_t offset = {}, uint32_t length = {}) const noexcept
|
||||
{
|
||||
|
||||
@@ -1688,18 +1688,22 @@ ReadResult tr_peerMsgsImpl::read_piece_data(MessageReader& payload)
|
||||
return { ReadState::Err, len };
|
||||
}
|
||||
|
||||
if (!active_requests.test(block))
|
||||
{
|
||||
logwarn(this, fmt::format("got unrequested block {:d} ({:d}:{:d}->{:d})", block, piece, offset, len));
|
||||
return { ReadState::Err, len };
|
||||
}
|
||||
|
||||
if (tor_.has_block(block))
|
||||
{
|
||||
logtrace(this, fmt::format("got completed block {:d} ({:d}:{:d}->{:d})", block, piece, offset, len));
|
||||
return { ReadState::Err, len };
|
||||
}
|
||||
|
||||
if (auto const block_loc = tor_.block_loc(block); !tor_.piece_is_wanted(block_loc.piece))
|
||||
{
|
||||
if (auto const block_last_loc = tor_.block_last_loc(block);
|
||||
block_loc.piece == block_last_loc.piece || !tor_.piece_is_wanted(block_last_loc.piece))
|
||||
{
|
||||
logwarn(this, fmt::format("got unwanted block {:d} ({:d}:{:d}->{:d})", block, piece, offset, len));
|
||||
return { ReadState::Err, len };
|
||||
}
|
||||
}
|
||||
|
||||
peer_info->set_latest_piece_data_time(tr_time());
|
||||
bytes_sent_to_client.add(tr_time(), len);
|
||||
publish(tr_peer_event::GotPieceData(len));
|
||||
|
||||
@@ -79,6 +79,10 @@ public:
|
||||
{
|
||||
return block_info().block_loc(block);
|
||||
}
|
||||
[[nodiscard]] constexpr auto block_last_loc(tr_block_index_t block) const noexcept
|
||||
{
|
||||
return block_info().block_last_loc(block);
|
||||
}
|
||||
[[nodiscard]] constexpr auto piece_loc(tr_piece_index_t piece, uint32_t offset = 0, uint32_t length = 0) const noexcept
|
||||
{
|
||||
return block_info().piece_loc(piece, offset, length);
|
||||
|
||||
@@ -267,6 +267,10 @@ struct tr_torrent
|
||||
{
|
||||
return metainfo_.block_loc(block);
|
||||
}
|
||||
[[nodiscard]] constexpr auto block_last_loc(tr_block_index_t block) const noexcept
|
||||
{
|
||||
return metainfo_.block_last_loc(block);
|
||||
}
|
||||
[[nodiscard]] constexpr auto piece_loc(tr_piece_index_t piece, uint32_t offset = 0, uint32_t length = 0) const noexcept
|
||||
{
|
||||
return metainfo_.piece_loc(piece, offset, length);
|
||||
|
||||
@@ -136,6 +136,41 @@ TEST_F(BlockInfoTest, blockLoc)
|
||||
EXPECT_EQ(0U, loc.piece_offset);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, blockLastLoc)
|
||||
{
|
||||
static auto constexpr ExpectedBlockSize = uint64_t{ 1024U } * 16U;
|
||||
static auto constexpr ExpectedBlocksPerPiece = uint64_t{ 4U };
|
||||
static auto constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
static auto constexpr PieceCount = uint64_t{ 5U };
|
||||
static auto constexpr TotalSize = (PieceSize * (PieceCount - 1U)) + 1U;
|
||||
|
||||
auto const info = tr_block_info{ TotalSize, PieceSize };
|
||||
|
||||
// begin
|
||||
auto loc = info.block_last_loc(0);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1U, loc.byte);
|
||||
EXPECT_EQ(0U, loc.block);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1U, loc.block_offset);
|
||||
EXPECT_EQ(0U, loc.piece);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1U, loc.piece_offset);
|
||||
|
||||
// third block is halfway through the first piece
|
||||
loc = info.block_last_loc(2);
|
||||
EXPECT_EQ((ExpectedBlockSize * 3U) - 1U, loc.byte);
|
||||
EXPECT_EQ(2U, loc.block);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1U, loc.block_offset);
|
||||
EXPECT_EQ(0U, loc.piece);
|
||||
EXPECT_EQ((ExpectedBlockSize * 3U) - 1U, loc.piece_offset);
|
||||
|
||||
// second piece aligns with fifth block
|
||||
loc = info.block_last_loc(4);
|
||||
EXPECT_EQ(PieceSize + ExpectedBlockSize - 1U, loc.byte);
|
||||
EXPECT_EQ(4U, loc.block);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1U, loc.block_offset);
|
||||
EXPECT_EQ(1U, loc.piece);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1U, loc.piece_offset);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, pieceLoc)
|
||||
{
|
||||
static auto constexpr ExpectedBlockSize = uint64_t{ 1024U } * 16U;
|
||||
|
||||
Reference in New Issue
Block a user