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