1 /*
2
3 Copyright (c) 2003-2018, Arvid Norberg, Daniel Wallin
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30
31 */
32
33 #ifndef TORRENT_ALERT_HPP_INCLUDED
34 #define TORRENT_ALERT_HPP_INCLUDED
35
36 #include <string>
37
38 // OVERVIEW
39 //
40 // The pop_alerts() function on session is the main interface for retrieving
41 // alerts (warnings, messages and errors from libtorrent). If no alerts have
42 // been posted by libtorrent pop_alerts() will return an empty list.
43 //
44 // By default, only errors are reported. settings_pack::alert_mask can be
45 // used to specify which kinds of events should be reported. The alert mask is
46 // a combination of the alert_category_t flags in the alert class.
47 //
48 // Every alert belongs to one or more category. There is a cost associated with
49 // posting alerts. Only alerts that belong to an enabled category are
50 // posted. Setting the alert bitmask to 0 will disable all alerts (except those
51 // that are non-discardable). Alerts that are responses to API calls such as
52 // save_resume_data() and post_session_stats() are non-discardable and will be
53 // posted even if their category is disabled.
54 //
55 // There are other alert base classes that some alerts derive from, all the
56 // alerts that are generated for a specific torrent are derived from
57 // torrent_alert, and tracker events derive from tracker_alert.
58 //
59 // Alerts returned by pop_alerts() are only valid until the next call to
60 // pop_alerts(). You may not copy an alert object to access it after the next
61 // call to pop_alerts(). Internal members of alerts also become invalid once
62 // pop_alerts() is called again.
63
64 #include "libtorrent/time.hpp"
65 #include "libtorrent/config.hpp"
66 #include "libtorrent/flags.hpp"
67
68 namespace libtorrent {
69
70 // bitmask type used to define alert categories. Categories can be enabled
71 // and disabled by the settings_pack::alert_mask setting. Constants are defined
72 // in the lt::alert_category namespace
73 using alert_category_t = flags::bitfield_flag<std::uint32_t, struct alert_category_tag>;
74
75 namespace alert_category {
76
77 // Enables alerts that report an error. This includes:
78 //
79 // * tracker errors
80 // * tracker warnings
81 // * file errors
82 // * resume data failures
83 // * web seed errors
84 // * .torrent files errors
85 // * listen socket errors
86 // * port mapping errors
87 constexpr alert_category_t error = 0_bit;
88
89 // Enables alerts when peers send invalid requests, get banned or
90 // snubbed.
91 constexpr alert_category_t peer = 1_bit;
92
93 // Enables alerts for port mapping events. For NAT-PMP and UPnP.
94 constexpr alert_category_t port_mapping = 2_bit;
95
96 // Enables alerts for events related to the storage. File errors and
97 // synchronization events for moving the storage, renaming files etc.
98 constexpr alert_category_t storage = 3_bit;
99
100 // Enables all tracker events. Includes announcing to trackers,
101 // receiving responses, warnings and errors.
102 constexpr alert_category_t tracker = 4_bit;
103
104 // Low level alerts for when peers are connected and disconnected.
105 constexpr alert_category_t connect = 5_bit;
106
107 // Enables alerts for when a torrent or the session changes state.
108 constexpr alert_category_t status = 6_bit;
109
110 // Alerts when a peer is blocked by the ip blocker or port blocker.
111 constexpr alert_category_t ip_block = 8_bit;
112
113 // Alerts when some limit is reached that might limit the download
114 // or upload rate.
115 constexpr alert_category_t performance_warning = 9_bit;
116
117 // Alerts on events in the DHT node. For incoming searches or
118 // bootstrapping being done etc.
119 constexpr alert_category_t dht = 10_bit;
120
121 // If you enable these alerts, you will receive a stats_alert
122 // approximately once every second, for every active torrent.
123 // These alerts contain all statistics counters for the interval since
124 // the lasts stats alert.
125 constexpr alert_category_t stats = 11_bit;
126
127 // Enables debug logging alerts. These are available unless libtorrent
128 // was built with logging disabled (``TORRENT_DISABLE_LOGGING``). The
129 // alerts being posted are log_alert and are session wide.
130 constexpr alert_category_t session_log = 13_bit;
131
132 // Enables debug logging alerts for torrents. These are available
133 // unless libtorrent was built with logging disabled
134 // (``TORRENT_DISABLE_LOGGING``). The alerts being posted are
135 // torrent_log_alert and are torrent wide debug events.
136 constexpr alert_category_t torrent_log = 14_bit;
137
138 // Enables debug logging alerts for peers. These are available unless
139 // libtorrent was built with logging disabled
140 // (``TORRENT_DISABLE_LOGGING``). The alerts being posted are
141 // peer_log_alert and low-level peer events and messages.
142 constexpr alert_category_t peer_log = 15_bit;
143
144 // enables the incoming_request_alert.
145 constexpr alert_category_t incoming_request = 16_bit;
146
147 // enables dht_log_alert, debug logging for the DHT
148 constexpr alert_category_t dht_log = 17_bit;
149
150 // enable events from pure dht operations not related to torrents
151 constexpr alert_category_t dht_operation = 18_bit;
152
153 // enables port mapping log events. This log is useful
154 // for debugging the UPnP or NAT-PMP implementation
155 constexpr alert_category_t port_mapping_log = 19_bit;
156
157 // enables verbose logging from the piece picker.
158 constexpr alert_category_t picker_log = 20_bit;
159
160 // alerts when files complete downloading
161 constexpr alert_category_t file_progress = 21_bit;
162
163 // alerts when pieces complete downloading or fail hash check
164 constexpr alert_category_t piece_progress = 22_bit;
165
166 // alerts when we upload blocks to other peers
167 constexpr alert_category_t upload = 23_bit;
168
169 // alerts on individual blocks being requested, downloading, finished,
170 // rejected, time-out and cancelled. This is likely to post alerts at a
171 // high rate.
172 constexpr alert_category_t block_progress = 24_bit;
173
174 // The full bitmask, representing all available categories.
175 //
176 // since the enum is signed, make sure this isn't
177 // interpreted as -1. For instance, boost.python
178 // does that and fails when assigning it to an
179 // unsigned parameter.
180 constexpr alert_category_t all = alert_category_t::all();
181
182 } // namespace alert_category
183
184 #ifdef __GNUC__
185 #pragma GCC diagnostic push
186 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
187 #endif
188
189 // The ``alert`` class is the base class that specific messages are derived from.
190 // alert types are not copyable, and cannot be constructed by the client. The
191 // pointers returned by libtorrent are short lived (the details are described
192 // under session_handle::pop_alerts())
193 class TORRENT_EXPORT alert
194 {
195 #ifdef __GNUC__
196 #pragma GCC diagnostic pop
197 #endif
198 public:
199
200 // hidden
201 alert(alert const& rhs) = delete;
202 alert& operator=(alert const&) = delete;
203 alert(alert&& rhs) noexcept = default;
204
205 #if TORRENT_ABI_VERSION == 1
206 // only here for backwards compatibility
207 enum TORRENT_DEPRECATED_ENUM severity_t { debug, info, warning, critical, fatal, none };
208
209 using category_t = alert_category_t;
210 #endif
211
212 static constexpr alert_category_t error_notification = 0_bit;
213 static constexpr alert_category_t peer_notification = 1_bit;
214 static constexpr alert_category_t port_mapping_notification = 2_bit;
215 static constexpr alert_category_t storage_notification = 3_bit;
216 static constexpr alert_category_t tracker_notification = 4_bit;
217 static constexpr alert_category_t connect_notification = 5_bit;
218 #if TORRENT_ABI_VERSION == 1
219 static constexpr alert_category_t TORRENT_DEPRECATED_MEMBER debug_notification = connect_notification;
220 #endif
221 static constexpr alert_category_t status_notification = 6_bit;
222 #if TORRENT_ABI_VERSION == 1
223 static constexpr alert_category_t TORRENT_DEPRECATED_MEMBER progress_notification = 7_bit;
224 #endif
225 static constexpr alert_category_t ip_block_notification = 8_bit;
226 static constexpr alert_category_t performance_warning = 9_bit;
227 static constexpr alert_category_t dht_notification = 10_bit;
228 static constexpr alert_category_t stats_notification = 11_bit;
229 #if TORRENT_ABI_VERSION == 1
230 static constexpr alert_category_t TORRENT_DEPRECATED_MEMBER rss_notification = 12_bit;
231 #endif
232 static constexpr alert_category_t session_log_notification = 13_bit;
233 static constexpr alert_category_t torrent_log_notification = 14_bit;
234 static constexpr alert_category_t peer_log_notification = 15_bit;
235 static constexpr alert_category_t incoming_request_notification = 16_bit;
236 static constexpr alert_category_t dht_log_notification = 17_bit;
237 static constexpr alert_category_t dht_operation_notification = 18_bit;
238 static constexpr alert_category_t port_mapping_log_notification = 19_bit;
239 static constexpr alert_category_t picker_log_notification = 20_bit;
240 static constexpr alert_category_t file_progress_notification = 21_bit;
241 static constexpr alert_category_t piece_progress_notification = 22_bit;
242 static constexpr alert_category_t upload_notification = 23_bit;
243 static constexpr alert_category_t block_progress_notification = 24_bit;
244 static constexpr alert_category_t all_categories = alert_category_t::all();
245
246 // hidden
247 alert();
248 // hidden
249 virtual ~alert();
250
251 // a timestamp is automatically created in the constructor
252 time_point timestamp() const;
253
254 // returns an integer that is unique to this alert type. It can be
255 // compared against a specific alert by querying a static constant called ``alert_type``
256 // in the alert. It can be used to determine the run-time type of an alert* in
257 // order to cast to that alert type and access specific members.
258 //
259 // e.g:
260 //
261 // .. code:: c++
262 //
263 // std::vector<alert*> alerts;
264 // ses.pop_alerts(&alerts);
265 // for (alert* a : alerts) {
266 // switch (a->type()) {
267 //
268 // case read_piece_alert::alert_type:
269 // {
270 // auto* p = static_cast<read_piece_alert*>(a);
271 // if (p->ec) {
272 // // read_piece failed
273 // break;
274 // }
275 // // use p
276 // break;
277 // }
278 // case file_renamed_alert::alert_type:
279 // {
280 // // etc...
281 // }
282 // }
283 // }
284 virtual int type() const noexcept = 0;
285
286 // returns a string literal describing the type of the alert. It does
287 // not include any information that might be bundled with the alert.
288 virtual char const* what() const noexcept = 0;
289
290 // generate a string describing the alert and the information bundled
291 // with it. This is mainly intended for debug and development use. It is not suitable
292 // to use this for applications that may be localized. Instead, handle each alert
293 // type individually and extract and render the information from the alert depending
294 // on the locale.
295 virtual std::string message() const = 0;
296
297 // returns a bitmask specifying which categories this alert belong to.
298 virtual alert_category_t category() const noexcept = 0;
299
300 #if TORRENT_ABI_VERSION == 1
301
302 #include "libtorrent/aux_/disable_warnings_push.hpp"
303
304 // determines whether or not an alert is allowed to be discarded
305 // when the alert queue is full. There are a few alerts which may not be discarded,
306 // since they would break the user contract, such as save_resume_data_alert.
307 TORRENT_DEPRECATED
discardable() const308 bool discardable() const { return discardable_impl(); }
309
310 TORRENT_DEPRECATED
severity() const311 severity_t severity() const { return warning; }
312
313 protected:
314
discardable_impl() const315 virtual bool discardable_impl() const { return true; }
316
317 #include "libtorrent/aux_/disable_warnings_pop.hpp"
318
319 #endif // TORRENT_ABI_VERSION
320
321 private:
322 time_point const m_timestamp;
323 };
324
325 // When you get an alert, you can use ``alert_cast<>`` to attempt to cast the
326 // pointer to a specific alert type, in order to query it for more
327 // information.
328 //
329 // .. note::
330 // ``alert_cast<>`` can only cast to an exact alert type, not a base class
alert_cast(alert * a)331 template <class T> T* alert_cast(alert* a)
332 {
333 static_assert(std::is_base_of<alert, T>::value
334 , "alert_cast<> can only be used with alert types (deriving from lt::alert)");
335
336 if (a == nullptr) return nullptr;
337 if (a->type() == T::alert_type) return static_cast<T*>(a);
338 return nullptr;
339 }
alert_cast(alert const * a)340 template <class T> T const* alert_cast(alert const* a)
341 {
342 static_assert(std::is_base_of<alert, T>::value
343 , "alert_cast<> can only be used with alert types (deriving from lt::alert)");
344 if (a == nullptr) return nullptr;
345 if (a->type() == T::alert_type) return static_cast<T const*>(a);
346 return nullptr;
347 }
348
349 } // namespace libtorrent
350
351 #endif // TORRENT_ALERT_HPP_INCLUDED
352