From aa5fc72fbf84e53c9b9ee9aa7639b9fd70caa617 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 23 Feb 2010 21:53:45 +0000 Subject: [PATCH] made tracker errors use error_code --- docs/manual.rst | 25 ++++++++++++++ include/libtorrent/alert_types.hpp | 20 +++-------- include/libtorrent/error_code.hpp | 21 ++++++++++++ include/libtorrent/torrent.hpp | 5 ++- include/libtorrent/tracker_manager.hpp | 11 +++--- src/error_code.cpp | 20 +++++++++++ src/http_tracker_connection.cpp | 41 +++++++++-------------- src/torrent.cpp | 46 +++----------------------- src/tracker_manager.cpp | 17 ++++------ src/udp_tracker_connection.cpp | 30 ++++++++--------- 10 files changed, 118 insertions(+), 118 deletions(-) diff --git a/docs/manual.rst b/docs/manual.rst index b36db463b..42e5e0a5e 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -6404,6 +6404,31 @@ I2P errors: 160 no_i2p_router The URL specified an i2p address, but no i2p router is configured ====== ========================================= ================================================================= +tracker errors: + +====== ========================================= ================================================================= +170 scrape_not_available The tracker URL doesn't support transforming it into a scrape + URL. i.e. it doesn't contain "announce. +------ ----------------------------------------- ----------------------------------------------------------------- +171 invalid_tracker_response invalid tracker response +------ ----------------------------------------- ----------------------------------------------------------------- +172 invalid_peer_dict invalid peer dictionary entry. Not a dictionary +------ ----------------------------------------- ----------------------------------------------------------------- +173 tracker_failure tracker sent a failure message +------ ----------------------------------------- ----------------------------------------------------------------- +174 invalid_files_entry missing or invalid 'files' entry +------ ----------------------------------------- ----------------------------------------------------------------- +175 invalid_hash_entry missing or invalid 'hash' entry +------ ----------------------------------------- ----------------------------------------------------------------- +176 invalid_peers_entry missing or invalid 'peers' and 'peers6' entry +------ ----------------------------------------- ----------------------------------------------------------------- +177 invalid_tracker_response_length udp tracker response packet has invalid size +------ ----------------------------------------- ----------------------------------------------------------------- +178 invalid_tracker_transaction_id invalid transaction id in udp tracker response +------ ----------------------------------------- ----------------------------------------------------------------- +179 invalid_tracker_action invalid action field in udp tracker response +====== ========================================= ================================================================= + The names of these error codes are declared in then ``libtorrent::errors`` namespace. There is also another error category, ``libtorrent::upnp_category``, defining errors diff --git a/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index 0ff66ddb1..0a23e8fc9 100644 --- a/include/libtorrent/alert_types.hpp +++ b/include/libtorrent/alert_types.hpp @@ -241,24 +241,13 @@ namespace libtorrent , int times , int status , std::string const& url_ - , error_code const& e) + , error_code const& e + , std::string const& m) : tracker_alert(h, url_) , times_in_row(times) , status_code(status) - , msg(e.message()) - { - TORRENT_ASSERT(!url.empty()); - } - - tracker_error_alert(torrent_handle const& h - , int times - , int status - , std::string const& url_ - , std::string const& msg_) - : tracker_alert(h, url_) - , times_in_row(times) - , status_code(status) - , msg(msg_) + , error(e) + , msg(msg) { TORRENT_ASSERT(!url.empty()); } @@ -270,6 +259,7 @@ namespace libtorrent int times_in_row; int status_code; + error_code error; std::string msg; }; diff --git a/include/libtorrent/error_code.hpp b/include/libtorrent/error_code.hpp index 3ca781803..08c45544a 100644 --- a/include/libtorrent/error_code.hpp +++ b/include/libtorrent/error_code.hpp @@ -224,6 +224,27 @@ namespace libtorrent reserved159, // i2p errors no_i2p_router, // 160 + reserved161, + reserved162, + reserved163, + reserved164, + reserved165, + reserved166, + reserved167, + reserved168, + reserved169, + +// tracker errors + scrape_not_available, // 170 + invalid_tracker_response, + invalid_peer_dict, + tracker_failure, + invalid_files_entry, + invalid_hash_entry, + invalid_peers_entry, + invalid_tracker_response_length, + invalid_tracker_transaction_id, + invalid_tracker_action, error_code_max }; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index d5f36aadd..1f28fd0b9 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -423,10 +423,9 @@ namespace libtorrent , std::list
const& ip_list , std::vector& e, int interval, int min_interval , int complete, int incomplete, address const& external_ip); - 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 retry_interval); + , int response_code, error_code const& ec, const std::string& msg + , 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/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index aff77bda6..15f23aede 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -135,12 +135,11 @@ namespace libtorrent , int complete , int incomplete , address const& external_ip) = 0; - virtual void tracker_request_timed_out( - tracker_request const& req) = 0; virtual void tracker_request_error( tracker_request const& req , int response_code - , const std::string& description + , error_code const& ec + , const std::string& msg , int retry_interval) = 0; union_endpoint m_tracker_address; @@ -201,9 +200,9 @@ 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, int interval = 0, int min_interval = 0); - void fail_timeout(); + void fail_disp(error_code ec) { fail(ec); } + void fail(error_code const& ec, int code = -1, char const* msg = "" + , int interval = 0, int min_interval = 0); virtual void start() = 0; virtual void close(); address const& bind_interface() const { return m_req.bind_ip; } diff --git a/src/error_code.cpp b/src/error_code.cpp index 00584ffe4..8f67a095c 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -213,6 +213,26 @@ namespace libtorrent "", // i2p errors "no i2p router is set up", + "", + "", + "", + "", + "", + "", + "", + "", + "", +// tracker errors + "scrape not available on tracker", + "invalid tracker response", + "invalid peer dictionary entry", + "tracker sent a failure message", + "missing or invalid 'files' entry", + "missing or invalid 'hash' entry", + "missing or invalid 'peers' and 'peers6' entry", + "udp tracker response packet has invalid size", + "invalid transaction id in udp tracker response", + "invalid action field in udp tracker response", }; if (ev < 0 || ev >= sizeof(msgs)/sizeof(msgs[0])) return "Unknown error"; diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index c05459c87..a2bec5bed 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -108,7 +108,7 @@ namespace libtorrent if (pos == std::string::npos) { m_ios.post(boost::bind(&http_tracker_connection::fail_disp, self() - , -1, "scrape is not available on url: '" + tracker_req().url +"'")); + , error_code(errors::scrape_not_available))); return; } url.replace(pos, 8, "scrape"); @@ -247,7 +247,7 @@ namespace libtorrent } if (endpoints.empty()) - fail(-1, "blocked by IP filter"); + fail(error_code(errors::banned_by_ip_filter)); } void http_tracker_connection::on_connect(http_connection& c) @@ -267,25 +267,25 @@ namespace libtorrent if (ec && ec != asio::error::eof) { - fail(-1, ec.message().c_str()); + fail(ec); return; } if (!parser.header_finished()) { - fail(-1, "premature end of file"); + fail(asio::error::eof); return; } if (parser.status_code() != 200) { - fail(parser.status_code(), parser.message().c_str()); + fail(error_code(errors::http_error), parser.status_code(), parser.message().c_str()); return; } if (ec && ec != asio::error::eof) { - fail(parser.status_code(), ec.message().c_str()); + fail(ec, parser.status_code()); return; } @@ -301,19 +301,7 @@ namespace libtorrent } else { - std::string error_str("invalid encoding of tracker response: \""); - for (char const* i = data, *end(data + size); i != end; ++i) - { - if (*i >= ' ' && *i <= '~') error_str += *i; - else - { - char val[30]; - snprintf(val, sizeof(val), "0x%02x ", *i); - error_str += val; - } - } - error_str += "\""; - fail(parser.status_code(), error_str.c_str()); + fail(error_code(errors::invalid_bencoding), parser.status_code()); } close(); } @@ -323,7 +311,7 @@ namespace libtorrent // extract peer id (if any) if (info.type() != lazy_entry::dict_t) { - fail(-1, "invalid response from tracker (invalid peer entry)"); + fail(error_code(errors::invalid_peer_dict)); return false; } lazy_entry const* i = info.dict_find_string("peer id"); @@ -341,7 +329,7 @@ namespace libtorrent i = info.dict_find_string("ip"); if (i == 0) { - fail(-1, "invalid response from tracker"); + fail(error_code(errors::invalid_tracker_response)); return false; } ret.ip = i->string_value(); @@ -350,7 +338,7 @@ namespace libtorrent i = info.dict_find_int("port"); if (i == 0) { - fail(-1, "invalid response from tracker"); + fail(error_code(errors::invalid_tracker_response)); return false; } ret.port = (unsigned short)i->int_value(); @@ -370,7 +358,8 @@ namespace libtorrent lazy_entry const* failure = e.dict_find_string("failure reason"); if (failure) { - fail(status_code, failure->string_value().c_str(), interval, min_interval); + fail(error_code(errors::tracker_failure), status_code + , failure->string_value().c_str(), interval, min_interval); return; } @@ -387,7 +376,7 @@ 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(error_code(errors::invalid_files_entry), -1, "" , interval, min_interval); return; } @@ -395,7 +384,7 @@ namespace libtorrent 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(error_code(errors::invalid_hash_entry), -1, "" , interval, min_interval); return; } @@ -469,7 +458,7 @@ namespace libtorrent if (peers_ent == 0 && ipv6_peers == 0) { - fail(-1, "missing 'peers' and 'peers6' entry in tracker response" + fail(error_code(errors::invalid_peers_entry), -1, "" , interval, min_interval); return; } diff --git a/src/torrent.cpp b/src/torrent.cpp index b5d420637..493d37740 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -6257,49 +6257,11 @@ namespace libtorrent return ret; } - void torrent::tracker_request_timed_out( - tracker_request const& r) - { - mutex::scoped_lock l(m_ses.m_mutex); - - INVARIANT_CHECK; - -#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING - debug_log("*** tracker timed out"); -#endif - - 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()) - { - m_ses.m_alerts.post_alert(tracker_error_alert(get_handle() - , ae?ae->fails:0, 0, r.url - , errors::timed_out)); - } - } - else if (r.kind == tracker_request::scrape_request) - { - if (m_ses.m_alerts.should_post()) - { - m_ses.m_alerts.post_alert(scrape_failed_alert(get_handle() - , r.url, errors::timed_out)); - } - } - update_tracker_timer(); - } - // TODO: with some response codes, we should just consider // 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, error_code const& ec, const std::string& msg , int retry_interval) { mutex::scoped_lock l(m_ses.m_mutex); @@ -6307,7 +6269,7 @@ namespace libtorrent INVARIANT_CHECK; #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING - debug_log(std::string("*** tracker error: ") + str); + debug_log("*** tracker error: " + ec.message() + " " + msg); #endif if (r.kind == tracker_request::announce_request) { @@ -6321,14 +6283,14 @@ namespace libtorrent if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(tracker_error_alert(get_handle() - , ae?ae->fails:0, response_code, r.url, str)); + , ae?ae->fails:0, response_code, r.url, ec, msg)); } } else if (r.kind == tracker_request::scrape_request) { if (m_ses.m_alerts.should_post()) { - 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, ec)); } } update_tracker_timer(); diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index 031f2c6de..480b6672c 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, int interval, int min_interval) + void tracker_connection::fail(error_code const& ec, 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, ec, msg , interval == 0 ? min_interval : interval); close(); } @@ -158,13 +159,6 @@ namespace libtorrent m_man.received_bytes(bytes); } - void tracker_connection::fail_timeout() - { - boost::shared_ptr cb = requester(); - if (cb) cb->tracker_request_timed_out(m_req); - close(); - } - void tracker_connection::close() { cancel(); @@ -246,8 +240,9 @@ 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, 0)); + ios.post(boost::bind(&request_callback::tracker_request_error, r, req + , -1, error_code(errors::unsupported_url_protocol) + , "", 0)); return; } diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index c0d999436..4e35bf16c 100644 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -97,7 +97,7 @@ namespace libtorrent if (ec) { - fail(-1, ec.message().c_str()); + fail(ec); return; } @@ -123,7 +123,7 @@ namespace libtorrent if (error == asio::error::operation_aborted) return; if (error || i == udp::resolver::iterator()) { - fail(-1, error.message().c_str()); + fail(error); return; } @@ -152,7 +152,7 @@ namespace libtorrent if (m_endpoints.empty()) { - fail(-1, "blocked by IP filter"); + fail(error_code(errors::banned_by_ip_filter)); return; } @@ -194,7 +194,7 @@ namespace libtorrent m_socket.bind(udp::endpoint(bind_interface(), 0), ec); if (ec) { - fail(-1, ec.message().c_str()); + fail(ec); return; } @@ -231,7 +231,7 @@ namespace libtorrent #endif m_socket.close(); m_name_lookup.cancel(); - fail_timeout(); + fail(error_code(errors::timed_out)); } void udp_tracker_connection::close() @@ -254,7 +254,7 @@ namespace libtorrent if (m_target != ep) return; received_bytes(size + 28); // assuming UDP/IP header - if (e) fail(-1, e.message().c_str()); + if (e) fail(e); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING boost::shared_ptr cb = requester(); @@ -289,7 +289,7 @@ namespace libtorrent if (action == action_error) { - fail(-1, std::string(ptr, size - 8).c_str()); + fail(error_code(errors::tracker_failure), -1, std::string(ptr, size - 8).c_str()); return; } @@ -379,7 +379,7 @@ namespace libtorrent ++m_attempts; if (ec) { - fail(-1, ec.message().c_str()); + fail(ec); return; } } @@ -415,7 +415,7 @@ namespace libtorrent ++m_attempts; if (ec) { - fail(-1, ec.message().c_str()); + fail(ec); return; } } @@ -433,7 +433,7 @@ namespace libtorrent int num_peers = (size - 20) / 6; if ((size - 20) % 6 != 0) { - fail(-1, "invalid udp tracker response length"); + fail(error_code(errors::invalid_tracker_response_length)); return; } @@ -495,25 +495,25 @@ namespace libtorrent if (transaction != m_transaction_id) { - fail(-1, "incorrect transaction id"); + fail(error_code(errors::invalid_tracker_transaction_id)); return; } if (action == action_error) { - fail(-1, std::string(buf, size - 8).c_str()); + fail(error_code(errors::tracker_failure), -1, std::string(buf, size - 8).c_str()); return; } if (action != action_scrape) { - fail(-1, "invalid action in announce response"); + fail(error_code(errors::invalid_tracker_action)); return; } if (size < 20) { - fail(-1, "got a message with size < 20"); + fail(error_code(errors::invalid_tracker_response_length)); return; } @@ -602,7 +602,7 @@ namespace libtorrent ++m_attempts; if (ec) { - fail(-1, ec.message().c_str()); + fail(ec); return; } }