From 57aa813135654651aafafd082ece084f588ba2b7 Mon Sep 17 00:00:00 2001 From: arvidn Date: Mon, 22 Feb 2016 20:07:29 -0500 Subject: [PATCH 1/5] fix auto-managed issue with torrents transitioning to 'slow' as they get paused, returning to life again later because of it --- simulation/test_auto_manage.cpp | 73 +++++++++++++++++++++++++++++++++ src/torrent.cpp | 10 +++++ 2 files changed, 83 insertions(+) diff --git a/simulation/test_auto_manage.cpp b/simulation/test_auto_manage.cpp index 052a9d1d9..468cdeb18 100644 --- a/simulation/test_auto_manage.cpp +++ b/simulation/test_auto_manage.cpp @@ -845,6 +845,79 @@ TORRENT_TEST(no_resume_when_started) }); } +// when setting active_seeds to 0, any completed torrent should be paused +TORRENT_TEST(pause_completed_torrents) +{ + run_test( + [](settings_pack& sett) { + // session settings + sett.set_bool(settings_pack::dont_count_slow_torrents, true); + sett.set_int(settings_pack::active_downloads, 1); + sett.set_int(settings_pack::active_seeds, 0); + }, + + [](lt::session& ses) { + // add torrent + lt::add_torrent_params params = create_torrent(0, true); + params.flags |= add_torrent_params::flag_auto_managed; + params.flags |= add_torrent_params::flag_paused; + ses.async_add_torrent(params); + }, + + [](lt::session& ses) { + // verify result + // the torrent should have been paused immediately as it completed, + // since we don't allow any seeding torrents + + std::vector alerts; + ses.pop_alerts(&alerts); + + lt::time_point start_time = alerts[0]->timestamp(); + + int num_started = 0; + int num_finished = 0; + int num_paused = 0; + lt::time_point finished; + lt::time_point paused; + for (alert* a : alerts) + { + printf("%-3d %s\n", int(duration_cast(a->timestamp() + - start_time).count()), a->message().c_str()); + if (alert_cast(a)) + ++num_started; + if (alert_cast(a)) + { + ++num_finished; + finished = a->timestamp(); + } + if (alert_cast(a)) + { + ++num_paused; + paused = a->timestamp(); + } + } + + TEST_EQUAL(num_started, 1); + TEST_EQUAL(num_finished, 1); + TEST_EQUAL(num_paused, 1); + + if (num_finished > 0 && num_paused > 0) + { + TEST_CHECK(paused >= finished); + TEST_CHECK(paused - finished < chrono::milliseconds(1)); + } + + num_paused = 0; + for (torrent_handle const& h : ses.get_torrents()) + { + TEST_CHECK(h.status().auto_managed); + num_paused += h.status().paused; + } + TEST_EQUAL(num_paused, 1); + }); +} + + // TODO: assert that the torrent_paused_alert is posted when pausing // downloading, seeding, checking torrents as well as the graceful pause // TODO: test limits of tracker, DHT and LSD announces diff --git a/src/torrent.cpp b/src/torrent.cpp index 899225ef4..51a566d78 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -9700,6 +9700,16 @@ namespace libtorrent TORRENT_ASSERT(is_single_thread()); if (!is_paused()) return; + // this torrent may be about to consider itself inactive. If so, we want + // to prevent it from doing so, since it's being paused unconditionally + // now. An illustrative example of this is a torrent that completes + // downloading when active_seeds = 0. It completes, it gets paused and it + // should not come back to life again. + if (m_pending_active_change) + { + m_inactivity_timer.cancel(); + } + #ifndef TORRENT_DISABLE_EXTENSIONS for (extension_list_t::iterator i = m_extensions.begin() , end(m_extensions.end()); i != end; ++i) From d748a590296ddd7d4669b0a55f4f58f3fd4c17fc Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 23 Feb 2016 19:13:14 -0500 Subject: [PATCH 2/5] attempt to fix test_transfer --- test/setup_transfer.cpp | 6 ++++++ test/test_transfer.cpp | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index d510817b2..e026b9def 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -841,10 +841,16 @@ setup_transfer(lt::session* ses1, lt::session* ses2, lt::session* ses3 error_code ec; int port = 0; if (use_ssl_ports) + { port = ses2->ssl_listen_port(); + fprintf(stderr, "%s: ses2->ssl_listen_port(): %d\n", time_now_string(), port); + } if (port == 0) + { port = ses2->listen_port(); + fprintf(stderr, "%s: ses2->listen_port(): %d\n", time_now_string(), port); + } fprintf(stderr, "%s: ses1: connecting peer port: %d\n" , time_now_string(), port); diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 17ce3bcf4..1a30f191c 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -127,8 +127,6 @@ void test_transfer(int proxy_type, settings_pack const& sett , bool test_disk_full = false , storage_mode_t storage_mode = storage_mode_sparse) { - static int listen_port = 0; - char const* test_name[] = {"no", "SOCKS4", "SOCKS5", "SOCKS5 password", "HTTP", "HTTP password"}; fprintf(stderr, "\n\n ==== TESTING %s proxy ==== disk-full: %s\n\n\n" @@ -160,7 +158,6 @@ void test_transfer(int proxy_type, settings_pack const& sett pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:49075"); lt::session ses2(pack); - listen_port += 10; int proxy_port = 0; if (proxy_type) @@ -183,6 +180,10 @@ void test_transfer(int proxy_type, settings_pack const& sett pack.set_str(settings_pack::proxy_hostname, "127.0.0.1"); ses1.apply_settings(pack); ses2.apply_settings(pack); + + // ses1 is connecting to ses2, so only ses1 should be using the proxy + pack.set_int(settings_pack::proxy_type, settings_pack::none); + ses1.apply_settings(pack); } pack = sett; From dcd6af64739fdf3bc4837262383e53bcf924e46d Mon Sep 17 00:00:00 2001 From: arvidn Date: Wed, 24 Feb 2016 00:03:56 -0500 Subject: [PATCH 3/5] more fixing of test_transfer proxy tests --- include/libtorrent/settings_pack.hpp | 12 ++++++------ src/session_impl.cpp | 4 ++-- test/test_transfer.cpp | 7 +------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index 19ae574e4..1e682746f 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -560,12 +560,12 @@ namespace libtorrent // If true, disables any communication that's not going over a proxy. // Enabling this requires a proxy to be configured as well, see - // ``set_proxy_settings``. The listen sockets are closed, and incoming - // connections will only be accepted through a SOCKS5 or I2P proxy (if - // a peer proxy is set up and is run on the same machine as the - // tracker proxy). This setting also disabled peer country lookups, - // since those are done via DNS lookups that aren't supported by - // proxies. + // proxy_type and proxy_hostname settings. The listen sockets are + // closed, and incoming connections will only be accepted through a + // SOCKS5 or I2P proxy (if a peer proxy is set up and is run on the + // same machine as the tracker proxy). This setting also disabled peer + // country lookups, since those are done via DNS lookups that aren't + // supported by proxies. force_proxy, // if false, prevents libtorrent to advertise share-mode support diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 86d961247..6ba412860 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -2221,7 +2221,7 @@ retry: void session_impl::open_new_incoming_socks_connection() { - int proxy_type = m_settings.get_int(settings_pack::proxy_type); + int const proxy_type = m_settings.get_int(settings_pack::proxy_type); if (proxy_type != settings_pack::socks5 && proxy_type != settings_pack::socks5_pw @@ -2231,7 +2231,7 @@ retry: if (m_socks_listen_socket) return; m_socks_listen_socket = boost::shared_ptr(new socket_type(m_io_service)); - bool ret = instantiate_connection(m_io_service, proxy() + bool const ret = instantiate_connection(m_io_service, proxy() , *m_socks_listen_socket, NULL, NULL, false, false); TORRENT_ASSERT_VAL(ret, ret); TORRENT_UNUSED(ret); diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 1a30f191c..cb00755da 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -169,6 +169,7 @@ void test_transfer(int proxy_type, settings_pack const& sett pack.set_str(settings_pack::proxy_password, "testpass"); pack.set_int(settings_pack::proxy_type, proxy_type); pack.set_int(settings_pack::proxy_port, proxy_port); + pack.set_bool(settings_pack::force_proxy, true); // test resetting the proxy in quick succession. // specifically the udp_socket connecting to a new @@ -176,14 +177,8 @@ void test_transfer(int proxy_type, settings_pack const& sett // in progress. pack.set_str(settings_pack::proxy_hostname, "5.6.7.8"); ses1.apply_settings(pack); - pack.set_str(settings_pack::proxy_hostname, "127.0.0.1"); ses1.apply_settings(pack); - ses2.apply_settings(pack); - - // ses1 is connecting to ses2, so only ses1 should be using the proxy - pack.set_int(settings_pack::proxy_type, settings_pack::none); - ses1.apply_settings(pack); } pack = sett; From e5ccb6337559da3dfbe5094e02ecb5c449294b30 Mon Sep 17 00:00:00 2001 From: arvidn Date: Wed, 24 Feb 2016 02:07:27 -0500 Subject: [PATCH 4/5] fix build with openssl and deprecated functions disabled --- src/session_impl.cpp | 5 ----- src/torrent.cpp | 2 +- test/test_ssl.cpp | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 6ba412860..dc695b902 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -5387,11 +5387,6 @@ retry: boost::uint16_t session_impl::ssl_listen_port() const { #ifdef TORRENT_USE_OPENSSL - - // honor the SSL listen port being disabled - if (m_settings.get_int(settings_pack::ssl_listen) == 0) - return 0; - // if peer connections are set up to be received over a socks // proxy, and it's the same one as we're using for the tracker // just tell the tracker the socks5 port we're listening on diff --git a/src/torrent.cpp b/src/torrent.cpp index 51a566d78..0a016cce0 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -7698,7 +7698,7 @@ namespace libtorrent void* userdata = 0; #ifdef TORRENT_USE_OPENSSL - if (is_ssl_torrent() && settings().get_int(settings_pack::ssl_listen) != 0) + if (is_ssl_torrent()) { userdata = m_ssl_ctx.get(); } diff --git a/test/test_ssl.cpp b/test/test_ssl.cpp index 83073433d..01c5bc7c7 100644 --- a/test/test_ssl.cpp +++ b/test/test_ssl.cpp @@ -205,8 +205,8 @@ void test_ssl(int test_idx, bool use_utp) { // this will cause a round-trip to the main thread, and make sure the // previous async. calls have completed - ses1.status(); - ses2.status(); + ses1.listen_port(); + ses2.listen_port(); } wait_for_alert(ses1, torrent_finished_alert::alert_type, "ses1"); From d4f259ccf0c2f5ff5058e833765cea56584aa66a Mon Sep 17 00:00:00 2001 From: arvidn Date: Wed, 24 Feb 2016 02:23:09 -0500 Subject: [PATCH 5/5] attempt to fix race when closing a web seed while it's receiving data --- src/web_peer_connection.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index 5f9a2b1fd..518dcd636 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -937,6 +937,8 @@ void web_peer_connection::incoming_payload(char const* buf, int len) received_bytes(len, 0); m_received_body += len; + if (is_disconnecting()) return; + #ifndef TORRENT_DISABLE_LOGGING peer_log(peer_log_alert::incoming_message, "INCOMING_PAYLOAD", "%d bytes", len); #endif @@ -944,6 +946,8 @@ void web_peer_connection::incoming_payload(char const* buf, int len) // deliver all complete bittorrent requests to the bittorrent engine while (len > 0) { + if (m_requests.empty()) return; + TORRENT_ASSERT(!m_requests.empty()); peer_request const& front_request = m_requests.front(); int const piece_size = int(m_piece.size());