From ab07eceead59da9a85d60d406f1a99ad86dbb2d5 Mon Sep 17 00:00:00 2001 From: arvidn Date: Wed, 8 Jan 2020 15:33:17 +0100 Subject: [PATCH] don't attempt sending event=stopped if event=start never succeeded --- ChangeLog | 1 + simulation/test_tracker.cpp | 61 +++++++++++++++++++++++++++++++++++++ src/torrent.cpp | 5 ++- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8a8a8adc2..edfa10255 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * don't attempt sending event=stopped if event=start never succeeded * make sure &key= stays consistent between different source IPs (as mandated by BEP7) * fix binding sockets to outgoing interface * add new socks5_alert to trouble shoot SOCKS5 proxies diff --git a/simulation/test_tracker.cpp b/simulation/test_tracker.cpp index ed296c15e..daa93a0e2 100644 --- a/simulation/test_tracker.cpp +++ b/simulation/test_tracker.cpp @@ -693,6 +693,67 @@ void announce_entry_test(Announce a, Test t, char const* url_path = "/announce") , url_path); } +// test that we correctly omit announcing an event=stopped to a tracker we never +// managed to send an event=start to +TORRENT_TEST(omit_stop_event) +{ + using sim::asio::ip::address_v4; + sim_config network_cfg; + sim::simulation sim{network_cfg}; + + lt::session_proxy zombie; + + asio::io_service ios(sim, { address_v4::from_string("123.0.0.3"), address_v6::from_string("ff::dead:beef")}); + lt::settings_pack sett = settings(); + std::unique_ptr ses(new lt::session(sett, ios)); + + print_alerts(*ses); + + lt::add_torrent_params p; + p.name = "test-torrent"; + p.save_path = "."; + p.info_hash.assign("abababababababababab"); + p.trackers.push_back("udp://tracker.com:8080/announce"); + ses->async_add_torrent(p); + + // run the test 5 seconds in + sim::timer t1(sim, lt::seconds(5) + , [&ses](boost::system::error_code const&) + { + std::vector torrents = ses->get_torrents(); + TEST_EQUAL(torrents.size(), 1); + torrent_handle h = torrents.front(); + }); + + int stop_announces = 0; + + sim::timer t2(sim, lt::seconds(1800) + , [&](boost::system::error_code const&) + { + // make sure we don't announce a stopped event when stopping + print_alerts(*ses, [&](lt::session&, lt::alert const* a) { + if (alert_cast(a)) + ++stop_announces; + }); + std::vector torrents = ses->get_torrents(); + TEST_EQUAL(torrents.size(), 1); + torrent_handle h = torrents.front(); + h.set_flags(torrent_flags::paused, torrent_flags::paused | torrent_flags::auto_managed); + }); + + // then shut down 10 seconds in + sim::timer t3(sim, lt::seconds(1810) + , [&](boost::system::error_code const&) + { + zombie = ses->abort(); + ses.reset(); + }); + + sim.run(); + + TEST_EQUAL(stop_announces, 0); +} + TORRENT_TEST(test_error) { announce_entry_test( diff --git a/src/torrent.cpp b/src/torrent.cpp index d9368a37c..c686101f1 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2940,7 +2940,10 @@ bool is_downloading_state(int const st) for (auto& aep : ae.endpoints) { - if (!aep.enabled) continue; + // if we haven't sent an event=start to the tracker, there's no + // point in sending an event=stopped + if (!aep.enabled || (!aep.start_sent && req.event == tracker_request::stopped)) + continue; auto aep_state_iter = std::find_if(listen_socket_states.begin(), listen_socket_states.end() , [&](announce_state const& s) { return s.socket == aep.socket; });