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

2
libtorrent/src/disk_io_thread.cpp

@ -2205,7 +2205,7 @@ namespace libtorrent
mutex::scoped_lock l(m_piece_mutex); mutex::scoped_lock l(m_piece_mutex);
INVARIANT_CHECK; 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& idx = m_pieces.get<0>();
cache_piece_index_t::iterator i = find_cached_piece(m_pieces, j, l); cache_piece_index_t::iterator i = find_cached_piece(m_pieces, j, l);
if (i != idx.end()) 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
#endif #endif
printf("node_impl::announce '%s' host: %s:%d myself=%d\n", trackerName.c_str(), addr.to_string().c_str(), listen_port, myself); 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. // do not announce other peers, just add them to our local m_map.
if( myself ) { if( myself ) {
@ -1239,6 +1241,8 @@ void node_impl::incoming_request(msg const& m, entry& e)
if( msg_keys[mk_r]->string_value() == "tracker" ) { if( msg_keys[mk_r]->string_value() == "tracker" ) {
lookup_peers(target, 20, reply, false, false); lookup_peers(target, 20, reply, false, false);
entry::list_type& pe = reply["values"].list();
printf("tracker=> replying with %d peers\n", pe.size());
} else { } else {
dht_storage_table_t::iterator i = m_storage_table.find(target); dht_storage_table_t::iterator i = m_storage_table.find(target);
if (i != m_storage_table.end()) if (i != m_storage_table.end())

25
libtorrent/src/peer_connection.cpp

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

1
libtorrent/src/storage.cpp

@ -865,6 +865,7 @@ namespace libtorrent
, disk_buffer_holder& buffer , disk_buffer_holder& buffer
, boost::function<void(int, disk_io_job const&)> const& handler) , 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); TORRENT_ASSERT(r.length <= 16 * 1024);
// the buffer needs to be allocated through the io_thread // the buffer needs to be allocated through the io_thread
TORRENT_ASSERT(m_io_thread.is_disk_buffer(buffer.get())); TORRENT_ASSERT(m_io_thread.is_disk_buffer(buffer.get()));

48
libtorrent/src/torrent.cpp

@ -1101,12 +1101,11 @@ namespace libtorrent
{ {
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
//[MF] increase num pieces to ensure we are not a seeder //[MF] increase num pieces to ensure we are not a seeder
increase_num_pieces(piece+2); increase_num_pieces(piece+2);
TORRENT_ASSERT(piece >= 0 && piece < m_torrent_file->num_pieces()); TORRENT_ASSERT(piece >= 0 && piece < m_torrent_file->num_pieces());
int piece_size = size; int piece_size = size;
int blocks_in_piece = (piece_size + block_size() - 1) / block_size();
// avoid crash trying to access the picker when there is none // avoid crash trying to access the picker when there is none
if (!has_picker()) return; if (!has_picker()) return;
@ -1119,36 +1118,33 @@ namespace libtorrent
p.piece = piece; p.piece = piece;
p.start = 0; p.start = 0;
picker().inc_refcount(piece, 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())); p.length = piece_size;
char* buffer = m_ses.allocate_disk_buffer("add piece"); char* buffer = m_ses.allocate_disk_buffer("add piece");
// out of memory // out of memory
if (buffer == 0) if (buffer == 0)
{ {
picker().dec_refcount(piece, 0); picker().dec_refcount(piece, 0);
return; 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);
} }
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 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); picker().dec_refcount(piece, 0);
} }
void torrent::on_disk_write_complete(int ret, disk_io_job const& j void torrent::on_disk_write_complete(int ret, disk_io_job const& j
, peer_request p) , peer_request p)
{ {
//printf("on_disk_write_complete: size %d\n", j.buffer_size);
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -2113,7 +2109,7 @@ namespace libtorrent
policy::peer const* p = *i; policy::peer const* p = *i;
if( p->connectable && !p->banned ) { 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 , p->address(), p->port, p->seed, false
, boost::bind(&nop)); , boost::bind(&nop));
} }

1
src/twister.cpp

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

Loading…
Cancel
Save