avoid connections to trackers when the event is stopped and stop_tracker_timeout <= 0 (#1932)

This commit is contained in:
Alden Torres 2017-04-22 18:33:26 -04:00 committed by Arvid Norberg
parent b553cb32f7
commit 735214a806
6 changed files with 98 additions and 2 deletions

View File

@ -127,7 +127,7 @@ namespace libtorrent {
{
// the tracker was part of the .torrent file
source_torrent = 1,
// the tracker was added programatically via the add_troacker()_ function
// the tracker was added programatically via the add_tracker() function
source_client = 2,
// the tracker was part of a magnet link
source_magnet_link = 4,

View File

@ -776,7 +776,7 @@ namespace libtorrent {
// in the download queue is vacated and avery subsequent torrent in the
// queue has their queue positions updated. This can potentially cause a
// large state_update to be posted. When removing all torrents, it is
// adviced to remove them from the back of the queue, to minimize the
// advised to remove them from the back of the queue, to minimize the
// shifting.
void remove_torrent(const torrent_handle& h, int options = 0);

View File

@ -729,6 +729,8 @@ namespace libtorrent {
// ``stop_tracker_timeout`` is the number of seconds to wait when
// sending a stopped message before considering a tracker to have
// timed out. This is usually shorter, to make the client quit faster.
// If the value is set to 0, the connections to trackers with the
// stopped event are suppressed.
stop_tracker_timeout,
// this is the maximum number of bytes in a tracker response. If a

View File

@ -2584,6 +2584,18 @@ namespace libtorrent {
if (m_abort) e = tracker_request::stopped;
// having stop_tracker_timeout <= 0 means that there is
// no need to send any request to trackers or trigger any
// related logic when the event is stopped
if (e == tracker_request::stopped
&& settings().get_int(settings_pack::stop_tracker_timeout) <= 0)
{
#ifndef TORRENT_DISABLE_LOGGING
debug_log("*** announce: event == stopped && stop_tracker_timeout <= 0");
#endif
return;
}
// if we're not announcing to trackers, only allow
// stopping
if (e != tracker_request::stopped && !m_announce_to_trackers)

View File

@ -248,6 +248,9 @@ TORRENT_TEST(settings_pack_abi)
TEST_EQUAL(settings_pack::proxy_tracker_connections, settings_pack::bool_type_base + 67);
// ints
TEST_EQUAL(settings_pack::tracker_completion_timeout, settings_pack::int_type_base + 0);
TEST_EQUAL(settings_pack::tracker_receive_timeout, settings_pack::int_type_base + 1);
TEST_EQUAL(settings_pack::stop_tracker_timeout, settings_pack::int_type_base + 2);
TEST_EQUAL(settings_pack::max_suggest_pieces, settings_pack::int_type_base + 66);
TEST_EQUAL(settings_pack::connections_slack, settings_pack::int_type_base + 86);
TEST_EQUAL(settings_pack::aio_threads, settings_pack::int_type_base + 104);

View File

@ -619,3 +619,82 @@ TORRENT_TEST(tracker_proxy)
test_proxy(true);
}
void test_stop_tracker_timeout(bool nostop)
{
int port = start_web_server();
auto count_stopped_events = [](session& ses)
{
int count = 0;
int num = 70; // this number is adjusted per version, an estimate
time_point const end_time = clock_type::now() + seconds(15);
while (true)
{
time_point const now = clock_type::now();
if (now > end_time) return count;
ses.wait_for_alert(end_time - now);
std::vector<alert*> alerts;
ses.pop_alerts(&alerts);
for (auto a : alerts)
{
std::printf("%d: [%s] %s\n", num, a->what(), a->message().c_str());
if (a->type() == log_alert::alert_type)
{
std::string const msg = a->message();
if (msg.find("&event=stopped") != std::string::npos)
count++;
}
num--;
}
if (num <= 0) return count;
}
return count;
};
settings_pack p = settings();
p.set_bool(settings_pack::announce_to_all_trackers, true);
p.set_bool(settings_pack::announce_to_all_tiers, true);
p.set_int(settings_pack::alert_mask, alert::all_categories);
if (nostop)
p.set_int(settings_pack::stop_tracker_timeout, 0);
lt::session s(p);
error_code ec;
remove_all("tmp4_tracker", ec);
create_directory("tmp4_tracker", ec);
std::ofstream file(combine_path("tmp4_tracker", "temporary").c_str());
std::shared_ptr<torrent_info> t = ::create_torrent(&file, "temporary", 16 * 1024, 13, false);
file.close();
add_torrent_params tp;
tp.flags &= ~add_torrent_params::flag_paused;
tp.flags &= ~add_torrent_params::flag_auto_managed;
tp.flags |= add_torrent_params::flag_seed_mode;
tp.ti = t;
tp.save_path = "tmp4_tracker";
torrent_handle h = s.add_torrent(tp);
char tracker_url[200];
std::snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.1:%d/announce", port);
announce_entry ae{tracker_url};
// trick to avoid use of tracker immediately
ae.next_announce = aux::time_now32() + seconds32(1);
ae.min_announce = aux::time_now32() + seconds32(1);
h.add_tracker(ae);
s.remove_torrent(h);
int const count = count_stopped_events(s);
TEST_EQUAL(count, nostop ? 0 : 1);
}
TORRENT_TEST(stop_tracker_timeout)
{
std::printf("\n\nexpect to get ONE request with &event=stopped\n\n");
test_stop_tracker_timeout(false);
std::printf("\n\nexpect to NOT get a request with &event=stopped\n\n");
test_stop_tracker_timeout(true);
}