2015-09-18 06:23:45 +02:00
|
|
|
/*
|
|
|
|
|
2016-01-18 00:57:46 +01:00
|
|
|
Copyright (c) 2015-2016, Arvid Norberg
|
2015-09-18 06:23:45 +02:00
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in
|
|
|
|
the documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the author nor the names of its
|
|
|
|
contributors may be used to endorse or promote products derived
|
|
|
|
from this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "libtorrent/config.hpp"
|
|
|
|
#include "libtorrent/announce_entry.hpp"
|
2016-08-18 23:08:40 +02:00
|
|
|
#include "libtorrent/string_util.hpp" // for is_space
|
2015-09-18 06:23:45 +02:00
|
|
|
#include "libtorrent/aux_/time.hpp"
|
|
|
|
#include "libtorrent/aux_/session_settings.hpp"
|
|
|
|
|
2017-04-12 19:00:57 +02:00
|
|
|
namespace libtorrent {
|
|
|
|
|
2017-02-06 01:18:06 +01:00
|
|
|
namespace {
|
2015-09-18 06:23:45 +02:00
|
|
|
// wait at least 5 seconds before retrying a failed tracker
|
2017-02-06 01:18:06 +01:00
|
|
|
seconds32 constexpr tracker_retry_delay_min{5};
|
|
|
|
|
|
|
|
// never wait more than 60 minutes to retry a tracker
|
|
|
|
minutes32 constexpr tracker_retry_delay_max{60};
|
|
|
|
}
|
2015-09-18 06:23:45 +02:00
|
|
|
|
2017-03-24 00:35:46 +01:00
|
|
|
announce_entry::announce_entry(string_view u)
|
|
|
|
: url(u.to_string())
|
2015-09-18 06:23:45 +02:00
|
|
|
, fails(0)
|
|
|
|
, updating(false)
|
|
|
|
, source(0)
|
|
|
|
, verified(false)
|
|
|
|
, start_sent(false)
|
|
|
|
, complete_sent(false)
|
2016-01-17 03:24:04 +01:00
|
|
|
, triggered_manually(false)
|
2015-09-18 06:23:45 +02:00
|
|
|
{}
|
|
|
|
|
|
|
|
announce_entry::announce_entry()
|
2016-09-22 21:00:31 +02:00
|
|
|
: fails(0)
|
2015-09-18 06:23:45 +02:00
|
|
|
, updating(false)
|
|
|
|
, source(0)
|
|
|
|
, verified(false)
|
|
|
|
, start_sent(false)
|
|
|
|
, complete_sent(false)
|
2016-01-17 03:24:04 +01:00
|
|
|
, triggered_manually(false)
|
2015-09-18 06:23:45 +02:00
|
|
|
{}
|
|
|
|
|
2016-07-10 13:34:45 +02:00
|
|
|
announce_entry::~announce_entry() = default;
|
2017-03-27 20:40:19 +02:00
|
|
|
announce_entry::announce_entry(announce_entry const&) = default;
|
|
|
|
announce_entry& announce_entry::operator=(announce_entry const&) = default;
|
2015-09-18 06:23:45 +02:00
|
|
|
|
2016-11-10 23:08:32 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2015-09-18 06:23:45 +02:00
|
|
|
int announce_entry::next_announce_in() const
|
2016-12-05 02:15:49 +01:00
|
|
|
{ return int(total_seconds(next_announce - aux::time_now())); }
|
2015-09-18 06:23:45 +02:00
|
|
|
|
|
|
|
int announce_entry::min_announce_in() const
|
2016-12-05 02:15:49 +01:00
|
|
|
{ return int(total_seconds(min_announce - aux::time_now())); }
|
2016-11-10 23:08:32 +01:00
|
|
|
#endif
|
2015-09-18 06:23:45 +02:00
|
|
|
|
|
|
|
void announce_entry::reset()
|
|
|
|
{
|
|
|
|
start_sent = false;
|
2017-02-06 01:18:06 +01:00
|
|
|
next_announce = time_point32::min();
|
|
|
|
min_announce = time_point32::min();
|
2015-09-18 06:23:45 +02:00
|
|
|
}
|
|
|
|
|
2017-02-06 01:18:06 +01:00
|
|
|
void announce_entry::failed(int const backoff_ratio, seconds32 const retry_interval)
|
2015-09-18 06:23:45 +02:00
|
|
|
{
|
|
|
|
++fails;
|
|
|
|
// the exponential back-off ends up being:
|
|
|
|
// 7, 15, 27, 45, 95, 127, 165, ... seconds
|
|
|
|
// with the default tracker_backoff of 250
|
2017-02-06 01:18:06 +01:00
|
|
|
int const fail_square = int(fails) * int(fails);
|
|
|
|
seconds32 const delay = std::max(retry_interval
|
|
|
|
, std::min(duration_cast<seconds32>(tracker_retry_delay_max)
|
|
|
|
, tracker_retry_delay_min
|
|
|
|
+ fail_square * tracker_retry_delay_min * backoff_ratio / 100
|
|
|
|
));
|
|
|
|
next_announce = aux::time_now32() + delay;
|
2015-09-18 06:23:45 +02:00
|
|
|
updating = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool announce_entry::can_announce(time_point now, bool is_seed) const
|
|
|
|
{
|
|
|
|
// if we're a seed and we haven't sent a completed
|
|
|
|
// event, we need to let this announce through
|
2016-09-22 21:00:31 +02:00
|
|
|
bool const need_send_complete = is_seed && !complete_sent;
|
2015-09-18 06:23:45 +02:00
|
|
|
|
|
|
|
return now >= next_announce
|
|
|
|
&& (now >= min_announce || need_send_complete)
|
|
|
|
&& (fails < fail_limit || fail_limit == 0)
|
|
|
|
&& !updating;
|
|
|
|
}
|
|
|
|
|
|
|
|
void announce_entry::trim()
|
|
|
|
{
|
|
|
|
while (!url.empty() && is_space(url[0]))
|
|
|
|
url.erase(url.begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|