Browse Source

allow bitfield with different number of pieces

miguelfreitas
Miguel Freitas 11 years ago
parent
commit
cefb94e321
  1. 4
      libtorrent/src/bt_peer_connection.cpp
  2. 2
      libtorrent/src/disk_io_thread.cpp
  3. 6
      libtorrent/src/kademlia/node.cpp
  4. 25
      libtorrent/src/peer_connection.cpp
  5. 1
      libtorrent/src/storage.cpp
  6. 48
      libtorrent/src/torrent.cpp
  7. 1
      src/twister.cpp

4
libtorrent/src/bt_peer_connection.cpp

@ -973,12 +973,14 @@ namespace libtorrent @@ -973,12 +973,14 @@ namespace libtorrent
m_statistics.received_bytes(0, received);
// if we don't have the metedata, we cannot
// verify the bitfield size
/* [MF] size may differ - client may know a different number of pieces
if (t->valid_metadata()
&& packet_size() - 1 != (t->torrent_file().num_pieces() + 7) / 8)
{
disconnect(errors::invalid_bitfield_size, 2);
return;
}
*/
if (!packet_finished()) return;
@ -986,7 +988,7 @@ namespace libtorrent @@ -986,7 +988,7 @@ namespace libtorrent
bitfield bits;
bits.borrow_bytes((char*)recv_buffer.begin + 1
, t->valid_metadata()?get_bitfield().size():(packet_size()-1)*8);
, (packet_size()-1)*8);
incoming_bitfield(bits);
}

2
libtorrent/src/disk_io_thread.cpp

@ -2205,7 +2205,7 @@ namespace libtorrent @@ -2205,7 +2205,7 @@ namespace libtorrent
mutex::scoped_lock l(m_piece_mutex);
INVARIANT_CHECK;
printf("disk_io_thread:hash for piece %d hash\n", j.piece);
//printf("disk_io_thread:hash for piece %d hash\n", j.piece);
cache_piece_index_t& idx = m_pieces.get<0>();
cache_piece_index_t::iterator i = find_cached_piece(m_pieces, j, l);
if (i != idx.end())

6
libtorrent/src/kademlia/node.cpp

@ -406,7 +406,9 @@ void node_impl::announce(std::string const& trackerName, sha1_hash const& info_h @@ -406,7 +406,9 @@ void node_impl::announce(std::string const& trackerName, sha1_hash const& info_h
#endif
printf("node_impl::announce '%s' host: %s:%d myself=%d\n", trackerName.c_str(), addr.to_string().c_str(), listen_port, myself);
add_peer( trackerName, info_hash, addr, listen_port, seed );
if( !addr.is_unspecified() ) {
add_peer( trackerName, info_hash, addr, listen_port, seed );
}
// do not announce other peers, just add them to our local m_map.
if( myself ) {
@ -1239,6 +1241,8 @@ void node_impl::incoming_request(msg const& m, entry& e) @@ -1239,6 +1241,8 @@ void node_impl::incoming_request(msg const& m, entry& e)
if( msg_keys[mk_r]->string_value() == "tracker" ) {
lookup_peers(target, 20, reply, false, false);
entry::list_type& pe = reply["values"].list();
printf("tracker=> replying with %d peers\n", pe.size());
} else {
dht_storage_table_t::iterator i = m_storage_table.find(target);
if (i != m_storage_table.end())

25
libtorrent/src/peer_connection.cpp

@ -539,7 +539,7 @@ namespace libtorrent @@ -539,7 +539,7 @@ namespace libtorrent
char buf[450];
snprintf(buf, sizeof(buf), "%s: %s\n", time_now_string(), usr);
//(*m_logger) << buf;
//printf(buf);
printf(buf);
}
#endif
@ -1767,13 +1767,16 @@ namespace libtorrent @@ -1767,13 +1767,16 @@ namespace libtorrent
// --------- BITFIELD ----------
// -----------------------------
void peer_connection::incoming_bitfield(bitfield const& bits)
void peer_connection::incoming_bitfield(bitfield const& origbits)
{
INVARIANT_CHECK;
boost::shared_ptr<torrent> t = m_torrent.lock();
TORRENT_ASSERT(t);
// [MF] do a deep copy (sorry) - needed for resize below
bitfield bits(origbits);
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i)
@ -1794,11 +1797,19 @@ namespace libtorrent @@ -1794,11 +1797,19 @@ namespace libtorrent
// if we don't have the metedata, we cannot
// verify the bitfield size
if (t->valid_metadata()
&& (bits.size() + 7) / 8 != (m_have_piece.size() + 7) / 8)
{
disconnect(errors::invalid_bitfield_size, 2);
return;
if (t->valid_metadata() &&
bits.size() != t->torrent_file().num_pieces() )
{
if( bits.size() > t->torrent_file().num_pieces() ) {
if(validatePostNumberForUser(t->name(), bits.size())) {
t->increase_num_pieces(bits.size());
} else {
disconnect(errors::invalid_bitfield_size, 2);
return;
}
} else {
bits.resize( t->torrent_file().num_pieces(), false);
}
}
if (m_bitfield_received)

1
libtorrent/src/storage.cpp

@ -865,6 +865,7 @@ namespace libtorrent @@ -865,6 +865,7 @@ namespace libtorrent
, disk_buffer_holder& buffer
, boost::function<void(int, disk_io_job const&)> const& handler)
{
//printf("async_write: piece %d size %d\n", r.piece, r.length );
TORRENT_ASSERT(r.length <= 16 * 1024);
// the buffer needs to be allocated through the io_thread
TORRENT_ASSERT(m_io_thread.is_disk_buffer(buffer.get()));

48
libtorrent/src/torrent.cpp

@ -1101,12 +1101,11 @@ namespace libtorrent @@ -1101,12 +1101,11 @@ namespace libtorrent
{
TORRENT_ASSERT(m_ses.is_network_thread());
//[MF] increase num pieces to ensure we are not a seeder
increase_num_pieces(piece+2);
//[MF] increase num pieces to ensure we are not a seeder
increase_num_pieces(piece+2);
TORRENT_ASSERT(piece >= 0 && piece < m_torrent_file->num_pieces());
int piece_size = size;
int blocks_in_piece = (piece_size + block_size() - 1) / block_size();
int piece_size = size;
// avoid crash trying to access the picker when there is none
if (!has_picker()) return;
@ -1119,36 +1118,33 @@ namespace libtorrent @@ -1119,36 +1118,33 @@ namespace libtorrent
p.piece = piece;
p.start = 0;
picker().inc_refcount(piece, 0);
for (int i = 0; i < blocks_in_piece; ++i, p.start += block_size())
{
if (picker().is_finished(piece_block(piece, i))
&& (flags & torrent::overwrite_existing) == 0)
continue;
p.length = (std::min)(piece_size - p.start, int(block_size()));
char* buffer = m_ses.allocate_disk_buffer("add piece");
// out of memory
if (buffer == 0)
{
picker().dec_refcount(piece, 0);
return;
}
disk_buffer_holder holder(m_ses, buffer);
std::memcpy(buffer, data + p.start, p.length);
filesystem().async_write(p, holder, boost::bind(&torrent::on_disk_write_complete
, shared_from_this(), _1, _2, p));
piece_block block(piece, i);
picker().mark_as_downloading(block, 0, piece_picker::fast);
picker().mark_as_writing(block, 0);
p.length = piece_size;
char* buffer = m_ses.allocate_disk_buffer("add piece");
// out of memory
if (buffer == 0)
{
picker().dec_refcount(piece, 0);
return;
}
disk_buffer_holder holder(m_ses, buffer);
std::memcpy(buffer, data + p.start, p.length);
filesystem().async_write(p, holder, boost::bind(&torrent::on_disk_write_complete
, shared_from_this(), _1, _2, p));
piece_block block(piece, 0);
picker().mark_as_downloading(block, 0, piece_picker::fast);
picker().mark_as_writing(block, 0);
async_verify_piece(piece, boost::bind(&torrent::piece_finished
, shared_from_this(), piece, _1, p.length));
, shared_from_this(), piece, _1, p.length));
picker().dec_refcount(piece, 0);
}
void torrent::on_disk_write_complete(int ret, disk_io_job const& j
, peer_request p)
{
//printf("on_disk_write_complete: size %d\n", j.buffer_size);
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK;
@ -2113,7 +2109,7 @@ namespace libtorrent @@ -2113,7 +2109,7 @@ namespace libtorrent
policy::peer const* p = *i;
if( p->connectable && !p->banned ) {
m_ses.m_dht->announce(name(), m_torrent_file->info_hash()
m_ses.m_dht->announce(name(), m_torrent_file->info_hash()
, p->address(), p->port, p->seed, false
, boost::bind(&nop));
}

1
src/twister.cpp

@ -146,6 +146,7 @@ torrent_handle startTorrentUser(std::string const &username) @@ -146,6 +146,7 @@ torrent_handle startTorrentUser(std::string const &username)
load_file(filename.c_str(), tparams.resume_data, ec);
m_userTorrent[username] = ses->add_torrent(tparams);
m_userTorrent[username].force_dht_announce();
}
return m_userTorrent[username];
}

Loading…
Cancel
Save