From e576babbb87abbd2c39499af334c930285905fba Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 6 Jul 2008 12:22:56 +0000 Subject: [PATCH] changed the alerts to have categories and to be filtered with a bitmask instead of having a severity and be filtered by a severity level. --- bindings/python/src/alert.cpp | 25 +- bindings/python/src/session.cpp | 1 + docs/building.html | 111 +-- docs/libtorrent_plugins.html | 81 +- docs/manual.html | 893 +++++++++++------------ docs/manual.rst | 487 ++++++------ examples/client_test.cpp | 101 +-- include/libtorrent/alert.hpp | 35 +- include/libtorrent/alert_types.hpp | 673 ++++++++++++++--- include/libtorrent/aux_/session_impl.hpp | 2 +- include/libtorrent/session.hpp | 3 +- src/alert.cpp | 55 +- src/metadata_transfer.cpp | 4 +- src/peer_connection.cpp | 69 +- src/policy.cpp | 26 +- src/session.cpp | 20 +- src/session_impl.cpp | 86 +-- src/torrent.cpp | 222 +++--- src/ut_metadata.cpp | 4 +- src/web_peer_connection.cpp | 2 +- 20 files changed, 1578 insertions(+), 1322 deletions(-) diff --git a/bindings/python/src/alert.cpp b/bindings/python/src/alert.cpp index 01b73ac61..7249f58dc 100644 --- a/bindings/python/src/alert.cpp +++ b/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/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index 294d9d534..4c9e65e42 100644 --- a/bindings/python/src/session.cpp +++ b/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/docs/building.html b/docs/building.html index 02a59978e..8f926773b 100644 --- a/docs/building.html +++ b/docs/building.html @@ -3,7 +3,7 @@ - + libtorrent manual @@ -16,40 +16,40 @@ Author: -Arvid Norberg, arvid@rasterbar.com +Arvid Norberg, arvid@rasterbar.com -
-

downloading and building

+
+

downloading and building

To acquire the latest version of libtorrent, you'll have to grab it from SVN. -You'll find instructions on how to do this here (see subversion access).

+You'll find instructions on how to do this here (see subversion access).

The build systems supported "out of the box" in libtorrent are boost-build v2 (BBv2) and autotools (for unix-like systems). If you still can't build after following these instructions, you can usually get help in the #libtorrent IRC channel on irc.freenode.net.

-

Community contributed build tutorials can be found on the wiki.

-
-

building from svn

+

Community contributed build tutorials can be found on the wiki.

+
+

building from svn

To build libtorrent from svn you need to check out the libtorrent sources from sourceforge and also check out the asio sources from its sourceforge cvs. If you downloaded a release tarball, you can skip this section.

To prepare the directory structure for building, follow these steps:

    -
  • Check out libtorrent (instructions).
  • -
  • Check out asio (instructions).
  • +
  • Check out libtorrent (instructions).
  • +
  • Check out asio (instructions).
  • Copy the asio/include/asio/ directory into the libtorrent/include/libtorrent/ directory. Alternatively you can make a symbolic link.
  • Copy asio/include/asio.hpp into libtorrent/include/libtorrent.
  • @@ -57,11 +57,11 @@ directory. Alternatively you can make a symbolic link.

    Now the libtorrent directory is ready for building. Follow the steps in one of the following sections depending on which build system you prefer to use.

-
-

building with BBv2

+
+

building with BBv2

The primary reason to use boost-build is that it will automatically build the dependent boost libraries with the correct compiler settings, in order to -ensure that the build targets are link compatible (see boost guidelines +ensure that the build targets are link compatible (see boost guidelines for some details on this issue).

Since BBv2 will build the boost libraries for you, you need the full boost source package. Having boost installed via some package system is usually not @@ -69,17 +69,17 @@ enough (and even if it is enough, the necessary environment variables are usually not set by the package installer).

If you want to build against an installed copy of boost, you can skip directly to step 3 (assuming you also have boost build installed).

-
-

Step 1: Download boost

-

You'll find boost here.

+
+

Step 1: Download boost

+

You'll find boost here.

Extract the archive to some directory where you want it. For the sake of this guide, let's assume you extract the package to c:\boost_1_34_0 (I'm using a windows path in this example since if you're on linux/unix you're more likely to use the autotools). You'll need at least version 1.34 of the boost library in order to build libtorrent.

-
-

Step 2: Setup BBv2

+
+

Step 2: Setup BBv2

First you need to build bjam. You do this by opening a terminal (In windows, run cmd). Change directory to c:\boost_1_34_0\tools\jam\src. Then run the script called @@ -129,10 +129,10 @@ using darwin : 3.3 : g++-3.3 ; using darwin : 4.0 : g++-4.0 ;

Note that the spaces around the semi-colons and colons are important!

-

Also see the official installation instructions.

+

Also see the official installation instructions.

-
-

Step 3: Building libtorrent

+
+

Step 3: Building libtorrent

When building libtorrent, the Jamfile expects the environment variable BOOST_ROOT to be set to the boost installation directory. It uses this to find the boost libraries it depends on, so they can be built and their headers @@ -194,7 +194,7 @@ Also, make sure the paths are correct in the different environments. In cygwin, /cygdrive/c/boost_1_34_0). In the windows environment, they should have the typical windows format (c:/boost_1_34_0).

The Jamfile will define NDEBUG when it's building a release build. -For more build configuration flags see Build configurations.

+For more build configuration flags see Build configurations.

Build features:

@@ -219,6 +219,15 @@ boost directory. + + + - - - - - - - - - - - + +
boost-link
    +
  • static - links statically against the boost +libraries.
  • +
  • shared - links dynamically against the boost +libraries.
  • +
+
logging
  • none - no logging.
  • @@ -260,10 +269,10 @@ with the libtorrent package.
geoip
  • off - geo ip lookups disabled
  • -
  • static - MaxMind geo ip lookup code linked +
  • static - MaxMind geo ip lookup code linked in statically. Note that this code is under LGPL license.
  • -
  • shared - The MaxMind geo ip lookup library +
  • shared - The MaxMind geo ip lookup library is expected to be installed on the system and it will be used.
@@ -372,12 +381,12 @@ the name of the feature, just the value.

When building the example client on windows, you need to build with link=static otherwise you may get unresolved external symbols for some boost.program-options symbols.

-

For more information, see the Boost build v2 documentation, or more -specifically the section on builtin features.

+

For more information, see the Boost build v2 documentation, or more +specifically the section on builtin features.

-
-

building with autotools

+
+

building with autotools

First of all, you need to install automake and autoconf. Many unix/linux systems comes with these preinstalled.

The prerequisites for building libtorrent are boost.thread, boost.date_time @@ -388,11 +397,11 @@ boost.integer, boost.iterator, boost.tuple, boost.array, boost.function, boost.smart_ptr, boost.preprocessor, boost.static_assert.

If you want to build the client_test example, you'll also need boost.regex and boost.program_options.

-
-

Step 1: Generating the build system

+
+

Step 1: Generating the build system

No build system is present if libtorrent is checked out from CVS - it needs to be generated first. If you're building from a released tarball, -you may skip directly to Step 2: Running configure.

+you may skip directly to Step 2: Running configure.

Execute the following commands, in the given order, to generate the build system:

@@ -404,8 +413,8 @@ autoconf
 

On darwin/OSX you have to run glibtoolize instead of libtoolize.

-
-

Step 2: Running configure

+
+

Step 2: Running configure

In your shell, change directory to the libtorrent directory and run ./configure. This will look for libraries and C++ features that libtorrent is dependent on. If something is missing or can't be found it will print an @@ -453,8 +462,8 @@ checking for main in -lboost_thread... yes directory contains spaces. Make sure you either rename the directories with spaces in their names to remove the spaces or move the libtorrent directory.

-
-

Creating a debug build

+
+

Creating a debug build

To tell configure to build a debug version (with debug info, asserts and invariant checks enabled), you have to run the configure script with the following option:

@@ -462,8 +471,8 @@ with the following option:

./configure --enable-debug=yes
-
-

Creating a release build

+
+

Creating a release build

To tell the configure to build a release version (without debug info, asserts and invariant checks), you have to run the configure script with the following option:

@@ -472,8 +481,8 @@ with the following option:

The above option make use of -DNDEBUG, which is used throughout libtorrent.

-
-

Step 3: Building libtorrent

+
+

Step 3: Building libtorrent

Once the configure script is run successfully, you just type make and libtorrent, the examples and the tests will be built.

When libtorrent is built it may be a good idea to run the tests, you do this @@ -487,8 +496,8 @@ make

-
-

building with other build systems

+
+

building with other build systems

If you're making your own project file, note that there are two versions of the file abstraction. There's one file_win.cpp which relies on windows file API that supports files larger than 2 Gigabytes. This does not work in @@ -501,10 +510,10 @@ filenames, so if your target is Windows 2000 and up, you may want to use

If you're building in MS Visual Studio, you may have to set the compiler options "force conformance in for loop scope", "treat wchar_t as built-in type" and "Enable Run-Time Type Info" to Yes. For a detailed description -on how to build libtorrent with VS, see the wiki.

+on how to build libtorrent with VS, see the wiki.

-
-

build configurations

+
+

build configurations

By default libtorrent is built In debug mode, and will have pretty expensive invariant checks and asserts built into it. If you want to disable such checks (you want to do that in a release build) you can see the table below for which diff --git a/docs/libtorrent_plugins.html b/docs/libtorrent_plugins.html index 834dc834c..b364860e9 100644 --- a/docs/libtorrent_plugins.html +++ b/docs/libtorrent_plugins.html @@ -3,42 +3,41 @@ - +

- - +
Author:Arvid Norberg, arvid@rasterbar.com
Arvid Norberg, arvid@rasterbar.com
-
-

libtorrent plugins

-
-

Contents

+
+

libtorrent plugins

+

libtorrent has a plugin interface for implementing extensions to the protocol. @@ -48,13 +47,13 @@ to fit a particular (closed) network.

In short, the plugin interface makes it possible to:

  • register extension messages (sent in the extension handshake), see -extensions.
  • +extensions.
  • add data and parse data from the extension handshake.
  • send extension messages and standard bittorrent messages.
  • override or block the handling of standard bittorrent messages.
-
-

a word of caution

+
+

a word of caution

Writing your own plugin is a very easy way to introduce serious bugs such as dead locks and race conditions. Since a plugin has access to internal structures it is also quite easy to sabotage libtorrent's operation.

@@ -65,12 +64,12 @@ thread, you cannot use any of the member functions on the internal structures in libtorrent, since those require the mutex to be locked. Futhermore, you would also need to have a mutex on your own shared data within the plugin, to make sure it is not accessed at the same time from the libtorrent thread (through a -callback). See boost thread's mutex. If you need to send out a message from +callback). See boost thread's mutex. If you need to send out a message from another thread, use an internal queue, and do the actual sending in tick().

-
-

plugin interface

+
+

plugin interface

The plugin interface consists of two base classes that the plugin may implement. These are called torrent_plugin and peer_plugin. They are both found in the <libtorrent/extensions.hpp> header.

@@ -93,8 +92,8 @@ for this torrent. If it is a valid pointer (to a class inheriting torrent_plugin), it will be associated with this torrent and callbacks will be made on torrent events.

-
-

torrent_plugin

+
+

torrent_plugin

The synopsis for torrent_plugin follows:

 struct torrent_plugin
@@ -116,8 +115,8 @@ struct torrent_plugin
 

This is the base class for a torrent_plugin. Your derived class is (if added as an extension) instantiated for each torrent in the session. The callback hook functions are defined as follows.

-
-

new_connection()

+
+

new_connection()

 boost::shared_ptr<peer_plugin> new_connection(peer_connection*);
 
@@ -134,8 +133,8 @@ held by the torrent object. So, it is generally a good idea to not keep a use weak_ptr.

If this function throws an exception, the connection will be closed.

-
-

on_piece_pass() on_piece_fail()

+
+

on_piece_pass() on_piece_fail()

 void on_piece_pass(int index);
 void on_piece_failed(int index);
@@ -145,16 +144,16 @@ check, respectively. The indextorrent and the piece_picker.

-
-

tick()

+
+

tick()

 void tick();
 

This hook is called approximately once per second. It is a way of making it easy for plugins to do timed events, for sending messages or whatever.

-
-

on_pause() on_resume()

+
+

on_pause() on_resume()

 bool on_pause();
 bool on_resume();
@@ -170,8 +169,8 @@ handler it will recurse back into your handler, so in order to invoke the
 standard handler, you have to keep your own state on whether you want standard
 behavior or overridden behavior.

-
-

on_files_checked()

+
+

on_files_checked()

 void on_files_checked();
 
@@ -181,8 +180,8 @@ checked. If there are no files to check, this function is called immediately.

-
-

peer_plugin

+
+

peer_plugin

 struct peer_plugin
 {
@@ -190,7 +189,7 @@ struct peer_plugin
 
         virtual void add_handshake(entry&);
         virtual bool on_handshake(char const* reserved_bits);
-        virtual bool on_extension_handshake(entry const& h);
+        virtual bool on_extension_handshake(lazy_entry const& h);
 
         virtual bool on_choke();
         virtual bool on_unchoke();
@@ -219,8 +218,8 @@ struct peer_plugin
 };
 
-
-

disk_buffer_holder

+
+

disk_buffer_holder

 struct disk_buffer_holder
 {
diff --git a/docs/manual.html b/docs/manual.html
index c7e43cb25..9631d6fc9 100644
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -24,201 +24,203 @@
 

Table of contents

@@ -291,6 +293,10 @@ class session: public boost::noncopyable torrent_handle add_torrent(add_torrent_params const& params); + void pause(); + void resume(); + bool is_paused() const; + session_proxy abort(); enum options_t @@ -346,7 +352,7 @@ class session: public boost::noncopyable std::auto_ptr<alert> pop_alert(); alert const* wait_for_alert(time_duration max_wait); - void set_severity_level(alert::severity_t s); + void set_alert_mask(int m); void add_extension(boost::function< boost::shared_ptr<torrent_plugin>(torrent*)> ext); @@ -402,10 +408,27 @@ destructing the session object. Because it can take a few second for it to finis timeout can be set with set_settings().

+

pause() resume() is_paused()

+
+
+
::
+
void pause(); +void resume(); +bool is_paused() const;
+
+
+

Pausing the session has the same effect as pausing every torrent in it. Resuming +will restore the torrents to their previous paused state. i.e. the session pause +state is separate from the torrent pause state. A torrent is inactive if it is +paused or if the session is paused.

+
+

abort()

+
 session_proxy abort();
 
+

In case you want to destruct the session asynchrounously, you can request a session destruction proxy. If you don't do this, the destructor of the session object will block while the trackers are contacted. If you keep one session_proxy to the @@ -440,7 +463,7 @@ struct add_torrent_params sha1_hash info_hash; char const* name; fs::path save_path; - entry const* resume_data; + std::vector<char>* resume_data; storage_mode_t storage_mode; bool paused; bool auto_managed; @@ -473,7 +496,8 @@ is set to false. In that case, ad torrent.

The optional parameter, resume_data can be given if up to date fast-resume data is available. The fast-resume data can be acquired from a running torrent by calling -save_resume_data() on torrent_handle. See fast resume.

+save_resume_data() on torrent_handle. See fast resume. The vector that is +passed in will be swapped into the running torrent instance with std::vector::swap().

The storage_mode parameter refers to the layout of the storage for this torrent. There are 3 different modes:

@@ -814,17 +838,17 @@ can only connect to a few peers at a time because of a built in limitation (in X Service pack 2).

-

pop_alert() set_severity_level() wait_for_alert()

+

pop_alert() set_alert_mask() wait_for_alert()

 std::auto_ptr<alert> pop_alert();
 alert const* wait_for_alert(time_duration max_wait);
-void set_severity_level(alert::severity_t s);
+void set_alert_mask(int m);
 

pop_alert() is used to ask the session if any errors or events has occurred. With -set_severity_level() you can filter how serious the event has to be for you to -receive it through pop_alert(). For information, see alerts.

+set_alert_mask() you can filter which alerts to receive through pop_alert(). +For information about the alert categories, see alerts.

wait_for_alert blocks until an alert is available, or for no more than max_wait time. If wait_for_alert returns because of the time-out, and no alerts are available, it returns 0. If at least one alert was generated, a pointer to that alert is returned. @@ -1220,7 +1244,7 @@ public: torrent_info(sha1_hash const& info_hash); torrent_info(lazy_entry const& torrent_file); torrent_info(char const* buffer, int size); - torrent_info(char const* filename); + torrent_info(boost::filesystem::path const& filename); void add_tracker(std::string const& url, int tier = 0); std::vector<announce_entry> const& trackers() const; @@ -1276,7 +1300,7 @@ public: torrent_info(sha1_hash const& info_hash); torrent_info(lazy_entry const& torrent_file); torrent_info(char const* buffer, int size); -torrent_info(char const* filename); +torrent_info(boost::filesystem::path const& filename);

The constructor that takes an info-hash will initialize the info-hash to the given value, @@ -1846,7 +1870,7 @@ void set_peer_download_limit(asio::ip::tcp::endpoint ip, int limit) const; peer instead of the whole torrent.

-

pause() resume() is_paused()

+

pause() resume() is_paused()

 void pause() const;
@@ -2010,7 +2034,7 @@ sha1_hash info_hash() const;
 

info_hash() returns the info-hash for the torrent.

-

set_max_uploads() set_max_connections()

+

set_max_uploads() set_max_connections()

 void set_max_uploads(int max_uploads) const;
@@ -2100,7 +2124,7 @@ while (num_resume_data > 0)
 
-

status()

+

status()

 torrent_status status() const;
@@ -2474,6 +2498,7 @@ struct peer_info
                 on_parole = 0x200,
                 seed = 0x400,
                 optimistic_unchoke = 0x800,
+                snubbed = 0x1000,
                 rc4_encrypted = 0x100000,
                 plaintext_encrypted = 0x200000
         };
@@ -2509,6 +2534,7 @@ struct peer_info
 
         time_duration last_request;
         time_duration last_active;
+        int request_timeout;
 
         int send_buffer_size;
         int used_send_buffer;
@@ -2620,21 +2646,11 @@ us in return an earn an upload/unchoke slot. If it
 doesn't within some period of time, it will be choked
 and another peer will be optimistically unchoked.
writingThe peer is currently waiting for a write operation -on the socket to complete.
readingThe peer is currently waiting for a read operation -on the socket to complete.
waiting_write_quotaThe peer is currently waiting for the bandwidth- -manager to hand out more write quota to this peer.
waiting_read_quotaThe peer is currently waiting for the bandwidth- -manager to hand out more read quota to this peer.
snubbedThis peer has recently failed to send a block within +the request timeout from when the request was sent. +We're currently picking one block at a time from this +peer.
@@ -2718,6 +2734,9 @@ limit and the torrent limit is always enforced anyway.

receive. -1 means it's unlimited.

last_request and last_active is the time since we last sent a request to this peer and since any transfer occurred with this peer, respectively.

+

request_timeout is the number of seconds until the current front piece request +will time out. This timeout can be adjusted through session_settings::request_timeout. +-1 means that there is not outstanding request.

send_buffer_size and used_send_buffer is the number of bytes allocated and used for the peer's send buffer, respectively.

receive_buffer_size and used_receive_buffer are the number of bytes @@ -2828,6 +2847,8 @@ struct session_settings int active_downloads; int active_seeds; + int active_limit; + bool dont_count_slow_torrents; int auto_manage_interval; float share_ratio_limit; float seed_time_ratio_limit; @@ -2986,7 +3007,7 @@ of time, on upload slot is closed. The number of upload slots will never be less than what has been set by session::set_max_uploads(). To query the current number of upload slots, see session_status::allowed_upload_slots.

cache_size is the disk write cache. It is specified in units of 16 KiB blocks. -It defaults to 128 (= 2 MB).

+It defaults to 512 (= 8 MB).

cache_expiry is the number of seconds from the last cached write to a piece in the write cache, to when it's forcefully flushed to disk. Default is 60 second.

outgoing_ports, if set to something other than (0, 0) is a range of ports @@ -3002,7 +3023,7 @@ the QBone scavenger service. For more details, see max(active_downloads, active_seeds). active_downloads and active_seeds are upper limits on the number of downloading torrents and -seeding torrents respectively.

+seeding torrents respectively. Setting the value to -1 will mean unlimited.

For example if there are 10 seeding torrents and 10 downloading torrents, and active_downloads is 4 and active_seeds is 4, there will be no seed active, but 4 downloading torrents. If the settings are active_downloads = 2 @@ -3010,6 +3031,12 @@ and active_seeds = 4, torrents active. Torrents that are not auto managed are also counted against these limits. If there are non-auto managed torrents that use up all the slots, no auto managed torrent will be activated.

+

if dont_count_slow_torrents is true, torrents without any payload transfers are +not subject to the active_seeds and active_downloads limits. This is intended +to make it more likely to utilize all available bandwidth, and avoid having torrents +that don't transfer anything block the active slots.

+

active_limit is a hard limit on the number of active seeds. This applies even to +slow torrents.

auto_manage_interval is the number of seconds between the torrent queue is updated, and rotated.

share_ratio_limit is the upload / download ratio limit for considering a @@ -3186,7 +3213,7 @@ public:

-

ip_filter()

+

ip_filter()

 ip_filter()
@@ -3543,59 +3570,70 @@ it will throw invalid_encoding
 

alerts

The pop_alert() function on session is the interface for retrieving -alerts, warnings, messages and errors from libtorrent. If there hasn't -occurred any errors (matching your severity level) pop_alert() will -return a zero pointer. If there has been some error, it will return a pointer -to an alert object describing it. You can then use the alert object and query -it for information about the error or message. To retrieve any alerts, you have -to select a severity level using session::set_severity_level(). It defaults to -alert::none, which means that you don't get any messages at all, ever. -You have the following levels to select among:

+alerts, warnings, messages and errors from libtorrent. If no alerts have +been posted by libtorrent pop_alert() will return a default initialized +auto_ptr object. If there is an alert in libtorrent's queue, the alert +from the front of the queue is popped and returned. +You can then use the alert object and query

+

By default, only errors are reported. session::set_alert_mask() can be +used to specify which kinds of events should be reported. The alert mask +is a bitmask with the following bits:

--++ - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + +
noneNo alert will ever have this severity level, which -effectively filters all messages.
error_notification

Enables alerts that report an error. This includes:

+
    +
  • tracker errors
  • +
  • tracker warnings
  • +
  • file errors
  • +
  • resume data failures
  • +
  • web seed errors
  • +
  • .torrent files errors
  • +
  • listen socket errors
  • +
  • port mapping errors
  • +
+
fatalFatal errors will have this severity level. Examples can -be disk full or something else that will make it -impossible to continue normal execution.
peer_notificationEnables alerts when peers send invalid requests, get banned or +snubbed.
criticalSignals errors that requires user interaction or -messages that almost never should be ignored. For -example, a chat message received from another peer is -announced as severity critical.
port_mapping_notificationEnables alerts for port mapping events. For NAT-PMP and UPnP.
warningMessages with the warning severity can be a tracker that -times out or responds with invalid data. It will be -retried automatically, and the possible next tracker in -a multitracker sequence will be tried. It does not -require any user interaction.
storage_notificationEnables alerts for events related to the storage. File errors and +synchronization events for moving the storage, renaming files etc.
infoEvents that can be considered normal, but still deserves -an event. This could be a piece hash that fails.
tracker_notificationEnables all tracker events. Includes announcing to trackers, +receiving responses, warnings and errors.
debugThis will include a lot of debug events that can be used -both for debugging libtorrent but also when debugging -other clients that are connected to libtorrent. It will -report strange behaviors among the connected peers.
debug_notificationLow level alerts for when peers are connected and disconnected.
status_notificationEnables alerts for when a torrent or the session changes state.
progress_notificationAlerts for when blocks are requested and completed. Also when +pieces are completed.
ip_block_notificationAlerts when a peer is blocked by the ip blocker or port blocker.
all_categoriesThe full bitmask, representing all available categories.
-

When setting a severity level, you will receive messages of that severity and all -messages that are more sever. If you set alert::none (the default) you will not receive -any events at all.

-

When you set a severity level other than none, you have the responsibility to call -pop_alert() from time to time. If you don't do that, the alert queue will just grow.

+

Every alert belongs to one or more category. There is a small cost involved in posting alerts. Only +alerts that belong to an enabled category are posted. Setting the alert bitmask to 0 will disable +all alerts

When you get an alert, you can use typeid() or dynamic_cast<> to get more detailed information on exactly which type it is. i.e. what kind of error it is. You can also use a dispatcher mechanism that's available in libtorrent.

@@ -3607,59 +3645,77 @@ class alert { public: - enum severity_t { debug, info, warning, critical, fatal, none }; + enum category_t + { + error_notification = implementation defined, + peer_notification = implementation defined, + port_mapping_notification = implementation defined, + storage_notification = implementation defined, + tracker_notification = implementation defined, + debug_notification = implementation defined, + status_notification = implementation defined, + progress_notification = implementation defined, + ip_block_notification = implementation defined, + + all_categories = implementation defined + }; + + ptime timestamp() const; - alert(severity_t severity, std::string const& msg); virtual ~alert(); - std::string const& msg() const; - severity_t severity() const; - + virtual std::string message() const = 0; + virtual char const* what() const = 0; + virtual int category() const = 0; virtual std::auto_ptr<alert> clone() const = 0; };
-

This means that all alerts have at least a string describing it. They also -have a severity level that can be used to sort them or present them to the -user in different ways.

-

There's another alert base class that all most alerts derives from, all the +

what() returns a string literal describing the type of the alert. It does +not include any information that might be bundled with the alert.

+

category() returns a bitmask specifying which categories this alert belong to.

+

clone() returns a pointer to a copy of the alert.

+

message() generate a string describing the alert and the information bundled +with it. This is mainly intended for debug and development use. It is not suitable +to use this for applications that may be localized. Instead, handle each alert +type individually and extract and render the information from the alert depending +on the locale.

+

There's another alert base class that most alerts derives from, all the alerts that are generated for a specific torrent are derived from:

 struct torrent_alert: alert
 {
-        torrent_alert(torrent_handle const& h, severity_t s, std::string const& msg);
-
+        // ...
         torrent_handle handle;
 };
 
-

The specific alerts, that all derives from alert, are:

+

There's also a base class for all alerts referring to tracker events:

+
+struct tracker_alert: torrent_alert
+{
+        // ...
+        std::string url;
+};
+
+

The specific alerts are:

external_ip_alert

Whenever libtorrent learns about the machines external IP, this alert is generated. The external IP address can be acquired from the tracker (if it supports that) or from peers that supports the extension protocol. -The address can be accessed through the external_address member. -This alert is generated as severity level info.

+The address can be accessed through the external_address member.

 struct external_ip_alert: alert
 {
-        external_ip_alert(address const& ip, const std::string& msg);
+        // ...
         address external_address;
-        virtual std::auto_ptr<alert> clone() const;
 };
 

listen_failed_alert

This alert is generated when none of the ports, given in the port range, to -session can be opened for listening. This alert is generated as severity -level fatal.

-
-struct listen_failed_alert: alert
-{
-        listen_failed_alert(const std::string& msg);
-        virtual std::auto_ptr<alert> clone() const;
-};
-
+session can be opened for listening. This alert doesn't have any extra +data members.

portmap_error_alert

@@ -3669,18 +3725,15 @@ may help the user figure out what is wrong. This alert is not generated in case it appears the client is not running on a NAT:ed network or if it appears there is no NAT router that can be remote controlled to add port mappings.

-

The alert is generated as severity warning, since it should be displayed -to the user somehow, and could mean reduced preformance.

mapping refers to the mapping index of the port map that failed, i.e. the index returned from add_mapping.

type is 0 for NAT-PMP and 1 for UPnP.

 struct portmap_error_alert: alert
 {
-        portmap_error_alert(int mapping, int type, const std::string& msg);
+        // ...
         int mapping;
         int type;
-        virtual std::auto_ptr<alert> clone() const;
 };
 
@@ -3689,8 +3742,7 @@ struct portmap_error_alert: alert

This alert is generated when a NAT router was successfully found and a port was successfully mapped on it. On a NAT:ed network with a NAT-PMP capable router, this is typically generated once when mapping the TCP -port and, if DHT is enabled, when the UDP port is mapped. This is merely -an informational alert, and is generated at severity level info.

+port and, if DHT is enabled, when the UDP port is mapped.

mapping refers to the mapping index of the port map that failed, i.e. the index returned from add_mapping.

external_port is the external port allocated for the mapping.

@@ -3698,64 +3750,39 @@ the index returned from add_mapping
 struct portmap_alert: alert
 {
-        portmap_alert(int mapping, int port, int type, const std::string& msg);
+        // ...
         int mapping;
         int external_port;
         int type;
-        virtual std::auto_ptr<alert> clone() const;
 };
 

file_error_alert

If the storage fails to read or write files that it needs access to, this alert is -generated and the torrent is paused. It is generated as severity level fatal.

+generated and the torrent is paused.

+

file is the path to the file that was accessed when the error occurred.

+

msg is the error message received from the OS.

 struct file_error_alert: torrent_alert
 {
-        file_error_alert(
-                const torrent_handle& h
-                , const std::string& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
+        // ...
+        std::string file;
+        std::string msg;
 };
 

tracker_announce_alert

This alert is generated each time a tracker announce is sent (or attempted to be sent). -It is generated at severity level info.

-
-struct tracker_announce_alert: torrent_alert
-{
-        tracker_announce_alert(
-                const torrent_handle& h
-                , const std::string& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
-};
-
-
-
-

tracker_alert

-

This is a base class for all alerts related to trackers.

-
-struct tracker_alert: torrent_alert
-{
-        tracker_alert(torrent_handle const& h
-                , std::string const& url
-                , alert::severity_t s
-                , std::string const& msg);
-
-        std::string url;
-};
-
+There are no extra data members in this alert. The url can be found in the base class +however.

tracker_error_alert

This alert is generated on tracker time outs, premature disconnects, invalid response or a HTTP response other than "200 OK". From the alert you can get the handle to the torrent -the tracker belongs to. This alert is generated as severity level warning.

+the tracker belongs to.

The times_in_row member says how many times in a row this tracker has failed. status_code is the code returned from the HTTP server. 401 means the tracker needs authentication, 404 means not found etc. If the tracker timed out, the code will be set @@ -3763,10 +3790,7 @@ to 0.

 struct tracker_error_alert: tracker_alert
 {
-        tracker_error_alert(torrent_handle const& h, int times, int status
-                , std::string const& url, std::string const& msg);
-        virtual std::auto_ptr<alert> clone() const;
-
+        // ...
         int times_in_row;
         int status_code;
 };
@@ -3776,89 +3800,80 @@ struct tracker_error_alert: tracker_alert
 

tracker_reply_alert

This alert is only for informational purpose. It is generated when a tracker announce succeeds. It is generated regardless what kind of tracker was used, be it UDP, HTTP or -the DHT. It is generated with severity level info.

+the DHT.

 struct tracker_reply_alert: tracker_alert
 {
-        tracker_reply_alert(const torrent_handle& h
-                , int num_peers
-                . std::string const& url
-                , std::string const& msg);
-
+        // ...
         int num_peers;
-
-        virtual std::auto_ptr<alert> clone() const;
 };
 

The num_peers tells how many peers were returned from the tracker. This is not necessarily all new peers, some of them may already be connected.

+

dht_reply_alert

+

This alert is generated each time the DHT receives peers from a node. num_peers +is the number of peers we received in this packet. Typically these packets are +received from multiple DHT nodes, and so the alerts are typically generated +a few at a time.

+
+struct dht_reply_alert: tracker_alert
+{
+        // ...
+        int num_peers;
+};
+
+
+

tracker_warning_alert

This alert is triggered if the tracker reply contains a warning field. Usually this means that the tracker announce was successful, but the tracker has a message to -the client. The message string in the alert will contain the warning message from -the tracker. It is generated with severity level warning.

+the client. The msg string in the alert contains the warning message from +the tracker.

 struct tracker_warning_alert: tracker_alert
 {
-        tracker_warning_alert(torrent_handle const& h
-                , std::string const& url
-                , std::string const& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
+        // ...
+        std::string msg;
 };
 

scrape_reply_alert

-
-struct scrape_reply_alert: tracker_alert
-{
-        scrape_reply_alert(torrent_handle const& h
-                , int incomplete_
-                , int complete_
-                , std::string const& url
-                , std::string const& msg);
-
-        int incomplete;
-        int complete;
-
-        virtual std::auto_ptr<alert> clone() const;
-};
-

This alert is generated when a scrape request succeeds. incomplete and complete is the data returned in the scrape response. These numbers may be -1 if the reponse was malformed.

+
+struct scrape_reply_alert: tracker_alert
+{
+        // ...
+        int incomplete;
+        int complete;
+};
+

scrape_failed_alert

+

If a scrape request fails, this alert is generated. This might be due +to the tracker timing out, refusing connection or returning an http response +code indicating an error. msg contains a message describing the error.

 struct scrape_failed_alert: tracker_alert
 {
-        scrape_failed_alert(torrent_handle const& h
-                , std::string const& url
-                , std::string const& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
+        // ...
+        std::string msg;
 };
 
-

If a scrape request fails, this alert is generated. This might be due -to the tracker timing out, refusing connection or returning an http response -code indicating an error.

url_seed_alert

-

This alert is generated when a HTTP seed name lookup fails. This alert is -generated as severity level warning.

+

This alert is generated when a HTTP seed name lookup fails.

It contains url to the HTTP seed that failed along with an error message.

 struct url_seed_alert: torrent_alert
 {
-        url_seed_alert(torrent_handle const& h, std::string const& url
-                , const std::string& msg);
-        virtual std::auto_ptr<alert> clone() const;
-
+        // ...
         std::string url;
 };
 
@@ -3866,18 +3881,11 @@ struct url_seed_alert: torrent_alert

hash_failed_alert

This alert is generated when a finished piece fails its hash check. You can get the handle -to the torrent which got the failed piece and the index of the piece itself from the alert. -This alert is generated as severity level info.

+to the torrent which got the failed piece and the index of the piece itself from the alert.

 struct hash_failed_alert: torrent_alert
 {
-        hash_failed_alert(
-                torrent_handle const& h
-                , int index
-                , const std::string& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
-
+        // ...
         int piece_index;
 };
 
@@ -3885,18 +3893,11 @@ struct hash_failed_alert: torrent_alert

peer_ban_alert

This alert is generated when a peer is banned because it has sent too many corrupt pieces -to us. It is generated at severity level info. The handle member is a torrent_handle -to the torrent that this peer was a member of.

+to us. ip is the endpoint to the peer that was banned.

 struct peer_ban_alert: torrent_alert
 {
-        peer_ban_alert(
-                asio::ip::tcp::endpoint const& pip
-                , torrent_handle h
-                , const std::string& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
-
+        // ...
         asio::ip::tcp::endpoint ip;
 };
 
@@ -3904,17 +3905,11 @@ struct peer_ban_alert: torrent_alert

peer_error_alert

This alert is generated when a peer sends invalid data over the peer-peer protocol. The peer -will be disconnected, but you get its ip address from the alert, to identify it. This alert -is generated as severity level debug.

+will be disconnected, but you get its ip address from the alert, to identify it.

-struct peer_error_alert: alert
+struct peer_error_alert: torrent_alert
 {
-        peer_error_alert(
-                asio::ip::tcp::endpoint const& pip
-                , peer_id const& pid
-                , const std::string& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
+        // ...
         asio::ip::tcp::endpoint ip;
         peer_id id;
 };
@@ -3922,10 +3917,9 @@ struct peer_error_alert: alert
 

invalid_request_alert

-

This is a debug alert that is generated by an incoming invalid piece request. The handle -is a handle to the torrent the peer is a member of. ìp is the address of the peer and the -request is the actual incoming request from the peer. The alert is generated as severity level -debug.

+

This is a debug alert that is generated by an incoming invalid piece request. +ìp is the address of the peer and the request is the actual incoming +request from the peer.

 struct invalid_request_alert: torrent_alert
 {
@@ -3960,81 +3954,46 @@ should be read, and length
 

torrent_finished_alert

This alert is generated when a torrent switches from being a downloader to a seed. It will only be generated once per torrent. It contains a torrent_handle to the -torrent in question. This alert is generated as severity level info.

-
-struct torrent_finished_alert: torrent_alert
-{
-        torrent_finished_alert(
-                const torrent_handle& h
-                , const std::string& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
-};
-
+torrent in question.

+

There are no additional data members in this alert.

metadata_failed_alert

This alert is generated when the metadata has been completely received and the info-hash failed to match it. i.e. the metadata that was received was corrupt. libtorrent will automatically retry to fetch it in this case. This is only relevant when running a -torrent-less download, with the metadata extension provided by libtorrent. -It is generated at severity level info.

-
-struct metadata_failed_alert: torrent_alert
-{
-        metadata_failed_alert(
-                torrent_handle const& h
-                , std::string const& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
-};
-
+torrent-less download, with the metadata extension provided by libtorrent.

+

There are no additional data members in this alert.

metadata_received_alert

This alert is generated when the metadata has been completely received and the torrent can start downloading. It is not generated on torrents that are started with metadata, but -only those that needs to download it from peers (when utilizing the libtorrent extension). -It is generated at severity level info.

-
-struct metadata_received_alert: torrent_alert
-{
-        metadata_received_alert(
-                torrent_handle const_& h
-                , std::string const& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
-};
-
+only those that needs to download it from peers (when utilizing the libtorrent extension).

+

There are no additional data members in this alert.

fastresume_rejected_alert

This alert is generated when a fastresume file has been passed to add_torrent but the files on disk did not match the fastresume file. The string explains the reason why the -resume file was rejected. It is generated at severity level warning.

+resume file was rejected.

 struct fastresume_rejected_alert: torrent_alert
 {
-        fastresume_rejected_alert(torrent_handle const& h
-                , std::string const& msg);
-
-        virtual std::auto_ptr<alert> clone() const;
+        // ...
+        std::string msg;
 };
 

peer_blocked_alert

-

This alert is generated when a peer is blocked by the IP filter. It has the severity leve -info. The ip member is the address that was blocked.

+

This alert is generated when a peer is blocked by the IP filter. The ip member is the +address that was blocked.

 struct peer_blocked_alert: alert
 {
-        peer_blocked_alert(address const& ip_
-                , std::string const& msg);
-
+        // ...
         address ip;
-
-        virtual std::auto_ptr<alert> clone() const;
 };
 
@@ -4042,12 +4001,13 @@ struct peer_blocked_alert: alert

storage_moved_alert

The storage_moved_alert is generated when all the disk IO has completed and the files have been moved, as an effect of a call to torrent_handle::move_storage. This -is useful to synchronize with the actual disk.

+is useful to synchronize with the actual disk. The path member is the new path of +the storage.

 struct storage_moved_alert: torrent_alert
 {
-        storage_moved_alert(torrent_handle const& h, std::string const& path);
-        virtual std::auto_ptr<alert> clone() const;
+        // ...
+        std::string path;
 };
 
@@ -4056,39 +4016,36 @@ struct storage_moved_alert: torrent_alert

This alert is generated as a response to a torrent_handle::pause request. It is generated once all disk IO is complete and the files in the torrent have been closed. This is useful for synchronizing with the disk.

-
-struct torrent_paused_alert: torrent_alert
-{
-        torrent_paused_alert(torrent_handle const& h, std::string const& msg);
-        virtual std::auto_ptr<alert> clone() const;
-};
-
-
-
-

save_resume_data_alert

-

This alert is generated as a response to a torrent_handle::save_resume_data request. -It is generated once the disk IO thread is done writing the state for this torrent. -The resume_data member points to the resume data or is 0 on errors.

-
-struct save_resume_data_alert: torrent_alert
-{
-        save_resume_alert(torrent_handle const& h, std::string const& msg);
-
-        boost::shared_ptr<entry> resume_data;
-
-        virtual std::auto_ptr<alert> clone() const;
-};
-
+

There are no additional data members in this alert.

torrent_resumed_alert

This alert is generated as a response to a torrent_handle::resume request. It is generated when a torrent goes from a paused state to an active state.

+

There are no additional data members in this alert.

+
+
+

save_resume_data_alert

+

This alert is generated as a response to a torrent_handle::save_resume_data request. +It is generated once the disk IO thread is done writing the state for this torrent. +The resume_data member points to the resume data.

-struct torrent_resumed_alert: torrent_alert
+struct save_resume_data_alert: torrent_alert
 {
-        torrent_resumed_alert(torrent_handle const& h, std::string const& msg);
-        virtual std::auto_ptr<alert> clone() const;
+        // ...
+        boost::shared_ptr<entry> resume_data;
+};
+
+
+
+

save_resume_data_failed_alert

+

This alert is generated instead of save_resume_data_alert if there was an error +generating the resume data. msg describes what went wrong.

+
+struct save_resume_data_failed_alert: torrent_alert
+{
+        // ...
+        std::string msg;
 };
 
@@ -4210,7 +4167,7 @@ struct storage_interface virtual size_type read(char* buf, int slot, int offset, int size) = 0; virtual void write(const char* buf, int slot, int offset, int size) = 0; virtual bool move_storage(fs::path save_path) = 0; - virtual bool verify_resume_data(entry& rd, std::string& error) = 0; + virtual bool verify_resume_data(lazy_entry& rd, std::string& error) = 0; virtual void write_resume_data(entry& rd) const = 0; virtual void move_slot(int src_slot, int dst_slot) = 0; virtual void swap_slots(int slot1, int slot2) = 0; @@ -4254,7 +4211,7 @@ void write(const char* buf, int slot, int offset, int size) = 0; offset in that slot. The buffer size is size.

-

move_storage()

+

move_storage()

 bool move_storage(fs::path save_path) = 0;
@@ -4376,14 +4333,12 @@ downloaded, the next in line is started.

limits. To make a torrent auto managed, set auto_managed to true when adding the torrent (see add_torrent()).

The limits of the number of downloading and seeding torrents are controlled via -active_downloads and active_seeds in session_settings. These limits takes -non auto managed torrents into account as well. If there are are more non-auto managed -torrents being downloaded than the active_downloads setting, any auto managed -torrents will be queued until torrents are removed so that the number drops below -the limit.

-

Seeding torrents counts as downloads, but downloading torrents don't count as -seeding. So, active_downloads should typically be greater than active_seeds. -The default values are 8 active downloads and 5 active seeds.

+active_downloads, active_seeds and active_limit in session_settings. +These limits takes non auto managed torrents into account as well. If there are +more non-auto managed torrents being downloaded than the active_downloads +setting, any auto managed torrents will be queued until torrents are removed so +that the number drops below the limit.

+

The default values are 8 active downloads and 5 active seeds.

At a regular interval, torrents are checked if there needs to be any re-ordering of which torrents are active and which are queued. This interval can be controlled via auto_manage_interval in session_settings. It defaults to every 30 seconds.

diff --git a/docs/manual.rst b/docs/manual.rst index 5224538e3..672a97566 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -141,7 +141,7 @@ The ``session`` class has the following synopsis:: std::auto_ptr pop_alert(); alert const* wait_for_alert(time_duration max_wait); - void set_severity_level(alert::severity_t s); + void set_alert_mask(int m); void add_extension(boost::function< boost::shared_ptr(torrent*)> ext); @@ -673,18 +673,18 @@ with a DHT ping packet, and connect to those that responds first. On windows one can only connect to a few peers at a time because of a built in limitation (in XP Service pack 2). -pop_alert() set_severity_level() wait_for_alert() -------------------------------------------------- +pop_alert() set_alert_mask() wait_for_alert() +--------------------------------------------- :: std::auto_ptr pop_alert(); alert const* wait_for_alert(time_duration max_wait); - void set_severity_level(alert::severity_t s); + void set_alert_mask(int m); ``pop_alert()`` is used to ask the session if any errors or events has occurred. With -``set_severity_level()`` you can filter how serious the event has to be for you to -receive it through ``pop_alert()``. For information, see alerts_. +``set_alert_mask()`` you can filter which alerts to receive through ``pop_alert()``. +For information about the alert categories, see alerts_. ``wait_for_alert`` blocks until an alert is available, or for no more than ``max_wait`` time. If ``wait_for_alert`` returns because of the time-out, and no alerts are available, @@ -3653,55 +3653,54 @@ alerts ====== The ``pop_alert()`` function on session is the interface for retrieving -alerts, warnings, messages and errors from libtorrent. If there hasn't -occurred any errors (matching your severity level) ``pop_alert()`` will -return a zero pointer. If there has been some error, it will return a pointer -to an alert object describing it. You can then use the alert object and query -it for information about the error or message. To retrieve any alerts, you have -to select a severity level using ``session::set_severity_level()``. It defaults to -``alert::none``, which means that you don't get any messages at all, ever. -You have the following levels to select among: +alerts, warnings, messages and errors from libtorrent. If no alerts have +been posted by libtorrent ``pop_alert()`` will return a default initialized +``auto_ptr`` object. If there is an alert in libtorrent's queue, the alert +from the front of the queue is popped and returned. +You can then use the alert object and query -+--------------+----------------------------------------------------------+ -| ``none`` | No alert will ever have this severity level, which | -| | effectively filters all messages. | -| | | -+--------------+----------------------------------------------------------+ -| ``fatal`` | Fatal errors will have this severity level. Examples can | -| | be disk full or something else that will make it | -| | impossible to continue normal execution. | -| | | -+--------------+----------------------------------------------------------+ -| ``critical`` | Signals errors that requires user interaction or | -| | messages that almost never should be ignored. For | -| | example, a chat message received from another peer is | -| | announced as severity ``critical``. | -| | | -+--------------+----------------------------------------------------------+ -| ``warning`` | Messages with the warning severity can be a tracker that | -| | times out or responds with invalid data. It will be | -| | retried automatically, and the possible next tracker in | -| | a multitracker sequence will be tried. It does not | -| | require any user interaction. | -| | | -+--------------+----------------------------------------------------------+ -| ``info`` | Events that can be considered normal, but still deserves | -| | an event. This could be a piece hash that fails. | -| | | -+--------------+----------------------------------------------------------+ -| ``debug`` | This will include a lot of debug events that can be used | -| | both for debugging libtorrent but also when debugging | -| | other clients that are connected to libtorrent. It will | -| | report strange behaviors among the connected peers. | -| | | -+--------------+----------------------------------------------------------+ +By default, only errors are reported. ``session::set_alert_mask()`` can be +used to specify which kinds of events should be reported. The alert mask +is a bitmask with the following bits: -When setting a severity level, you will receive messages of that severity and all -messages that are more sever. If you set ``alert::none`` (the default) you will not receive -any events at all. ++--------------------------------+---------------------------------------------------------------------+ +| ``error_notification`` | Enables alerts that report an error. This includes: | +| | | +| | * tracker errors | +| | * tracker warnings | +| | * file errors | +| | * resume data failures | +| | * web seed errors | +| | * .torrent files errors | +| | * listen socket errors | +| | * port mapping errors | ++--------------------------------+---------------------------------------------------------------------+ +| ``peer_notification`` | Enables alerts when peers send invalid requests, get banned or | +| | snubbed. | ++--------------------------------+---------------------------------------------------------------------+ +| ``port_mapping_notification`` | Enables alerts for port mapping events. For NAT-PMP and UPnP. | ++--------------------------------+---------------------------------------------------------------------+ +| ``storage_notification`` | Enables alerts for events related to the storage. File errors and | +| | synchronization events for moving the storage, renaming files etc. | ++--------------------------------+---------------------------------------------------------------------+ +| ``tracker_notification`` | Enables all tracker events. Includes announcing to trackers, | +| | receiving responses, warnings and errors. | ++--------------------------------+---------------------------------------------------------------------+ +| ``debug_notification`` | Low level alerts for when peers are connected and disconnected. | ++--------------------------------+---------------------------------------------------------------------+ +| ``status_notification`` | Enables alerts for when a torrent or the session changes state. | ++--------------------------------+---------------------------------------------------------------------+ +| ``progress_notification`` | Alerts for when blocks are requested and completed. Also when | +| | pieces are completed. | ++--------------------------------+---------------------------------------------------------------------+ +| ``ip_block_notification`` | Alerts when a peer is blocked by the ip blocker or port blocker. | ++--------------------------------+---------------------------------------------------------------------+ +| ``all_categories`` | The full bitmask, representing all available categories. | ++--------------------------------+---------------------------------------------------------------------+ -When you set a severity level other than ``none``, you have the responsibility to call -``pop_alert()`` from time to time. If you don't do that, the alert queue will just grow. +Every alert belongs to one or more category. There is a small cost involved in posting alerts. Only +alerts that belong to an enabled category are posted. Setting the alert bitmask to 0 will disable +all alerts When you get an alert, you can use ``typeid()`` or ``dynamic_cast<>`` to get more detailed information on exactly which type it is. i.e. what kind of error it is. You can also use a @@ -3710,38 +3709,70 @@ dispatcher_ mechanism that's available in libtorrent. All alert types are defined in the ```` header file. The ``alert`` class is the base class that specific messages are derived from. This -is its synopsis:: +is its synopsis: + +.. parsed-literal:: class alert { public: - enum severity_t { debug, info, warning, critical, fatal, none }; + enum category_t + { + error_notification = *implementation defined*, + peer_notification = *implementation defined*, + port_mapping_notification = *implementation defined*, + storage_notification = *implementation defined*, + tracker_notification = *implementation defined*, + debug_notification = *implementation defined*, + status_notification = *implementation defined*, + progress_notification = *implementation defined*, + ip_block_notification = *implementation defined*, + + all_categories = *implementation defined* + }; + + ptime timestamp() const; - alert(severity_t severity, std::string const& msg); virtual ~alert(); - std::string const& msg() const; - severity_t severity() const; - + virtual std::string message() const = 0; + virtual char const* what() const = 0; + virtual int category() const = 0; virtual std::auto_ptr clone() const = 0; }; -This means that all alerts have at least a string describing it. They also -have a severity level that can be used to sort them or present them to the -user in different ways. +``what()`` returns a string literal describing the type of the alert. It does +not include any information that might be bundled with the alert. -There's another alert base class that all most alerts derives from, all the +``category()`` returns a bitmask specifying which categories this alert belong to. + +``clone()`` returns a pointer to a copy of the alert. + +``message()`` generate a string describing the alert and the information bundled +with it. This is mainly intended for debug and development use. It is not suitable +to use this for applications that may be localized. Instead, handle each alert +type individually and extract and render the information from the alert depending +on the locale. + +There's another alert base class that most alerts derives from, all the alerts that are generated for a specific torrent are derived from:: struct torrent_alert: alert { - torrent_alert(torrent_handle const& h, severity_t s, std::string const& msg); - + // ... torrent_handle handle; }; -The specific alerts, that all derives from ``alert``, are: +There's also a base class for all alerts referring to tracker events:: + + struct tracker_alert: torrent_alert + { + // ... + std::string url; + }; + +The specific alerts are: external_ip_alert ----------------- @@ -3750,15 +3781,13 @@ Whenever libtorrent learns about the machines external IP, this alert is generated. The external IP address can be acquired from the tracker (if it supports that) or from peers that supports the extension protocol. The address can be accessed through the ``external_address`` member. -This alert is generated as severity level ``info``. :: struct external_ip_alert: alert { - external_ip_alert(address const& ip, const std::string& msg); + // ... address external_address; - virtual std::auto_ptr clone() const; }; @@ -3766,16 +3795,9 @@ listen_failed_alert ------------------- This alert is generated when none of the ports, given in the port range, to -session_ can be opened for listening. This alert is generated as severity -level ``fatal``. +session_ can be opened for listening. This alert doesn't have any extra +data members. -:: - - struct listen_failed_alert: alert - { - listen_failed_alert(const std::string& msg); - virtual std::auto_ptr clone() const; - }; portmap_error_alert ------------------- @@ -3787,9 +3809,6 @@ case it appears the client is not running on a NAT:ed network or if it appears there is no NAT router that can be remote controlled to add port mappings. -The alert is generated as severity ``warning``, since it should be displayed -to the user somehow, and could mean reduced preformance. - ``mapping`` refers to the mapping index of the port map that failed, i.e. the index returned from add_mapping_. @@ -3799,10 +3818,9 @@ the index returned from add_mapping_. struct portmap_error_alert: alert { - portmap_error_alert(int mapping, int type, const std::string& msg); + // ... int mapping; int type; - virtual std::auto_ptr clone() const; }; portmap_alert @@ -3811,8 +3829,7 @@ portmap_alert This alert is generated when a NAT router was successfully found and a port was successfully mapped on it. On a NAT:ed network with a NAT-PMP capable router, this is typically generated once when mapping the TCP -port and, if DHT is enabled, when the UDP port is mapped. This is merely -an informational alert, and is generated at severity level ``info``. +port and, if DHT is enabled, when the UDP port is mapped. ``mapping`` refers to the mapping index of the port map that failed, i.e. the index returned from add_mapping_. @@ -3825,28 +3842,29 @@ the index returned from add_mapping_. struct portmap_alert: alert { - portmap_alert(int mapping, int port, int type, const std::string& msg); + // ... int mapping; int external_port; int type; - virtual std::auto_ptr clone() const; }; file_error_alert ---------------- If the storage fails to read or write files that it needs access to, this alert is -generated and the torrent is paused. It is generated as severity level ``fatal``. +generated and the torrent is paused. + +``file`` is the path to the file that was accessed when the error occurred. + +``msg`` is the error message received from the OS. :: struct file_error_alert: torrent_alert { - file_error_alert( - const torrent_handle& h - , const std::string& msg); - - virtual std::auto_ptr clone() const; + // ... + std::string file; + std::string msg; }; @@ -3854,43 +3872,16 @@ tracker_announce_alert ---------------------- This alert is generated each time a tracker announce is sent (or attempted to be sent). -It is generated at severity level ``info``. +There are no extra data members in this alert. The url can be found in the base class +however. -:: - - struct tracker_announce_alert: torrent_alert - { - tracker_announce_alert( - const torrent_handle& h - , const std::string& msg); - - virtual std::auto_ptr clone() const; - }; - - -tracker_alert -------------- - -This is a base class for all alerts related to trackers. - -:: - - struct tracker_alert: torrent_alert - { - tracker_alert(torrent_handle const& h - , std::string const& url - , alert::severity_t s - , std::string const& msg); - - std::string url; - }; tracker_error_alert ------------------- This alert is generated on tracker time outs, premature disconnects, invalid response or a HTTP response other than "200 OK". From the alert you can get the handle to the torrent -the tracker belongs to. This alert is generated as severity level ``warning``. +the tracker belongs to. The ``times_in_row`` member says how many times in a row this tracker has failed. ``status_code`` is the code returned from the HTTP server. 401 means the tracker needs @@ -3901,10 +3892,7 @@ to 0. struct tracker_error_alert: tracker_alert { - tracker_error_alert(torrent_handle const& h, int times, int status - , std::string const& url, std::string const& msg); - virtual std::auto_ptr clone() const; - + // ... int times_in_row; int status_code; }; @@ -3915,90 +3903,88 @@ tracker_reply_alert This alert is only for informational purpose. It is generated when a tracker announce succeeds. It is generated regardless what kind of tracker was used, be it UDP, HTTP or -the DHT. It is generated with severity level ``info``. +the DHT. :: struct tracker_reply_alert: tracker_alert { - tracker_reply_alert(const torrent_handle& h - , int num_peers - . std::string const& url - , std::string const& msg); - + // ... int num_peers; - - virtual std::auto_ptr clone() const; }; The ``num_peers`` tells how many peers were returned from the tracker. This is not necessarily all new peers, some of them may already be connected. - + +dht_reply_alert +------------------- + +This alert is generated each time the DHT receives peers from a node. ``num_peers`` +is the number of peers we received in this packet. Typically these packets are +received from multiple DHT nodes, and so the alerts are typically generated +a few at a time. + +:: + + struct dht_reply_alert: tracker_alert + { + // ... + int num_peers; + }; + + tracker_warning_alert --------------------- This alert is triggered if the tracker reply contains a warning field. Usually this means that the tracker announce was successful, but the tracker has a message to -the client. The message string in the alert will contain the warning message from -the tracker. It is generated with severity level ``warning``. +the client. The ``msg`` string in the alert contains the warning message from +the tracker. :: struct tracker_warning_alert: tracker_alert { - tracker_warning_alert(torrent_handle const& h - , std::string const& url - , std::string const& msg); - - virtual std::auto_ptr clone() const; + // ... + std::string msg; }; scrape_reply_alert ------------------ -:: - - struct scrape_reply_alert: tracker_alert - { - scrape_reply_alert(torrent_handle const& h - , int incomplete_ - , int complete_ - , std::string const& url - , std::string const& msg); - - int incomplete; - int complete; - - virtual std::auto_ptr clone() const; - }; - This alert is generated when a scrape request succeeds. ``incomplete`` and ``complete`` is the data returned in the scrape response. These numbers may be -1 if the reponse was malformed. +:: + + struct scrape_reply_alert: tracker_alert + { + // ... + int incomplete; + int complete; + }; + + scrape_failed_alert ------------------- +If a scrape request fails, this alert is generated. This might be due +to the tracker timing out, refusing connection or returning an http response +code indicating an error. ``msg`` contains a message describing the error. + :: struct scrape_failed_alert: tracker_alert { - scrape_failed_alert(torrent_handle const& h - , std::string const& url - , std::string const& msg); - - virtual std::auto_ptr clone() const; + // ... + std::string msg; }; -If a scrape request fails, this alert is generated. This might be due -to the tracker timing out, refusing connection or returning an http response -code indicating an error. - url_seed_alert -------------- -This alert is generated when a HTTP seed name lookup fails. This alert is -generated as severity level ``warning``. +This alert is generated when a HTTP seed name lookup fails. It contains ``url`` to the HTTP seed that failed along with an error message. @@ -4006,10 +3992,7 @@ It contains ``url`` to the HTTP seed that failed along with an error message. struct url_seed_alert: torrent_alert { - url_seed_alert(torrent_handle const& h, std::string const& url - , const std::string& msg); - virtual std::auto_ptr clone() const; - + // ... std::string url; }; @@ -4019,19 +4002,12 @@ hash_failed_alert This alert is generated when a finished piece fails its hash check. You can get the handle to the torrent which got the failed piece and the index of the piece itself from the alert. -This alert is generated as severity level ``info``. :: struct hash_failed_alert: torrent_alert { - hash_failed_alert( - torrent_handle const& h - , int index - , const std::string& msg); - - virtual std::auto_ptr clone() const; - + // ... int piece_index; }; @@ -4040,20 +4016,13 @@ peer_ban_alert -------------- This alert is generated when a peer is banned because it has sent too many corrupt pieces -to us. It is generated at severity level ``info``. The ``handle`` member is a torrent_handle_ -to the torrent that this peer was a member of. +to us. ``ip`` is the endpoint to the peer that was banned. :: struct peer_ban_alert: torrent_alert { - peer_ban_alert( - asio::ip::tcp::endpoint const& pip - , torrent_handle h - , const std::string& msg); - - virtual std::auto_ptr clone() const; - + // ... asio::ip::tcp::endpoint ip; }; @@ -4062,19 +4031,13 @@ peer_error_alert ---------------- This alert is generated when a peer sends invalid data over the peer-peer protocol. The peer -will be disconnected, but you get its ip address from the alert, to identify it. This alert -is generated as severity level ``debug``. +will be disconnected, but you get its ip address from the alert, to identify it. :: - struct peer_error_alert: alert + struct peer_error_alert: torrent_alert { - peer_error_alert( - asio::ip::tcp::endpoint const& pip - , peer_id const& pid - , const std::string& msg); - - virtual std::auto_ptr clone() const; + // ... asio::ip::tcp::endpoint ip; peer_id id; }; @@ -4083,10 +4046,9 @@ is generated as severity level ``debug``. invalid_request_alert --------------------- -This is a debug alert that is generated by an incoming invalid piece request. The ``handle`` -is a handle to the torrent the peer is a member of. ``ìp`` is the address of the peer and the -``request`` is the actual incoming request from the peer. The alert is generated as severity level -``debug``. +This is a debug alert that is generated by an incoming invalid piece request. +``ìp`` is the address of the peer and the ``request`` is the actual incoming +request from the peer. :: @@ -4125,18 +4087,9 @@ torrent_finished_alert This alert is generated when a torrent switches from being a downloader to a seed. It will only be generated once per torrent. It contains a torrent_handle to the -torrent in question. This alert is generated as severity level ``info``. +torrent in question. -:: - - struct torrent_finished_alert: torrent_alert - { - torrent_finished_alert( - const torrent_handle& h - , const std::string& msg); - - virtual std::auto_ptr clone() const; - }; +There are no additional data members in this alert. metadata_failed_alert @@ -4146,18 +4099,8 @@ This alert is generated when the metadata has been completely received and the i failed to match it. i.e. the metadata that was received was corrupt. libtorrent will automatically retry to fetch it in this case. This is only relevant when running a torrent-less download, with the metadata extension provided by libtorrent. -It is generated at severity level ``info``. -:: - - struct metadata_failed_alert: torrent_alert - { - metadata_failed_alert( - torrent_handle const& h - , std::string const& msg); - - virtual std::auto_ptr clone() const; - }; +There are no additional data members in this alert. metadata_received_alert @@ -4166,18 +4109,8 @@ metadata_received_alert This alert is generated when the metadata has been completely received and the torrent can start downloading. It is not generated on torrents that are started with metadata, but only those that needs to download it from peers (when utilizing the libtorrent extension). -It is generated at severity level ``info``. -:: - - struct metadata_received_alert: torrent_alert - { - metadata_received_alert( - torrent_handle const_& h - , std::string const& msg); - - virtual std::auto_ptr clone() const; - }; +There are no additional data members in this alert. fastresume_rejected_alert @@ -4185,52 +4118,49 @@ fastresume_rejected_alert This alert is generated when a fastresume file has been passed to ``add_torrent`` but the files on disk did not match the fastresume file. The string explains the reason why the -resume file was rejected. It is generated at severity level ``warning``. +resume file was rejected. :: struct fastresume_rejected_alert: torrent_alert { - fastresume_rejected_alert(torrent_handle const& h - , std::string const& msg); - - virtual std::auto_ptr clone() const; + // ... + std::string msg; }; peer_blocked_alert ------------------ -This alert is generated when a peer is blocked by the IP filter. It has the severity leve -``info``. The ``ip`` member is the address that was blocked. +This alert is generated when a peer is blocked by the IP filter. The ``ip`` member is the +address that was blocked. :: struct peer_blocked_alert: alert { - peer_blocked_alert(address const& ip_ - , std::string const& msg); - + // ... address ip; - - virtual std::auto_ptr clone() const; }; + storage_moved_alert ------------------- The ``storage_moved_alert`` is generated when all the disk IO has completed and the files have been moved, as an effect of a call to ``torrent_handle::move_storage``. This -is useful to synchronize with the actual disk. +is useful to synchronize with the actual disk. The ``path`` member is the new path of +the storage. :: struct storage_moved_alert: torrent_alert { - storage_moved_alert(torrent_handle const& h, std::string const& path); - virtual std::auto_ptr clone() const; + // ... + std::string path; }; + torrent_paused_alert -------------------- @@ -4238,31 +4168,7 @@ This alert is generated as a response to a ``torrent_handle::pause`` request. It generated once all disk IO is complete and the files in the torrent have been closed. This is useful for synchronizing with the disk. -:: - - struct torrent_paused_alert: torrent_alert - { - torrent_paused_alert(torrent_handle const& h, std::string const& msg); - virtual std::auto_ptr clone() const; - }; - -save_resume_data_alert ----------------------- - -This alert is generated as a response to a ``torrent_handle::save_resume_data`` request. -It is generated once the disk IO thread is done writing the state for this torrent. -The ``resume_data`` member points to the resume data or is 0 on errors. - -:: - - struct save_resume_data_alert: torrent_alert - { - save_resume_alert(torrent_handle const& h, std::string const& msg); - - boost::shared_ptr resume_data; - - virtual std::auto_ptr clone() const; - }; +There are no additional data members in this alert. torrent_resumed_alert --------------------- @@ -4270,12 +4176,35 @@ torrent_resumed_alert This alert is generated as a response to a ``torrent_handle::resume`` request. It is generated when a torrent goes from a paused state to an active state. +There are no additional data members in this alert. + +save_resume_data_alert +---------------------- + +This alert is generated as a response to a ``torrent_handle::save_resume_data`` request. +It is generated once the disk IO thread is done writing the state for this torrent. +The ``resume_data`` member points to the resume data. + :: - struct torrent_resumed_alert: torrent_alert + struct save_resume_data_alert: torrent_alert { - torrent_resumed_alert(torrent_handle const& h, std::string const& msg); - virtual std::auto_ptr clone() const; + // ... + boost::shared_ptr resume_data; + }; + +save_resume_data_failed_alert +----------------------------- + +This alert is generated instead of ``save_resume_data_alert`` if there was an error +generating the resume data. ``msg`` describes what went wrong. + +:: + + struct save_resume_data_failed_alert: torrent_alert + { + // ... + std::string msg; }; dispatcher diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 0ed8d9ddc..9503f84ca 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -584,6 +584,33 @@ libtorrent::torrent_handle get_active_torrent(handles_t const& handles) return i->second; } +void handle_alert(libtorrent::session& ses, libtorrent::alert* a) +{ + using namespace libtorrent; + + if (torrent_finished_alert* p = dynamic_cast(a)) + { + p->handle.set_max_connections(30); + + // write resume data for the finished torrent + torrent_handle h = p->handle; + h.save_resume_data(); + } + else if (save_resume_data_alert* p = dynamic_cast(a)) + { + torrent_handle h = p->handle; + TORRENT_ASSERT(p->resume_data); + if (p->resume_data) + { + boost::filesystem::ofstream out(h.save_path() / (h.name() + ".fastresume") + , std::ios_base::binary); + out.unsetf(std::ios_base::skipws); + bencode(std::ostream_iterator(out), *p->resume_data); + if (h.is_paused() && !h.is_auto_managed()) ses.remove_torrent(h); + } + } +} + static char const* state_str[] = {"checking (q)", "checking", "connecting", "dl metadata" , "downloading", "finished", "seeding", "allocating"}; @@ -1047,7 +1074,7 @@ int main(int ac, char* av[]) save_resume_data_alert const* rd = dynamic_cast(a); if (!rd) { - std::cout << a->msg() << std::endl; + std::cout << a->message() << std::endl; continue; } --num_resume_data; @@ -1133,78 +1160,22 @@ int main(int ac, char* av[]) while (a.get()) { std::stringstream event_string; - if (a->severity() == alert::fatal) - event_string << esc("31"); // red - else if (a->severity() == alert::warning) - event_string << esc("33"); // yellow - event_string << now << ": "; - if (torrent_finished_alert* p = dynamic_cast(a.get())) + if (a->category() & alert::error_notification) { - p->handle.set_max_connections(30); - - // write resume data for the finished torrent - torrent_handle h = p->handle; - h.save_resume_data(); - - event_string << h.name() << ": " << a->msg(); + event_string << esc("31"); } - else if (peer_error_alert* p = dynamic_cast(a.get())) + else if (a->category() & (alert::peer_notification | alert::storage_notification)) { - event_string << identify_client(p->pid) << ", " << p->ip << ": " << a->msg(); - } - else if (invalid_request_alert* p = dynamic_cast(a.get())) - { - event_string << identify_client(p->pid) << ": " << a->msg(); - } - else if (tracker_warning_alert* p = dynamic_cast(a.get())) - { - event_string << "tracker message: " << p->msg() << " (" << p->url << ") (" << p->handle.name() << ")"; - } - else if (tracker_reply_alert* p = dynamic_cast(a.get())) - { - event_string << p->msg() << " (" << p->num_peers << ") (" << p->url << ") (" << p->handle.name() << ")"; - } - else if (url_seed_alert* p = dynamic_cast(a.get())) - { - event_string << "web seed '" << p->url << "': " << p->msg() << " (" << p->handle.name() << ")"; - } - else if (peer_blocked_alert* p = dynamic_cast(a.get())) - { - event_string << "(" << p->ip << ") " << p->msg(); - } - else if (save_resume_data_alert* p = dynamic_cast(a.get())) - { - torrent_handle h = p->handle; - event_string << "(" << h.name() << ") " << p->msg(); - if (p->resume_data) - { - boost::filesystem::ofstream out(h.save_path() / (h.name() + ".fastresume"), std::ios_base::binary); - out.unsetf(std::ios_base::skipws); - bencode(std::ostream_iterator(out), *p->resume_data); - if (h.is_paused() && !h.is_auto_managed()) ses.remove_torrent(h); - } - } - else if (state_changed_alert* p = dynamic_cast(a.get())) - { - std::string name; - if (p->handle.is_valid()) name = p->handle.name(); - event_string << "(" << name << ") " << p->msg() << " " << state_str[p->state]; - } - else if (torrent_alert* p = dynamic_cast(a.get())) - { - std::string name; - if (p->handle.is_valid()) name = p->handle.name(); - event_string << "(" << name << ") " << p->msg(); - } - else - { - event_string << a->msg(); + event_string << esc("33"); } + event_string << a->message(); event_string << esc("0"); events.push_back(event_string.str()); - if (events.size() >= 20) events.pop_front(); + + ::handle_alert(ses, a.get()); + a = ses.pop_alert(); } diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp index ab8065f1f..afa8e978f 100644 --- a/include/libtorrent/alert.hpp +++ b/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/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index 5d26a66c2..4422c6f87 100644 --- a/include/libtorrent/alert_types.hpp +++ b/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,193 @@ 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_snubbed_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_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 +466,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 +475,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 +493,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 +521,14 @@ 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 block_finished_alert: torrent_alert @@ -300,9 +536,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 +547,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 +564,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 +660,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 +748,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 +774,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 +959,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/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index fa4f0d276..57da44b4a 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/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/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index d95782d79..6b628bdbf 100644 --- a/include/libtorrent/session.hpp +++ b/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/src/alert.cpp b/src/alert.cpp index be6f718ee..844cfb93b 100644 --- a/src/alert.cpp +++ b/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/src/metadata_transfer.cpp b/src/metadata_transfer.cpp index 8e27eeabf..a347223e3 100644 --- a/src/metadata_transfer.cpp +++ b/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/src/peer_connection.cpp b/src/peer_connection.cpp index 8f69665fa..89b429fe7 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -1378,14 +1378,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)); } } } @@ -1524,13 +1520,10 @@ namespace libtorrent 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 " @@ -1637,7 +1630,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 +1645,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? @@ -1934,10 +1927,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); @@ -2238,18 +2231,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)); } } @@ -2616,7 +2611,15 @@ namespace libtorrent && now > m_requested + seconds(m_ses.settings().request_timeout) && t->has_picker()) { - m_snubbed = true; + 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; piece_picker& picker = t->picker(); // the front request timed out! @@ -2695,7 +2698,15 @@ namespace libtorrent << " " << total_seconds(now - m_last_piece) << "] ***\n"; #endif - m_snubbed = true; + 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->is_seed()) @@ -2843,10 +2854,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 +3387,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)); } } diff --git a/src/policy.cpp b/src/policy.cpp index 07791adba..bb75e0994 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -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++); } @@ -771,11 +765,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 +788,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/src/session.cpp b/src/session.cpp index 194af5b73..5e0ad1205 100644 --- a/src/session.cpp +++ b/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/src/session_impl.cpp b/src/session_impl.cpp index 0e33421e7..92ad41db6 100644 --- a/src/session_impl.cpp +++ b/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/src/torrent.cpp b/src/torrent.cpp index d7e989d37..ef0e93de4 100644 --- a/src/torrent.cpp +++ b/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 @@ -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)); } @@ -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/src/ut_metadata.cpp b/src/ut_metadata.cpp index 17246e5b6..848c3795d 100644 --- a/src/ut_metadata.cpp +++ b/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/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index 50402cd34..d31094f86 100644 --- a/src/web_peer_connection.cpp +++ b/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()