added support for torrents with odd piece sizes
This commit is contained in:
parent
5c5f1d23a9
commit
eff49e42a7
|
@ -106,7 +106,7 @@
|
|||
* improved LSD performance and made the interval configurable
|
||||
* improved UDP tracker support by caching connect tokens
|
||||
* fast piece optimization
|
||||
* fixed error handling with torrents with invalid piece sizes
|
||||
* added support for torrents with odd piece sizes
|
||||
* fixed issue with disk read cache not being cleared when removing torrents
|
||||
|
||||
release 0.14.9
|
||||
|
|
|
@ -6275,8 +6275,7 @@ code symbol description
|
|||
------ ----------------------------------------- -----------------------------------------------------------------
|
||||
81 packet_too_large The packet size exceeded the upper sanity check-limit
|
||||
------ ----------------------------------------- -----------------------------------------------------------------
|
||||
82 torrent_invalid_piece_size The .torrent file has an invalid piece size. It needs to be an
|
||||
even 16 kiB multiple
|
||||
82 reserved
|
||||
------ ----------------------------------------- -----------------------------------------------------------------
|
||||
83 http_error The web server responded with an error
|
||||
------ ----------------------------------------- -----------------------------------------------------------------
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace libtorrent
|
|||
duplicate_peer_id,
|
||||
torrent_removed,
|
||||
packet_too_large,
|
||||
torrent_invalid_piece_size,
|
||||
reserved,
|
||||
http_error,
|
||||
missing_location,
|
||||
invalid_redirection,
|
||||
|
|
|
@ -192,7 +192,7 @@ namespace libtorrent
|
|||
int sparse_regions() const { return m_sparse_regions; }
|
||||
|
||||
// sets all pieces to dont-have
|
||||
void init(int blocks_per_piece, int total_num_blocks);
|
||||
void init(int blocks_per_piece, int blocks_in_last_piece, int total_num_pieces);
|
||||
int num_pieces() const { return int(m_piece_map.size()); }
|
||||
|
||||
bool have_piece(int index) const
|
||||
|
|
|
@ -559,7 +559,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
int block_size() const { TORRENT_ASSERT(m_block_size_shift > 0); return 1 << m_block_size_shift; }
|
||||
peer_request to_req(piece_block const& p);
|
||||
peer_request to_req(piece_block const& p) const;
|
||||
|
||||
void disconnect_all(error_code const& ec);
|
||||
int disconnect_peers(int num);
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace libtorrent
|
|||
"duplicate peer-id",
|
||||
"torrent removed",
|
||||
"packet too large",
|
||||
"invalid piece size in torrent file",
|
||||
"",
|
||||
"HTTP error",
|
||||
"missing location header",
|
||||
"invalid redirection",
|
||||
|
|
|
@ -1037,19 +1037,10 @@ namespace libtorrent
|
|||
torrent_info const& ti = t->torrent_file();
|
||||
|
||||
return p.piece >= 0
|
||||
&& p.piece < t->torrent_file().num_pieces()
|
||||
&& p.length >= 0
|
||||
&& p.piece < ti.num_pieces()
|
||||
&& p.start >= 0
|
||||
&& (p.length == t->block_size()
|
||||
|| (p.length < t->block_size()
|
||||
&& p.piece == ti.num_pieces()-1
|
||||
&& p.start + p.length == ti.piece_size(p.piece))
|
||||
|| (m_request_large_blocks
|
||||
&& p.length <= ti.piece_length() * (m_prefer_whole_pieces == 0 ?
|
||||
1 : m_prefer_whole_pieces)))
|
||||
&& p.piece * size_type(ti.piece_length()) + p.start + p.length
|
||||
<= ti.total_size()
|
||||
&& (p.start % t->block_size() == 0);
|
||||
&& p.start < ti.piece_length()
|
||||
&& t->to_req(piece_block(p.piece, p.start / t->block_size())) == p;
|
||||
}
|
||||
|
||||
void peer_connection::attach_to_torrent(sha1_hash const& ih)
|
||||
|
@ -2088,7 +2079,7 @@ namespace libtorrent
|
|||
if (!t->is_seed())
|
||||
{
|
||||
const int blocks_per_piece = static_cast<int>(
|
||||
t->torrent_file().piece_length() / t->block_size());
|
||||
(t->torrent_file().piece_length() + t->block_size() - 1) / t->block_size());
|
||||
|
||||
std::vector<piece_picker::downloading_piece> const& dl_queue
|
||||
= t->picker().get_download_queue();
|
||||
|
@ -2216,9 +2207,7 @@ namespace libtorrent
|
|||
|
||||
std::vector<piece_block> finished_blocks;
|
||||
piece_block block_finished(p.piece, p.start / t->block_size());
|
||||
TORRENT_ASSERT(p.start % t->block_size() == 0);
|
||||
TORRENT_ASSERT(p.length == t->block_size()
|
||||
|| p.length == t->torrent_file().total_size() % t->block_size());
|
||||
TORRENT_ASSERT(verify_piece(p));
|
||||
|
||||
std::vector<pending_block>::iterator b
|
||||
= std::find_if(
|
||||
|
@ -4967,13 +4956,9 @@ namespace libtorrent
|
|||
in_download_queue = true;
|
||||
outstanding_bytes += p->full_block_bytes - m_received_in_piece;
|
||||
}
|
||||
else if (i->block == last_block)
|
||||
{
|
||||
outstanding_bytes += last_block_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
outstanding_bytes += block_size;
|
||||
outstanding_bytes += t->to_req(i->block).length;
|
||||
}
|
||||
}
|
||||
//if (p && p->bytes_downloaded < p->full_block_bytes) TORRENT_ASSERT(in_download_queue);
|
||||
|
|
|
@ -76,18 +76,17 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
void piece_picker::init(int blocks_per_piece, int total_num_blocks)
|
||||
void piece_picker::init(int blocks_per_piece, int blocks_in_last_piece, int total_num_pieces)
|
||||
{
|
||||
TORRENT_ASSERT(blocks_per_piece > 0);
|
||||
TORRENT_ASSERT(total_num_blocks >= 0);
|
||||
TORRENT_ASSERT(total_num_pieces > 0);
|
||||
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
std::cerr << "piece_picker::init()" << std::endl;
|
||||
#endif
|
||||
// allocate the piece_map to cover all pieces
|
||||
// and make them invalid (as if we don't have a single piece)
|
||||
m_piece_map.resize((total_num_blocks + blocks_per_piece-1) / blocks_per_piece
|
||||
, piece_pos(0, 0));
|
||||
m_piece_map.resize(total_num_pieces, piece_pos(0, 0));
|
||||
m_reverse_cursor = int(m_piece_map.size());
|
||||
m_cursor = 0;
|
||||
|
||||
|
@ -118,7 +117,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_piece_map.size() < piece_pos::we_have_index);
|
||||
|
||||
m_blocks_per_piece = blocks_per_piece;
|
||||
m_blocks_in_last_piece = total_num_blocks % blocks_per_piece;
|
||||
m_blocks_in_last_piece = blocks_in_last_piece;
|
||||
if (m_blocks_in_last_piece == 0) m_blocks_in_last_piece = blocks_per_piece;
|
||||
|
||||
TORRENT_ASSERT(m_blocks_in_last_piece <= m_blocks_per_piece);
|
||||
|
|
|
@ -744,7 +744,7 @@ namespace libtorrent
|
|||
return m_torrent_file->add_merkle_nodes(nodes, piece);
|
||||
}
|
||||
|
||||
peer_request torrent::to_req(piece_block const& p)
|
||||
peer_request torrent::to_req(piece_block const& p) const
|
||||
{
|
||||
int block_offset = p.block_index * block_size();
|
||||
int block = (std::min)(torrent_file().piece_size(
|
||||
|
@ -817,14 +817,6 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_torrent_file->piece_length() % block_size() != 0)
|
||||
{
|
||||
// TODO: try to adjust the block size
|
||||
set_error(errors::torrent_invalid_piece_size, "");
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// the shared_from_this() will create an intentional
|
||||
// cycle of ownership, se the hpp file for description.
|
||||
m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file
|
||||
|
@ -834,8 +826,10 @@ namespace libtorrent
|
|||
|
||||
if (has_picker())
|
||||
{
|
||||
m_picker->init((std::max)(m_torrent_file->piece_length() / block_size(), 1)
|
||||
, int((m_torrent_file->total_size()+block_size()-1) / block_size()));
|
||||
int blocks_per_piece = (m_torrent_file->piece_length() + block_size() - 1) / block_size();
|
||||
int blocks_in_last_piece = ((m_torrent_file->total_size() % m_torrent_file->piece_length())
|
||||
+ block_size() - 1) / block_size();
|
||||
m_picker->init(blocks_per_piece, blocks_in_last_piece, m_torrent_file->num_pieces());
|
||||
}
|
||||
|
||||
std::vector<std::string> const& url_seeds = m_torrent_file->url_seeds();
|
||||
|
@ -1153,8 +1147,11 @@ namespace libtorrent
|
|||
m_owning_storage->async_release_files();
|
||||
if (!m_picker) m_picker.reset(new piece_picker());
|
||||
std::fill(m_file_progress.begin(), m_file_progress.end(), 0);
|
||||
m_picker->init(m_torrent_file->piece_length() / block_size()
|
||||
, int((m_torrent_file->total_size() + block_size()-1)/block_size()));
|
||||
|
||||
int blocks_per_piece = (m_torrent_file->piece_length() + block_size() - 1) / block_size();
|
||||
int blocks_in_last_piece = ((m_torrent_file->total_size() % m_torrent_file->piece_length())
|
||||
+ block_size() - 1) / block_size();
|
||||
m_picker->init(blocks_per_piece, blocks_in_last_piece, m_torrent_file->num_pieces());
|
||||
// assume that we don't have anything
|
||||
TORRENT_ASSERT(m_picker->num_have() == 0);
|
||||
m_files_checked = false;
|
||||
|
@ -1972,11 +1969,8 @@ namespace libtorrent
|
|||
}
|
||||
#ifdef TORRENT_DEBUG
|
||||
TORRENT_ASSERT(p->bytes_downloaded <= p->full_block_bytes);
|
||||
if (p->piece_index == last_piece_index
|
||||
&& p->block_index == m_torrent_file->piece_size(last_piece) / block_size())
|
||||
TORRENT_ASSERT(p->full_block_bytes == m_torrent_file->piece_size(last_piece) % block_size());
|
||||
else
|
||||
TORRENT_ASSERT(p->full_block_bytes == block_size());
|
||||
TORRENT_ASSERT(p->full_block_bytes == to_req(piece_block(
|
||||
p->piece_index, p->block_index)).length);
|
||||
#endif
|
||||
}
|
||||
for (std::map<piece_block, int>::iterator i = downloading_piece.begin();
|
||||
|
@ -4856,7 +4850,6 @@ namespace libtorrent
|
|||
if (m_files_checked && valid_metadata())
|
||||
{
|
||||
TORRENT_ASSERT(block_size() > 0);
|
||||
TORRENT_ASSERT((m_torrent_file->piece_length() & (block_size()-1)) == 0);
|
||||
}
|
||||
// if (is_seed()) TORRENT_ASSERT(m_picker.get() == 0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue