fix infinite loop when announcing

In torrent::announce_with_tracker there is a check after announcing all of
a tracker's endpoints to see if all required announces have already been sent
according to the tier settings.

	if (std::all_of(listen_socket_states.begin(), listen_socket_states.end()
		, [](announce_state const& s) { return s.done; }))
		break;

Commit ab07eceead added a check which can cause listen_socket_states to not be
populated if all endpoints for the first tracker are disabled. This causes the
early break out code above to trigger and prevent any announces from being sent.

The extra check is not in torrent::update_tracker_timer though, so if it thinks there
is at least one endpoint ready to announce it will immediately trigger another
on_tracker_announce, again, and again.

Simple fix is to move the offending check below the code which populates
listen_socket_states so the the latter will execute unconditionally.
This commit is contained in:
Steven Siloti 2020-01-24 21:38:30 -08:00 committed by Arvid Norberg
parent 4054cbbaee
commit cc8cbcaf9d
1 changed files with 10 additions and 4 deletions

View File

@ -2937,10 +2937,11 @@ bool is_downloading_state(int const st)
for (auto& aep : ae.endpoints)
{
// 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;
// do not add code which continues to the next endpoint here!
// listen_socket_states needs to be populated even if none of the endpoints
// will be announcing for this tracker
// otherwise the early bail out when neither announce_to_all_trackers
// nor announce_to_all_tiers is set may be triggered prematurely
auto aep_state_iter = std::find_if(listen_socket_states.begin(), listen_socket_states.end()
, [&](announce_state const& s) { return s.socket == aep.socket; });
@ -2953,6 +2954,11 @@ bool is_downloading_state(int const st)
if (state.done) 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;
#ifndef TORRENT_DISABLE_LOGGING
if (should_log())
{