diff --git a/deluge/core/alertmanager.py b/deluge/core/alertmanager.py index d0d403151..b12dd96d1 100644 --- a/deluge/core/alertmanager.py +++ b/deluge/core/alertmanager.py @@ -44,7 +44,14 @@ class AlertManager(component.Component): log.debug("AlertManager initialized..") component.Component.__init__(self, "AlertManager", interval=50) self.session = session - self.session.set_severity_level(lt.alert.severity_levels.info) + self.session.set_alert_mask( + lt.alert.category_t.error_notification | + lt.alert.category_t.port_mapping_notification | + lt.alert.category_t.storage_notification | + lt.alert.category_t.tracker_notification | + lt.alert.category_t.status_notification | + lt.alert.category_t.ip_block_notification) + # handlers is a dictionary of lists {"alert_type": [handler1,h2,..]} self.handlers = {} @@ -87,7 +94,7 @@ class AlertManager(component.Component): # Do some magic to get the alert type as a string alert_type = str(type(alert)).split("'")[1].split(".")[2] # Display the alert message - log.debug("%s: %s", alert_type, alert.msg()) + log.debug("%s: %s", alert_type, alert.message()) # Call any handlers for this alert type if alert_type in self.handlers.keys(): for handler in self.handlers[alert_type]: diff --git a/libtorrent/bindings/python/src/alert.cpp b/libtorrent/bindings/python/src/alert.cpp index 01b73ac61..7249f58dc 100755 --- a/libtorrent/bindings/python/src/alert.cpp +++ b/libtorrent/bindings/python/src/alert.cpp @@ -53,15 +53,11 @@ void bind_alert() { scope alert_scope = class_("alert", alert_doc, no_init) - .def( - "msg", &alert::msg, return_value_policy() - , alert_msg_doc - ) + .def("message", &alert::message, alert_msg_doc) + .def("what", &alert::what) + .def("category", &alert::category) .def("severity", &alert::severity, alert_severity_doc) - .def( - "__str__", &alert::msg, return_value_policy() - , alert_msg_doc - ) + .def("__str__", &alert::message, alert_msg_doc) ; enum_("severity_levels") @@ -72,6 +68,19 @@ void bind_alert() .value("fatal", alert::fatal) .value("none", alert::none) ; + + enum_("category_t") + .value("error_notification", alert::error_notification) + .value("peer_notification", alert::peer_notification) + .value("port_mapping_notification", alert::port_mapping_notification) + .value("storage_notification", alert::storage_notification) + .value("tracker_notification", alert::tracker_notification) + .value("debug_notification", alert::debug_notification) + .value("status_notification", alert::status_notification) + .value("progress_notification", alert::progress_notification) + .value("ip_block_notification", alert::ip_block_notification) + .value("all_categories", alert::all_categories) + ; } class_, noncopyable>( diff --git a/libtorrent/bindings/python/src/session.cpp b/libtorrent/bindings/python/src/session.cpp index 294d9d534..4c9e65e42 100755 --- a/libtorrent/bindings/python/src/session.cpp +++ b/libtorrent/bindings/python/src/session.cpp @@ -323,6 +323,7 @@ void bind_session() "set_severity_level", allow_threads(&session::set_severity_level) , session_set_severity_level_doc ) + .def("set_alert_mask", allow_threads(&session::set_alert_mask)) .def("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc) .def("add_extension", &add_extension) .def("set_peer_proxy", allow_threads(&session::set_peer_proxy)) diff --git a/libtorrent/include/libtorrent/alert.hpp b/libtorrent/include/libtorrent/alert.hpp index ab8065f1f..afa8e978f 100644 --- a/libtorrent/include/libtorrent/alert.hpp +++ b/libtorrent/include/libtorrent/alert.hpp @@ -67,23 +67,40 @@ namespace libtorrent { class TORRENT_EXPORT alert { public: + + // only here for backwards compatibility enum severity_t { debug, info, warning, critical, fatal, none }; - alert(severity_t severity, const std::string& msg); + enum category_t + { + error_notification = 0x1, + peer_notification = 0x2, + port_mapping_notification = 0x4, + storage_notification = 0x8, + tracker_notification = 0x10, + debug_notification = 0x20, + status_notification = 0x40, + progress_notification = 0x80, + ip_block_notification = 0x100, + + all_categories = 0xffffffff + }; + + alert(); virtual ~alert(); // a timestamp is automatically created in the constructor ptime timestamp() const; - std::string const& msg() const; + virtual char const* what() const = 0; + virtual std::string message() const = 0; + virtual int category() const = 0; - severity_t severity() const; + severity_t severity() const TORRENT_DEPRECATED { return warning; } virtual std::auto_ptr clone() const = 0; private: - std::string m_msg; - severity_t m_severity; ptime m_timestamp; }; @@ -97,16 +114,18 @@ namespace libtorrent { bool pending() const; std::auto_ptr get(); - void set_severity(alert::severity_t severity); - bool should_post(alert::severity_t severity) const; + template + bool should_post() const { return m_alert_mask & T::static_category; } alert const* wait_for_alert(time_duration max_wait); + void set_alert_mask(int m) { m_alert_mask = m; } + private: std::queue m_alerts; - alert::severity_t m_severity; mutable boost::mutex m_mutex; boost::condition m_condition; + int m_alert_mask; }; struct TORRENT_EXPORT unhandled_alert : std::exception diff --git a/libtorrent/include/libtorrent/alert_types.hpp b/libtorrent/include/libtorrent/alert_types.hpp index 5d26a66c2..69f971f13 100644 --- a/libtorrent/include/libtorrent/alert_types.hpp +++ b/libtorrent/include/libtorrent/alert_types.hpp @@ -40,16 +40,19 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/assert.hpp" +#include + namespace libtorrent { struct TORRENT_EXPORT torrent_alert: alert { - torrent_alert(torrent_handle const& h, alert::severity_t s - , std::string const& msg) - : alert(s, msg) - , handle(h) + torrent_alert(torrent_handle const& h) + : handle(h) {} + virtual std::string message() const + { return handle.is_valid()?handle.name():"- "; } + torrent_handle handle; }; @@ -57,41 +60,100 @@ namespace libtorrent { file_renamed_alert(torrent_handle const& h , std::string const& name_ - , std::string const& msg) - : torrent_alert(h, alert::warning, msg) + , int index_) + : torrent_alert(h) , name(name_) + , index(index_) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new file_renamed_alert(*this)); } + const static int static_category = alert::storage_notification; + virtual int category() const { return static_category; } + virtual char const* what() const { return "file renamed"; } + virtual std::string message() const + { + return torrent_alert::message() + ": file " + + boost::lexical_cast(index) + " renamed to " + + name; + } std::string name; + int index; + }; + + struct TORRENT_EXPORT file_rename_failed_alert: torrent_alert + { + file_rename_failed_alert(torrent_handle const& h + , std::string const& msg_ + , int index_) + : torrent_alert(h) + , msg(msg_) + , index(index_) + {} + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new file_rename_failed_alert(*this)); } + + virtual char const* what() const { return "file rename failed"; } + virtual std::string message() const + { + return torrent_alert::message() + ": failed to rename file " + + boost::lexical_cast(index) + ": " + + msg; + } + + const static int static_category = alert::storage_notification; + virtual int category() const { return static_category; } + + std::string msg; + int index; }; struct TORRENT_EXPORT state_changed_alert: torrent_alert { state_changed_alert(torrent_handle const& h - , torrent_status::state_t const& state_ - , std::string const& msg) - : torrent_alert(h, alert::info, msg) + , torrent_status::state_t const& state_) + : torrent_alert(h) , state(state_) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new state_changed_alert(*this)); } + virtual char const* what() const { return "torrent state changed"; } + virtual std::string message() const + { + static char const* state_str[] = + {"checking (q)", "checking", "connecting", "dl metadata" + , "downloading", "finished", "seeding", "allocating"}; + + return torrent_alert::message() + ": state changed to: " + + state_str[state]; + } + + + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + torrent_status::state_t state; }; struct TORRENT_EXPORT tracker_alert: torrent_alert { tracker_alert(torrent_handle const& h - , std::string const& url_ - , alert::severity_t s - , std::string const& msg) - : torrent_alert(h, s, msg) + , std::string const& url_) + : torrent_alert(h) , url(url_) - {} + { assert(!url.empty()); } + + const static int static_category = alert::tracker_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " (" + url + ")"; + } + std::string url; }; @@ -102,29 +164,51 @@ namespace libtorrent , int times , int status , std::string const& url - , std::string const& msg) - : tracker_alert(h, url, alert::warning, msg) + , std::string const& msg_) + : tracker_alert(h, url) , times_in_row(times) , status_code(status) + , msg(msg_) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new tracker_error_alert(*this)); } + const static int static_category = alert::tracker_notification | alert::error_notification; + virtual int category() const { return static_category; } + virtual char const* what() const { return "tracker error"; } + virtual std::string message() const + { + return tracker_alert::message() + " (" + + boost::lexical_cast(status_code) + + ") " + msg + " (" + boost::lexical_cast(times_in_row) + + ")"; + } int times_in_row; int status_code; + std::string msg; }; struct TORRENT_EXPORT tracker_warning_alert: tracker_alert { tracker_warning_alert(torrent_handle const& h , std::string const& url - , std::string const& msg) - : tracker_alert(h, url, alert::warning, msg) + , std::string const& msg_) + : tracker_alert(h, url) + , msg(msg_) {} + std::string msg; + virtual std::auto_ptr clone() const { return std::auto_ptr(new tracker_warning_alert(*this)); } + const static int static_category = alert::tracker_notification | alert::error_notification; + virtual int category() const { return static_category; } + virtual char const* what() const { return "tracker warning"; } + virtual std::string message() const + { + return tracker_alert::message() + " warning: " + msg; + } }; struct TORRENT_EXPORT scrape_reply_alert: tracker_alert @@ -132,9 +216,8 @@ namespace libtorrent scrape_reply_alert(torrent_handle const& h , int incomplete_ , int complete_ - , std::string const& url - , std::string const& msg) - : tracker_alert(h, url, alert::info, msg) + , std::string const& url) + : tracker_alert(h, url) , incomplete(incomplete_) , complete(complete_) {} @@ -144,27 +227,43 @@ namespace libtorrent virtual std::auto_ptr clone() const { return std::auto_ptr(new scrape_reply_alert(*this)); } + virtual char const* what() const { return "tracker scrape reply"; } + virtual std::string message() const + { + return tracker_alert::message() + " scrape reply: " + + boost::lexical_cast(incomplete) + " " + + boost::lexical_cast(complete); + } }; struct TORRENT_EXPORT scrape_failed_alert: tracker_alert { scrape_failed_alert(torrent_handle const& h , std::string const& url - , std::string const& msg) - : tracker_alert(h, url, alert::warning, msg) + , std::string const& msg_) + : tracker_alert(h, url) + , msg(msg_) {} + std::string msg; + virtual std::auto_ptr clone() const { return std::auto_ptr(new scrape_failed_alert(*this)); } + const static int static_category = alert::tracker_notification | alert::error_notification; + virtual int category() const { return static_category; } + virtual char const* what() const { return "tracker scrape failed"; } + virtual std::string message() const + { + return tracker_alert::message() + " scrape failed: " + msg; + } }; struct TORRENT_EXPORT tracker_reply_alert: tracker_alert { tracker_reply_alert(torrent_handle const& h , int np - , std::string const& url - , std::string const& msg) - : tracker_alert(h, url, alert::info, msg) + , std::string const& url) + : tracker_alert(h, url) , num_peers(np) {} @@ -172,77 +271,218 @@ namespace libtorrent virtual std::auto_ptr clone() const { return std::auto_ptr(new tracker_reply_alert(*this)); } + virtual char const* what() const { return "tracker reply"; } + virtual std::string message() const + { + return tracker_alert::message() + " received peers: " + + boost::lexical_cast(num_peers); + } + }; + + struct TORRENT_EXPORT dht_reply_alert: tracker_alert + { + dht_reply_alert(torrent_handle const& h + , int np) + : tracker_alert(h, "") + , num_peers(np) + {} + + int num_peers; + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new dht_reply_alert(*this)); } + virtual char const* what() const { return "DHT reply"; } + virtual std::string message() const + { + return torrent_alert::message() + " received DHT peers: " + + boost::lexical_cast(num_peers); + } }; struct TORRENT_EXPORT tracker_announce_alert: tracker_alert { tracker_announce_alert(torrent_handle const& h - , std::string const& url - , std::string const& msg) - : tracker_alert(h, url, alert::info, msg) + , std::string const& url) + : tracker_alert(h, url) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new tracker_announce_alert(*this)); } + virtual char const* what() const { return "tracker announce sent"; } + virtual std::string message() const + { + return tracker_alert::message() + " sending announce"; + } }; struct TORRENT_EXPORT hash_failed_alert: torrent_alert { hash_failed_alert( torrent_handle const& h - , int index - , std::string const& msg) - : torrent_alert(h, alert::info, msg) + , int index) + : torrent_alert(h) , piece_index(index) { TORRENT_ASSERT(index >= 0);} virtual std::auto_ptr clone() const { return std::auto_ptr(new hash_failed_alert(*this)); } + virtual char const* what() const { return "piece hash failed"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " hash for piece " + + boost::lexical_cast(piece_index) + " failed"; + } int piece_index; }; struct TORRENT_EXPORT peer_ban_alert: torrent_alert { - peer_ban_alert(tcp::endpoint const& pip, torrent_handle h, std::string const& msg) - : torrent_alert(h, alert::info, msg) + peer_ban_alert(tcp::endpoint const& pip, torrent_handle h) + : torrent_alert(h) , ip(pip) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new peer_ban_alert(*this)); } + virtual char const* what() const { return "peer banned"; } + const static int static_category = alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " banned peer " + + ip.address().to_string(ec); + } tcp::endpoint ip; }; - struct TORRENT_EXPORT peer_error_alert: alert + struct TORRENT_EXPORT peer_unsnubbed_alert: torrent_alert { - peer_error_alert(tcp::endpoint const& pip, peer_id const& pid_, std::string const& msg) - : alert(alert::info, msg) - , ip(pip) + peer_unsnubbed_alert(torrent_handle const& h, tcp::endpoint const& ip_ + , peer_id const& pid_) + : torrent_alert(h) + , ip(ip_) , pid(pid_) {} + virtual std::auto_ptr clone() const + { return std::auto_ptr(new peer_unsnubbed_alert(*this)); } + virtual char const* what() const { return "peer unsnubbed"; } + const static int static_category = alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " peer unsnubbed: (" + ip.address().to_string(ec) + + ")"; + } + + tcp::endpoint ip; + peer_id pid; + }; + + struct TORRENT_EXPORT peer_snubbed_alert: torrent_alert + { + peer_snubbed_alert(torrent_handle const& h, tcp::endpoint const& ip_ + , peer_id const& pid_) + : torrent_alert(h) + , ip(ip_) + , pid(pid_) + {} + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new peer_snubbed_alert(*this)); } + virtual char const* what() const { return "peer snubbed"; } + const static int static_category = alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " peer snubbed: (" + ip.address().to_string(ec) + + ")"; + } + + tcp::endpoint ip; + peer_id pid; + }; + + struct TORRENT_EXPORT peer_error_alert: torrent_alert + { + peer_error_alert(torrent_handle const& h, tcp::endpoint const& ip_ + , peer_id const& pid_, std::string const& msg_) + : torrent_alert(h) + , ip(ip_) + , pid(pid_) + , msg(msg_) + {} + virtual std::auto_ptr clone() const { return std::auto_ptr(new peer_error_alert(*this)); } + virtual char const* what() const { return "peer error"; } + const static int static_category = alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " peer error: (" + ip.address().to_string(ec) + + ") " + msg; + } tcp::endpoint ip; peer_id pid; + std::string msg; }; - struct TORRENT_EXPORT peer_disconnected_alert: alert + struct TORRENT_EXPORT peer_connect_alert: torrent_alert { - peer_disconnected_alert(tcp::endpoint const& pip, peer_id const& pid_, std::string const& msg) - : alert(alert::debug, msg) - , ip(pip) + peer_connect_alert(torrent_handle const& h, tcp::endpoint const& ip_) + : torrent_alert(h), ip(ip_) + {} + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new peer_connect_alert(*this)); } + virtual char const* what() const { return "connecting to peer"; } + const static int static_category = alert::debug_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " connecting to peer " + + ip.address().to_string(ec); + } + + tcp::endpoint ip; + }; + + struct TORRENT_EXPORT peer_disconnected_alert: torrent_alert + { + peer_disconnected_alert(torrent_handle const& h, tcp::endpoint const& ip_ + , peer_id const& pid_, std::string const& msg_) + : torrent_alert(h) + , ip(ip_) , pid(pid_) + , msg(msg_) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new peer_disconnected_alert(*this)); } + virtual char const* what() const { return "peer disconnected"; } + const static int static_category = alert::debug_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " disconnecting " + + ip.address().to_string(ec) + ": " + msg; + } tcp::endpoint ip; peer_id pid; + std::string msg; }; struct TORRENT_EXPORT invalid_request_alert: torrent_alert @@ -251,9 +491,8 @@ namespace libtorrent peer_request const& r , torrent_handle const& h , tcp::endpoint const& sender - , peer_id const& pid_ - , std::string const& msg) - : torrent_alert(h, alert::debug, msg) + , peer_id const& pid_) + : torrent_alert(h) , ip(sender) , request(r) , pid(pid_) @@ -261,6 +500,15 @@ namespace libtorrent virtual std::auto_ptr clone() const { return std::auto_ptr(new invalid_request_alert(*this)); } + virtual char const* what() const { return "invalid piece request"; } + const static int static_category = alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " peer " + + ip.address().to_string(ec) + " sent an invalid piece request"; + } tcp::endpoint ip; peer_request request; @@ -270,22 +518,27 @@ namespace libtorrent struct TORRENT_EXPORT torrent_finished_alert: torrent_alert { torrent_finished_alert( - const torrent_handle& h - , const std::string& msg) - : torrent_alert(h, alert::warning, msg) + const torrent_handle& h) + : torrent_alert(h) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new torrent_finished_alert(*this)); } + virtual char const* what() const { return "torrent finished"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " torrent finished downloading"; + } }; struct TORRENT_EXPORT piece_finished_alert: torrent_alert { piece_finished_alert( const torrent_handle& h - , int piece_num - , const std::string& msg) - : torrent_alert(h, alert::debug, msg) + , int piece_num) + : torrent_alert(h) , piece_index(piece_num) { TORRENT_ASSERT(piece_index >= 0);} @@ -293,6 +546,70 @@ namespace libtorrent virtual std::auto_ptr clone() const { return std::auto_ptr(new piece_finished_alert(*this)); } + virtual char const* what() const { return "piece finished downloading"; } + const static int static_category = alert::progress_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " piece " + + boost::lexical_cast(piece_index) + " finished downloading"; + } + }; + + struct TORRENT_EXPORT request_dropped_alert: torrent_alert + { + request_dropped_alert( + const torrent_handle& h + , int block_num + , int piece_num) + : torrent_alert(h) + , block_index(block_num) + , piece_index(piece_num) + { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} + + int block_index; + int piece_index; + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new request_dropped_alert(*this)); } + virtual char const* what() const { return "block request dropped"; } + const static int static_category = alert::progress_notification + | alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " block " + + boost::lexical_cast(block_index) + " in piece " + + boost::lexical_cast(piece_index) + " was dropped by remote peer"; + } + }; + + struct TORRENT_EXPORT block_timeout_alert: torrent_alert + { + block_timeout_alert( + const torrent_handle& h + , int block_num + , int piece_num) + : torrent_alert(h) + , block_index(block_num) + , piece_index(piece_num) + { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} + + int block_index; + int piece_index; + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new block_timeout_alert(*this)); } + virtual char const* what() const { return "block timed out"; } + const static int static_category = alert::progress_notification + | alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " timed out block " + + boost::lexical_cast(block_index) + " in piece " + + boost::lexical_cast(piece_index); + } }; struct TORRENT_EXPORT block_finished_alert: torrent_alert @@ -300,9 +617,8 @@ namespace libtorrent block_finished_alert( const torrent_handle& h , int block_num - , int piece_num - , const std::string& msg) - : torrent_alert(h, alert::debug, msg) + , int piece_num) + : torrent_alert(h) , block_index(block_num) , piece_index(piece_num) { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} @@ -312,6 +628,15 @@ namespace libtorrent virtual std::auto_ptr clone() const { return std::auto_ptr(new block_finished_alert(*this)); } + virtual char const* what() const { return "block finished downloading"; } + const static int static_category = alert::progress_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " block " + + boost::lexical_cast(block_index) + " in piece " + + boost::lexical_cast(piece_index) + " finished downloading"; + } }; struct TORRENT_EXPORT block_downloading_alert: torrent_alert @@ -320,47 +645,95 @@ namespace libtorrent const torrent_handle& h , char const* speedmsg , int block_num - , int piece_num - , const std::string& msg) - : torrent_alert(h, alert::debug, msg) + , int piece_num) + : torrent_alert(h) , peer_speedmsg(speedmsg) , block_index(block_num) , piece_index(piece_num) { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} - std::string peer_speedmsg; + char const* peer_speedmsg; int block_index; int piece_index; virtual std::auto_ptr clone() const { return std::auto_ptr(new block_downloading_alert(*this)); } + virtual char const* what() const { return "block requested"; } + const static int static_category = alert::progress_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " requested block " + + boost::lexical_cast(block_index) + " in piece " + + boost::lexical_cast(piece_index); + } }; struct TORRENT_EXPORT storage_moved_alert: torrent_alert { - storage_moved_alert(torrent_handle const& h, std::string const& path) - : torrent_alert(h, alert::warning, path) + storage_moved_alert(torrent_handle const& h, std::string const& path_) + : torrent_alert(h) + , path(path_) {} + std::string path; + virtual std::auto_ptr clone() const { return std::auto_ptr(new storage_moved_alert(*this)); } + virtual char const* what() const { return "storage moved"; } + const static int static_category = alert::storage_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " moved storage to: " + + path; + } }; struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert { - torrent_deleted_alert(torrent_handle const& h, std::string const& msg) - : torrent_alert(h, alert::warning, msg) + torrent_deleted_alert(torrent_handle const& h) + : torrent_alert(h) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new torrent_deleted_alert(*this)); } + virtual char const* what() const { return "torrent deleted"; } + const static int static_category = alert::storage_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " deleted"; + } + }; + + struct TORRENT_EXPORT torrent_delete_failed_alert: torrent_alert + { + torrent_delete_failed_alert(torrent_handle const& h, std::string msg_) + : torrent_alert(h) + , msg(msg_) + {} + + std::string msg; + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new torrent_delete_failed_alert(*this)); } + virtual char const* what() const { return "torrent delete failed"; } + const static int static_category = alert::storage_notification + | alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " torrent deletion failed: " + + msg; + } }; struct TORRENT_EXPORT save_resume_data_alert: torrent_alert { save_resume_data_alert(boost::shared_ptr const& rd - , torrent_handle const& h, std::string const& msg) - : torrent_alert(h, alert::warning, msg) + , torrent_handle const& h) + : torrent_alert(h) , resume_data(rd) {} @@ -368,26 +741,86 @@ namespace libtorrent virtual std::auto_ptr clone() const { return std::auto_ptr(new save_resume_data_alert(*this)); } + virtual char const* what() const { return "save resume data complete"; } + const static int static_category = alert::storage_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " resume data generated"; + } + }; + + struct TORRENT_EXPORT save_resume_data_failed_alert: torrent_alert + { + save_resume_data_failed_alert(torrent_handle const& h + , std::string const& msg_) + : torrent_alert(h) + , msg(msg_) + {} + + std::string msg; + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new save_resume_data_failed_alert(*this)); } + virtual char const* what() const { return "save resume data failed"; } + const static int static_category = alert::storage_notification + | alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " resume data was not generated: " + + msg; + } }; struct TORRENT_EXPORT torrent_paused_alert: torrent_alert { - torrent_paused_alert(torrent_handle const& h, std::string const& msg) - : torrent_alert(h, alert::warning, msg) + torrent_paused_alert(torrent_handle const& h) + : torrent_alert(h) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new torrent_paused_alert(*this)); } + virtual char const* what() const { return "torrent paused"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " paused"; + } + }; + + struct TORRENT_EXPORT torrent_resumed_alert: torrent_alert + { + torrent_resumed_alert(torrent_handle const& h) + : torrent_alert(h) {} + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new torrent_resumed_alert(*this)); } + virtual char const* what() const { return "torrent resumed"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " resumed"; + } }; struct TORRENT_EXPORT torrent_checked_alert: torrent_alert { - torrent_checked_alert(torrent_handle const& h, std::string const& msg) - : torrent_alert(h, alert::info, msg) + torrent_checked_alert(torrent_handle const& h) + : torrent_alert(h) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new torrent_checked_alert(*this)); } + virtual char const* what() const { return "torrent checked"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " checked"; + } }; @@ -396,15 +829,25 @@ namespace libtorrent url_seed_alert( torrent_handle const& h , const std::string& url_ - , const std::string& msg) - : torrent_alert(h, alert::warning, msg) + , const std::string& msg_) + : torrent_alert(h) , url(url_) + , msg(msg_) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new url_seed_alert(*this)); } + virtual char const* what() const { return "web seed error"; } + const static int static_category = alert::peer_notification | alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " url seed (" + + url + ") failed: " + msg; + } std::string url; + std::string msg; }; struct TORRENT_EXPORT file_error_alert: torrent_alert @@ -412,118 +855,183 @@ namespace libtorrent file_error_alert( std::string const& f , const torrent_handle& h - , const std::string& msg) - : torrent_alert(h, alert::fatal, msg) + , const std::string& msg_) + : torrent_alert(h) , file(f) + , msg(msg_) {} std::string file; + std::string msg; virtual std::auto_ptr clone() const { return std::auto_ptr(new file_error_alert(*this)); } + virtual char const* what() const { return "file error"; } + const static int static_category = alert::status_notification + | alert::error_notification + | alert::storage_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " file (" + file + ") error: " + + msg; + } }; struct TORRENT_EXPORT metadata_failed_alert: torrent_alert { - metadata_failed_alert( - const torrent_handle& h - , const std::string& msg) - : torrent_alert(h, alert::info, msg) + metadata_failed_alert(const torrent_handle& h) + : torrent_alert(h) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new metadata_failed_alert(*this)); } + virtual char const* what() const { return "metadata failed"; } + const static int static_category = alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " invalid metadata received"; + } }; struct TORRENT_EXPORT metadata_received_alert: torrent_alert { metadata_received_alert( - const torrent_handle& h - , const std::string& msg) - : torrent_alert(h, alert::info, msg) + const torrent_handle& h) + : torrent_alert(h) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new metadata_received_alert(*this)); } + virtual char const* what() const { return "metadata received"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " metadata successfully received"; + } }; struct TORRENT_EXPORT udp_error_alert: alert { udp_error_alert( udp::endpoint const& ep - , std::string const& msg) - : alert(alert::info, msg) - , endpoint(ep) + , error_code const& ec) + : endpoint(ep) + , error(ec) {} udp::endpoint endpoint; + error_code error; virtual std::auto_ptr clone() const { return std::auto_ptr(new udp_error_alert(*this)); } + virtual char const* what() const { return "udp error"; } + const static int static_category = alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return "UDP error: " + error.message() + " from: " + endpoint.address().to_string(ec); + } }; struct TORRENT_EXPORT external_ip_alert: alert { - external_ip_alert( - address const& ip - , std::string const& msg) - : alert(alert::info, msg) - , external_address(ip) + external_ip_alert(address const& ip) + : external_address(ip) {} address external_address; virtual std::auto_ptr clone() const { return std::auto_ptr(new external_ip_alert(*this)); } + virtual char const* what() const { return "external IP received"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return "external IP received: " + external_address.to_string(ec); + } }; struct TORRENT_EXPORT listen_failed_alert: alert { listen_failed_alert( tcp::endpoint const& ep - , std::string const& msg) - : alert(alert::fatal, msg) - , endpoint(ep) + , error_code const& ec) + : endpoint(ep) + , error(ec) {} tcp::endpoint endpoint; + error_code error; virtual std::auto_ptr clone() const { return std::auto_ptr(new listen_failed_alert(*this)); } + virtual char const* what() const { return "listen failed"; } + const static int static_category = alert::status_notification | alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return "listening on " + endpoint.address().to_string(ec) + ":" + + boost::lexical_cast(endpoint.port()) + " failed: " + + error.message(); + } }; struct TORRENT_EXPORT listen_succeeded_alert: alert { - listen_succeeded_alert( - tcp::endpoint const& ep - , std::string const& msg) - : alert(alert::fatal, msg) - , endpoint(ep) + listen_succeeded_alert(tcp::endpoint const& ep) + : endpoint(ep) {} tcp::endpoint endpoint; virtual std::auto_ptr clone() const { return std::auto_ptr(new listen_succeeded_alert(*this)); } + virtual char const* what() const { return "listen succeeded"; } + const static int static_category = alert::status_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return "successfully listening on " + endpoint.address().to_string(ec) + + ":" + boost::lexical_cast(endpoint.port()); + } }; struct TORRENT_EXPORT portmap_error_alert: alert { - portmap_error_alert(int i, int t, const std::string& msg) - : alert(alert::warning, msg), mapping(i), type(t) + portmap_error_alert(int i, int t, const std::string& msg_) + : mapping(i), type(t), msg(msg_) {} int mapping; int type; + std::string msg; virtual std::auto_ptr clone() const { return std::auto_ptr(new portmap_error_alert(*this)); } + virtual char const* what() const { return "port map error"; } + const static int static_category = alert::port_mapping_notification + | alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + static char const* type_str[] = {"NAT-PMP", "UPnP"}; + return std::string("could not map port using ") + type_str[type] + + ": " + msg; + } }; struct TORRENT_EXPORT portmap_alert: alert { - portmap_alert(int i, int port, int t, const std::string& msg) - : alert(alert::info, msg), mapping(i), external_port(port), type(t) + portmap_alert(int i, int port, int t) + : mapping(i), external_port(port), type(t) {} int mapping; @@ -532,41 +1040,57 @@ namespace libtorrent virtual std::auto_ptr clone() const { return std::auto_ptr(new portmap_alert(*this)); } + virtual char const* what() const { return "port map succeeded"; } + const static int static_category = alert::port_mapping_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + static char const* type_str[] = {"NAT-PMP", "UPnP"}; + return std::string("successfully mapped port using ") + type_str[type] + + ". external port: " + boost::lexical_cast(external_port); + } }; struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert { fastresume_rejected_alert(torrent_handle const& h - , std::string const& msg) - : torrent_alert(h, alert::warning, msg) + , std::string const& msg_) + : torrent_alert(h) + , msg(msg_) {} + std::string msg; + virtual std::auto_ptr clone() const { return std::auto_ptr(new fastresume_rejected_alert(*this)); } + virtual char const* what() const { return "resume data rejected"; } + const static int static_category = alert::status_notification + | alert::error_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " fast resume rejected: " + msg; + } }; struct TORRENT_EXPORT peer_blocked_alert: alert { - peer_blocked_alert(address const& ip_ - , std::string const& msg) - : alert(alert::info, msg) - , ip(ip_) + peer_blocked_alert(address const& ip_) + : ip(ip_) {} address ip; virtual std::auto_ptr clone() const { return std::auto_ptr(new peer_blocked_alert(*this)); } - }; - - struct TORRENT_EXPORT torrent_resumed_alert: torrent_alert - { - torrent_resumed_alert(torrent_handle const& h, std::string const& msg) - : torrent_alert(h, alert::warning, msg) - {} - - virtual std::auto_ptr clone() const - { return std::auto_ptr(new torrent_resumed_alert(*this)); } + virtual char const* what() const { return "peer blocked"; } + const static int static_category = alert::ip_block_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return "blocked peer: " + ip.to_string(ec); + } }; } diff --git a/libtorrent/include/libtorrent/aux_/session_impl.hpp b/libtorrent/include/libtorrent/aux_/session_impl.hpp index fa4f0d276..57da44b4a 100644 --- a/libtorrent/include/libtorrent/aux_/session_impl.hpp +++ b/libtorrent/include/libtorrent/aux_/session_impl.hpp @@ -211,7 +211,7 @@ namespace libtorrent void check_torrent(boost::shared_ptr const& t); void done_checking(boost::shared_ptr const& t); - void set_severity_level(alert::severity_t s); + void set_alert_mask(int m); std::auto_ptr pop_alert(); alert const* wait_for_alert(time_duration max_wait); diff --git a/libtorrent/include/libtorrent/peer_connection.hpp b/libtorrent/include/libtorrent/peer_connection.hpp index f43857d5e..8eebb113b 100644 --- a/libtorrent/include/libtorrent/peer_connection.hpp +++ b/libtorrent/include/libtorrent/peer_connection.hpp @@ -88,9 +88,21 @@ namespace libtorrent struct session_impl; } - struct TORRENT_EXPORT protocol_error: std::runtime_error + struct pending_block { - protocol_error(const std::string& msg): std::runtime_error(msg) {}; + pending_block(piece_block const& b): skipped(0), block(b) {} + int skipped; + // the number of times the request + // has been skipped by out of order blocks + piece_block block; + }; + + struct has_block + { + has_block(piece_block const& b): block(b) {} + piece_block const& block; + bool operator()(pending_block const& pb) const + { return pb.block == block; } }; class TORRENT_EXPORT peer_connection @@ -209,7 +221,7 @@ namespace libtorrent void set_pid(const peer_id& pid) { m_peer_id = pid; } bool has_piece(int i) const; - std::deque const& download_queue() const; + std::deque const& download_queue() const; std::deque const& request_queue() const; std::deque const& upload_queue() const; @@ -238,6 +250,8 @@ namespace libtorrent // is called once every second by the main loop void second_tick(float tick_interval); + void timeout_requests(); + boost::shared_ptr get_socket() const { return m_socket; } tcp::endpoint const& remote() const { return m_remote; } @@ -349,6 +363,8 @@ namespace libtorrent void send_interested(); void send_not_interested(); + void snub_peer(); + // adds a block to the request queue void add_request(piece_block const& b); // removes a block from the request queue or download queue @@ -573,6 +589,11 @@ namespace libtorrent // download queue. Used for request timeout ptime m_requested; + // if the timeout is extended for the outstanding + // requests, this is the number of seconds it was + // extended. + int m_timeout_extend; + // a timestamp when the remote download rate // was last updated ptime m_remote_dl_update; @@ -646,7 +667,7 @@ namespace libtorrent // the queue of blocks we have requested // from this peer - std::deque m_download_queue; + std::deque m_download_queue; // the pieces we will send to the peer // if requested (regardless of choke state) @@ -792,13 +813,6 @@ namespace libtorrent // is used to fill the bitmask in init() bool m_have_all:1; - // if this is true, this peer is assumed to handle all piece - // requests in fifo order. All skipped blocks are re-requested - // immediately instead of having a looser requirement - // where blocks can be sent out of order. The default is to - // allow non-fifo order. - bool m_assume_fifo:1; - // this is true if this connection has been added // to the list of connections that will be closed. bool m_disconnecting:1; diff --git a/libtorrent/include/libtorrent/policy.hpp b/libtorrent/include/libtorrent/policy.hpp index 0c9380b8a..158163531 100644 --- a/libtorrent/include/libtorrent/policy.hpp +++ b/libtorrent/include/libtorrent/policy.hpp @@ -99,8 +99,6 @@ namespace libtorrent // the peer has got at least one interesting piece void peer_is_interesting(peer_connection& c); - int count_choked() const; - // the peer unchoked us void unchoked(peer_connection& c); diff --git a/libtorrent/include/libtorrent/session.hpp b/libtorrent/include/libtorrent/session.hpp index d95782d79..6b628bdbf 100644 --- a/libtorrent/include/libtorrent/session.hpp +++ b/libtorrent/include/libtorrent/session.hpp @@ -317,7 +317,8 @@ namespace libtorrent void set_max_half_open_connections(int limit); std::auto_ptr pop_alert(); - void set_severity_level(alert::severity_t s); + void set_severity_level(alert::severity_t s) TORRENT_DEPRECATED; + void set_alert_mask(int m); alert const* wait_for_alert(time_duration max_wait); diff --git a/libtorrent/src/alert.cpp b/libtorrent/src/alert.cpp index be6f718ee..844cfb93b 100755 --- a/libtorrent/src/alert.cpp +++ b/libtorrent/src/alert.cpp @@ -35,38 +35,16 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert.hpp" #include +enum { queue_size_limit = 1000 }; + namespace libtorrent { - alert::alert(severity_t severity, const std::string& msg) - : m_msg(msg) - , m_severity(severity) - , m_timestamp(time_now()) - { - } - - alert::~alert() - { - } - - ptime alert::timestamp() const - { - return m_timestamp; - } - - const std::string& alert::msg() const - { - return m_msg; - } - - alert::severity_t alert::severity() const - { - return m_severity; - } - - + alert::alert() : m_timestamp(time_now()) {} + alert::~alert() {} + ptime alert::timestamp() const { return m_timestamp; } alert_manager::alert_manager() - : m_severity(alert::fatal) + : m_alert_mask(alert::error_notification) {} alert_manager::~alert_manager() @@ -105,15 +83,8 @@ namespace libtorrent { void alert_manager::post_alert(const alert& alert_) { boost::mutex::scoped_lock lock(m_mutex); - if (m_severity > alert_.severity()) return; - // the internal limit is 100 alerts - if (m_alerts.size() == 100) - { - alert* result = m_alerts.front(); - m_alerts.pop(); - delete result; - } + if (m_alerts.size() >= queue_size_limit) return; m_alerts.push(alert_.clone().release()); m_condition.notify_all(); } @@ -136,17 +107,5 @@ namespace libtorrent { return !m_alerts.empty(); } - void alert_manager::set_severity(alert::severity_t severity) - { - boost::mutex::scoped_lock lock(m_mutex); - - m_severity = severity; - } - - bool alert_manager::should_post(alert::severity_t severity) const - { - return severity >= m_severity; - } - } // namespace libtorrent diff --git a/libtorrent/src/bt_peer_connection.cpp b/libtorrent/src/bt_peer_connection.cpp index 16e63728a..cf9e3bc34 100755 --- a/libtorrent/src/bt_peer_connection.cpp +++ b/libtorrent/src/bt_peer_connection.cpp @@ -826,7 +826,7 @@ namespace libtorrent TORRENT_ASSERT(t); while (!download_queue().empty()) { - piece_block const& b = download_queue().front(); + piece_block const& b = download_queue().front().block; peer_request r; r.piece = b.piece_index; r.start = b.block_index * t->block_size(); diff --git a/libtorrent/src/metadata_transfer.cpp b/libtorrent/src/metadata_transfer.cpp index 8e27eeabf..a347223e3 100644 --- a/libtorrent/src/metadata_transfer.cpp +++ b/libtorrent/src/metadata_transfer.cpp @@ -173,10 +173,10 @@ namespace libtorrent { namespace m_metadata_progress = 0; m_metadata_size = 0; - if (m_torrent.alerts().should_post(alert::info)) + if (m_torrent.alerts().should_post()) { m_torrent.alerts().post_alert(metadata_failed_alert( - m_torrent.get_handle(), "invalid metadata received from swarm")); + m_torrent.get_handle())); } return false; diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index 8f69665fa..6c2b2eb88 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -82,6 +82,7 @@ namespace libtorrent , m_last_receive(time_now()) , m_last_sent(time_now()) , m_requested(min_time()) + , m_timeout_extend(0) , m_remote_dl_update(time_now()) , m_became_uninterested(time_now()) , m_became_uninteresting(time_now()) @@ -121,7 +122,6 @@ namespace libtorrent , m_failed(false) , m_ignore_bandwidth_limits(false) , m_have_all(false) - , m_assume_fifo(false) , m_disconnecting(false) , m_connecting(true) , m_queued(true) @@ -185,6 +185,7 @@ namespace libtorrent , m_last_receive(time_now()) , m_last_sent(time_now()) , m_requested(min_time()) + , m_timeout_extend(0) , m_remote_dl_update(time_now()) , m_became_uninterested(time_now()) , m_became_uninteresting(time_now()) @@ -223,7 +224,6 @@ namespace libtorrent , m_failed(false) , m_ignore_bandwidth_limits(false) , m_have_all(false) - , m_assume_fifo(false) , m_disconnecting(false) , m_connecting(false) , m_queued(false) @@ -574,7 +574,7 @@ namespace libtorrent return m_request_queue; } - std::deque const& peer_connection::download_queue() const + std::deque const& peer_connection::download_queue() const { return m_download_queue; } @@ -851,9 +851,10 @@ namespace libtorrent if (is_disconnecting()) return; - std::deque::iterator i = std::find_if( + std::deque::iterator i = std::find_if( m_download_queue.begin(), m_download_queue.end() - , bind(match_request, boost::cref(r), _1, t->block_size())); + , bind(match_request, boost::cref(r), bind(&pending_block::block, _1) + , t->block_size())); #ifdef TORRENT_VERBOSE_LOGGING (*m_logger) << time_now_string() @@ -863,7 +864,7 @@ namespace libtorrent piece_block b(-1, 0); if (i != m_download_queue.end()) { - b = *i; + b = i->block; m_download_queue.erase(i); // if the peer is in parole mode, keep the request @@ -1378,14 +1379,10 @@ namespace libtorrent write_reject_request(r); ++m_num_invalid_requests; - if (t->alerts().should_post(alert::debug)) + if (t->alerts().should_post()) { - t->alerts().post_alert(invalid_request_alert( - r - , t->get_handle() - , m_remote - , m_peer_id - , "peer sent an illegal piece request")); + t->alerts().post_alert(invalid_request_alert(r + , t->get_handle(), m_remote, m_peer_id)); } } } @@ -1516,21 +1513,18 @@ namespace libtorrent TORRENT_ASSERT(p.length == t->block_size() || p.length == t->torrent_file().total_size() % t->block_size()); - std::deque::iterator b - = std::find( + std::deque::iterator b + = std::find_if( m_download_queue.begin() , m_download_queue.end() - , block_finished); + , has_block(block_finished)); if (b == m_download_queue.end()) { - if (t->alerts().should_post(alert::debug)) + if (t->alerts().should_post()) { - t->alerts().post_alert( - peer_error_alert( - m_remote - , m_peer_id - , "got a block that was not in the request queue")); + t->alerts().post_alert(peer_error_alert(t->get_handle(), m_remote + , m_peer_id, "got a block that was not in the request queue")); } #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING (*m_logger) << " *** The block we just got was not in the " @@ -1542,39 +1536,41 @@ namespace libtorrent return; } - if (m_assume_fifo) + for (std::deque::iterator i = m_download_queue.begin(); + i != b;) { - for (std::deque::iterator i = m_download_queue.begin(); - i != b; ++i) - { + #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING - (*m_logger) << time_now_string() - << " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | " - "b: " << i->block_index << " ] ***\n"; + (*m_logger) << time_now_string() + << " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | " + "b: " << i->block_index << " ] ***\n"; #endif - // since this piece was skipped, clear it and allow it to - // be requested from other peers - // TODO: send cancel? - picker.abort_download(*i); + + ++i->skipped; + // if the number of times a block is skipped by out of order + // blocks exceeds the size of the outstanding queue, assume that + // the other end dropped the request. + if (i->skipped > m_desired_queue_size) + { + if (m_ses.m_alerts.should_post()) + m_ses.m_alerts.post_alert(request_dropped_alert(t->get_handle() + , i->block.block_index, i->block.piece_index)); + picker.abort_download(i->block); + i = m_download_queue.erase(i); + } + else + { + ++i; } - - // remove the request that just finished - // from the download queue plus the - // skipped blocks. - m_download_queue.erase(m_download_queue.begin(), b); - b = m_download_queue.begin(); - TORRENT_ASSERT(*b == block_finished); } - - if (total_seconds(time_now() - m_requested) < m_ses.settings().request_timeout) - m_snubbed = false; - + // if the block we got is already finished, then ignore it if (picker.is_downloaded(block_finished)) { t->received_redundant_data(p.length); m_download_queue.erase(b); + m_timeout_extend = 0; if (!m_download_queue.empty()) m_requested = time_now(); @@ -1584,12 +1580,25 @@ namespace libtorrent return; } + if (total_seconds(time_now() - m_requested) + < m_ses.settings().request_timeout + && m_snubbed) + { + m_snubbed = false; + if (m_ses.m_alerts.should_post()) + { + m_ses.m_alerts.post_alert(peer_unsnubbed_alert(t->get_handle() + , m_remote, m_peer_id)); + } + } + fs.async_write(p, data, bind(&peer_connection::on_disk_write_complete , self(), _1, _2, p, t)); m_outstanding_writing_bytes += p.length; TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle); m_download_queue.erase(b); + m_timeout_extend = 0; if (!m_download_queue.empty()) m_requested = time_now(); @@ -1637,7 +1646,7 @@ namespace libtorrent return; } - if (t->alerts().should_post(alert::fatal)) + if (t->alerts().should_post()) { t->alerts().post_alert(file_error_alert(j.error_file, t->get_handle(), j.str)); } @@ -1652,10 +1661,10 @@ namespace libtorrent TORRENT_ASSERT(p.piece == j.piece); TORRENT_ASSERT(p.start == j.offset); picker.mark_as_finished(block_finished, peer_info_struct()); - if (t->alerts().should_post(alert::debug)) + if (t->alerts().should_post()) { t->alerts().post_alert(block_finished_alert(t->get_handle(), - block_finished.block_index, block_finished.piece_index, "block finished")); + block_finished.block_index, block_finished.piece_index)); } // did we just finish the piece? @@ -1909,8 +1918,10 @@ namespace libtorrent TORRENT_ASSERT(block.block_index < t->torrent_file().piece_size(block.piece_index)); TORRENT_ASSERT(!t->picker().is_requested(block) || (t->picker().num_peers(block) > 0)); TORRENT_ASSERT(!t->have_piece(block.piece_index)); - TORRENT_ASSERT(std::find(m_download_queue.begin(), m_download_queue.end(), block) == m_download_queue.end()); - TORRENT_ASSERT(std::find(m_request_queue.begin(), m_request_queue.end(), block) == m_request_queue.end()); + TORRENT_ASSERT(std::find_if(m_download_queue.begin(), m_download_queue.end() + , has_block(block)) == m_download_queue.end()); + TORRENT_ASSERT(std::find(m_request_queue.begin(), m_request_queue.end() + , block) == m_request_queue.end()); piece_picker::piece_state_t state; peer_speed_t speed = peer_speed(); @@ -1934,10 +1945,10 @@ namespace libtorrent if (!t->picker().mark_as_downloading(block, peer_info_struct(), state)) return; - if (t->alerts().should_post(alert::debug)) + if (t->alerts().should_post()) { t->alerts().post_alert(block_downloading_alert(t->get_handle(), - speedmsg, block.block_index, block.piece_index, "block downloading")); + speedmsg, block.block_index, block.piece_index)); } m_request_queue.push_back(block); @@ -1962,18 +1973,20 @@ namespace libtorrent // cancelled, then just ignore the cancel. if (!t->picker().is_requested(block)) return; - std::deque::iterator it - = std::find(m_download_queue.begin(), m_download_queue.end(), block); + std::deque::iterator it + = std::find_if(m_download_queue.begin(), m_download_queue.end(), has_block(block)); if (it == m_download_queue.end()) { - it = std::find(m_request_queue.begin(), m_request_queue.end(), block); + std::deque::iterator rit = std::find(m_request_queue.begin() + , m_request_queue.end(), block); + // when a multi block is received, it is cancelled // from all peers, so if this one hasn't requested // the block, just ignore to cancel it. - if (it == m_request_queue.end()) return; + if (rit == m_request_queue.end()) return; t->picker().abort_download(block); - m_request_queue.erase(it); + m_request_queue.erase(rit); // since we found it in the request queue, it means it hasn't been // sent yet, so we don't have to send a cancel. return; @@ -2238,18 +2251,20 @@ namespace libtorrent } boost::shared_ptr t = m_torrent.lock(); + torrent_handle handle; + if (t) handle = t->get_handle(); if (message) { - if (error > 1 && m_ses.m_alerts.should_post(alert::info)) + if (error > 1 && m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( - peer_error_alert(remote(), pid(), message)); + peer_error_alert(handle, remote(), pid(), message)); } - else if (error <= 1 && m_ses.m_alerts.should_post(alert::debug)) + else if (error <= 1 && m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( - peer_disconnected_alert(remote(), pid(), message)); + peer_disconnected_alert(handle, remote(), pid(), message)); } } @@ -2265,7 +2280,7 @@ namespace libtorrent while (!m_download_queue.empty()) { - picker.abort_download(m_download_queue.back()); + picker.abort_download(m_download_queue.back().block); m_download_queue.pop_back(); } while (!m_request_queue.empty()) @@ -2359,7 +2374,8 @@ namespace libtorrent p.send_quota = m_bandwidth_limit[upload_channel].quota_left(); p.receive_quota = m_bandwidth_limit[download_channel].quota_left(); if (m_download_queue.empty()) p.request_timeout = -1; - else p.request_timeout = total_seconds(m_requested - now) + m_ses.settings().request_timeout; + else p.request_timeout = total_seconds(m_requested - now) + m_ses.settings().request_timeout + + m_timeout_extend; #ifndef TORRENT_DISABLE_GEO_IP p.inet_as_name = m_inet_as_name; #endif @@ -2613,21 +2629,12 @@ namespace libtorrent } if (!m_download_queue.empty() - && now > m_requested + seconds(m_ses.settings().request_timeout) - && t->has_picker()) + && now > m_requested + seconds(m_ses.settings().request_timeout + + m_timeout_extend)) { - m_snubbed = true; - m_desired_queue_size = 1; - piece_picker& picker = t->picker(); - // the front request timed out! - picker.abort_download(m_download_queue[0]); - m_download_queue.pop_front(); - if (!m_download_queue.empty()) - m_requested = time_now(); - request_a_block(*t, *this); - send_block_requests(); + snub_peer(); } - + // if we haven't sent something in too long, send a keep-alive keep_alive(); @@ -2683,7 +2690,8 @@ namespace libtorrent } if (!m_download_queue.empty() - && now - m_last_piece > seconds(m_ses.settings().piece_timeout)) + && now - m_last_piece > seconds(m_ses.settings().piece_timeout + + m_timeout_extend)) { // this peer isn't sending the pieces we've // requested (this has been observed by BitComet) @@ -2695,43 +2703,7 @@ namespace libtorrent << " " << total_seconds(now - m_last_piece) << "] ***\n"; #endif - m_snubbed = true; - m_desired_queue_size = 1; - - if (t->is_seed()) - { - m_download_queue.clear(); - m_request_queue.clear(); - } - else - { - piece_picker& picker = t->picker(); - - std::deque dl(m_download_queue); - for (std::deque::iterator i = dl.begin() - , end(dl.end()); i != end; ++i) - { - piece_block const& r = m_download_queue.back(); -#ifdef TORRENT_VERBOSE_LOGGING - (*m_logger) << time_now_string() - << " ==> CANCEL [ piece: " << r.piece_index - << " | block: " << r.block_index - << " ]\n"; -#endif - write_cancel(t->to_req(r)); - } - while (!m_request_queue.empty()) - { - piece_block const& r = m_request_queue.back(); - picker.abort_download(r); - m_request_queue.pop_back(); - } - - m_assume_fifo = true; - - request_a_block(*t, *this); - send_block_requests(); - } + snub_peer(); } // If the client sends more data @@ -2791,6 +2763,71 @@ namespace libtorrent fill_send_buffer(); } + void peer_connection::snub_peer() + { + boost::shared_ptr t = m_torrent.lock(); + TORRENT_ASSERT(t); + + if (!m_snubbed) + { + m_snubbed = true; + if (m_ses.m_alerts.should_post()) + { + m_ses.m_alerts.post_alert(peer_snubbed_alert(t->get_handle() + , m_remote, m_peer_id)); + } + } + m_desired_queue_size = 1; + + if (!t->has_picker()) return; + piece_picker& picker = t->picker(); + + piece_block r(-1, -1); + // time out the last request in the queue + if (!m_request_queue.empty()) + { + r = m_request_queue.back(); + m_request_queue.pop_back(); + } + else + { + TORRENT_ASSERT(!m_download_queue.empty()); + r = m_download_queue.back().block; + + // only time out a request if it blocks the piece + // from being completed (i.e. no free blocks to + // request from it) + piece_picker::downloading_piece p; + picker.piece_info(r.piece_index, p); + int free_blocks = picker.blocks_in_piece(r.piece_index) + - p.finished - p.writing - p.requested; + if (free_blocks > 0) + { + m_timeout_extend += m_ses.settings().request_timeout; + return; + } + + if (m_ses.m_alerts.should_post()) + { + m_ses.m_alerts.post_alert(block_timeout_alert(t->get_handle() + , r.block_index, r.piece_index)); + } + m_download_queue.pop_back(); + } + if (!m_download_queue.empty() || !m_request_queue.empty()) + m_timeout_extend += m_ses.settings().request_timeout; + + request_a_block(*t, *this); + send_block_requests(); + + // abort the block after the new one has + // been requested in order to prevent it from + // picking the same block again, stalling the + // same piece indefinitely. + if (r != piece_block(-1, -1)) + picker.abort_download(r); + } + void peer_connection::fill_send_buffer() { INVARIANT_CHECK; @@ -2843,10 +2880,8 @@ namespace libtorrent return; } - if (t->alerts().should_post(alert::fatal)) - { + if (t->alerts().should_post()) t->alerts().post_alert(file_error_alert(j.error_file, t->get_handle(), j.str)); - } t->set_error(j.str); t->pause(); return; @@ -3378,10 +3413,10 @@ namespace libtorrent , bind(&peer_connection::on_connection_complete, self(), _1)); m_connect = time_now(); - if (t->alerts().should_post(alert::debug)) + if (t->alerts().should_post()) { - t->alerts().post_alert(peer_error_alert( - m_remote, m_peer_id, "connecting to peer")); + t->alerts().post_alert(peer_connect_alert( + t->get_handle(), m_remote)); } } @@ -3521,7 +3556,8 @@ namespace libtorrent TORRENT_ASSERT(m_bandwidth_limit[upload_channel].quota_left() == 0); std::set unique; - std::copy(m_download_queue.begin(), m_download_queue.end(), std::inserter(unique, unique.begin())); + std::transform(m_download_queue.begin(), m_download_queue.end() + , std::inserter(unique, unique.begin()), boost::bind(&pending_block::block, _1)); std::copy(m_request_queue.begin(), m_request_queue.end(), std::inserter(unique, unique.begin())); TORRENT_ASSERT(unique.size() == m_download_queue.size() + m_request_queue.size()); if (m_peer_info) @@ -3556,9 +3592,9 @@ namespace libtorrent for (std::deque::const_iterator i = p.request_queue().begin() , end(p.request_queue().end()); i != end; ++i) ++num_requests[*i]; - for (std::deque::const_iterator i = p.download_queue().begin() + for (std::deque::const_iterator i = p.download_queue().begin() , end(p.download_queue().end()); i != end; ++i) - ++num_requests[*i]; + ++num_requests[i->block]; } for (std::map::iterator i = num_requests.begin() , end(num_requests.end()); i != end; ++i) diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index 07791adba..944585a76 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -271,7 +271,7 @@ namespace libtorrent (*c.m_logger) << time_now_string() << " PIECE_PICKER [ php: " << prefer_whole_pieces << " picked: " << interesting_pieces.size() << " ]\n"; #endif - std::deque const& dq = c.download_queue(); + std::deque const& dq = c.download_queue(); std::deque const& rq = c.request_queue(); for (std::vector::iterator i = interesting_pieces.begin(); i != interesting_pieces.end(); ++i) @@ -282,7 +282,7 @@ namespace libtorrent { if (num_requests <= 0) break; // don't request pieces we already have in our request queue - if (std::find(dq.begin(), dq.end(), *i) != dq.end() + if (std::find_if(dq.begin(), dq.end(), has_block(*i)) != dq.end() || std::find(rq.begin(), rq.end(), *i) != rq.end()) continue; @@ -359,21 +359,15 @@ namespace libtorrent if (i->second.connection) { i->second.connection->disconnect("peer banned by IP filter"); - if (ses.m_alerts.should_post(alert::info)) - { - ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address() - , "disconnected blocked peer")); - } + if (ses.m_alerts.should_post()) + ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address())); TORRENT_ASSERT(i->second.connection == 0 || i->second.connection->peer_info_struct() == 0); } else { - if (ses.m_alerts.should_post(alert::info)) - { - ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address() - , "blocked peer removed from peer list")); - } + if (ses.m_alerts.should_post()) + ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address())); } erase_peer(i++); } @@ -545,22 +539,6 @@ namespace libtorrent } } - int policy::count_choked() const - { - int ret = 0; - for (const_iterator i = m_peers.begin(); - i != m_peers.end(); ++i) - { - if (!i->second.connection - || i->second.connection->is_connecting() - || i->second.connection->is_disconnecting() - || !i->second.connection->is_peer_interested()) - continue; - if (i->second.connection->is_choked()) ++ret; - } - return ret; - } - bool policy::new_connection(peer_connection& c) { TORRENT_ASSERT(!c.is_local()); @@ -771,11 +749,8 @@ namespace libtorrent port_filter const& pf = ses.m_port_filter; if (pf.access(remote.port()) & port_filter::blocked) { - if (ses.m_alerts.should_post(alert::info)) - { - ses.m_alerts.post_alert(peer_blocked_alert(remote.address() - , "outgoing port blocked, peer not added to peer list")); - } + if (ses.m_alerts.should_post()) + ses.m_alerts.post_alert(peer_blocked_alert(remote.address())); return 0; } @@ -797,10 +772,9 @@ namespace libtorrent // if the IP is blocked, don't add it if (ses.m_ip_filter.access(remote.address()) & ip_filter::blocked) { - if (ses.m_alerts.should_post(alert::info)) + if (ses.m_alerts.should_post()) { - ses.m_alerts.post_alert(peer_blocked_alert(remote.address() - , "blocked peer not added to peer list")); + ses.m_alerts.post_alert(peer_blocked_alert(remote.address())); } return 0; } diff --git a/libtorrent/src/session.cpp b/libtorrent/src/session.cpp index 194af5b73..5e0ad1205 100755 --- a/libtorrent/src/session.cpp +++ b/libtorrent/src/session.cpp @@ -513,9 +513,27 @@ namespace libtorrent return m_impl->wait_for_alert(max_wait); } + void session::set_alert_mask(int m) + { + m_impl->set_alert_mask(m); + } + void session::set_severity_level(alert::severity_t s) { - m_impl->set_severity_level(s); + int m = 0; + switch (s) + { + case alert::debug: m = alert::all_categories; break; + case alert::info: m = alert::all_categories & ~(alert::debug_notification + | alert::progress_notification); break; + case alert::warning: m = alert::all_categories & ~(alert::debug_notification + | alert::status_notification | alert::progress_notification); break; + case alert::critical: m = alert::error_notification | alert::storage_notification; break; + case alert::fatal: m = alert::error_notification; break; + default: break; + } + + m_impl->set_alert_mask(m); } void session::start_lsd() diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index 0e33421e7..92ad41db6 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -605,13 +605,8 @@ namespace aux { if (ec) { // not even that worked, give up - if (m_alerts.should_post(alert::fatal)) - { - std::stringstream msg; - msg << "cannot bind to interface '"; - print_endpoint(msg, ep) << "' " << ec.message(); - m_alerts.post_alert(listen_failed_alert(ep, msg.str())); - } + if (m_alerts.should_post()) + m_alerts.post_alert(listen_failed_alert(ep, ec)); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) std::stringstream msg; msg << "cannot bind to interface '"; @@ -624,13 +619,8 @@ namespace aux { s.sock->listen(0, ec); if (ec) { - if (m_alerts.should_post(alert::fatal)) - { - std::stringstream msg; - msg << "cannot listen on interface '"; - print_endpoint(msg, ep) << "' " << ec.message(); - m_alerts.post_alert(listen_failed_alert(ep, msg.str())); - } + if (m_alerts.should_post()) + m_alerts.post_alert(listen_failed_alert(ep, ec)); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) std::stringstream msg; msg << "cannot listen on interface '"; @@ -640,12 +630,8 @@ namespace aux { return listen_socket_t(); } - if (m_alerts.should_post(alert::fatal)) - { - std::string msg = "listening on interface " - + boost::lexical_cast(ep); - m_alerts.post_alert(listen_succeeded_alert(ep, msg)); - } + if (m_alerts.should_post()) + m_alerts.post_alert(listen_succeeded_alert(ep)); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << "listening on: " << ep @@ -767,12 +753,8 @@ namespace aux { || e == asio::error::connection_aborted) m_dht->on_unreachable(ep); - if (m_alerts.should_post(alert::info)) - { - std::string msg = "UDP socket error from '" - + boost::lexical_cast(ep) + "' " + e.message(); - m_alerts.post_alert(udp_error_alert(ep, msg)); - } + if (m_alerts.should_post()) + m_alerts.post_alert(udp_error_alert(ep, e)); return; } @@ -832,12 +814,8 @@ namespace aux { return; } #endif - if (m_alerts.should_post(alert::fatal)) - { - std::string msg = "error accepting connection on '" - + boost::lexical_cast(ep) + "' " + e.message(); - m_alerts.post_alert(listen_failed_alert(ep, msg)); - } + if (m_alerts.should_post()) + m_alerts.post_alert(listen_failed_alert(ep, e)); return; } async_accept(listener); @@ -870,11 +848,8 @@ namespace aux { #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << "filtered blocked ip\n"; #endif - if (m_alerts.should_post(alert::info)) - { - m_alerts.post_alert(peer_blocked_alert(endp.address() - , "incoming connection blocked by IP filter")); - } + if (m_alerts.should_post()) + m_alerts.post_alert(peer_blocked_alert(endp.address())); return; } @@ -1108,11 +1083,10 @@ namespace aux { m_tracker_manager.queue_request(m_io_service, m_half_open, req , t.tracker_login(), m_listen_interface.address(), i->second); - if (m_alerts.should_post(alert::info)) + if (m_alerts.should_post()) { m_alerts.post_alert( - tracker_announce_alert( - t.get_handle(), req.url, "tracker announce")); + tracker_announce_alert(t.get_handle(), req.url)); } } @@ -1867,11 +1841,10 @@ namespace aux { , t.tracker_login(), m_listen_interface.address()); #endif - if (m_alerts.should_post(alert::info)) + if (m_alerts.should_post()) { m_alerts.post_alert( - tracker_announce_alert( - t.get_handle(), req.url, "tracker announce, event=stopped")); + tracker_announce_alert(t.get_handle(), req.url)); } } #ifndef NDEBUG @@ -1984,9 +1957,9 @@ namespace aux { { m_external_udp_port = port; m_dht_settings.service_port = port; - if (m_alerts.should_post(alert::info)) + if (m_alerts.should_post()) m_alerts.post_alert(portmap_alert(mapping, port - , map_transport, "successfully mapped UDP port")); + , map_transport)); return; } #endif @@ -1995,23 +1968,23 @@ namespace aux { { if (!m_listen_sockets.empty()) m_listen_sockets.front().external_port = port; - if (m_alerts.should_post(alert::info)) + if (m_alerts.should_post()) m_alerts.post_alert(portmap_alert(mapping, port - , map_transport, "successfully mapped TCP port")); + , map_transport)); return; } if (!errmsg.empty()) { - if (m_alerts.should_post(alert::warning)) + if (m_alerts.should_post()) m_alerts.post_alert(portmap_error_alert(mapping , map_transport, errmsg)); } else { - if (m_alerts.should_post(alert::warning)) + if (m_alerts.should_post()) m_alerts.post_alert(portmap_alert(mapping, port - , map_transport, "successfully mapped port")); + , map_transport)); } } @@ -2309,10 +2282,10 @@ namespace aux { return m_alerts.wait_for_alert(max_wait); } - void session_impl::set_severity_level(alert::severity_t s) + void session_impl::set_alert_mask(int m) { mutex_t::scoped_lock l(m_mutex); - m_alerts.set_severity(s); + m_alerts.set_alert_mask(m); } int session_impl::upload_rate_limit() const @@ -2437,13 +2410,8 @@ namespace aux { if (m_external_address == ip) return; m_external_address = ip; - if (m_alerts.should_post(alert::info)) - { - std::stringstream msg; - msg << "external address is '"; - print_address(msg, ip) << "'"; - m_alerts.post_alert(external_ip_alert(ip, msg.str())); - } + if (m_alerts.should_post()) + m_alerts.post_alert(external_ip_alert(ip)); } void session_impl::free_disk_buffer(char* buf) diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index d7e989d37..b9dea84f6 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -297,7 +297,7 @@ namespace libtorrent + m_resume_data.size(), m_resume_entry) != 0) { std::vector().swap(m_resume_data); - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), "parse failed")); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING @@ -461,7 +461,7 @@ namespace libtorrent if (!error && sha1_hash(info_hash) != m_torrent_file->info_hash()) error = "mismatching info-hash"; - if (error && m_ses.m_alerts.should_post(alert::warning)) + if (error && m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), error)); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING @@ -493,7 +493,7 @@ namespace libtorrent if (ret == piece_manager::fatal_disk_error) { - if (m_ses.m_alerts.should_post(alert::fatal)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(file_error_alert(j.error_file, get_handle(), j.str)); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING @@ -552,7 +552,7 @@ namespace libtorrent bool fastresume_rejected = !j.str.empty(); - if (fastresume_rejected && m_ses.m_alerts.should_post(alert::warning)) + if (fastresume_rejected && m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), j.str)); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING @@ -672,7 +672,7 @@ namespace libtorrent if (ret == piece_manager::fatal_disk_error) { - if (m_ses.m_alerts.should_post(alert::fatal)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(file_error_alert(j.error_file, get_handle(), j.str)); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING @@ -710,7 +710,7 @@ namespace libtorrent } if (ret == piece_manager::fatal_disk_error) { - if (m_ses.m_alerts.should_post(alert::fatal)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(file_error_alert(j.error_file, get_handle(), j.str)); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING @@ -809,10 +809,10 @@ namespace libtorrent { if (peers.empty()) return; - if (m_ses.m_alerts.should_post(alert::info)) + if (m_ses.m_alerts.should_post()) { - m_ses.m_alerts.post_alert(tracker_reply_alert( - get_handle(), peers.size(), "DHT", "Got peers from DHT")); + m_ses.m_alerts.post_alert(dht_reply_alert( + get_handle(), peers.size())); } std::for_each(peers.begin(), peers.end(), bind( &policy::peer_from_tracker, boost::ref(m_policy), _1, peer_id(0) @@ -861,10 +861,8 @@ namespace libtorrent INVARIANT_CHECK; - if (m_ses.m_alerts.should_post(alert::warning)) - { + if (m_ses.m_alerts.should_post()) m_ses.m_alerts.post_alert(tracker_warning_alert(get_handle(), req.url, msg)); - } } void torrent::tracker_scrape_response(tracker_request const& req @@ -878,10 +876,10 @@ namespace libtorrent if (complete >= 0) m_complete = complete; if (incomplete >= 0) m_incomplete = incomplete; - if (m_ses.m_alerts.should_post(alert::info)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(scrape_reply_alert( - get_handle(), m_incomplete, m_complete, req.url, "got scrape response from tracker")); + get_handle(), m_incomplete, m_complete, req.url)); } } @@ -964,11 +962,8 @@ namespace libtorrent #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING debug_log("blocked ip from tracker: " + i->ip); #endif - if (m_ses.m_alerts.should_post(alert::info)) - { - m_ses.m_alerts.post_alert(peer_blocked_alert(a.address() - , "peer from tracker blocked by IP filter")); - } + if (m_ses.m_alerts.should_post()) + m_ses.m_alerts.post_alert(peer_blocked_alert(a.address())); continue; } @@ -977,10 +972,10 @@ namespace libtorrent } } - if (m_ses.m_alerts.should_post(alert::info)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(tracker_reply_alert( - get_handle(), peer_list.size(), r.url, "got response from tracker")); + get_handle(), peer_list.size(), r.url)); } m_got_tracker_response = true; } @@ -1000,10 +995,9 @@ namespace libtorrent #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING debug_log("blocked ip from tracker: " + host->endpoint().address().to_string()); #endif - if (m_ses.m_alerts.should_post(alert::info)) + if (m_ses.m_alerts.should_post()) { - m_ses.m_alerts.post_alert(peer_blocked_alert(host->endpoint().address() - , "peer from tracker blocked by IP filter")); + m_ses.m_alerts.post_alert(peer_blocked_alert(host->endpoint().address())); } return; @@ -1276,10 +1270,10 @@ namespace libtorrent TORRENT_ASSERT(index >= 0); TORRENT_ASSERT(index < m_torrent_file->num_pieces()); - if (m_ses.m_alerts.should_post(alert::debug)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(piece_finished_alert(get_handle() - , index, "piece finished")); + , index)); } bool was_finished = m_picker->num_filtered() + num_have() @@ -1365,12 +1359,9 @@ namespace libtorrent TORRENT_ASSERT(index >= 0); TORRENT_ASSERT(index < m_torrent_file->num_pieces()); - if (m_ses.m_alerts.should_post(alert::info)) - { - std::stringstream s; - s << "hash for piece " << index << " failed"; - m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index, s.str())); - } + if (m_ses.m_alerts.should_post()) + m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index)); + // increase the total amount of failed bytes m_total_failed_bytes += m_torrent_file->piece_size(index); @@ -1424,12 +1415,10 @@ namespace libtorrent { // we don't trust this peer anymore // ban it. - if (m_ses.m_alerts.should_post(alert::info)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(peer_ban_alert( - p->ip - , get_handle() - , "banning peer because of too many corrupt pieces")); + p->ip, get_handle())); } // mark the peer as banned @@ -1485,13 +1474,13 @@ namespace libtorrent i != m_connections.end(); ++i) { peer_connection* p = *i; - std::deque const& dq = p->download_queue(); + std::deque const& dq = p->download_queue(); std::deque const& rq = p->request_queue(); - for (std::deque::const_iterator k = dq.begin() + for (std::deque::const_iterator k = dq.begin() , end(dq.end()); k != end; ++k) { - if (k->piece_index != index) continue; - m_picker->mark_as_downloading(*k, p->peer_info_struct() + if (k->block.piece_index != index) continue; + m_picker->mark_as_downloading(k->block, p->peer_info_struct() , (piece_picker::piece_state_t)p->peer_speed()); } for (std::deque::const_iterator k = rq.begin() @@ -1539,16 +1528,15 @@ namespace libtorrent { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - if (alerts().should_post(alert::warning)) + if (ret != 0) { - if (ret != 0) - { - alerts().post_alert(torrent_deleted_alert(get_handle(), "delete files failed: " + j.str)); - } - else - { - alerts().post_alert(torrent_deleted_alert(get_handle(), "files deleted")); - } + if (alerts().should_post()) + alerts().post_alert(torrent_delete_failed_alert(get_handle(), j.str)); + } + else + { + if (alerts().should_post()) + alerts().post_alert(torrent_deleted_alert(get_handle())); } } @@ -1557,9 +1545,9 @@ namespace libtorrent /* session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - if (alerts().should_post(alert::warning)) + if (alerts().should_post()) { - alerts().post_alert(torrent_paused_alert(get_handle(), "torrent paused")); + alerts().post_alert(torrent_paused_alert(get_handle())); } */ } @@ -1568,20 +1556,17 @@ namespace libtorrent { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - if (alerts().should_post(alert::warning)) + if (!j.resume_data && alerts().should_post()) { - char const* msg; - if (j.resume_data) - { - write_resume_data(*j.resume_data); - msg = "resume data generated"; - } - else - { - msg = j.str.c_str(); - } + alerts().post_alert(save_resume_data_failed_alert(get_handle(), j.str)); + return; + } + + if (j.resume_data && alerts().should_post()) + { + write_resume_data(*j.resume_data); alerts().post_alert(save_resume_data_alert(j.resume_data - , get_handle(), msg)); + , get_handle())); } } @@ -1589,14 +1574,17 @@ namespace libtorrent { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - if (alerts().should_post(alert::warning)) { - if (ret == 0) - alerts().post_alert(file_renamed_alert(get_handle(), j.str - , "renamed file: " + j.str)); + { + if (alerts().should_post()) + alerts().post_alert(file_renamed_alert(get_handle(), j.str, j.piece)); + } else - alerts().post_alert(file_renamed_alert(get_handle(), "", j.str)); + { + if (alerts().should_post()) + alerts().post_alert(file_rename_failed_alert(get_handle(), j.str, j.piece)); + } } } @@ -1604,10 +1592,8 @@ namespace libtorrent { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - if (alerts().should_post(alert::warning)) - { - alerts().post_alert(torrent_paused_alert(get_handle(), "torrent paused")); - } + if (alerts().should_post()) + alerts().post_alert(torrent_paused_alert(get_handle())); } std::string torrent::tracker_login() const @@ -2050,7 +2036,7 @@ namespace libtorrent if (protocol != "http") #endif { - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( url_seed_alert(get_handle(), url, "unknown protocol")); @@ -2062,7 +2048,7 @@ namespace libtorrent if (hostname.empty()) { - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( url_seed_alert(get_handle(), url, "invalid hostname")); @@ -2074,7 +2060,7 @@ namespace libtorrent if (port == 0) { - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( url_seed_alert(get_handle(), url, "invalid port")); @@ -2099,7 +2085,7 @@ namespace libtorrent { if (m_ses.m_port_filter.access(port) & port_filter::blocked) { - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( url_seed_alert(get_handle(), url, "port blocked by port-filter")); @@ -2130,7 +2116,7 @@ namespace libtorrent if (e || host == tcp::resolver::iterator()) { - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( url_seed_alert(get_handle(), url, e.message())); @@ -2155,7 +2141,7 @@ namespace libtorrent if (error) { - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert( url_seed_alert(get_handle(), url, error)); @@ -2166,11 +2152,8 @@ namespace libtorrent if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) { - if (m_ses.m_alerts.should_post(alert::info)) - { - m_ses.m_alerts.post_alert(peer_blocked_alert(a.address() - , "proxy (" + hostname + ") blocked by IP filter")); - } + if (m_ses.m_alerts.should_post()) + m_ses.m_alerts.post_alert(peer_blocked_alert(a.address())); return; } @@ -2195,7 +2178,7 @@ namespace libtorrent if (e || host == tcp::resolver::iterator()) { - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { std::stringstream msg; msg << "HTTP seed hostname lookup failed: " << e.message(); @@ -2218,11 +2201,8 @@ namespace libtorrent if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) { - if (m_ses.m_alerts.should_post(alert::info)) - { - m_ses.m_alerts.post_alert(peer_blocked_alert(a.address() - , "web seed (" + url + ") blocked by IP filter")); - } + if (m_ses.m_alerts.should_post()) + m_ses.m_alerts.post_alert(peer_blocked_alert(a.address())); return; } @@ -2770,10 +2750,10 @@ namespace libtorrent return false; } - if (m_ses.m_alerts.should_post(alert::info)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(metadata_received_alert( - get_handle(), "metadata successfully received from swarm")); + get_handle())); } init(); @@ -3054,11 +3034,10 @@ namespace libtorrent { INVARIANT_CHECK; - if (alerts().should_post(alert::info)) + if (alerts().should_post()) { alerts().post_alert(torrent_finished_alert( - get_handle() - , "torrent has finished downloading")); + get_handle())); } set_state(torrent_status::finished); @@ -3243,11 +3222,10 @@ namespace libtorrent } } - if (m_ses.m_alerts.should_post(alert::info)) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(torrent_checked_alert( - get_handle() - , "torrent finished checking")); + get_handle())); } m_files_checked = true; @@ -3296,7 +3274,7 @@ namespace libtorrent { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - if (alerts().should_post(alert::warning)) + if (alerts().should_post()) { alerts().post_alert(storage_moved_alert(get_handle(), j.str)); } @@ -3352,9 +3330,9 @@ namespace libtorrent for (std::deque::const_iterator i = p.request_queue().begin() , end(p.request_queue().end()); i != end; ++i) ++num_requests[*i]; - for (std::deque::const_iterator i = p.download_queue().begin() + for (std::deque::const_iterator i = p.download_queue().begin() , end(p.download_queue().end()); i != end; ++i) - ++num_requests[*i]; + ++num_requests[i->block]; if (!p.is_choked()) ++num_uploads; torrent* associated_torrent = p.associated_torrent().lock().get(); if (associated_torrent != this) @@ -3682,10 +3660,10 @@ namespace libtorrent if (m_state == torrent_status::queued_for_checking || m_state == torrent_status::checking_files) { - if (alerts().should_post(alert::warning)) + if (alerts().should_post()) { - alerts().post_alert(save_resume_data_alert(boost::shared_ptr() - , get_handle(), "won't save resume data, torrent does not have a complete resume state yet")); + alerts().post_alert(save_resume_data_failed_alert(get_handle() + , "won't save resume data, torrent does not have a complete resume state yet")); } } else @@ -3696,10 +3674,10 @@ namespace libtorrent } else { - if (alerts().should_post(alert::warning)) + if (alerts().should_post()) { - alerts().post_alert(save_resume_data_alert(boost::shared_ptr() - , get_handle(), "save resume data failed, torrent is being destructed")); + alerts().post_alert(save_resume_data_failed_alert(get_handle() + , "save resume data failed, torrent is being destructed")); } } } @@ -3759,10 +3737,8 @@ namespace libtorrent } else { - if (alerts().should_post(alert::warning)) - { - alerts().post_alert(torrent_paused_alert(get_handle(), "torrent paused")); - } + if (alerts().should_post()) + alerts().post_alert(torrent_paused_alert(get_handle())); } } @@ -3796,10 +3772,8 @@ namespace libtorrent m_started = time_now(); m_error.clear(); - if (alerts().should_post(alert::warning)) - { - alerts().post_alert(torrent_resumed_alert(get_handle(), "torrent resumed")); - } + if (alerts().should_post()) + alerts().post_alert(torrent_resumed_alert(get_handle())); // tell the tracker that we're back m_event = tracker_request::started; @@ -3982,10 +3956,8 @@ namespace libtorrent if (ret == -1) { - if (alerts().should_post(alert::fatal)) - { + if (alerts().should_post()) alerts().post_alert(file_error_alert(j.error_file, get_handle(), j.str)); - } m_error = j.str; pause(); } @@ -4043,11 +4015,8 @@ namespace libtorrent { if (m_state == s) return; m_state = s; - if (m_ses.m_alerts.should_post(alert::info)) - { - m_ses.m_alerts.post_alert(state_changed_alert(get_handle() - , s, "torrent status changed")); - } + if (m_ses.m_alerts.should_post()) + m_ses.m_alerts.post_alert(state_changed_alert(get_handle(), s)); } torrent_status torrent::status() const @@ -4215,16 +4184,20 @@ namespace libtorrent debug_log("*** tracker timed out"); #endif - if (m_ses.m_alerts.should_post(alert::warning)) + if (r.kind == tracker_request::announce_request) { - if (r.kind == tracker_request::announce_request) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(tracker_error_alert(get_handle() , m_failed_trackers + 1, 0, r.url, "tracker timed out")); } - else if (r.kind == tracker_request::scrape_request) + } + 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, "tracker timed out")); + m_ses.m_alerts.post_alert(scrape_failed_alert(get_handle() + , r.url, "tracker timed out")); } } @@ -4245,14 +4218,17 @@ namespace libtorrent #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING debug_log(std::string("*** tracker error: ") + str); #endif - if (m_ses.m_alerts.should_post(alert::warning)) + if (r.kind == tracker_request::announce_request) { - if (r.kind == tracker_request::announce_request) + if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(tracker_error_alert(get_handle() , m_failed_trackers + 1, response_code, r.url, str)); } - else if (r.kind == tracker_request::scrape_request) + } + 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)); } diff --git a/libtorrent/src/ut_metadata.cpp b/libtorrent/src/ut_metadata.cpp index 17246e5b6..848c3795d 100644 --- a/libtorrent/src/ut_metadata.cpp +++ b/libtorrent/src/ut_metadata.cpp @@ -139,10 +139,10 @@ namespace libtorrent { namespace { std::fill(m_requested_metadata.begin(), m_requested_metadata.end(), 0); - if (m_torrent.alerts().should_post(alert::info)) + if (m_torrent.alerts().should_post()) { m_torrent.alerts().post_alert(metadata_failed_alert( - m_torrent.get_handle(), "invalid metadata received from swarm")); + m_torrent.get_handle())); } return false; diff --git a/libtorrent/src/web_peer_connection.cpp b/libtorrent/src/web_peer_connection.cpp index 50402cd34..d31094f86 100755 --- a/libtorrent/src/web_peer_connection.cpp +++ b/libtorrent/src/web_peer_connection.cpp @@ -386,7 +386,7 @@ namespace libtorrent t->remove_url_seed(m_url); std::string error_msg = boost::lexical_cast(m_parser.status_code()) + " " + m_parser.message(); - if (m_ses.m_alerts.should_post(alert::warning)) + if (m_ses.m_alerts.should_post()) { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); m_ses.m_alerts.post_alert(url_seed_alert(t->get_handle(), url()