From f8e72650bd120ab4dee07afff5a3499b662e9a3d Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 25 Feb 2009 05:53:24 +0000 Subject: [PATCH] fixed #488 --- ChangeLog | 1 + include/libtorrent/policy.hpp | 2 ++ src/smart_ban.cpp | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d767d95c..69693d964 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,7 @@ release 0.14.3 * fixed bug where web seeds would be connected before the files were checked * fixed filename bug when using wide characters + * fixed rare crash in peer banning code release 0.14.2 diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index 62d165b77..c510b87c1 100644 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -246,6 +246,8 @@ namespace libtorrent iterator end_peer() { return m_peers.end(); } const_iterator begin_peer() const { return m_peers.begin(); } const_iterator end_peer() const { return m_peers.end(); } + std::pair find_peers(address const& a) + { return m_peers.equal_range(a); } bool connect_one_peer(); diff --git a/src/smart_ban.cpp b/src/smart_ban.cpp index 8e7bc90b4..383030c2c 100644 --- a/src/smart_ban.cpp +++ b/src/smart_ban.cpp @@ -142,7 +142,7 @@ namespace libtorrent { namespace if (*i != 0) { m_torrent.filesystem().async_read(r, bind(&smart_ban_plugin::on_read_failed_block - , shared_from_this(), pb, (policy::peer*)*i, _1, _2)); + , shared_from_this(), pb, ((policy::peer*)*i)->addr, _1, _2)); } r.start += 16*1024; @@ -163,9 +163,8 @@ namespace libtorrent { namespace unsigned long crc; }; - void on_read_failed_block(piece_block b, policy::peer* p, int ret, disk_io_job const& j) + void on_read_failed_block(piece_block b, address a, int ret, disk_io_job const& j) { - TORRENT_ASSERT(p); // ignore read errors if (ret != j.buffer_size) return; @@ -173,13 +172,21 @@ namespace libtorrent { namespace crc.update(j.buffer, j.buffer_size); crc.update((char const*)&m_salt, sizeof(m_salt)); - block_entry e = {p, crc.final()}; - // since this callback is called directory from the disk io // thread, the session mutex is not locked when we get here aux::session_impl::mutex_t::scoped_lock l(m_torrent.session().m_mutex); + std::pair range + = m_torrent.get_policy().find_peers(a); + + // there is no peer with this address anymore + if (range.first == range.second) return; + + policy::peer* p = &range.first->second; + block_entry e = {p, crc.final()}; + std::map::iterator i = m_block_crc.lower_bound(b); + if (i != m_block_crc.end() && i->first == b && i->second.peer == p) { // this peer has sent us this block before @@ -189,7 +196,6 @@ namespace libtorrent { namespace // from the first time it sent it // at least one of them must be bad - if (p == 0) return; if (!m_torrent.get_policy().has_peer(p)) return; #ifdef TORRENT_LOGGING