diff --git a/libtorrent/include/libtorrent/session.hpp b/libtorrent/include/libtorrent/session.hpp index fcae0be32..ebd6b7ea5 100755 --- a/libtorrent/include/libtorrent/session.hpp +++ b/libtorrent/include/libtorrent/session.hpp @@ -129,7 +129,7 @@ namespace libtorrent , resume_data(0) , storage_mode(storage_mode_sparse) , paused(true) - , auto_managed(true) + , auto_managed(false) , duplicate_is_error(false) , storage(sc) , userdata(0) diff --git a/libtorrent/include/libtorrent/storage.hpp b/libtorrent/include/libtorrent/storage.hpp index a1fbdc2ba..8a7bb15a8 100755 --- a/libtorrent/include/libtorrent/storage.hpp +++ b/libtorrent/include/libtorrent/storage.hpp @@ -321,7 +321,7 @@ namespace libtorrent int rename_file_impl(int index, std::string const& new_filename) { return m_storage->rename_file(index, new_filename); } - bool move_storage_impl(fs::path const& save_path); + int move_storage_impl(fs::path const& save_path); int allocate_slot_for_piece(int piece_index); #ifndef NDEBUG diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index 778d4d4aa..d08ee8b89 100755 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -164,6 +164,8 @@ namespace libtorrent void abort(); bool is_aborted() const { return m_abort; } + torrent_status::state_t state() const { return m_state; } + session_settings const& settings() const; aux::session_impl& session() { return m_ses; } diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index f01193b96..c355a6d23 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -3270,11 +3270,21 @@ namespace libtorrent // this means the connection just succeeded + TORRENT_ASSERT(m_socket); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING (*m_ses.m_logger) << time_now_string() << " COMPLETED: " << m_remote.address().to_string() << " rtt = " << m_rtt << "\n"; #endif + error_code ec; + if (m_remote == m_socket->local_endpoint(ec)) + { + // if the remote endpoint is the same as the local endpoint, we're connected + // to ourselves + disconnect("connected to ourselves", 1); + return; + } + if (m_remote.address().is_v4()) { error_code ec; diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index d73fc1a9f..20d38fdf4 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -459,14 +459,19 @@ namespace libtorrent pinged = true; } #endif - // this timeout has to be customizable! - // don't remove banned peers, they should - // remain banned + // if the number of peers is growing large + // we need to start weeding. + // don't remove peers we're connected to + // don't remove peers we've never even tried + // don't remove banned peers unless they're 2 + // hours old. They should remain banned for + // at least that long + // don't remove peers that we still can try again if (pe.connection == 0 && pe.connected != min_time() - && !pe.banned - && (now - pe.connected > minutes(120) - || m_peers.size() >= m_torrent->settings().max_peerlist_size * 0.9)) + && (!pe.banned || now - pe.connected > hours(2)) + && !is_connect_candidate(pe, finished) + && m_peers.size() >= m_torrent->settings().max_peerlist_size * 0.9) { erase_peer(m_round_robin++); continue; @@ -474,14 +479,13 @@ namespace libtorrent ++m_round_robin; - if (!is_connect_candidate(pe, finished)) continue; if (candidate != m_peers.end() && !compare_peer(candidate->second, pe, external_ip)) continue; if (now - pe.connected < - seconds(pe.failcount * min_reconnect_time)) + seconds((pe.failcount + 1) * min_reconnect_time)) continue; candidate = current; @@ -614,6 +618,35 @@ namespace libtorrent if (i->second.connection != 0) { + boost::shared_ptr other_socket + = i->second.connection->get_socket(); + boost::shared_ptr this_socket + = c.get_socket(); + + error_code ec1; + error_code ec2; + bool self_connection = + other_socket->remote_endpoint(ec2) == this_socket->local_endpoint(ec1) + || other_socket->local_endpoint(ec2) == this_socket->remote_endpoint(ec1); + + if (ec1) + { + c.disconnect(ec1.message().c_str()); + return false; + } + + if (ec2) + { + i->second.connection->disconnect(ec2.message().c_str()); + } + + if (self_connection) + { + c.disconnect("connected to ourselves", 1); + i->second.connection->disconnect("connected to ourselves", 1); + return false; + } + TORRENT_ASSERT(i->second.connection != &c); // the new connection is a local (outgoing) connection // or the current one is already connected diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index dd422b3a4..e12075129 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -1308,6 +1308,11 @@ namespace aux { int num_downloaders = settings().active_downloads; int num_seeds = settings().active_seeds; + if (num_downloaders == -1) + num_downloaders = (std::numeric_limits::max)(); + if (num_seeds == -1) + num_seeds = (std::numeric_limits::max)(); + for (torrent_map::iterator i = m_torrents.begin() , end(m_torrents.end()); i != end; ++i) { @@ -1327,14 +1332,8 @@ namespace aux { // this is not an auto managed torrent, // if it's running, decrease the respective // counters. - if (t->is_finished()) - { - --num_seeds; - } - else - { - --num_downloaders; - } + --num_downloaders; + --num_seeds; } } @@ -1358,9 +1357,12 @@ namespace aux { , end(downloaders.end()); i != end; ++i) { torrent* t = *i; - if (num_downloaders > 0) + if (num_downloaders > 0 + && t->state() != torrent_status::queued_for_checking + && t->state() != torrent_status::checking_files) { --num_downloaders; + --num_seeds; if (t->is_paused()) t->resume(); } else @@ -1375,6 +1377,7 @@ namespace aux { torrent* t = *i; if (num_seeds > 0) { + --num_downloaders; --num_seeds; if (t->is_paused()) t->resume(); } diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index 327d9e20a..1c16a866d 100755 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -1409,14 +1409,14 @@ namespace libtorrent return m_storage->hash_for_slot(slot, ph, m_files.piece_size(piece)); } - bool piece_manager::move_storage_impl(fs::path const& save_path) + int piece_manager::move_storage_impl(fs::path const& save_path) { if (m_storage->move_storage(save_path)) { m_save_path = fs::complete(save_path); - return true; + return 0; } - return false; + return -1; } void piece_manager::write_resume_data(entry& rd) const diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 7e74379ba..400f2c150 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -632,6 +632,7 @@ namespace libtorrent // assume that we don't have anything m_files_checked = false; m_state = torrent_status::queued_for_checking; + set_queue_position((std::numeric_limits::max)()); m_resume_data = entry(); m_storage->async_check_fastresume(&m_resume_data @@ -3249,6 +3250,7 @@ namespace libtorrent { alerts().post_alert(storage_moved_alert(get_handle(), j.str)); } + m_save_path = j.str; } piece_manager& torrent::filesystem() @@ -3392,11 +3394,23 @@ namespace libtorrent void torrent::set_queue_position(int p) { + TORRENT_ASSERT((p == -1) == is_finished()); if (is_finished() && p != -1) return; if (p == m_sequence_number) return; session_impl::torrent_map& torrents = m_ses.m_torrents; - if (p < 0) + if (p >= 0 && m_sequence_number == -1) + { + int max_seq = 0; + for (session_impl::torrent_map::iterator i = torrents.begin() + , end(torrents.end()); i != end; ++i) + { + torrent* t = i->second.get(); + if (t->m_sequence_number > max_seq) max_seq = t->m_sequence_number; + } + m_sequence_number = (std::min)(max_seq + 1, p); + } + else if (p < 0) { for (session_impl::torrent_map::iterator i = torrents.begin() , end(torrents.end()); i != end; ++i) @@ -3435,8 +3449,8 @@ namespace libtorrent if (t == this) continue; if (pos <= p - && pos > m_sequence_number - && pos != -1) + && pos > m_sequence_number + && pos != -1) --t->m_sequence_number; }