merge RC_1_1 into master

This commit is contained in:
arvidn 2018-08-12 22:58:31 +02:00
commit b3dbce5790
13 changed files with 54 additions and 37 deletions

View File

@ -88,6 +88,8 @@
* resume data no longer has timestamps of files * resume data no longer has timestamps of files
* require C++11 to build libtorrent * require C++11 to build libtorrent
* improve connect-boost feature, to make new torrents quickly connect peers
1.1.9 release 1.1.9 release
* save both file and piece priorities in resume file * save both file and piece priorities in resume file

View File

@ -1444,6 +1444,7 @@ namespace libtorrent {
// them starting up. The normal connect scheduler is run once every // them starting up. The normal connect scheduler is run once every
// second, this allows peers to be connected immediately instead of // second, this allows peers to be connected immediately instead of
// waiting for the session tick to trigger connections. // waiting for the session tick to trigger connections.
// This may not be set higher than 255.
torrent_connect_boost, torrent_connect_boost,
// ``alert_queue_size`` is the maximum number of alerts queued up // ``alert_queue_size`` is the maximum number of alerts queued up

View File

@ -1568,13 +1568,6 @@ namespace libtorrent {
// 1 bit here // 1 bit here
// this is set to true when the torrent starts up
// The first tracker response, when this is true,
// will attempt to connect to a bunch of peers immediately
// and set this to false. We only do this once to get
// the torrent kick-started
bool m_need_connect_boost:1;
// rotating sequence number for LSD announces sent out. // rotating sequence number for LSD announces sent out.
// used to only use IP broadcast for every 8th lsd announce // used to only use IP broadcast for every 8th lsd announce
std::uint8_t m_lsd_seq:3; std::uint8_t m_lsd_seq:3;
@ -1601,7 +1594,14 @@ namespace libtorrent {
// the number of bytes of padding files // the number of bytes of padding files
std::uint32_t m_padding:24; std::uint32_t m_padding:24;
// TODO: gap of 8 bits available here // this is set to the connect boost quota for this torrent.
// After having received this many priority peer connection attempts, it
// falls back onto the steady state peer connection logic, driven by the
// session tick. Each tracker response, as long as this is non-zero, will
// attempt to connect to peers immediately and decrement the counter.
// We give torrents a connect boost when they are first added and then
// every time they resume from being paused.
std::uint8_t m_connect_boost_counter;
// ---- // ----

View File

@ -175,6 +175,11 @@ namespace torrent_flags {
// for the state_changed_alert and then call pause(). The download/seeding // for the state_changed_alert and then call pause(). The download/seeding
// will most likely start in between posting the alert and receiving the // will most likely start in between posting the alert and receiving the
// call to pause. // call to pause.
//
// A downloading state is one where peers are being connected. Which means
// just downloading the metadata via the ``ut_metadata`` extension counts
// as a downloading state. In order to stop a torrent once the metadata
// has been downloaded, instead set all file priorities to dont_download
constexpr torrent_flags_t stop_when_ready = 10_bit; constexpr torrent_flags_t stop_when_ready = 10_bit;
// when this flag is set, the tracker list in the add_torrent_params // when this flag is set, the tracker list in the add_torrent_params

View File

@ -689,9 +689,8 @@ TORRENT_IPV6_NAMESPACE_END
// extern int outstanding_resume_data; // global counter of outstanding resume data // extern int outstanding_resume_data; // global counter of outstanding resume data
// std::vector<torrent_handle> handles = ses.get_torrents(); // std::vector<torrent_handle> handles = ses.get_torrents();
// ses.pause(); // ses.pause();
// for (torrent_handle i : handles) // for (torrent_handle const& h : handles)
// { // {
// torrent_handle& h = *i;
// if (!h.is_valid()) continue; // if (!h.is_valid()) continue;
// torrent_status s = h.status(); // torrent_status s = h.status();
// if (!s.has_metadata || !s.need_save_resume_data()) continue; // if (!s.has_metadata || !s.need_save_resume_data()) continue;
@ -705,7 +704,7 @@ TORRENT_IPV6_NAMESPACE_END
// alert const* a = ses.wait_for_alert(seconds(10)); // alert const* a = ses.wait_for_alert(seconds(10));
// //
// // if we don't get an alert within 10 seconds, abort // // if we don't get an alert within 10 seconds, abort
// if (a == 0) break; // if (a == nullptr) break;
// //
// std::vector<alert*> alerts; // std::vector<alert*> alerts;
// ses.pop_alerts(&alerts); // ses.pop_alerts(&alerts);
@ -720,7 +719,7 @@ TORRENT_IPV6_NAMESPACE_END
// } // }
// //
// save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(a); // save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(a);
// if (rd == 0) // if (rd == nullptr)
// { // {
// process_alert(a); // process_alert(a);
// continue; // continue;
@ -754,9 +753,10 @@ TORRENT_IPV6_NAMESPACE_END
// time. // time.
// //
//.. note:: //.. note::
// A torrent's resume data is considered saved as soon as the alert is // A torrent's resume data is considered saved as soon as the
// posted. It is important to make sure this alert is received and // save_resume_data_alert is posted. It is important to make sure this
// handled in order for this function to be meaningful. // alert is received and handled in order for this function to be
// meaningful.
bool need_save_resume_data() const; bool need_save_resume_data() const;
// Every torrent that is added is assigned a queue position exactly one // Every torrent that is added is assigned a queue position exactly one

View File

@ -299,7 +299,7 @@ void test_stop_start_download(swarm_test type, bool graceful)
std::printf("tick: %d\n", ticks); std::printf("tick: %d\n", ticks);
const int timeout = type == swarm_test::download ? 20 : 100; const int timeout = type == swarm_test::download ? 21 : 100;
if (ticks > timeout) if (ticks > timeout)
{ {
TEST_ERROR("timeout"); TEST_ERROR("timeout");

View File

@ -275,9 +275,7 @@ namespace {
// number of disk threads for low level file operations // number of disk threads for low level file operations
set.set_int(settings_pack::aio_threads, 8); set.set_int(settings_pack::aio_threads, 8);
// keep 5 MiB outstanding when checking hashes set.set_int(settings_pack::checking_mem_usage, 2048);
// of a resumed file
set.set_int(settings_pack::checking_mem_usage, 320);
return set; return set;
} }

View File

@ -4085,16 +4085,14 @@ namespace aux {
// attempt this tick // attempt this tick
int max_connections = m_settings.get_int(settings_pack::connection_speed); int max_connections = m_settings.get_int(settings_pack::connection_speed);
// zero connections speeds are allowed, we just won't make any connections
if (max_connections <= 0) return;
// this loop will "hand out" connection_speed to the torrents, in a round // this loop will "hand out" connection_speed to the torrents, in a round
// robin fashion, so that every torrent is equally likely to connect to a // robin fashion, so that every torrent is equally likely to connect to a
// peer // peer
// boost connections are connections made by torrent connection // boost connections are connections made by torrent connection
// boost, which are done immediately on a tracker response. These // boost, which are done immediately on a tracker response. These
// connections needs to be deducted from this second // connections needs to be deducted from the regular connection attempt
// quota for this tick
if (m_boost_connections > 0) if (m_boost_connections > 0)
{ {
if (m_boost_connections > max_connections) if (m_boost_connections > max_connections)
@ -4109,6 +4107,9 @@ namespace aux {
} }
} }
// zero connections speeds are allowed, we just won't make any connections
if (max_connections <= 0) return;
// TODO: use a lower limit than m_settings.connections_limit // TODO: use a lower limit than m_settings.connections_limit
// to allocate the to 10% or so of connection slots for incoming // to allocate the to 10% or so of connection slots for incoming
// connections // connections

View File

@ -233,7 +233,7 @@ constexpr int CLOSE_FILE_INTERVAL = 0;
SET(max_failcount, 3, &session_impl::update_max_failcount), SET(max_failcount, 3, &session_impl::update_max_failcount),
SET(min_reconnect_time, 60, nullptr), SET(min_reconnect_time, 60, nullptr),
SET(peer_connect_timeout, 15, nullptr), SET(peer_connect_timeout, 15, nullptr),
SET(connection_speed, 10, &session_impl::update_connection_speed), SET(connection_speed, 30, &session_impl::update_connection_speed),
SET(inactivity_timeout, 600, nullptr), SET(inactivity_timeout, 600, nullptr),
SET(unchoke_interval, 15, nullptr), SET(unchoke_interval, 15, nullptr),
SET(optimistic_unchoke_interval, 30, nullptr), SET(optimistic_unchoke_interval, 30, nullptr),
@ -313,7 +313,7 @@ constexpr int CLOSE_FILE_INTERVAL = 0;
SET(utp_loss_multiplier, 50, nullptr), SET(utp_loss_multiplier, 50, nullptr),
SET(mixed_mode_algorithm, settings_pack::peer_proportional, nullptr), SET(mixed_mode_algorithm, settings_pack::peer_proportional, nullptr),
SET(listen_queue_size, 5, nullptr), SET(listen_queue_size, 5, nullptr),
SET(torrent_connect_boost, 10, nullptr), SET(torrent_connect_boost, 80, nullptr),
SET(alert_queue_size, 1000, &session_impl::update_alert_queue_size), SET(alert_queue_size, 1000, &session_impl::update_alert_queue_size),
SET(max_metadata_size, 3 * 1024 * 10240, nullptr), SET(max_metadata_size, 3 * 1024 * 10240, nullptr),
DEPRECATED_SET(hashing_threads, 1, nullptr), DEPRECATED_SET(hashing_threads, 1, nullptr),

View File

@ -139,7 +139,7 @@ namespace libtorrent {
return; return;
} }
if (m_part_file) if (m_part_file && use_partfile(i))
{ {
m_part_file->export_file([&f, &ec](std::int64_t file_offset, span<char> buf) m_part_file->export_file([&f, &ec](std::int64_t file_offset, span<char> buf)
{ {

View File

@ -207,12 +207,12 @@ bool is_downloading_state(int const st)
, m_max_uploads((1 << 24) - 1) , m_max_uploads((1 << 24) - 1)
, m_save_resume_flags() , m_save_resume_flags()
, m_num_uploads(0) , m_num_uploads(0)
, m_need_connect_boost(true)
, m_lsd_seq(0) , m_lsd_seq(0)
, m_magnet_link(false) , m_magnet_link(false)
, m_apply_ip_filter(p.flags & torrent_flags::apply_ip_filter) , m_apply_ip_filter(p.flags & torrent_flags::apply_ip_filter)
, m_pending_active_change(false) , m_pending_active_change(false)
, m_padding(0) , m_padding(0)
, m_connect_boost_counter(static_cast<std::uint8_t>(settings().get_int(settings_pack::torrent_connect_boost)))
, m_incomplete(0xffffff) , m_incomplete(0xffffff)
, m_announce_to_dht(!(p.flags & torrent_flags::paused)) , m_announce_to_dht(!(p.flags & torrent_flags::paused))
, m_ssl_torrent(false) , m_ssl_torrent(false)
@ -3267,23 +3267,24 @@ bool is_downloading_state(int const st)
void torrent::do_connect_boost() void torrent::do_connect_boost()
{ {
if (!m_need_connect_boost) return; if (m_connect_boost_counter == 0) return;
// this is the first tracker response for this torrent // this is the first tracker response for this torrent
// instead of waiting one second for session_impl::on_tick() // instead of waiting one second for session_impl::on_tick()
// to be called, connect to a few peers immediately // to be called, connect to a few peers immediately
int conns = std::min( int conns = std::min(int(m_connect_boost_counter)
settings().get_int(settings_pack::torrent_connect_boost)
, settings().get_int(settings_pack::connections_limit) - m_ses.num_connections()); , settings().get_int(settings_pack::connections_limit) - m_ses.num_connections());
if (conns > 0) m_need_connect_boost = false; if (conns == 0) return;
// if we don't know of any peers // if we don't know of any peers
if (!m_peer_list) return; if (!m_peer_list) return;
while (want_peers() && conns > 0) while (want_peers() && conns > 0)
{ {
TORRENT_ASSERT(m_connect_boost_counter > 0);
--conns; --conns;
--m_connect_boost_counter;
torrent_state st = get_peer_list_state(); torrent_state st = get_peer_list_state();
torrent_peer* p = m_peer_list->connect_one_peer(m_ses.session_time(), &st); torrent_peer* p = m_peer_list->connect_one_peer(m_ses.session_time(), &st);
peers_erased(st.erased); peers_erased(st.erased);
@ -8496,7 +8497,8 @@ bool is_downloading_state(int const st)
} }
#endif #endif
m_need_connect_boost = true; m_connect_boost_counter
= static_cast<std::uint8_t>(settings().get_int(settings_pack::torrent_connect_boost));
m_inactive = false; m_inactive = false;
update_state_list(); update_state_list();

View File

@ -321,6 +321,7 @@ namespace libtorrent { namespace {
p = pex_msg.dict_find_string("added"); p = pex_msg.dict_find_string("added");
bdecode_node const pf = pex_msg.dict_find_string("added.f"); bdecode_node const pf = pex_msg.dict_find_string("added.f");
bool peers_added = false;
#ifndef TORRENT_DISABLE_LOGGING #ifndef TORRENT_DISABLE_LOGGING
if (p) num_added += p.string_length() / 6; if (p) num_added += p.string_length() / 6;
#endif #endif
@ -347,6 +348,7 @@ namespace libtorrent { namespace {
if (j != m_peers.end() && *j == v) continue; if (j != m_peers.end() && *j == v) continue;
m_peers.insert(j, v); m_peers.insert(j, v);
m_torrent.add_peer(adr, peer_info::pex, flags); m_torrent.add_peer(adr, peer_info::pex, flags);
peers_added = true;
} }
} }
@ -398,6 +400,7 @@ namespace libtorrent { namespace {
if (j != m_peers6.end() && *j == v) continue; if (j != m_peers6.end() && *j == v) continue;
m_peers6.insert(j, v); m_peers6.insert(j, v);
m_torrent.add_peer(adr, peer_info::pex, flags); m_torrent.add_peer(adr, peer_info::pex, flags);
peers_added = true;
} }
} }
#endif #endif
@ -407,6 +410,8 @@ namespace libtorrent { namespace {
#endif #endif
m_pc.stats_counters().inc_stats_counter(counters::num_incoming_pex); m_pc.stats_counters().inc_stats_counter(counters::num_incoming_pex);
if (peers_added) m_torrent.do_connect_boost();
return true; return true;
} }

View File

@ -79,7 +79,7 @@ struct test_config_t
int ssl_disconnects; int ssl_disconnects;
}; };
test_config_t test_config[] = test_config_t const test_config[] =
{ {
// name sslport sd-cert dl-cert dl-port expect peer-error ssl-disconn // name sslport sd-cert dl-cert dl-port expect peer-error ssl-disconn
{"nobody has a cert (connect to regular port)", false, false, false, true, false, 0, 1}, {"nobody has a cert (connect to regular port)", false, false, false, true, false, 0, 1},
@ -125,7 +125,7 @@ bool on_alert(alert const* a)
return false; return false;
} }
void test_ssl(int test_idx, bool use_utp) void test_ssl(int const test_idx, bool const use_utp)
{ {
// these are declared before the session objects // these are declared before the session objects
// so that they are destructed last. This enables // so that they are destructed last. This enables
@ -289,10 +289,13 @@ void test_ssl(int test_idx, bool use_utp)
std::printf("peer_errors: %d expected_errors: %d\n" std::printf("peer_errors: %d expected_errors: %d\n"
, peer_errors, test.peer_errors); , peer_errors, test.peer_errors);
TEST_EQUAL(peer_errors > 0, test.peer_errors > 0);
std::printf("ssl_disconnects: %d expected: %d\n", ssl_peer_disconnects, test.ssl_disconnects); std::printf("ssl_disconnects: %d expected: %d\n", ssl_peer_disconnects, test.ssl_disconnects);
TEST_EQUAL(ssl_peer_disconnects > 0, test.ssl_disconnects > 0); if (!use_utp)
{
TEST_EQUAL(ssl_peer_disconnects > 0, test.ssl_disconnects > 0);
TEST_EQUAL(peer_errors > 0, test.peer_errors > 0);
}
char const* now = time_now_string(); char const* now = time_now_string();
std::printf("%s: EXPECT: %s\n", now, test.expected_to_complete ? "SUCCEESS" : "FAILURE"); std::printf("%s: EXPECT: %s\n", now, test.expected_to_complete ? "SUCCEESS" : "FAILURE");
@ -328,7 +331,7 @@ enum attack_flags_t
valid_bittorrent_hash = 16, valid_bittorrent_hash = 16,
}; };
attack_t attacks[] = attack_t const attacks[] =
{ {
// positive test // positive test
{ valid_certificate | valid_sni_hash | valid_bittorrent_hash, true}, { valid_certificate | valid_sni_hash | valid_bittorrent_hash, true},