int piece_manager::async_write( peer_request const& r , 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())); disk_io_job j; j.storage = this; j.action = disk_io_job::write; j.piece = r.piece; j.offset = r.start; j.buffer_size = r.length; j.buffer = buffer.get(); int queue_size = m_io_thread.add_job(j, handler); buffer.release(); return queue_size; }
void on_read_ok_block(std::pair<piece_block, block_entry> b, address a , disk_buffer_holder buffer, int const block_size, disk_job_flags_t , storage_error const& error) { TORRENT_ASSERT(m_torrent.session().is_single_thread()); // ignore read errors if (error) return; hasher h; h.update({buffer.get(), std::size_t(block_size)}); h.update(reinterpret_cast<char const*>(&m_salt), sizeof(m_salt)); sha1_hash const ok_digest = h.final(); if (b.second.digest == ok_digest) return; // find the peer std::pair<peer_list::iterator, peer_list::iterator> range = m_torrent.find_peers(a); if (range.first == range.second) return; torrent_peer* p = nullptr; for (; range.first != range.second; ++range.first) { if (b.second.peer != *range.first) continue; p = *range.first; } if (p == nullptr) return; #ifndef TORRENT_DISABLE_LOGGING if (m_torrent.should_log()) { char const* client = "-"; peer_info info; if (p->connection) { p->connection->get_peer_info(info); client = info.client.c_str(); } m_torrent.debug_log(" BANNING PEER [ p: %d | b: %d | c: %s" " | ok_digest: %s | bad_digest: %s | ip: %s ]" , static_cast<int>(b.first.piece_index), b.first.block_index, client , aux::to_hex(ok_digest).c_str() , aux::to_hex(b.second.digest).c_str() , print_address(p->ip().address()).c_str()); } #endif m_torrent.ban_peer(p); if (p->connection) p->connection->disconnect( errors::peer_banned, operation_t::bittorrent); }