1 :Author: Arvid Norberg, arvid@rasterbar.com
8 libtorrent has a plugin interface for implementing extensions to the protocol.
9 These can be general extensions for transferring metadata or peer exchange
10 extensions, or it could be used to provide a way to customize the protocol
11 to fit a particular (closed) network.
13 In short, the plugin interface makes it possible to:
15 * register extension messages (sent in the extension handshake), see
17 * add data and parse data from the extension handshake.
18 * send extension messages and standard bittorrent messages.
19 * override or block the handling of standard bittorrent messages.
21 .. _extensions: extension_protocol.html
26 Writing your own plugin is a very easy way to introduce serious bugs such as
27 dead locks and race conditions. Since a plugin has access to internal
28 structures it is also quite easy to sabotage libtorrent's operation.
30 All the callbacks in this interface are called with the main libtorrent thread
31 mutex locked. And they are always called from the libtorrent main thread. In
32 case portions of your plugin are called from other threads, typically the main
33 thread, you cannot use any of the member functions on the internal structures
34 in libtorrent, since those require the mutex to be locked. Futhermore, you would
35 also need to have a mutex on your own shared data within the plugin, to make
36 sure it is not accessed at the same time from the libtorrent thread (through a
37 callback). See `boost thread's mutex`_. If you need to send out a message from
38 another thread, use an internal queue, and do the actual sending in ``tick()``.
40 .. _`boost thread's mutex`: http://www.boost.org/doc/html/mutex.html
46 The plugin interface consists of two base classes that the plugin may
47 implement. These are called ``torrent_plugin`` and ``peer_plugin``. They are
48 both found in the ``<libtorrent/extensions.hpp>`` header.
50 These plugins are instantiated for each torrent and possibly each peer,
53 This is done by passing in a function or function object to
54 ``session::add_extension()`` or ``torrent_handle::add_extension()`` (if the
55 torrent has already been started and you want to hook in the extension at
58 The signature of the function is::
60 boost::shared_ptr<torrent_plugin> (*)(torrent*, void*);
62 The first argument is the internal torrent object, the second argument
63 is the userdata passed to ``session::add_torrent()`` or
64 ``torrent_handle::add_extension()``.
66 The function should return a ``boost::shared_ptr<torrent_plugin>`` which
67 may or may not be 0. If it is a null pointer, the extension is simply ignored
68 for this torrent. If it is a valid pointer (to a class inheriting
69 ``torrent_plugin``), it will be associated with this torrent and callbacks
70 will be made on torrent events.
76 The synopsis for ``torrent_plugin`` follows::
80 virtual ~torrent_plugin();
81 virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection*);
83 virtual void on_piece_pass(int index);
84 virtual void on_piece_failed(int index);
88 virtual bool on_pause();
89 virtual bool on_resume();
91 virtual void on_files_checked();
94 This is the base class for a torrent_plugin. Your derived class is (if added
95 as an extension) instantiated for each torrent in the session. The callback
96 hook functions are defined as follows.
104 boost::shared_ptr<peer_plugin> new_connection(peer_connection*);
106 This function is called each time a new peer is connected to the torrent. You
107 may choose to ignore this by just returning a default constructed
108 ``shared_ptr`` (in which case you don't need to override this member
111 If you need an extension to the peer connection (which most plugins do) you
112 are supposed to return an instance of your ``peer_plugin`` class. Which in
113 turn will have its hook functions called on event specific to that peer.
115 The ``peer_connection`` will be valid as long as the ``shared_ptr`` is being
116 held by the torrent object. So, it is generally a good idea to not keep a
117 ``shared_ptr`` to your own peer_plugin. If you want to keep references to it,
120 If this function throws an exception, the connection will be closed.
122 on_piece_pass() on_piece_fail()
123 -------------------------------
127 void on_piece_pass(int index);
128 void on_piece_failed(int index);
130 These hooks are called when a piece passes the hash check or fails the hash
131 check, respectively. The ``index`` is the piece index that was downloaded.
132 It is possible to access the list of peers that participated in sending the
133 piece through the ``torrent`` and the ``piece_picker``.
142 This hook is called approximately once per second. It is a way of making it
143 easy for plugins to do timed events, for sending messages or whatever.
146 on_pause() on_resume()
147 ----------------------
154 These hooks are called when the torrent is paused and unpaused respectively.
155 The return value indicates if the event was handled. A return value of
156 ``true`` indicates that it was handled, and no other plugin after this one
157 will have this hook function called, and the standard handler will also not be
158 invoked. So, returning true effectively overrides the standard behavior of
161 Note that if you call ``pause()`` or ``resume()`` on the torrent from your
162 handler it will recurse back into your handler, so in order to invoke the
163 standard handler, you have to keep your own state on whether you want standard
164 behavior or overridden behavior.
171 void on_files_checked();
173 This function is called when the initial files of the torrent have been
174 checked. If there are no files to check, this function is called immediately.
176 i.e. This function is always called when the torrent is in a state where it
177 can start downloading.
187 virtual ~peer_plugin();
189 virtual void add_handshake(entry&);
190 virtual bool on_handshake(char const* reserved_bits);
191 virtual bool on_extension_handshake(lazy_entry const& h);
193 virtual bool on_choke();
194 virtual bool on_unchoke();
195 virtual bool on_interested();
196 virtual bool on_not_interested();
197 virtual bool on_have(int index);
198 virtual bool on_bitfield(bitfield const& bits);
199 virtual bool on_have_all();
200 virtual bool on_have_none();
201 virtual bool on_allowed_fast(int index);
202 virtual bool on_request(peer_request const& req);
203 virtual bool on_piece(peer_request const& piece, disk_buffer_holder& buffer);
204 virtual bool on_cancel(peer_request const& req);
205 virtual bool on_reject(peer_request const& req);
206 virtual bool on_suggest(int index);
207 virtual bool on_extended(int length
208 , int msg, buffer::const_interval body);
209 virtual bool on_unknown_message(int length, int msg
210 , buffer::const_interval body);
211 virtual void on_piece_pass(int index);
212 virtual void on_piece_failed(int index);
216 virtual bool write_request(peer_request const& r);
224 struct disk_buffer_holder
226 disk_buffer_holder(aux::session_impl& s, char* b);
227 ~disk_buffer_holder();
232 The disk buffer holder acts like a ``scoped_ptr`` that frees a disk buffer
233 when it's destructed, unless it's released. ``release`` returns the disk
234 buffer and transferres ownership and responsibility to free it to the caller.
236 A disk buffer is freed by passing it to ``session_impl::free_disk_buffer()``.
238 ``buffer()`` returns the pointer without transferring responsibility. If
239 this buffer has been released, ``buffer()`` will return 0.