forked from premiere/premiere-libtorrent
changed how trackers are handled. Implements #297 by setting session_settings::announce_to_all_trackers to true
This commit is contained in:
parent
acbdbfc1ef
commit
d1a2b774e6
|
@ -1482,11 +1482,42 @@ ones with lower tier will always be tried before the one with higher tier number
|
||||||
std::string url;
|
std::string url;
|
||||||
boost::uint8_t tier;
|
boost::uint8_t tier;
|
||||||
boost::uint8_t fail_limit;
|
boost::uint8_t fail_limit;
|
||||||
|
boost::uint8_t fails;
|
||||||
|
|
||||||
|
enum tracker_source
|
||||||
|
{
|
||||||
|
source_torrent = 1,
|
||||||
|
source_client = 2,
|
||||||
|
source_magnet_link = 4,
|
||||||
|
source_tex = 8
|
||||||
|
};
|
||||||
|
boost::uint8_t source;
|
||||||
|
|
||||||
|
bool verified:1;
|
||||||
|
bool updating:1;
|
||||||
|
bool start_sent:1;
|
||||||
|
bool complete_sent:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
``fail_limit`` is the max number of failures to announce to this tracker in
|
``fail_limit`` is the max number of failures to announce to this tracker in
|
||||||
a row, before this tracker is not used anymore.
|
a row, before this tracker is not used anymore.
|
||||||
|
|
||||||
|
``fails`` is the number of times in a row we have failed to announce to this
|
||||||
|
tracker.
|
||||||
|
|
||||||
|
``source`` is a bitmask specifying which sources we got this tracker from.
|
||||||
|
|
||||||
|
``verified`` is set to true the first time we receive a valid response
|
||||||
|
from this tracker.
|
||||||
|
|
||||||
|
``updating`` is true while we're waiting for a response from the tracker.
|
||||||
|
|
||||||
|
``start_sent`` is set to true when we get a valid response from an announce
|
||||||
|
with event=started. If it is set, we won't send start in the subsequent
|
||||||
|
announces.
|
||||||
|
|
||||||
|
``complete_sent`` is set to true when we send a event=completed.
|
||||||
|
|
||||||
|
|
||||||
total_size() piece_length() piece_size() num_pieces()
|
total_size() piece_length() piece_size() num_pieces()
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
@ -3057,6 +3088,8 @@ that will be sent to the tracker. The user-agent is a good way to identify your
|
||||||
int auto_manage_startup;
|
int auto_manage_startup;
|
||||||
|
|
||||||
bool rate_limit_ip_overhead;
|
bool rate_limit_ip_overhead;
|
||||||
|
|
||||||
|
bool announce_to_all_trackers;
|
||||||
};
|
};
|
||||||
|
|
||||||
``user_agent`` this is the client identification to the tracker.
|
``user_agent`` this is the client identification to the tracker.
|
||||||
|
@ -3341,6 +3374,14 @@ have a fair chance to start downloading.
|
||||||
If ``rate_limit_ip_overhead`` is set to true, the estimated TCP/IP overhead is
|
If ``rate_limit_ip_overhead`` is set to true, the estimated TCP/IP overhead is
|
||||||
drained from the rate limiters, to avoid exceeding the limits with the total traffic
|
drained from the rate limiters, to avoid exceeding the limits with the total traffic
|
||||||
|
|
||||||
|
``announce_to_all_trackers`` controls how multi tracker torrents are
|
||||||
|
treated. If this is set to true, all trackers in the same tier are
|
||||||
|
announced to in parallel. If all trackers in tier 0 fails, all trackers
|
||||||
|
in tier 1 are announced as well. This is the uTorrent behavior. If it's
|
||||||
|
set to false, the behavior is as defined by the multi tracker
|
||||||
|
specification. It defaults to false, which is the same behavior previous
|
||||||
|
versions of libtorrent has had as well.
|
||||||
|
|
||||||
|
|
||||||
pe_settings
|
pe_settings
|
||||||
===========
|
===========
|
||||||
|
|
|
@ -154,6 +154,7 @@ void clear_home()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool print_trackers = false;
|
||||||
bool print_peers = false;
|
bool print_peers = false;
|
||||||
bool print_log = false;
|
bool print_log = false;
|
||||||
bool print_downloads = false;
|
bool print_downloads = false;
|
||||||
|
@ -849,6 +850,7 @@ int main(int ac, char* av[])
|
||||||
|
|
||||||
settings.user_agent = "client_test/" LIBTORRENT_VERSION;
|
settings.user_agent = "client_test/" LIBTORRENT_VERSION;
|
||||||
settings.urlseed_wait_retry = wait_retry;
|
settings.urlseed_wait_retry = wait_retry;
|
||||||
|
settings.announce_to_all_trackers = true;
|
||||||
|
|
||||||
settings.outgoing_ports.first = bind_port_start;
|
settings.outgoing_ports.first = bind_port_start;
|
||||||
settings.outgoing_ports.second = bind_port_end;
|
settings.outgoing_ports.second = bind_port_end;
|
||||||
|
@ -1214,6 +1216,7 @@ int main(int ac, char* av[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// toggle displays
|
// toggle displays
|
||||||
|
if (c == 't') print_trackers = !print_trackers;
|
||||||
if (c == 'i') print_peers = !print_peers;
|
if (c == 'i') print_peers = !print_peers;
|
||||||
if (c == 'l') print_log = !print_log;
|
if (c == 'l') print_log = !print_log;
|
||||||
if (c == 'd') print_downloads = !print_downloads;
|
if (c == 'd') print_downloads = !print_downloads;
|
||||||
|
@ -1348,7 +1351,7 @@ int main(int ac, char* av[])
|
||||||
<< std::hex << s.seed_rank << std::dec << " "
|
<< std::hex << s.seed_rank << std::dec << " "
|
||||||
<< s.last_scrape << "\n" << esc("0");
|
<< s.last_scrape << "\n" << esc("0");
|
||||||
|
|
||||||
if (torrent_index != active_torrent && s.state != torrent_status::seeding) continue;
|
if (torrent_index != active_torrent && s.state == torrent_status::seeding) continue;
|
||||||
char const* progress_bar_color = "33"; // yellow
|
char const* progress_bar_color = "33"; // yellow
|
||||||
if (s.state == torrent_status::checking_files
|
if (s.state == torrent_status::checking_files
|
||||||
|| s.state == torrent_status::downloading_metadata)
|
|| s.state == torrent_status::downloading_metadata)
|
||||||
|
@ -1388,6 +1391,7 @@ int main(int ac, char* av[])
|
||||||
<< to_string(t.seconds(), 2) << esc("0") << " ";
|
<< to_string(t.seconds(), 2) << esc("0") << " ";
|
||||||
out << "tracker: " << esc("36") << s.current_tracker << esc("0") << "\n";
|
out << "tracker: " << esc("36") << s.current_tracker << esc("0") << "\n";
|
||||||
|
|
||||||
|
if (torrent_index != active_torrent) continue;
|
||||||
active_handle = h;
|
active_handle = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1451,6 +1455,23 @@ int main(int ac, char* av[])
|
||||||
if (print_peers && !peers.empty())
|
if (print_peers && !peers.empty())
|
||||||
print_peer_info(out, peers);
|
print_peer_info(out, peers);
|
||||||
|
|
||||||
|
if (print_trackers)
|
||||||
|
{
|
||||||
|
std::vector<announce_entry> tr = h.trackers();
|
||||||
|
ptime now = time_now();
|
||||||
|
for (std::vector<announce_entry>::iterator i = tr.begin()
|
||||||
|
, end(tr.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
std::string url = i->url;
|
||||||
|
url.resize(55, ' ');
|
||||||
|
out << to_string(i->tier, 2) << " " << url << " "
|
||||||
|
<< to_string(i->fails, 3) << " " << (i->verified?"OK ":"- ");
|
||||||
|
if (i->updating) out << "updating";
|
||||||
|
else out << to_string(total_seconds(i->next_announce - now), 8);
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (print_downloads)
|
if (print_downloads)
|
||||||
{
|
{
|
||||||
h.get_download_queue(queue);
|
h.get_download_queue(queue);
|
||||||
|
|
|
@ -144,6 +144,7 @@ namespace libtorrent
|
||||||
, prioritize_partial_pieces(false)
|
, prioritize_partial_pieces(false)
|
||||||
, auto_manage_startup(120)
|
, auto_manage_startup(120)
|
||||||
, rate_limit_ip_overhead(true)
|
, rate_limit_ip_overhead(true)
|
||||||
|
, announce_to_all_trackers(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// this is the user agent that will be sent to the tracker
|
// this is the user agent that will be sent to the tracker
|
||||||
|
@ -456,6 +457,11 @@ namespace libtorrent
|
||||||
// drained from the rate limiters, to avoid exceeding
|
// drained from the rate limiters, to avoid exceeding
|
||||||
// the limits with the total traffic
|
// the limits with the total traffic
|
||||||
bool rate_limit_ip_overhead;
|
bool rate_limit_ip_overhead;
|
||||||
|
|
||||||
|
// if set to true, multi tracker torrents are treated
|
||||||
|
// the same way uTorrent treats them. It defaults to
|
||||||
|
// false in order to comply with the extension definition.
|
||||||
|
bool announce_to_all_trackers;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
|
@ -81,6 +81,8 @@ namespace libtorrent
|
||||||
class piece_manager;
|
class piece_manager;
|
||||||
struct torrent_plugin;
|
struct torrent_plugin;
|
||||||
struct bitfield;
|
struct bitfield;
|
||||||
|
struct announce_entry;
|
||||||
|
struct tracker_request;
|
||||||
|
|
||||||
namespace aux
|
namespace aux
|
||||||
{
|
{
|
||||||
|
@ -409,6 +411,8 @@ namespace libtorrent
|
||||||
// announce ourself at the last time we tried to announce
|
// announce ourself at the last time we tried to announce
|
||||||
const tcp::endpoint& current_tracker() const;
|
const tcp::endpoint& current_tracker() const;
|
||||||
|
|
||||||
|
announce_entry* find_tracker(tracker_request const& r);
|
||||||
|
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
// PIECE MANAGEMENT
|
// PIECE MANAGEMENT
|
||||||
|
|
||||||
|
@ -586,7 +590,7 @@ namespace libtorrent
|
||||||
{ return m_trackers; }
|
{ return m_trackers; }
|
||||||
|
|
||||||
void replace_trackers(std::vector<announce_entry> const& urls);
|
void replace_trackers(std::vector<announce_entry> const& urls);
|
||||||
void add_tracker(announce_entry const& urls);
|
void add_tracker(announce_entry const& url);
|
||||||
|
|
||||||
torrent_handle get_handle();
|
torrent_handle get_handle();
|
||||||
|
|
||||||
|
@ -656,8 +660,9 @@ namespace libtorrent
|
||||||
void on_piece_verified(int ret, disk_io_job const& j
|
void on_piece_verified(int ret, disk_io_job const& j
|
||||||
, boost::function<void(int)> f);
|
, boost::function<void(int)> f);
|
||||||
|
|
||||||
void try_next_tracker(tracker_request const& req);
|
|
||||||
int prioritize_tracker(int tracker_index);
|
int prioritize_tracker(int tracker_index);
|
||||||
|
int deprioritize_tracker(int tracker_index);
|
||||||
|
|
||||||
void on_country_lookup(error_code const& error, tcp::resolver::iterator i
|
void on_country_lookup(error_code const& error, tcp::resolver::iterator i
|
||||||
, boost::intrusive_ptr<peer_connection> p) const;
|
, boost::intrusive_ptr<peer_connection> p) const;
|
||||||
bool request_bandwidth_from_session(int channel) const;
|
bool request_bandwidth_from_session(int channel) const;
|
||||||
|
@ -718,9 +723,6 @@ namespace libtorrent
|
||||||
// the object.
|
// the object.
|
||||||
piece_manager* m_storage;
|
piece_manager* m_storage;
|
||||||
|
|
||||||
// the time of next tracker announce
|
|
||||||
ptime m_next_tracker_announce;
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
public:
|
public:
|
||||||
#endif
|
#endif
|
||||||
|
@ -757,7 +759,7 @@ namespace libtorrent
|
||||||
// used for tracker announces
|
// used for tracker announces
|
||||||
deadline_timer m_tracker_timer;
|
deadline_timer m_tracker_timer;
|
||||||
|
|
||||||
void restart_tracker_timer(ptime announce_at);
|
void update_tracker_timer();
|
||||||
|
|
||||||
static void on_tracker_announce_disp(boost::weak_ptr<torrent> p
|
static void on_tracker_announce_disp(boost::weak_ptr<torrent> p
|
||||||
, error_code const& e);
|
, error_code const& e);
|
||||||
|
@ -895,10 +897,6 @@ namespace libtorrent
|
||||||
// torrent object, these points are called connect_points.
|
// torrent object, these points are called connect_points.
|
||||||
int m_deficit_counter;
|
int m_deficit_counter;
|
||||||
|
|
||||||
// the number number of seconds between requests
|
|
||||||
// from the tracker
|
|
||||||
boost::int16_t m_duration;
|
|
||||||
|
|
||||||
// the sequence number for this torrent, this is a
|
// the sequence number for this torrent, this is a
|
||||||
// monotonically increasing number for each added torrent
|
// monotonically increasing number for each added torrent
|
||||||
boost::int16_t m_sequence_number;
|
boost::int16_t m_sequence_number;
|
||||||
|
@ -906,10 +904,6 @@ namespace libtorrent
|
||||||
// the index to the last tracker that worked
|
// the index to the last tracker that worked
|
||||||
boost::int8_t m_last_working_tracker;
|
boost::int8_t m_last_working_tracker;
|
||||||
|
|
||||||
// the tracker that is currently (or was last)
|
|
||||||
// tried
|
|
||||||
boost::int8_t m_currently_trying_tracker;
|
|
||||||
|
|
||||||
// the number of connection attempts that has
|
// the number of connection attempts that has
|
||||||
// failed in a row, this is currently used to
|
// failed in a row, this is currently used to
|
||||||
// determine the timeout until next try.
|
// determine the timeout until next try.
|
||||||
|
@ -979,27 +973,30 @@ namespace libtorrent
|
||||||
// this is true while tracker announcing is enabled
|
// this is true while tracker announcing is enabled
|
||||||
// is is disabled while paused and checking files
|
// is is disabled while paused and checking files
|
||||||
bool m_announcing:1;
|
bool m_announcing:1;
|
||||||
|
|
||||||
// this is true if event start has been sent to the tracker
|
|
||||||
bool m_start_sent:1;
|
|
||||||
|
|
||||||
// this is true if event completed has been sent to the tracker
|
|
||||||
bool m_complete_sent:1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ptime torrent::next_announce() const
|
inline ptime torrent::next_announce() const
|
||||||
{
|
{
|
||||||
return m_next_tracker_announce;
|
return m_tracker_timer.expires_at();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void torrent::force_tracker_request()
|
inline void torrent::force_tracker_request()
|
||||||
{
|
{
|
||||||
if (!is_paused()) announce_with_tracker();
|
if (is_paused()) return;
|
||||||
|
ptime now = time_now();
|
||||||
|
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
i->next_announce = now;
|
||||||
|
update_tracker_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void torrent::force_tracker_request(ptime t)
|
inline void torrent::force_tracker_request(ptime t)
|
||||||
{
|
{
|
||||||
if (!is_paused()) restart_tracker_timer(t);
|
if (is_paused()) return;
|
||||||
|
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
i->next_announce = t;
|
||||||
|
update_tracker_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void torrent::set_tracker_login(
|
inline void torrent::set_tracker_login(
|
||||||
|
|
|
@ -329,7 +329,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void clear_error() const;
|
void clear_error() const;
|
||||||
|
|
||||||
std::vector<announce_entry> const& trackers() const;
|
std::vector<announce_entry> trackers() const;
|
||||||
void replace_trackers(std::vector<announce_entry> const&) const;
|
void replace_trackers(std::vector<announce_entry> const&) const;
|
||||||
void add_tracker(announce_entry const&) const;
|
void add_tracker(announce_entry const&) const;
|
||||||
|
|
||||||
|
|
|
@ -66,15 +66,34 @@ namespace libtorrent
|
||||||
namespace gr = boost::gregorian;
|
namespace gr = boost::gregorian;
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// wait 60 seconds before retrying a failed tracker
|
||||||
|
tracker_retry_delay_min = 10
|
||||||
|
// when tracker_failed_max trackers
|
||||||
|
// has failed, wait 60 minutes instead
|
||||||
|
, tracker_retry_delay_max = 60 * 60
|
||||||
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT announce_entry
|
struct TORRENT_EXPORT announce_entry
|
||||||
{
|
{
|
||||||
announce_entry(std::string const& u)
|
announce_entry(std::string const& u)
|
||||||
: url(u), tier(0)
|
: url(u)
|
||||||
, fail_limit(3), fails(0)
|
, tier(0)
|
||||||
|
, fail_limit(3)
|
||||||
|
, fails(0)
|
||||||
|
, source(0)
|
||||||
, verified(false)
|
, verified(false)
|
||||||
|
, updating(false)
|
||||||
|
, start_sent(false)
|
||||||
|
, complete_sent(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string url;
|
std::string url;
|
||||||
|
|
||||||
|
// the time of next tracker announce
|
||||||
|
ptime next_announce;
|
||||||
|
|
||||||
boost::uint8_t tier;
|
boost::uint8_t tier;
|
||||||
// the number of times this tracker can fail
|
// the number of times this tracker can fail
|
||||||
// in a row before it's removed. 0 means unlimited
|
// in a row before it's removed. 0 means unlimited
|
||||||
|
@ -83,12 +102,56 @@ namespace libtorrent
|
||||||
// the number of times in a row this tracker has failed
|
// the number of times in a row this tracker has failed
|
||||||
boost::uint8_t fails;
|
boost::uint8_t fails;
|
||||||
|
|
||||||
|
enum tracker_source
|
||||||
|
{
|
||||||
|
source_torrent = 1,
|
||||||
|
source_client = 2,
|
||||||
|
source_magnet_link = 4,
|
||||||
|
source_tex = 8
|
||||||
|
};
|
||||||
|
// where did we get this tracker from
|
||||||
|
boost::uint8_t source;
|
||||||
|
|
||||||
// is set to true if we have ever received a response from
|
// is set to true if we have ever received a response from
|
||||||
// this tracker
|
// this tracker
|
||||||
bool verified:1;
|
bool verified:1;
|
||||||
|
|
||||||
bool can_announce() const
|
// true if we're currently trying to announce with
|
||||||
{ return fails < fail_limit || fail_limit == 0; }
|
// this tracker
|
||||||
|
bool updating:1;
|
||||||
|
|
||||||
|
// this is true if event start has been sent to the tracker
|
||||||
|
bool start_sent:1;
|
||||||
|
|
||||||
|
// this is true if event completed has been sent to the tracker
|
||||||
|
bool complete_sent:1;
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
start_sent = false;
|
||||||
|
next_announce = min_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
void failed()
|
||||||
|
{
|
||||||
|
++fails;
|
||||||
|
int delay = (std::min)(tracker_retry_delay_min + int(fails) * int(fails) * tracker_retry_delay_min
|
||||||
|
, int(tracker_retry_delay_max));
|
||||||
|
next_announce = time_now() + seconds(delay);
|
||||||
|
updating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool can_announce(ptime now) const
|
||||||
|
{
|
||||||
|
return now >= next_announce
|
||||||
|
&& (fails < fail_limit || fail_limit == 0)
|
||||||
|
&& !updating;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_working() const
|
||||||
|
{
|
||||||
|
return fails == 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
|
|
@ -221,6 +221,7 @@ namespace libtorrent { namespace
|
||||||
announce_entry e(added->list_string_value_at(i));
|
announce_entry e(added->list_string_value_at(i));
|
||||||
if (e.url.empty()) continue;
|
if (e.url.empty()) continue;
|
||||||
e.fail_limit = 3;
|
e.fail_limit = 3;
|
||||||
|
e.source = announce_entry::source_tex;
|
||||||
m_torrent.add_tracker(e);
|
m_torrent.add_tracker(e);
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
log_line << e.url << " ";
|
log_line << e.url << " ";
|
||||||
|
|
346
src/torrent.cpp
346
src/torrent.cpp
|
@ -86,16 +86,6 @@ using libtorrent::aux::session_impl;
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
// wait 60 seconds before retrying a failed tracker
|
|
||||||
tracker_retry_delay_min = 60
|
|
||||||
// when tracker_failed_max trackers
|
|
||||||
// has failed, wait 10 minutes instead
|
|
||||||
, tracker_retry_delay_max = 10 * 60
|
|
||||||
, tracker_failed_max = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
struct find_peer_by_ip
|
struct find_peer_by_ip
|
||||||
{
|
{
|
||||||
find_peer_by_ip(tcp::endpoint const& a, const torrent* t)
|
find_peer_by_ip(tcp::endpoint const& a, const torrent* t)
|
||||||
|
@ -156,7 +146,6 @@ namespace libtorrent
|
||||||
, m_last_scrape(min_time())
|
, m_last_scrape(min_time())
|
||||||
, m_torrent_file(tf)
|
, m_torrent_file(tf)
|
||||||
, m_storage(0)
|
, m_storage(0)
|
||||||
, m_next_tracker_announce(time_now())
|
|
||||||
, m_host_resolver(ses.m_io_service)
|
, m_host_resolver(ses.m_io_service)
|
||||||
, m_lsd_announce_timer(ses.m_io_service)
|
, m_lsd_announce_timer(ses.m_io_service)
|
||||||
, m_tracker_timer(ses.m_io_service)
|
, m_tracker_timer(ses.m_io_service)
|
||||||
|
@ -182,11 +171,8 @@ namespace libtorrent
|
||||||
, m_complete(-1)
|
, m_complete(-1)
|
||||||
, m_incomplete(-1)
|
, m_incomplete(-1)
|
||||||
, m_deficit_counter(0)
|
, m_deficit_counter(0)
|
||||||
, m_duration(1800)
|
|
||||||
, m_sequence_number(seq)
|
, m_sequence_number(seq)
|
||||||
, m_last_working_tracker(-1)
|
, m_last_working_tracker(-1)
|
||||||
, m_currently_trying_tracker(-1)
|
|
||||||
, m_failed_trackers(0)
|
|
||||||
, m_time_scaler(0)
|
, m_time_scaler(0)
|
||||||
, m_abort(false)
|
, m_abort(false)
|
||||||
, m_paused(paused)
|
, m_paused(paused)
|
||||||
|
@ -201,8 +187,6 @@ namespace libtorrent
|
||||||
, m_has_incoming(false)
|
, m_has_incoming(false)
|
||||||
, m_files_checked(false)
|
, m_files_checked(false)
|
||||||
, m_announcing(false)
|
, m_announcing(false)
|
||||||
, m_start_sent(false)
|
|
||||||
, m_complete_sent(false)
|
|
||||||
{
|
{
|
||||||
if (resume_data) m_resume_data.swap(*resume_data);
|
if (resume_data) m_resume_data.swap(*resume_data);
|
||||||
|
|
||||||
|
@ -237,7 +221,6 @@ namespace libtorrent
|
||||||
, m_last_scrape(min_time())
|
, m_last_scrape(min_time())
|
||||||
, m_torrent_file(new torrent_info(info_hash))
|
, m_torrent_file(new torrent_info(info_hash))
|
||||||
, m_storage(0)
|
, m_storage(0)
|
||||||
, m_next_tracker_announce(time_now())
|
|
||||||
, m_host_resolver(ses.m_io_service)
|
, m_host_resolver(ses.m_io_service)
|
||||||
, m_lsd_announce_timer(ses.m_io_service)
|
, m_lsd_announce_timer(ses.m_io_service)
|
||||||
, m_tracker_timer(ses.m_io_service)
|
, m_tracker_timer(ses.m_io_service)
|
||||||
|
@ -262,11 +245,8 @@ namespace libtorrent
|
||||||
, m_complete(-1)
|
, m_complete(-1)
|
||||||
, m_incomplete(-1)
|
, m_incomplete(-1)
|
||||||
, m_deficit_counter(0)
|
, m_deficit_counter(0)
|
||||||
, m_duration(1800)
|
|
||||||
, m_sequence_number(seq)
|
, m_sequence_number(seq)
|
||||||
, m_last_working_tracker(-1)
|
, m_last_working_tracker(-1)
|
||||||
, m_currently_trying_tracker(-1)
|
|
||||||
, m_failed_trackers(0)
|
|
||||||
, m_time_scaler(0)
|
, m_time_scaler(0)
|
||||||
, m_abort(false)
|
, m_abort(false)
|
||||||
, m_paused(paused)
|
, m_paused(paused)
|
||||||
|
@ -281,8 +261,6 @@ namespace libtorrent
|
||||||
, m_has_incoming(false)
|
, m_has_incoming(false)
|
||||||
, m_files_checked(false)
|
, m_files_checked(false)
|
||||||
, m_announcing(false)
|
, m_announcing(false)
|
||||||
, m_start_sent(false)
|
|
||||||
, m_complete_sent(false)
|
|
||||||
{
|
{
|
||||||
if (resume_data) m_resume_data.swap(*resume_data);
|
if (resume_data) m_resume_data.swap(*resume_data);
|
||||||
|
|
||||||
|
@ -304,6 +282,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
m_trackers.push_back(announce_entry(tracker_url));
|
m_trackers.push_back(announce_entry(tracker_url));
|
||||||
m_trackers.back().fail_limit = 0;
|
m_trackers.back().fail_limit = 0;
|
||||||
|
m_trackers.back().source = announce_entry::source_magnet_link;
|
||||||
m_torrent_file->add_tracker(tracker_url);
|
m_torrent_file->add_tracker(tracker_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,7 +334,12 @@ namespace libtorrent
|
||||||
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
|
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
|
||||||
if (m_trackers.empty()) return true;
|
if (m_trackers.empty()) return true;
|
||||||
|
|
||||||
return m_failed_trackers > 0 || !m_ses.settings().use_dht_as_fallback;
|
int verified_trackers = 0;
|
||||||
|
for (std::vector<announce_entry>::const_iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
if (i->verified) ++verified_trackers;
|
||||||
|
|
||||||
|
return verified_trackers == 0 || !m_settings.use_dht_as_fallback;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -919,16 +903,8 @@ namespace libtorrent
|
||||||
|
|
||||||
if (m_trackers.empty()) return;
|
if (m_trackers.empty()) return;
|
||||||
|
|
||||||
restart_tracker_timer(time_now() + seconds(tracker_retry_delay_max));
|
|
||||||
|
|
||||||
if (m_abort) e = tracker_request::stopped;
|
if (m_abort) e = tracker_request::stopped;
|
||||||
|
|
||||||
if (e == tracker_request::none)
|
|
||||||
{
|
|
||||||
if (!m_start_sent) e = tracker_request::started;
|
|
||||||
if (!m_complete_sent && is_seed()) e = tracker_request::completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
tracker_request req;
|
tracker_request req;
|
||||||
req.info_hash = m_torrent_file->info_hash();
|
req.info_hash = m_torrent_file->info_hash();
|
||||||
req.pid = m_ses.get_peer_id();
|
req.pid = m_ses.get_peer_id();
|
||||||
|
@ -942,11 +918,6 @@ namespace libtorrent
|
||||||
if (ep != tcp::endpoint())
|
if (ep != tcp::endpoint())
|
||||||
req.ipv6 = ep.address().to_string(ec);
|
req.ipv6 = ep.address().to_string(ec);
|
||||||
|
|
||||||
if (m_currently_trying_tracker == -1) m_currently_trying_tracker = 0;
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker >= 0);
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker < int(m_trackers.size()));
|
|
||||||
req.url = m_trackers[m_currently_trying_tracker].url;
|
|
||||||
TORRENT_ASSERT(m_trackers[m_currently_trying_tracker].can_announce());
|
|
||||||
// if we are aborting. we don't want any new peers
|
// if we are aborting. we don't want any new peers
|
||||||
req.num_want = (req.event == tracker_request::stopped)
|
req.num_want = (req.event == tracker_request::stopped)
|
||||||
?0:m_settings.num_want;
|
?0:m_settings.num_want;
|
||||||
|
@ -955,24 +926,51 @@ namespace libtorrent
|
||||||
?0:m_ses.m_listen_sockets.front().external_port;
|
?0:m_ses.m_listen_sockets.front().external_port;
|
||||||
req.key = m_ses.m_key;
|
req.key = m_ses.m_key;
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
ptime now = time_now();
|
||||||
if (m_abort)
|
|
||||||
{
|
|
||||||
boost::shared_ptr<aux::tracker_logger> tl(new aux::tracker_logger(m_ses));
|
|
||||||
m_ses.m_tracker_manager.queue_request(m_ses.m_io_service, m_ses.m_half_open, req
|
|
||||||
, tracker_login(), m_ses.m_listen_interface.address(), tl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
m_ses.m_tracker_manager.queue_request(m_ses.m_io_service, m_ses.m_half_open, req
|
|
||||||
, tracker_login(), m_ses.m_listen_interface.address()
|
|
||||||
, m_abort?boost::shared_ptr<torrent>():shared_from_this());
|
|
||||||
|
|
||||||
if (m_ses.m_alerts.should_post<tracker_announce_alert>())
|
int tier = INT_MAX;
|
||||||
|
for (int i = 0; i < m_trackers.size(); ++i)
|
||||||
{
|
{
|
||||||
m_ses.m_alerts.post_alert(
|
announce_entry& ae = m_trackers[i];
|
||||||
tracker_announce_alert(get_handle(), req.url, req.event));
|
if (ae.tier > tier) break;
|
||||||
|
if (ae.is_working()) tier = ae.tier;
|
||||||
|
if (!ae.can_announce(now))
|
||||||
|
{
|
||||||
|
if (ae.is_working() && !m_settings.announce_to_all_trackers) break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
req.url = ae.url;
|
||||||
|
req.event = e;
|
||||||
|
if (req.event == tracker_request::none)
|
||||||
|
{
|
||||||
|
if (!ae.start_sent) req.event = tracker_request::started;
|
||||||
|
if (!ae.complete_sent && is_seed()) req.event = tracker_request::completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
if (m_abort)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<aux::tracker_logger> tl(new aux::tracker_logger(m_ses));
|
||||||
|
m_ses.m_tracker_manager.queue_request(m_ses.m_io_service, m_ses.m_half_open, req
|
||||||
|
, tracker_login(), m_ses.m_listen_interface.address(), tl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
m_ses.m_tracker_manager.queue_request(m_ses.m_io_service, m_ses.m_half_open, req
|
||||||
|
, tracker_login(), m_ses.m_listen_interface.address()
|
||||||
|
, m_abort?boost::shared_ptr<torrent>():shared_from_this());
|
||||||
|
ae.updating = true;
|
||||||
|
|
||||||
|
if (m_ses.m_alerts.should_post<tracker_announce_alert>())
|
||||||
|
{
|
||||||
|
m_ses.m_alerts.post_alert(
|
||||||
|
tracker_announce_alert(get_handle(), req.url, req.event));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ae.is_working() && !m_settings.announce_to_all_trackers) break;
|
||||||
}
|
}
|
||||||
|
update_tracker_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::scrape_tracker()
|
void torrent::scrape_tracker()
|
||||||
|
@ -980,7 +978,6 @@ namespace libtorrent
|
||||||
if (m_trackers.empty()) return;
|
if (m_trackers.empty()) return;
|
||||||
|
|
||||||
int i = m_last_working_tracker;
|
int i = m_last_working_tracker;
|
||||||
if (i == -1) i = m_currently_trying_tracker;
|
|
||||||
if (i == -1) i = 0;
|
if (i == -1) i = 0;
|
||||||
|
|
||||||
tracker_request req;
|
tracker_request req;
|
||||||
|
@ -1037,42 +1034,36 @@ namespace libtorrent
|
||||||
if (external_ip != address())
|
if (external_ip != address())
|
||||||
m_ses.set_external_address(external_ip);
|
m_ses.set_external_address(external_ip);
|
||||||
|
|
||||||
if (!m_start_sent && r.event == tracker_request::started)
|
ptime now = time_now();
|
||||||
m_start_sent = true;
|
|
||||||
if (!m_complete_sent && r.event == tracker_request::completed)
|
|
||||||
m_complete_sent = true;
|
|
||||||
|
|
||||||
m_failed_trackers = 0;
|
if (interval < m_settings.min_announce_interval)
|
||||||
|
interval = m_settings.min_announce_interval;
|
||||||
|
|
||||||
if (interval < m_ses.settings().min_announce_interval)
|
announce_entry* ae = find_tracker(r);
|
||||||
interval = m_ses.settings().min_announce_interval;
|
if (ae)
|
||||||
|
|
||||||
if (m_currently_trying_tracker != -1)
|
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker >= 0);
|
if (!ae->start_sent && r.event == tracker_request::started)
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker < int(m_trackers.size()));
|
ae->start_sent = true;
|
||||||
TORRENT_ASSERT(m_trackers[m_currently_trying_tracker].url == r.url);
|
if (!ae->complete_sent && r.event == tracker_request::completed)
|
||||||
|
ae->complete_sent = true;
|
||||||
m_trackers[m_currently_trying_tracker].verified = true;
|
ae->verified = true;
|
||||||
|
ae->updating = false;
|
||||||
m_last_working_tracker
|
ae->fails = 0;
|
||||||
= prioritize_tracker(m_currently_trying_tracker);
|
ae->next_announce = now + seconds(interval);
|
||||||
m_currently_trying_tracker = 0;
|
int tracker_index = ae - &m_trackers[0];
|
||||||
TORRENT_ASSERT(m_trackers[m_currently_trying_tracker].url == r.url);
|
m_last_working_tracker = prioritize_tracker(tracker_index);
|
||||||
}
|
}
|
||||||
|
update_tracker_timer();
|
||||||
m_duration = interval;
|
|
||||||
restart_tracker_timer(time_now() + seconds(m_duration));
|
|
||||||
|
|
||||||
if (complete >= 0) m_complete = complete;
|
if (complete >= 0) m_complete = complete;
|
||||||
if (incomplete >= 0) m_incomplete = incomplete;
|
if (incomplete >= 0) m_incomplete = incomplete;
|
||||||
if (complete >= 0 && incomplete >= 0)
|
if (complete >= 0 && incomplete >= 0)
|
||||||
m_last_scrape = time_now();
|
m_last_scrape = now;
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "TRACKER RESPONSE:\n"
|
s << "TRACKER RESPONSE:\n"
|
||||||
"interval: " << m_duration << "\n"
|
"interval: " << interval << "\n"
|
||||||
"peers:\n";
|
"peers:\n";
|
||||||
for (std::vector<peer_entry>::const_iterator i = peer_list.begin();
|
for (std::vector<peer_entry>::const_iterator i = peer_list.begin();
|
||||||
i != peer_list.end(); ++i)
|
i != peer_list.end(); ++i)
|
||||||
|
@ -1117,16 +1108,6 @@ namespace libtorrent
|
||||||
get_handle(), peer_list.size(), r.url));
|
get_handle(), peer_list.size(), r.url));
|
||||||
}
|
}
|
||||||
m_got_tracker_response = true;
|
m_got_tracker_response = true;
|
||||||
|
|
||||||
// when the tracker succeeds, reset the fails-in-a-row counter
|
|
||||||
if (m_currently_trying_tracker != -1)
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker >= 0);
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker < int(m_trackers.size()));
|
|
||||||
TORRENT_ASSERT(m_trackers[m_currently_trying_tracker].url == r.url);
|
|
||||||
|
|
||||||
m_trackers[m_currently_trying_tracker].fails = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::on_peer_name_lookup(error_code const& e, tcp::resolver::iterator host
|
void torrent::on_peer_name_lookup(error_code const& e, tcp::resolver::iterator host
|
||||||
|
@ -2083,7 +2064,10 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
m_trackers = urls;
|
m_trackers = urls;
|
||||||
m_last_working_tracker = -1;
|
m_last_working_tracker = -1;
|
||||||
m_currently_trying_tracker = -1;
|
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
if (i->source == 0) i->source = announce_entry::source_client;
|
||||||
|
|
||||||
if (!m_trackers.empty()) start_announcing();
|
if (!m_trackers.empty()) start_announcing();
|
||||||
else stop_announcing();
|
else stop_announcing();
|
||||||
}
|
}
|
||||||
|
@ -2092,12 +2076,16 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
std::vector<announce_entry>::iterator k = std::find_if(m_trackers.begin()
|
std::vector<announce_entry>::iterator k = std::find_if(m_trackers.begin()
|
||||||
, m_trackers.end(), boost::bind(&announce_entry::url, _1) == url.url);
|
, m_trackers.end(), boost::bind(&announce_entry::url, _1) == url.url);
|
||||||
if (k != m_trackers.end()) return;
|
if (k != m_trackers.end())
|
||||||
|
{
|
||||||
|
k->source |= url.source;
|
||||||
|
return;
|
||||||
|
}
|
||||||
k = std::upper_bound(m_trackers.begin(), m_trackers.end(), url
|
k = std::upper_bound(m_trackers.begin(), m_trackers.end(), url
|
||||||
, boost::bind(&announce_entry::tier, _1) < boost::bind(&announce_entry::tier, _2));
|
, boost::bind(&announce_entry::tier, _1) < boost::bind(&announce_entry::tier, _2));
|
||||||
if (k - m_trackers.begin() < m_currently_trying_tracker) ++m_currently_trying_tracker;
|
|
||||||
if (k - m_trackers.begin() < m_last_working_tracker) ++m_last_working_tracker;
|
if (k - m_trackers.begin() < m_last_working_tracker) ++m_last_working_tracker;
|
||||||
m_trackers.insert(k, url);
|
k = m_trackers.insert(k, url);
|
||||||
|
if (k->source == 0) k->source = announce_entry::source_client;
|
||||||
if (!m_trackers.empty()) start_announcing();
|
if (!m_trackers.empty()) start_announcing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3454,7 +3442,16 @@ namespace libtorrent
|
||||||
m_picker.reset();
|
m_picker.reset();
|
||||||
|
|
||||||
set_state(torrent_status::seeding);
|
set_state(torrent_status::seeding);
|
||||||
if (!m_complete_sent && m_announcing) announce_with_tracker();
|
if (!m_announcing) return;
|
||||||
|
|
||||||
|
ptime now = time_now();
|
||||||
|
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
if (i->complete_sent) continue;
|
||||||
|
i->next_announce = now;
|
||||||
|
}
|
||||||
|
announce_with_tracker();
|
||||||
}
|
}
|
||||||
|
|
||||||
// this will move the tracker with the given index
|
// this will move the tracker with the given index
|
||||||
|
@ -3470,67 +3467,30 @@ namespace libtorrent
|
||||||
|
|
||||||
while (index > 0 && m_trackers[index].tier == m_trackers[index-1].tier)
|
while (index > 0 && m_trackers[index].tier == m_trackers[index-1].tier)
|
||||||
{
|
{
|
||||||
std::swap(m_trackers[index].url, m_trackers[index-1].url);
|
using std::swap;
|
||||||
|
swap(m_trackers[index], m_trackers[index-1]);
|
||||||
|
if (m_last_working_tracker == index) ++m_last_working_tracker;
|
||||||
--index;
|
--index;
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::try_next_tracker(tracker_request const& req)
|
int torrent::deprioritize_tracker(int index)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_trackers.empty())
|
TORRENT_ASSERT(index >= 0);
|
||||||
|
TORRENT_ASSERT(index < m_trackers.size());
|
||||||
|
if (index >= (int)m_trackers.size()) return -1;
|
||||||
|
|
||||||
|
while (index < m_trackers.size() - 1 && m_trackers[index].tier == m_trackers[index + 1].tier)
|
||||||
{
|
{
|
||||||
m_currently_trying_tracker = -1;
|
using std::swap;
|
||||||
return;
|
swap(m_trackers[index], m_trackers[index + 1]);
|
||||||
|
if (m_last_working_tracker == index) --m_last_working_tracker;
|
||||||
|
++index;
|
||||||
}
|
}
|
||||||
|
return index;
|
||||||
// increase tracker index until we find a tracker we can use
|
|
||||||
// or until we reach the end of the tracker list
|
|
||||||
do
|
|
||||||
{
|
|
||||||
++m_currently_trying_tracker;
|
|
||||||
} while (m_currently_trying_tracker < m_trackers.size()
|
|
||||||
&& !m_trackers[m_currently_trying_tracker].can_announce());
|
|
||||||
|
|
||||||
if (m_currently_trying_tracker < int(m_trackers.size()))
|
|
||||||
{
|
|
||||||
announce_with_tracker(req.event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int delay = tracker_retry_delay_min
|
|
||||||
+ (std::min)(int(m_failed_trackers), int(tracker_failed_max))
|
|
||||||
* (tracker_retry_delay_max - tracker_retry_delay_min)
|
|
||||||
/ tracker_failed_max;
|
|
||||||
|
|
||||||
++m_failed_trackers;
|
|
||||||
// if we've looped the tracker list, wait a bit before retrying
|
|
||||||
m_currently_trying_tracker = -1;
|
|
||||||
|
|
||||||
// if we're stopping, just give up. Don't bother retrying
|
|
||||||
if (req.event == tracker_request::stopped)
|
|
||||||
return;
|
|
||||||
|
|
||||||
restart_tracker_timer(time_now() + seconds(delay));
|
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
|
||||||
if (m_abort) return;
|
|
||||||
|
|
||||||
// only start the announce if we want to announce with the dht
|
|
||||||
ptime now = time_now();
|
|
||||||
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
|
||||||
{
|
|
||||||
// force the DHT to reannounce
|
|
||||||
m_last_dht_announce = now;
|
|
||||||
boost::weak_ptr<torrent> self(shared_from_this());
|
|
||||||
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
|
||||||
, m_ses.m_listen_sockets.front().external_port
|
|
||||||
, bind(&torrent::on_dht_announce_response_disp, self, _1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::files_checked()
|
void torrent::files_checked()
|
||||||
|
@ -3562,7 +3522,9 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_complete_sent = true;
|
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
i->complete_sent = true;
|
||||||
if (m_state != torrent_status::finished) finished();
|
if (m_state != torrent_status::finished) finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4206,14 +4168,31 @@ namespace libtorrent
|
||||||
start_announcing();
|
start_announcing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::restart_tracker_timer(ptime announce_at)
|
void torrent::update_tracker_timer()
|
||||||
{
|
{
|
||||||
if (!m_announcing) return;
|
if (!m_announcing) return;
|
||||||
|
|
||||||
m_next_tracker_announce = announce_at;
|
ptime next_announce = max_time();
|
||||||
|
int tier = INT_MAX;
|
||||||
|
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
if (i->tier > tier) break;
|
||||||
|
if (i->is_working()) tier = i->tier;
|
||||||
|
if (i->fails >= i->fail_limit && i->fail_limit != 0) continue;
|
||||||
|
if (i->updating) continue;
|
||||||
|
if (i->next_announce < next_announce) next_announce = i->next_announce;
|
||||||
|
if (i->is_working() && !m_settings.announce_to_all_trackers) break;
|
||||||
|
}
|
||||||
|
if (next_announce == max_time()) return;
|
||||||
|
|
||||||
|
// since we don't know if we have to re-issue the async_wait or not
|
||||||
|
// always do it
|
||||||
|
// if (m_tracker_timer.expires_at() <= next_announce) return;
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
boost::weak_ptr<torrent> self(shared_from_this());
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
m_tracker_timer.expires_at(m_next_tracker_announce, ec);
|
m_tracker_timer.expires_at(next_announce, ec);
|
||||||
m_tracker_timer.async_wait(bind(&torrent::on_tracker_announce_disp, self, _1));
|
m_tracker_timer.async_wait(bind(&torrent::on_tracker_announce_disp, self, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4231,7 +4210,8 @@ namespace libtorrent
|
||||||
if (!m_trackers.empty())
|
if (!m_trackers.empty())
|
||||||
{
|
{
|
||||||
// tell the tracker that we're back
|
// tell the tracker that we're back
|
||||||
m_start_sent = false;
|
std::for_each(m_trackers.begin(), m_trackers.end()
|
||||||
|
, bind(&announce_entry::reset, _1));
|
||||||
m_stat.clear();
|
m_stat.clear();
|
||||||
announce_with_tracker();
|
announce_with_tracker();
|
||||||
}
|
}
|
||||||
|
@ -4258,8 +4238,11 @@ namespace libtorrent
|
||||||
|
|
||||||
m_announcing = false;
|
m_announcing = false;
|
||||||
|
|
||||||
if (!m_trackers.empty())
|
ptime now = time_now();
|
||||||
announce_with_tracker(tracker_request::stopped);
|
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
|
||||||
|
, end(m_trackers.end()); i != end; ++i)
|
||||||
|
i->next_announce = now;
|
||||||
|
announce_with_tracker(tracker_request::stopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::second_tick(stat& accumulator, float tick_interval)
|
void torrent::second_tick(stat& accumulator, float tick_interval)
|
||||||
|
@ -4447,6 +4430,15 @@ namespace libtorrent
|
||||||
return m_tracker_address;
|
return m_tracker_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
announce_entry* torrent::find_tracker(tracker_request const& r)
|
||||||
|
{
|
||||||
|
std::vector<announce_entry>::iterator i = std::find_if(
|
||||||
|
m_trackers.begin(), m_trackers.end()
|
||||||
|
, bind(&announce_entry::url, _1) == r.url);
|
||||||
|
if (i == m_trackers.end()) return 0;
|
||||||
|
return &*i;
|
||||||
|
}
|
||||||
|
|
||||||
void torrent::file_progress(std::vector<float>& fp) const
|
void torrent::file_progress(std::vector<float>& fp) const
|
||||||
{
|
{
|
||||||
fp.clear();
|
fp.clear();
|
||||||
|
@ -4683,19 +4675,19 @@ namespace libtorrent
|
||||||
if (st.next_announce.is_negative() || is_paused())
|
if (st.next_announce.is_negative() || is_paused())
|
||||||
st.next_announce = boost::posix_time::seconds(0);
|
st.next_announce = boost::posix_time::seconds(0);
|
||||||
|
|
||||||
st.announce_interval = boost::posix_time::seconds(m_duration);
|
st.announce_interval = boost::posix_time::seconds(0);
|
||||||
|
|
||||||
if (m_last_working_tracker >= 0)
|
if (m_last_working_tracker >= 0)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_last_working_tracker < m_trackers.size());
|
TORRENT_ASSERT(m_last_working_tracker < m_trackers.size());
|
||||||
st.current_tracker
|
st.current_tracker = m_trackers[m_last_working_tracker].url;
|
||||||
= m_trackers[m_last_working_tracker].url;
|
|
||||||
}
|
}
|
||||||
else if (m_currently_trying_tracker >= 0)
|
else
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker < m_trackers.size());
|
std::vector<announce_entry>::const_iterator i;
|
||||||
st.current_tracker
|
for (i = m_trackers.begin(); i != m_trackers.end(); ++i)
|
||||||
= m_trackers[m_currently_trying_tracker].url;
|
if (i->updating) break;
|
||||||
|
if (i != m_trackers.end()) st.current_tracker = i->url;
|
||||||
}
|
}
|
||||||
|
|
||||||
st.num_uploads = m_num_uploads;
|
st.num_uploads = m_num_uploads;
|
||||||
|
@ -4797,18 +4789,17 @@ namespace libtorrent
|
||||||
|
|
||||||
if (r.kind == tracker_request::announce_request)
|
if (r.kind == tracker_request::announce_request)
|
||||||
{
|
{
|
||||||
|
announce_entry* ae = find_tracker(r);
|
||||||
|
if (ae)
|
||||||
|
{
|
||||||
|
ae->failed();
|
||||||
|
int tracker_index = ae - &m_trackers[0];
|
||||||
|
deprioritize_tracker(tracker_index);
|
||||||
|
}
|
||||||
if (m_ses.m_alerts.should_post<tracker_error_alert>())
|
if (m_ses.m_alerts.should_post<tracker_error_alert>())
|
||||||
{
|
{
|
||||||
m_ses.m_alerts.post_alert(tracker_error_alert(get_handle()
|
m_ses.m_alerts.post_alert(tracker_error_alert(get_handle()
|
||||||
, m_failed_trackers + 1, 0, r.url, "tracker timed out"));
|
, ae?ae->fails:0, 0, r.url, "tracker timed out"));
|
||||||
}
|
|
||||||
if (m_currently_trying_tracker != -1)
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker >= 0);
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker < int(m_trackers.size()));
|
|
||||||
TORRENT_ASSERT(m_trackers[m_currently_trying_tracker].url == r.url);
|
|
||||||
|
|
||||||
++m_trackers[m_currently_trying_tracker].fails;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (r.kind == tracker_request::scrape_request)
|
else if (r.kind == tracker_request::scrape_request)
|
||||||
|
@ -4819,9 +4810,7 @@ namespace libtorrent
|
||||||
, r.url, "tracker timed out"));
|
, r.url, "tracker timed out"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
update_tracker_timer();
|
||||||
if (r.kind == tracker_request::announce_request)
|
|
||||||
try_next_tracker(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: with some response codes, we should just consider
|
// TODO: with some response codes, we should just consider
|
||||||
|
@ -4839,18 +4828,17 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
if (r.kind == tracker_request::announce_request)
|
if (r.kind == tracker_request::announce_request)
|
||||||
{
|
{
|
||||||
|
announce_entry* ae = find_tracker(r);
|
||||||
|
if (ae)
|
||||||
|
{
|
||||||
|
ae->failed();
|
||||||
|
int tracker_index = ae - &m_trackers[0];
|
||||||
|
deprioritize_tracker(tracker_index);
|
||||||
|
}
|
||||||
if (m_ses.m_alerts.should_post<tracker_error_alert>())
|
if (m_ses.m_alerts.should_post<tracker_error_alert>())
|
||||||
{
|
{
|
||||||
m_ses.m_alerts.post_alert(tracker_error_alert(get_handle()
|
m_ses.m_alerts.post_alert(tracker_error_alert(get_handle()
|
||||||
, m_failed_trackers + 1, response_code, r.url, str));
|
, ae?ae->fails:0, response_code, r.url, str));
|
||||||
}
|
|
||||||
if (m_currently_trying_tracker != -1)
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker >= 0);
|
|
||||||
TORRENT_ASSERT(m_currently_trying_tracker < int(m_trackers.size()));
|
|
||||||
TORRENT_ASSERT(m_trackers[m_currently_trying_tracker].url == r.url);
|
|
||||||
|
|
||||||
++m_trackers[m_currently_trying_tracker].fails;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (r.kind == tracker_request::scrape_request)
|
else if (r.kind == tracker_request::scrape_request)
|
||||||
|
@ -4860,9 +4848,7 @@ namespace libtorrent
|
||||||
m_ses.m_alerts.post_alert(scrape_failed_alert(get_handle(), r.url, str));
|
m_ses.m_alerts.post_alert(scrape_failed_alert(get_handle(), r.url, str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
update_tracker_timer();
|
||||||
if (r.kind == tracker_request::announce_request)
|
|
||||||
try_next_tracker(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -478,7 +478,7 @@ namespace libtorrent
|
||||||
// ============ end deprecation ===============
|
// ============ end deprecation ===============
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<announce_entry> const& torrent_handle::trackers() const
|
std::vector<announce_entry> torrent_handle::trackers() const
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
const static std::vector<announce_entry> empty;
|
const static std::vector<announce_entry> empty;
|
||||||
|
|
|
@ -540,6 +540,7 @@ namespace libtorrent
|
||||||
if (e.url.empty()) continue;
|
if (e.url.empty()) continue;
|
||||||
e.tier = j;
|
e.tier = j;
|
||||||
e.fail_limit = 0;
|
e.fail_limit = 0;
|
||||||
|
e.source = announce_entry::source_torrent;
|
||||||
m_urls.push_back(e);
|
m_urls.push_back(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -565,6 +566,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
announce_entry e(torrent_file.dict_find_string_value("announce"));
|
announce_entry e(torrent_file.dict_find_string_value("announce"));
|
||||||
e.fail_limit = 0;
|
e.fail_limit = 0;
|
||||||
|
e.source = announce_entry::source_torrent;
|
||||||
if (!e.url.empty()) m_urls.push_back(e);
|
if (!e.url.empty()) m_urls.push_back(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,11 +640,12 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
announce_entry e(url);
|
announce_entry e(url);
|
||||||
e.tier = tier;
|
e.tier = tier;
|
||||||
|
e.source = announce_entry::source_client;
|
||||||
m_urls.push_back(e);
|
m_urls.push_back(e);
|
||||||
|
|
||||||
using boost::bind;
|
using boost::bind;
|
||||||
std::sort(m_urls.begin(), m_urls.end(), boost::bind<bool>(std::less<int>()
|
std::sort(m_urls.begin(), m_urls.end(), bind(&announce_entry::tier, _1)
|
||||||
, bind(&announce_entry::tier, _1), bind(&announce_entry::tier, _2)));
|
< bind(&announce_entry::tier, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
|
|
Loading…
Reference in New Issue