diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index bdef2918a..4b61cce2f 100755 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -458,6 +458,13 @@ namespace libtorrent // test void piece_finished(int index, bool passed_hash_check); void piece_failed(int index); + + // this will restore the piece picker state for a piece + // by re marking all the requests to blocks in this piece + // that are still outstanding in peers' download queues. + // this is done when a piece fails + void restore_piece_state(int index); + void received_redundant_data(int num_bytes) { TORRENT_ASSERT(num_bytes > 0); m_total_redundant_bytes += num_bytes; } diff --git a/libtorrent/include/libtorrent/version.hpp b/libtorrent/include/libtorrent/version.hpp index de1b8bcc8..c2cc705eb 100755 --- a/libtorrent/include/libtorrent/version.hpp +++ b/libtorrent/include/libtorrent/version.hpp @@ -36,6 +36,6 @@ POSSIBILITY OF SUCH DAMAGE. #define LIBTORRENT_VERSION_MAJOR 0 #define LIBTORRENT_VERSION_MINOR 13 -#define LIBTORRENT_VERSION "0.13.0.0" +#define LIBTORRENT_VERSION "0.13.1.0" #endif diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index d07ed5dee..0632e2cb9 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -53,6 +53,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/socket_type.hpp" #include "libtorrent/assert.hpp" +//#define TORRENT_CORRUPT_DATA + using boost::bind; using boost::shared_ptr; using libtorrent::aux::session_impl; @@ -1271,6 +1273,15 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); TORRENT_ASSERT(t); +#ifdef TORRENT_CORRUPT_DATA + // corrupt all pieces from certain peers + if (m_remote.address().is_v4() + && (m_remote.address().to_v4().to_ulong() & 0xf) == 0) + { + const_cast(data[0]) = ~data[0]; + } +#endif + #ifndef TORRENT_DISABLE_EXTENSIONS for (extension_list_t::iterator i = m_extensions.begin() , end(m_extensions.end()); i != end; ++i) diff --git a/libtorrent/src/piece_picker.cpp b/libtorrent/src/piece_picker.cpp index 9bd02f3c4..dafca67d2 100755 --- a/libtorrent/src/piece_picker.cpp +++ b/libtorrent/src/piece_picker.cpp @@ -1731,12 +1731,17 @@ namespace libtorrent TORRENT_ASSERT(block.piece_index < (int)m_piece_map.size()); TORRENT_ASSERT(block.block_index < blocks_in_piece(block.piece_index)); + // this might be the case if a piece fails, is restored, and then + // completed from a different peer (from which the piece was requested + // before it failed the hash check) + TORRENT_ASSERT(m_piece_map[block.piece_index].downloading); std::vector::iterator i = std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index)); TORRENT_ASSERT(i != m_downloads.end()); block_info& info = i->info[block.block_index]; + info.peer = peer; TORRENT_ASSERT(info.state == block_info::state_requested); if (info.state == block_info::state_requested) --i->requested; diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 983778c94..a28916c60 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -1084,12 +1084,39 @@ namespace libtorrent // start with redownloading the pieces that the client // that has sent the least number of pieces m_picker->restore_piece(index); + restore_piece_state(index); TORRENT_ASSERT(m_storage); m_storage->mark_failed(index); TORRENT_ASSERT(m_have_pieces[index] == false); } + void torrent::restore_piece_state(int index) + { + TORRENT_ASSERT(has_picker()); + for (peer_iterator i = m_connections.begin(); + i != m_connections.end(); ++i) + { + peer_connection* p = *i; + std::deque const& dq = p->download_queue(); + std::deque const& rq = p->request_queue(); + for (std::deque::const_iterator k = dq.begin() + , end(dq.end()); k != end; ++k) + { + if (k->piece_index != index) continue; + m_picker->mark_as_downloading(*k, p->peer_info_struct() + , (piece_picker::piece_state_t)p->peer_speed()); + } + for (std::deque::const_iterator k = rq.begin() + , end(rq.end()); k != end; ++k) + { + if (k->piece_index != index) continue; + m_picker->mark_as_downloading(*k, p->peer_info_struct() + , (piece_picker::piece_state_t)p->peer_speed()); + } + } + } + void torrent::abort() { INVARIANT_CHECK;