1 /* 2 3 Copyright (c) 2006-2018, Arvid Norberg 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_EXTENSIONS_HPP_INCLUDED 34 #define TORRENT_EXTENSIONS_HPP_INCLUDED 35 36 #include "libtorrent/units.hpp" 37 #include "libtorrent/flags.hpp" 38 #include "libtorrent/peer_info.hpp" // for peer_source_flags_t 39 #include "libtorrent/torrent_status.hpp" // for torrent_status::state_t 40 41 // OVERVIEW 42 // 43 // libtorrent has a plugin interface for implementing extensions to the protocol. 44 // These can be general extensions for transferring metadata or peer exchange 45 // extensions, or it could be used to provide a way to customize the protocol 46 // to fit a particular (closed) network. 47 // 48 // In short, the plugin interface makes it possible to: 49 // 50 // * register extension messages (sent in the extension handshake), see 51 // extensions_. 52 // * add data and parse data from the extension handshake. 53 // * send extension messages and standard bittorrent messages. 54 // * override or block the handling of standard bittorrent messages. 55 // * save and restore state via the session state 56 // * see all alerts that are posted 57 // 58 // .. _extensions: extension_protocol.html 59 // 60 // a word of caution 61 // ----------------- 62 // 63 // Writing your own plugin is a very easy way to introduce serious bugs such as 64 // dead locks and race conditions. Since a plugin has access to internal 65 // structures it is also quite easy to sabotage libtorrent's operation. 66 // 67 // All the callbacks are always called from the libtorrent network thread. In 68 // case portions of your plugin are called from other threads, typically the main 69 // thread, you cannot use any of the member functions on the internal structures 70 // in libtorrent, since those require being called from the libtorrent network 71 // thread . Furthermore, you also need to synchronize your own shared data 72 // within the plugin, to make sure it is not accessed at the same time from the 73 // libtorrent thread (through a callback). If you need to send out a message 74 // from another thread, it is advised to use an internal queue, and do the 75 // actual sending in ``tick()``. 76 // 77 // Since the plugin interface gives you easy access to internal structures, it 78 // is not supported as a stable API. Plugins should be considered specific to a 79 // specific version of libtorrent. Although, in practice the internals mostly 80 // don't change that dramatically. 81 // 82 // 83 // plugin-interface 84 // ================ 85 // 86 // The plugin interface consists of three base classes that the plugin may 87 // implement. These are called plugin, torrent_plugin and peer_plugin. 88 // They are found in the ``<libtorrent/extensions.hpp>`` header. 89 // 90 // These plugins are instantiated for each session, torrent and possibly each peer, 91 // respectively. 92 // 93 // For plugins that only need per torrent state, it is enough to only implement 94 // ``torrent_plugin`` and pass a constructor function or function object to 95 // ``session::add_extension()`` or ``torrent_handle::add_extension()`` (if the 96 // torrent has already been started and you want to hook in the extension at 97 // run-time). 98 // 99 // The signature of the function is: 100 // 101 // .. code:: c++ 102 // 103 // std::shared_ptr<torrent_plugin> (*)(torrent_handle const&, void*); 104 // 105 // The second argument is the userdata passed to ``session::add_torrent()`` or 106 // ``torrent_handle::add_extension()``. 107 // 108 // The function should return a ``std::shared_ptr<torrent_plugin>`` which 109 // may or may not be 0. If it is a nullptr, the extension is simply ignored 110 // for this torrent. If it is a valid pointer (to a class inheriting 111 // ``torrent_plugin``), it will be associated with this torrent and callbacks 112 // will be made on torrent events. 113 // 114 // For more elaborate plugins which require session wide state, you would 115 // implement ``plugin``, construct an object (in a ``std::shared_ptr``) and pass 116 // it in to ``session::add_extension()``. 117 // 118 // custom alerts 119 // ============= 120 // 121 // Since plugins are running within internal libtorrent threads, one convenient 122 // way to communicate with the client is to post custom alerts. 123 // 124 // The expected interface of any alert, apart from deriving from the alert 125 // base class, looks like this: 126 // 127 // .. parsed-literal:: 128 // 129 // static const int alert_type = *<unique alert ID>*; 130 // virtual int type() const { return alert_type; } 131 // 132 // virtual std::string message() const; 133 // 134 // static const alert_category_t static_category = *<bitmask of alert::category_t flags>*; 135 // virtual alert_category_t category() const { return static_category; } 136 // 137 // virtual char const* what() const { return *<string literal of the name of this alert>*; } 138 // 139 // The ``alert_type`` is used for the type-checking in ``alert_cast``. It must 140 // not collide with any other alert. The built-in alerts in libtorrent will 141 // not use alert type IDs greater than ``user_alert_id``. When defining your 142 // own alert, make sure it's greater than this constant. 143 // 144 // ``type()`` is the run-time equivalence of the ``alert_type``. 145 // 146 // The ``message()`` virtual function is expected to construct a useful 147 // string representation of the alert and the event or data it represents. 148 // Something convenient to put in a log file for instance. 149 // 150 // ``clone()`` is used internally to copy alerts. The suggested implementation 151 // of simply allocating a new instance as a copy of ``*this`` is all that's 152 // expected. 153 // 154 // The static category is required for checking whether or not the category 155 // for a specific alert is enabled or not, without instantiating the alert. 156 // The ``category`` virtual function is the run-time equivalence. 157 // 158 // The ``what()`` virtual function may simply be a string literal of the class 159 // name of your alert. 160 // 161 // For more information, see the `alert section`_. 162 // 163 // .. _`alert section`: reference-Alerts.html 164 165 #include <vector> 166 167 #include "libtorrent/config.hpp" 168 #include "libtorrent/fwd.hpp" 169 #include "libtorrent/span.hpp" 170 #include "libtorrent/sha1_hash.hpp" 171 #include "libtorrent/string_view.hpp" 172 #include "libtorrent/socket.hpp" 173 #include "libtorrent/error_code.hpp" 174 175 namespace libtorrent { 176 177 #ifndef TORRENT_DISABLE_EXTENSIONS 178 179 // these are flags that can be returned by implemented_features() 180 // indicating which callbacks this plugin is interested in 181 using feature_flags_t = flags::bitfield_flag<std::uint8_t, struct feature_flags_tag>; 182 183 // this is the base class for a session plugin. One primary feature 184 // is that it is notified of all torrents that are added to the session, 185 // and can add its own torrent_plugins. 186 struct TORRENT_EXPORT plugin 187 { 188 // hidden ~pluginlibtorrent::plugin189 virtual ~plugin() {} 190 191 #if TORRENT_ABI_VERSION == 1 192 using feature_flags_t = libtorrent::feature_flags_t; 193 #endif 194 195 // include this bit if your plugin needs to alter the order of the 196 // optimistic unchoke of peers. i.e. have the on_optimistic_unchoke() 197 // callback be called. 198 static constexpr feature_flags_t optimistic_unchoke_feature = 1_bit; 199 200 // include this bit if your plugin needs to have on_tick() called 201 static constexpr feature_flags_t tick_feature = 2_bit; 202 203 // include this bit if your plugin needs to have on_dht_request() 204 // called 205 static constexpr feature_flags_t dht_request_feature = 3_bit; 206 207 // include this bit if your plugin needs to have on_alert() 208 // called 209 static constexpr feature_flags_t alert_feature = 4_bit; 210 211 // This function is expected to return a bitmask indicating which features 212 // this plugin implements. Some callbacks on this object may not be called 213 // unless the corresponding feature flag is returned here. Note that 214 // callbacks may still be called even if the corresponding feature is not 215 // specified in the return value here. See feature_flags_t for possible 216 // flags to return. implemented_featureslibtorrent::plugin217 virtual feature_flags_t implemented_features() { return {}; } 218 219 // this is called by the session every time a new torrent is added. 220 // The ``torrent*`` points to the internal torrent object created 221 // for the new torrent. The ``void*`` is the userdata pointer as 222 // passed in via add_torrent_params. 223 // 224 // If the plugin returns a torrent_plugin instance, it will be added 225 // to the new torrent. Otherwise, return an empty shared_ptr to a 226 // torrent_plugin (the default). new_torrentlibtorrent::plugin227 virtual std::shared_ptr<torrent_plugin> new_torrent(torrent_handle const&, void*) 228 { return std::shared_ptr<torrent_plugin>(); } 229 230 // called when plugin is added to a session addedlibtorrent::plugin231 virtual void added(session_handle const&) {} 232 233 // called when a dht request is received. 234 // If your plugin expects this to be called, make sure to include the flag 235 // ``dht_request_feature`` in the return value from implemented_features(). on_dht_requestlibtorrent::plugin236 virtual bool on_dht_request(string_view /* query */ 237 , udp::endpoint const& /* source */, bdecode_node const& /* message */ 238 , entry& /* response */) 239 { return false; } 240 241 // called when an alert is posted alerts that are filtered are not posted. 242 // If your plugin expects this to be called, make sure to include the flag 243 // ``alert_feature`` in the return value from implemented_features(). on_alertlibtorrent::plugin244 virtual void on_alert(alert const*) {} 245 246 // return true if the add_torrent_params should be added on_unknown_torrentlibtorrent::plugin247 virtual bool on_unknown_torrent(sha1_hash const& /* info_hash */ 248 , peer_connection_handle const& /* pc */, add_torrent_params& /* p */) 249 { return false; } 250 251 // called once per second. 252 // If your plugin expects this to be called, make sure to include the flag 253 // ``tick_feature`` in the return value from implemented_features(). on_ticklibtorrent::plugin254 virtual void on_tick() {} 255 256 // called when choosing peers to optimistically unchoke. The return value 257 // indicates the peer's priority for unchoking. Lower return values 258 // correspond to higher priority. Priorities above 2^63-1 are reserved. 259 // If your plugin has no priority to assign a peer it should return 2^64-1. 260 // If your plugin expects this to be called, make sure to include the flag 261 // ``optimistic_unchoke_feature`` in the return value from implemented_features(). 262 // If multiple plugins implement this function the lowest return value 263 // (i.e. the highest priority) is used. get_unchoke_prioritylibtorrent::plugin264 virtual uint64_t get_unchoke_priority(peer_connection_handle const& /* peer */) 265 { return (std::numeric_limits<uint64_t>::max)(); } 266 267 // called when saving settings state save_statelibtorrent::plugin268 virtual void save_state(entry&) {} 269 270 // called when loading settings state load_statelibtorrent::plugin271 virtual void load_state(bdecode_node const&) {} 272 }; 273 274 using add_peer_flags_t = flags::bitfield_flag<std::uint8_t, struct add_peer_flags_tag>; 275 276 // Torrent plugins are associated with a single torrent and have a number 277 // of functions called at certain events. Many of its functions have the 278 // ability to change or override the default libtorrent behavior. 279 struct TORRENT_EXPORT torrent_plugin 280 { 281 // hidden ~torrent_pluginlibtorrent::torrent_plugin282 virtual ~torrent_plugin() {} 283 284 #if TORRENT_ABI_VERSION == 1 285 using flags_t = libtorrent::add_peer_flags_t; 286 #endif 287 288 // This function is called each time a new peer is connected to the torrent. You 289 // may choose to ignore this by just returning a default constructed 290 // ``shared_ptr`` (in which case you don't need to override this member 291 // function). 292 // 293 // If you need an extension to the peer connection (which most plugins do) you 294 // are supposed to return an instance of your peer_plugin class. Which in 295 // turn will have its hook functions called on event specific to that peer. 296 // 297 // The ``peer_connection_handle`` will be valid as long as the ``shared_ptr`` 298 // is being held by the torrent object. So, it is generally a good idea to not 299 // keep a ``shared_ptr`` to your own peer_plugin. If you want to keep references 300 // to it, use ``weak_ptr``. 301 // 302 // If this function throws an exception, the connection will be closed. new_connectionlibtorrent::torrent_plugin303 virtual std::shared_ptr<peer_plugin> new_connection(peer_connection_handle const&) 304 { return std::shared_ptr<peer_plugin>(); } 305 306 // These hooks are called when a piece passes the hash check or fails the hash 307 // check, respectively. The ``index`` is the piece index that was downloaded. 308 // It is possible to access the list of peers that participated in sending the 309 // piece through the ``torrent`` and the ``piece_picker``. on_piece_passlibtorrent::torrent_plugin310 virtual void on_piece_pass(piece_index_t) {} on_piece_failedlibtorrent::torrent_plugin311 virtual void on_piece_failed(piece_index_t) {} 312 313 // This hook is called approximately once per second. It is a way of making it 314 // easy for plugins to do timed events, for sending messages or whatever. ticklibtorrent::torrent_plugin315 virtual void tick() {} 316 317 // These hooks are called when the torrent is paused and resumed respectively. 318 // The return value indicates if the event was handled. A return value of 319 // ``true`` indicates that it was handled, and no other plugin after this one 320 // will have this hook function called, and the standard handler will also not be 321 // invoked. So, returning true effectively overrides the standard behavior of 322 // pause or resume. 323 // 324 // Note that if you call ``pause()`` or ``resume()`` on the torrent from your 325 // handler it will recurse back into your handler, so in order to invoke the 326 // standard handler, you have to keep your own state on whether you want standard 327 // behavior or overridden behavior. on_pauselibtorrent::torrent_plugin328 virtual bool on_pause() { return false; } on_resumelibtorrent::torrent_plugin329 virtual bool on_resume() { return false; } 330 331 // This function is called when the initial files of the torrent have been 332 // checked. If there are no files to check, this function is called immediately. 333 // 334 // i.e. This function is always called when the torrent is in a state where it 335 // can start downloading. on_files_checkedlibtorrent::torrent_plugin336 virtual void on_files_checked() {} 337 338 // called when the torrent changes state 339 // the state is one of torrent_status::state_t 340 // enum members on_statelibtorrent::torrent_plugin341 virtual void on_state(torrent_status::state_t) {} 342 343 // this is the first time we see this peer 344 static constexpr add_peer_flags_t first_time = 1_bit; 345 346 // this peer was not added because it was 347 // filtered by the IP filter 348 static constexpr add_peer_flags_t filtered = 2_bit; 349 350 // called every time a new peer is added to the peer list. 351 // This is before the peer is connected to. For ``flags``, see 352 // torrent_plugin::flags_t. The ``source`` argument refers to 353 // the source where we learned about this peer from. It's a 354 // bitmask, because many sources may have told us about the same 355 // peer. For peer source flags, see peer_info::peer_source_flags. on_add_peerlibtorrent::torrent_plugin356 virtual void on_add_peer(tcp::endpoint const&, 357 peer_source_flags_t, add_peer_flags_t) {} 358 }; 359 360 // peer plugins are associated with a specific peer. A peer could be 361 // both a regular bittorrent peer (``bt_peer_connection``) or one of the 362 // web seed connections (``web_peer_connection`` or ``http_seed_connection``). 363 // In order to only attach to certain peers, make your 364 // torrent_plugin::new_connection only return a plugin for certain peer 365 // connection types 366 struct TORRENT_EXPORT peer_plugin 367 { 368 // hidden ~peer_pluginlibtorrent::peer_plugin369 virtual ~peer_plugin() {} 370 371 // This function is expected to return the name of 372 // the plugin. typelibtorrent::peer_plugin373 virtual string_view type() const { return {}; } 374 375 // can add entries to the extension handshake 376 // this is not called for web seeds add_handshakelibtorrent::peer_plugin377 virtual void add_handshake(entry&) {} 378 379 // called when the peer is being disconnected. on_disconnectlibtorrent::peer_plugin380 virtual void on_disconnect(error_code const&) {} 381 382 // called when the peer is successfully connected. Note that 383 // incoming connections will have been connected by the time 384 // the peer plugin is attached to it, and won't have this hook 385 // called. on_connectedlibtorrent::peer_plugin386 virtual void on_connected() {} 387 388 // throwing an exception from any of the handlers (except add_handshake) 389 // closes the connection 390 391 // this is called when the initial bittorrent handshake is received. 392 // Returning false means that the other end doesn't support this extension 393 // and will remove it from the list of plugins. this is not called for web 394 // seeds on_handshakelibtorrent::peer_plugin395 virtual bool on_handshake(span<char const>) { return true; } 396 397 // called when the extension handshake from the other end is received 398 // if this returns false, it means that this extension isn't 399 // supported by this peer. It will result in this peer_plugin 400 // being removed from the peer_connection and destructed. 401 // this is not called for web seeds on_extension_handshakelibtorrent::peer_plugin402 virtual bool on_extension_handshake(bdecode_node const&) { return true; } 403 404 // returning true from any of the message handlers 405 // indicates that the plugin has handled the message. 406 // it will break the plugin chain traversing and not let 407 // anyone else handle the message, including the default 408 // handler. on_chokelibtorrent::peer_plugin409 virtual bool on_choke() { return false; } on_unchokelibtorrent::peer_plugin410 virtual bool on_unchoke() { return false; } on_interestedlibtorrent::peer_plugin411 virtual bool on_interested() { return false; } on_not_interestedlibtorrent::peer_plugin412 virtual bool on_not_interested() { return false; } on_havelibtorrent::peer_plugin413 virtual bool on_have(piece_index_t) { return false; } on_dont_havelibtorrent::peer_plugin414 virtual bool on_dont_have(piece_index_t) { return false; } on_bitfieldlibtorrent::peer_plugin415 virtual bool on_bitfield(bitfield const& /*bitfield*/) { return false; } on_have_alllibtorrent::peer_plugin416 virtual bool on_have_all() { return false; } on_have_nonelibtorrent::peer_plugin417 virtual bool on_have_none() { return false; } on_allowed_fastlibtorrent::peer_plugin418 virtual bool on_allowed_fast(piece_index_t) { return false; } on_requestlibtorrent::peer_plugin419 virtual bool on_request(peer_request const&) { return false; } 420 421 // This function is called when the peer connection is receiving 422 // a piece. ``buf`` points (non-owning pointer) to the data in an 423 // internal immutable disk buffer. The length of the data is specified 424 // in the ``length`` member of the ``piece`` parameter. 425 // returns true to indicate that the piece is handled and the 426 // rest of the logic should be ignored. on_piecelibtorrent::peer_plugin427 virtual bool on_piece(peer_request const& /*piece*/ 428 , span<char const> /*buf*/) { return false; } 429 on_cancellibtorrent::peer_plugin430 virtual bool on_cancel(peer_request const&) { return false; } on_rejectlibtorrent::peer_plugin431 virtual bool on_reject(peer_request const&) { return false; } on_suggestlibtorrent::peer_plugin432 virtual bool on_suggest(piece_index_t) { return false; } 433 434 // called after a choke message has been sent to the peer sent_unchokelibtorrent::peer_plugin435 virtual void sent_unchoke() {} 436 437 // called after piece data has been sent to the peer 438 // this can be used for stats book keeping sent_payloadlibtorrent::peer_plugin439 virtual void sent_payload(int /* bytes */) {} 440 441 // called when libtorrent think this peer should be disconnected. 442 // if the plugin returns false, the peer will not be disconnected. can_disconnectlibtorrent::peer_plugin443 virtual bool can_disconnect(error_code const& /*ec*/) { return true; } 444 445 // called when an extended message is received. If returning true, 446 // the message is not processed by any other plugin and if false 447 // is returned the next plugin in the chain will receive it to 448 // be able to handle it. This is not called for web seeds. 449 // thus function may be called more than once per incoming message, but 450 // only the last of the calls will the ``body`` size equal the ``length``. 451 // i.e. Every time another fragment of the message is received, this 452 // function will be called, until finally the whole message has been 453 // received. The purpose of this is to allow early disconnects for invalid 454 // messages and for reporting progress of receiving large messages. on_extendedlibtorrent::peer_plugin455 virtual bool on_extended(int /*length*/, int /*msg*/, 456 span<char const> /*body*/) 457 { return false; } 458 459 // this is not called for web seeds on_unknown_messagelibtorrent::peer_plugin460 virtual bool on_unknown_message(int /*length*/, int /*msg*/, 461 span<char const> /*body*/) 462 { return false; } 463 464 // called when a piece that this peer participated in either 465 // fails or passes the hash_check on_piece_passlibtorrent::peer_plugin466 virtual void on_piece_pass(piece_index_t) {} on_piece_failedlibtorrent::peer_plugin467 virtual void on_piece_failed(piece_index_t) {} 468 469 // called approximately once every second ticklibtorrent::peer_plugin470 virtual void tick() {} 471 472 // called each time a request message is to be sent. If true 473 // is returned, the original request message won't be sent and 474 // no other plugin will have this function called. write_requestlibtorrent::peer_plugin475 virtual bool write_request(peer_request const&) { return false; } 476 }; 477 #endif // TORRENT_DISABLE_EXTENSIONS 478 479 #if !defined TORRENT_DISABLE_ENCRYPTION 480 481 struct TORRENT_EXPORT crypto_plugin 482 { 483 // hidden ~crypto_pluginlibtorrent::crypto_plugin484 virtual ~crypto_plugin() {} 485 486 virtual void set_incoming_key(span<char const> key) = 0; 487 virtual void set_outgoing_key(span<char const> key) = 0; 488 489 // encrypted the provided buffers and returns the number of bytes which 490 // are now ready to be sent to the lower layer. This must be at least 491 // as large as the number of bytes passed in and may be larger if there 492 // is additional data to be inserted at the head of the send buffer. 493 // The additional data is returned as the second tuple value. Any 494 // returned buffer as well as the iovec itself, to be prepended to the 495 // send buffer, must be owned by the crypto plugin and guaranteed to stay 496 // alive until the crypto_plugin is destructed or this function is called 497 // again. 498 virtual std::tuple<int, span<span<char const>>> 499 encrypt(span<span<char>> /*send_vec*/) = 0; 500 501 // decrypt the provided buffers. 502 // returns is a tuple representing the values 503 // (consume, produce, packet_size) 504 // 505 // consume is set to the number of bytes which should be trimmed from the 506 // head of the buffers, default is 0 507 // 508 // produce is set to the number of bytes of payload which are now ready to 509 // be sent to the upper layer. default is the number of bytes passed in receive_vec 510 // 511 // packet_size is set to the minimum number of bytes which must be read to 512 // advance the next step of decryption. default is 0 513 virtual std::tuple<int, int, int> decrypt(span<span<char>> /*receive_vec*/) = 0; 514 }; 515 516 #endif // TORRENT_DISABLE_ENCRYPTION 517 } 518 519 #endif // TORRENT_EXTENSIONS_HPP_INCLUDED 520