diff --git a/ChangeLog b/ChangeLog index 349e2eee5..7905db013 100644 --- a/ChangeLog +++ b/ChangeLog @@ -83,6 +83,7 @@ * added torrent_info::remap_files() * support min_interval tracker extension * added session saving and loading functions + * added support for min-interval in tracker responses release 0.14.8 diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 3618faf6a..1f1b84785 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -393,7 +393,7 @@ namespace libtorrent virtual void tracker_request_timed_out( tracker_request const& r); virtual void tracker_request_error(tracker_request const& r - , int response_code, const std::string& str); + , int response_code, const std::string& str, int retry_interval); virtual void tracker_warning(tracker_request const& req , std::string const& msg); virtual void tracker_scrape_response(tracker_request const& req diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index 004875dd8..eae74e225 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -140,7 +140,7 @@ namespace libtorrent min_announce = min_time(); } - void failed(); + void failed(int retry_interval = 0); bool can_announce(ptime now) const { diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index a7bb42c81..7cbcf85bf 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -138,7 +138,8 @@ namespace libtorrent virtual void tracker_request_error( tracker_request const& req , int response_code - , const std::string& description) = 0; + , const std::string& description + , int retry_interval) = 0; tcp::endpoint m_tracker_address; @@ -199,7 +200,7 @@ namespace libtorrent tracker_request const& tracker_req() const { return m_req; } void fail_disp(int code, std::string const& msg) { fail(code, msg.c_str()); } - void fail(int code, char const* msg); + void fail(int code, char const* msg, int interval = 0, int min_interval = 0); void fail_timeout(); virtual void start() = 0; virtual void close(); diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 90861d77d..3a64b709c 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -361,11 +361,14 @@ namespace libtorrent boost::shared_ptr cb = requester(); if (!cb) return; + int interval = e.dict_find_int_value("interval", 1800); + int min_interval = e.dict_find_int_value("min interval", 60); + // parse the response lazy_entry const* failure = e.dict_find_string("failure reason"); if (failure) { - fail(status_code, failure->string_value().c_str()); + fail(status_code, failure->string_value().c_str(), interval, min_interval); return; } @@ -382,14 +385,16 @@ namespace libtorrent lazy_entry const* files = e.dict_find_dict("files"); if (files == 0) { - fail(-1, "invalid or missing 'files' entry in scrape response"); + fail(-1, "invalid or missing 'files' entry in scrape response" + , interval, min_interval); return; } lazy_entry const* scrape_data = files->dict_find_dict(ih.c_str()); if (scrape_data == 0) { - fail(-1, "missing or invalid info-hash entry in scrape response"); + fail(-1, "missing or invalid info-hash entry in scrape response" + , interval, min_interval); return; } int complete = scrape_data->dict_find_int_value("complete", -1); @@ -400,9 +405,6 @@ namespace libtorrent return; } - int interval = e.dict_find_int_value("interval", 1800); - int min_interval = e.dict_find_int_value("min interval", 60); - lazy_entry const* peers_ent = e.dict_find("peers"); if (peers_ent && peers_ent->type() == lazy_entry::string_t) { @@ -465,7 +467,8 @@ namespace libtorrent if (peers_ent == 0 && ipv6_peers == 0) { - fail(-1, "missing 'peers' and 'peers6' entry in tracker response"); + fail(-1, "missing 'peers' and 'peers6' entry in tracker response" + , interval, min_interval); return; } diff --git a/src/torrent.cpp b/src/torrent.cpp index 8d4a695aa..7490ec9d9 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -6069,7 +6069,8 @@ namespace libtorrent // the tracker as a failure and not retry // it anymore void torrent::tracker_request_error(tracker_request const& r - , int response_code, const std::string& str) + , int response_code, const std::string& str + , int retry_interval) { mutex::scoped_lock l(m_ses.m_mutex); @@ -6083,7 +6084,7 @@ namespace libtorrent announce_entry* ae = find_tracker(r); if (ae) { - ae->failed(); + ae->failed(retry_interval); int tracker_index = ae - &m_trackers[0]; deprioritize_tracker(tracker_index); } diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index e77f7e7c9..8305d8354 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -406,11 +406,12 @@ namespace libtorrent int announce_entry::min_announce_in() const { return total_seconds(time_now() - min_announce); } - void announce_entry::failed() + void announce_entry::failed(int retry_interval) { ++fails; - int delay = (std::min)(tracker_retry_delay_min + int(fails) * int(fails) * tracker_retry_delay_min - , int(tracker_retry_delay_max)); + int delay = (std::min)(tracker_retry_delay_min + int(fails) * int(fails) + * tracker_retry_delay_min, int(tracker_retry_delay_max)); + delay = (std::max)(delay, retry_interval); next_announce = time_now() + seconds(delay); updating = false; } diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index d0a3f1ff9..031f2c6de 100644 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -140,10 +140,11 @@ namespace libtorrent return m_requester.lock(); } - void tracker_connection::fail(int code, char const* msg) + void tracker_connection::fail(int code, char const* msg, int interval, int min_interval) { boost::shared_ptr cb = requester(); - if (cb) cb->tracker_request_error(m_req, code, msg); + if (cb) cb->tracker_request_error(m_req, code, msg + , interval == 0 ? min_interval : interval); close(); } @@ -246,7 +247,7 @@ namespace libtorrent // we need to post the error to avoid deadlock if (boost::shared_ptr r = c.lock()) ios.post(boost::bind(&request_callback::tracker_request_error, r, req, -1 - , "unknown protocol in tracker url: " + req.url)); + , "unknown protocol in tracker url: " + req.url, 0)); return; }