diff --git a/libtorrent/include/libtorrent/aux_/session_impl.hpp b/libtorrent/include/libtorrent/aux_/session_impl.hpp index e3dabcae0..6b76b43f9 100644 --- a/libtorrent/include/libtorrent/aux_/session_impl.hpp +++ b/libtorrent/include/libtorrent/aux_/session_impl.hpp @@ -115,6 +115,7 @@ namespace libtorrent std::vector unfinished_pieces; std::vector block_info; std::vector peers; + std::vector banned_peers; entry resume_data; // this is true if this torrent is being processed (checked) diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index a4d66f79c..209833de5 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -730,6 +730,15 @@ namespace libtorrent << " *** PIECE NOT IN REQUEST QUEUE\n"; } #endif + if (has_peer_choked()) + { + // if we're choked and we got a rejection of + // a piece in the allowed fast set, remove it + // from the allow fast set. + std::vector::iterator i = std::find( + m_allowed_fast.begin(), m_allowed_fast.end(), r.piece); + if (i != m_allowed_fast.end()) m_allowed_fast.erase(i); + } if (m_request_queue.empty()) { if (m_download_queue.size() < 2) diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index e7e9a974a..212e09f3c 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -673,8 +673,11 @@ namespace libtorrent for (iterator i = m_peers.begin(); i != m_peers.end();) { // this timeout has to be customizable! + // don't remove banned peers, they should + // remain banned if (i->second.connection == 0 && i->second.connected != min_time() + && !i->second.banned && now - i->second.connected > minutes(120)) { if (p) p->clear_peer(&i->second); diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index f8f40548e..2eed1c328 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -254,6 +254,14 @@ namespace detail t->torrent_ptr->get_policy().peer_from_tracker(*i, id , peer_info::resume_data, 0); } + + for (std::vector::const_iterator i = t->banned_peers.begin(); + i != t->banned_peers.end(); ++i) + { + policy::peer* p = t->torrent_ptr->get_policy().peer_from_tracker(*i, id + , peer_info::resume_data, 0); + if (p) p->banned = true; + } } else { @@ -2371,9 +2379,9 @@ namespace detail // the peers - if (rd.find_key("peers")) + if (entry* peers_entry = rd.find_key("peers")) { - entry::list_type& peer_list = rd["peers"].list(); + entry::list_type& peer_list = peers_entry->list(); std::vector tmp_peers; tmp_peers.reserve(peer_list.size()); @@ -2389,6 +2397,24 @@ namespace detail peers.swap(tmp_peers); } + if (entry* banned_peers_entry = rd.find_key("banned_peers")) + { + entry::list_type& peer_list = banned_peers_entry->list(); + + std::vector tmp_peers; + tmp_peers.reserve(peer_list.size()); + for (entry::list_type::iterator i = peer_list.begin(); + i != peer_list.end(); ++i) + { + tcp::endpoint a( + address::from_string((*i)["ip"].string()) + , (unsigned short)(*i)["port"].integer()); + tmp_peers.push_back(a); + } + + banned_peers.swap(tmp_peers); + } + // read piece map const entry::list_type& slots = rd["slots"].list(); if ((int)slots.size() > info.num_pieces()) diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 14fa6f5e9..35abc2c49 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -2397,6 +2397,8 @@ namespace libtorrent #ifndef NDEBUG void torrent::check_invariant() const { + session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); + int num_uploads = 0; std::map num_requests; for (const_peer_iterator i = begin(); i != end(); ++i) diff --git a/libtorrent/src/torrent_handle.cpp b/libtorrent/src/torrent_handle.cpp index 5bbadcc90..d52a18dd2 100755 --- a/libtorrent/src/torrent_handle.cpp +++ b/libtorrent/src/torrent_handle.cpp @@ -737,14 +737,23 @@ namespace libtorrent } // write local peers - ret["peers"] = entry::list_type(); entry::list_type& peer_list = ret["peers"].list(); + entry::list_type& banned_peer_list = ret["banned_peers"].list(); policy& pol = t->get_policy(); for (policy::iterator i = pol.begin_peer() , end(pol.end_peer()); i != end; ++i) { + if (i->second.banned) + { + tcp::endpoint ip = i->second.ip; + entry peer(entry::dictionary_t); + peer["ip"] = ip.address().to_string(); + peer["port"] = ip.port(); + banned_peer_list.push_back(peer); + continue; + } // we cannot save remote connection // since we don't know their listen port // unless they gave us their listen port @@ -752,8 +761,7 @@ namespace libtorrent // so, if the peer is not connectable (i.e. we // don't know its listen port) or if it has // been banned, don't save it. - if (i->second.type == policy::peer::not_connectable - || i->second.banned) continue; + if (i->second.type == policy::peer::not_connectable) continue; tcp::endpoint ip = i->second.ip; entry peer(entry::dictionary_t);