forked from premiere/premiere-libtorrent
*** empty log message ***
This commit is contained in:
parent
3033f16f47
commit
97b387b196
|
@ -58,10 +58,14 @@
|
|||
<li><a class="reference" href="#simple-client" id="id34" name="id34">simple client</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#fast-resume" id="id35" name="id35">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id36" name="id36">file format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#feedback" id="id35" name="id35">Feedback</a></li>
|
||||
<li><a class="reference" href="#aknowledgements" id="id36" name="id36">Aknowledgements</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#feedback" id="id37" name="id37">Feedback</a></li>
|
||||
<li><a class="reference" href="#aknowledgements" id="id38" name="id38">Aknowledgements</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
|
@ -94,13 +98,14 @@ thread-safe library interface. (i.e. There's no way for the user to cause a dead
|
|||
<li>piece-wise file allocation</li>
|
||||
<li>tries to maintain a 1:1 share ratio between all peers but also shifts free
|
||||
download to peers as free upload. To maintain a global 1:1 ratio.</li>
|
||||
<li>fast resume support, a way to get rid of the costly piece check at the start
|
||||
of a resumed torrent. Saves the storage state in a separate fast-resume file.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>Functions that are yet to be implemented:</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>choke/unchoke policy for seed-mode</li>
|
||||
<li>fast resume</li>
|
||||
<li>number of connections limit</li>
|
||||
<li>better handling of peers that send bad data</li>
|
||||
<li>ip-filters</li>
|
||||
|
@ -170,6 +175,11 @@ class session: public boost::noncopyable
|
|||
session(int listen_port);
|
||||
|
||||
torrent_handle add_torrent(const torrent_info& t, const std::string& save_path);
|
||||
torrent_handle add_torrent(
|
||||
const torrent_info& t
|
||||
, const std::string& save_path
|
||||
, const std::vector<char>& resume_data);
|
||||
|
||||
void remove_torrent(const torrent_handle& h);
|
||||
|
||||
void set_http_settings(const http_settings& settings);
|
||||
|
@ -187,6 +197,9 @@ object representing the information found in the torrent file and the path where
|
|||
want to save the files. The <tt class="literal"><span class="pre">save_path</span></tt> will be prepended to the directory-
|
||||
structure in the torrent-file. <tt class="literal"><span class="pre">add_torrent</span></tt> will throw <tt class="literal"><span class="pre">duplicate_torrent</span></tt> exception
|
||||
if the torrent already exists in the session.</p>
|
||||
<p>The optional last parameter, <tt class="literal"><span class="pre">resume_data</span></tt> 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
|
||||
<tt class="literal"><span class="pre">torrent_handle::write_resume_data()</span></tt>. See <a class="reference" href="#fast-resume">fast resume</a>.</p>
|
||||
<p><tt class="literal"><span class="pre">remove_torrent()</span></tt> will close all peer connections associated with the torrent and tell
|
||||
the tracker that we've stopped participating in the swarm.</p>
|
||||
<p>If the torrent you are trying to add already exists in the session (is either queued
|
||||
|
@ -506,6 +519,8 @@ struct torrent_handle
|
|||
const torrent_info& get_torrent_info();
|
||||
bool is_valid();
|
||||
|
||||
void write_resume_data(std::vector<char>& data);
|
||||
|
||||
boost::filsystem::path save_path() const;
|
||||
|
||||
void set_max_uploads(int max_uploads);
|
||||
|
@ -525,10 +540,12 @@ was started.</p>
|
|||
<p><tt class="literal"><span class="pre">info_hash()</span></tt> returns the info hash for the torrent.</p>
|
||||
<p><tt class="literal"><span class="pre">set_max_uploads()</span></tt> sets the maximum number of peers that's unchoked at the same time on this
|
||||
torrent. If you set this to -1, there will be no limit.</p>
|
||||
<p><tt class="literal"><span class="pre">write_resume_data()</span></tt> takes a non-const reference to a char-vector, that vector will be filled
|
||||
with the fast-resume data. For more information about hpw fast-resume works, see <a class="reference" href="#fast-resume">fast resume</a>.</p>
|
||||
<div class="section" id="status">
|
||||
<h3><a class="toc-backref" href="#id15" name="status">status()</a></h3>
|
||||
<p><tt class="literal"><span class="pre">status()</span></tt> will return a structure with information about the status of this
|
||||
torrent. If the <tt class="literal"><span class="pre">torrent_handle</span></tt> is invalid, it will throw <tt class="literal"><span class="pre">invalid_handle</span></tt> exception.
|
||||
torrent. If the <a class="reference" href="#torrent-handle">torrent_handle</a> is invalid, it will throw <a class="reference" href="#invalid-handle">invalid_handle</a> exception.
|
||||
It contains the following fields:</p>
|
||||
<pre class="literal-block">
|
||||
struct torrent_status
|
||||
|
@ -604,7 +621,7 @@ data), these counters ignore any protocol overhead.</p>
|
|||
the pieces we don't have.</p>
|
||||
<p><tt class="literal"><span class="pre">download_rate</span></tt> and <tt class="literal"><span class="pre">upload_rate</span></tt> are the total rates for all peers for this
|
||||
torrent. These will usually have better precision than summing the rates from
|
||||
all peers.</p>
|
||||
all peers. The rates are given as the number of bytes per second.</p>
|
||||
<p><tt class="literal"><span class="pre">total_done</span></tt> is the total number of bytes of the file(s) that we have.</p>
|
||||
</div>
|
||||
<div class="section" id="get-download-queue">
|
||||
|
@ -643,7 +660,7 @@ may pass then.</p>
|
|||
<h3><a class="toc-backref" href="#id17" name="get-peer-info">get_peer_info()</a></h3>
|
||||
<p><tt class="literal"><span class="pre">get_peer_info()</span></tt> takes a reference to a vector that will be cleared and filled
|
||||
with one entry for each peer connected to this torrent, given the handle is valid. If the
|
||||
<tt class="literal"><span class="pre">torrent_handle</span></tt> is invalid, it will throw <tt class="literal"><span class="pre">invalid_handle</span></tt> exception. Each entry in
|
||||
<a class="reference" href="#torrent-handle">torrent_handle</a> is invalid, it will throw <tt class="literal"><span class="pre">invalid_handle</span></tt> exception. Each entry in
|
||||
the vector contains information about that particular peer. It contains the following
|
||||
fields:</p>
|
||||
<pre class="literal-block">
|
||||
|
@ -717,8 +734,8 @@ the total number of bytes in this block.</p>
|
|||
<div class="section" id="get-torrent-info">
|
||||
<h3><a class="toc-backref" href="#id18" name="get-torrent-info">get_torrent_info()</a></h3>
|
||||
<p>Returns a const reference to the <tt class="literal"><span class="pre">torrent_info</span></tt> object associated with this torrent.
|
||||
This reference is valid as long as the <tt class="literal"><span class="pre">torrent_handle</span></tt> is valid, no longer. If the
|
||||
<tt class="literal"><span class="pre">torrent_handle</span></tt> is invalid, <tt class="literal"><span class="pre">invalid_handle</span></tt> exception will be thrown.</p>
|
||||
This reference is valid as long as the <a class="reference" href="#torrent-handle">torrent_handle</a> is valid, no longer. If the
|
||||
<a class="reference" href="#torrent-handle">torrent_handle</a> is invalid, <a class="reference" href="#invalid-handle">invalid_handle</a> exception will be thrown.</p>
|
||||
</div>
|
||||
<div class="section" id="is-valid">
|
||||
<h3><a class="toc-backref" href="#id19" name="is-valid">is_valid()</a></h3>
|
||||
|
@ -922,7 +939,7 @@ public:
|
|||
here's a complete list with description.</p>
|
||||
<div class="section" id="invalid-handle">
|
||||
<h3><a class="toc-backref" href="#id27" name="invalid-handle">invalid_handle</a></h3>
|
||||
<p>This exception is thrown when querying information from a <tt class="literal"><span class="pre">torrent_handle</span></tt> that hasn't
|
||||
<p>This exception is thrown when querying information from a <a class="reference" href="#torrent-handle">torrent_handle</a> that hasn't
|
||||
been initialized or that has become invalid.</p>
|
||||
<pre class="literal-block">
|
||||
struct invalid_handle: std::exception
|
||||
|
@ -1093,14 +1110,49 @@ int main(int argc, char* argv[])
|
|||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="fast-resume">
|
||||
<h2><a class="toc-backref" href="#id35" name="fast-resume">fast resume</a></h2>
|
||||
<p>The fast resume mechanism is a way to remember which pieces are downloaded and where they
|
||||
are put between sessions. You can generate fast resume data by calling
|
||||
<tt class="literal"><span class="pre">torrent_handle::write_resume_data()</span></tt> on <a class="reference" href="#torrent-handle">torrent_handle</a>. You can then save this data
|
||||
to disk and use it when resuming the torrent. libtorrent will not check the piece hashes
|
||||
then, and rely on the information given in the fast-resume data. The fast-resume data
|
||||
also contains information about which bocks in the unfinished pieces were downloaded, so
|
||||
it will not have to start from scratch on the partially downloaded pieces.</p>
|
||||
<p>To use the fast-resume data you simply give it to <tt class="literal"><span class="pre">session::add_torrent()</span></tt>, and it
|
||||
will skip the time consuming checks. It may have to do the checking anyway, if the
|
||||
fast-resume data is corrupt or doesn't fit the storage for that torrent, then it will
|
||||
not trust the fast-resume data and just do the checking.</p>
|
||||
<div class="section" id="file-format">
|
||||
<h3><a class="toc-backref" href="#id36" name="file-format">file format</a></h3>
|
||||
<p>The format of the fast-resume data is as follows, given that all
|
||||
4-byte integers are stored as big-endian:</p>
|
||||
<pre class="literal-block">
|
||||
20 bytes, the info_hash for the torrent
|
||||
4 bytes, the number of allocated slots in the storage
|
||||
for each slot
|
||||
4 bytes, piece index in this slot,
|
||||
-1 means there's no storage for the slot
|
||||
-2 means there's no piece at this slot, it's free
|
||||
4 bytes, the number of blocks per piece.
|
||||
this must be piece_size / 16k or 1 if piece_size is < 16k
|
||||
and can be 128 at max.
|
||||
4 bytes, the number of unfinished pieces
|
||||
for each unfinished piece
|
||||
4 bytes, index of the unfinished piece
|
||||
blocks_per_piece / 32 bytes, the bitmask describing which
|
||||
blocks are finished in this piece.
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="feedback">
|
||||
<h1><a class="toc-backref" href="#id35" name="feedback">Feedback</a></h1>
|
||||
<h1><a class="toc-backref" href="#id37" name="feedback">Feedback</a></h1>
|
||||
<p>There's a <a class="reference" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>.</p>
|
||||
<p>You can usually find me as hydri in <tt class="literal"><span class="pre">#btports</span> <span class="pre">@</span> <span class="pre">irc.freenode.net</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="aknowledgements">
|
||||
<h1><a class="toc-backref" href="#id36" name="aknowledgements">Aknowledgements</a></h1>
|
||||
<h1><a class="toc-backref" href="#id38" name="aknowledgements">Aknowledgements</a></h1>
|
||||
<p>Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003</p>
|
||||
<p>Contributions by Magnus Jonsson</p>
|
||||
<p>Thanks to Reimond Retz for bugfixes, suggestions and testing</p>
|
||||
|
|
|
@ -43,6 +43,8 @@ The current state includes the following features:
|
|||
* piece-wise file allocation
|
||||
* tries to maintain a 1:1 share ratio between all peers but also shifts free
|
||||
download to peers as free upload. To maintain a global 1:1 ratio.
|
||||
* fast resume support, a way to get rid of the costly piece check at the start
|
||||
of a resumed torrent. Saves the storage state in a separate fast-resume file.
|
||||
|
||||
__ http://home.elp.rr.com/tur/multitracker-spec.txt
|
||||
.. _Azureus: http://azureus.sourceforge.net
|
||||
|
@ -50,7 +52,6 @@ __ http://home.elp.rr.com/tur/multitracker-spec.txt
|
|||
Functions that are yet to be implemented:
|
||||
|
||||
* choke/unchoke policy for seed-mode
|
||||
* fast resume
|
||||
* number of connections limit
|
||||
* better handling of peers that send bad data
|
||||
* ip-filters
|
||||
|
@ -134,6 +135,11 @@ The ``session`` class has the following synopsis::
|
|||
session(int listen_port);
|
||||
|
||||
torrent_handle add_torrent(const torrent_info& t, const std::string& save_path);
|
||||
torrent_handle add_torrent(
|
||||
const torrent_info& t
|
||||
, const std::string& save_path
|
||||
, const std::vector<char>& resume_data);
|
||||
|
||||
void remove_torrent(const torrent_handle& h);
|
||||
|
||||
void set_http_settings(const http_settings& settings);
|
||||
|
@ -152,6 +158,10 @@ want to save the files. The ``save_path`` will be prepended to the directory-
|
|||
structure in the torrent-file. ``add_torrent`` will throw ``duplicate_torrent`` exception
|
||||
if the torrent already exists in the session.
|
||||
|
||||
The optional last 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
|
||||
``torrent_handle::write_resume_data()``. See `fast resume`_.
|
||||
|
||||
``remove_torrent()`` will close all peer connections associated with the torrent and tell
|
||||
the tracker that we've stopped participating in the swarm.
|
||||
|
||||
|
@ -515,6 +525,8 @@ Its declaration looks like this::
|
|||
const torrent_info& get_torrent_info();
|
||||
bool is_valid();
|
||||
|
||||
void write_resume_data(std::vector<char>& data);
|
||||
|
||||
boost::filsystem::path save_path() const;
|
||||
|
||||
void set_max_uploads(int max_uploads);
|
||||
|
@ -538,11 +550,14 @@ was started.
|
|||
``set_max_uploads()`` sets the maximum number of peers that's unchoked at the same time on this
|
||||
torrent. If you set this to -1, there will be no limit.
|
||||
|
||||
``write_resume_data()`` takes a non-const reference to a char-vector, that vector will be filled
|
||||
with the fast-resume data. For more information about hpw fast-resume works, see `fast resume`_.
|
||||
|
||||
status()
|
||||
~~~~~~~~
|
||||
|
||||
``status()`` will return a structure with information about the status of this
|
||||
torrent. If the ``torrent_handle`` is invalid, it will throw ``invalid_handle`` exception.
|
||||
torrent. If the torrent_handle_ is invalid, it will throw invalid_handle_ exception.
|
||||
It contains the following fields::
|
||||
|
||||
struct torrent_status
|
||||
|
@ -662,7 +677,7 @@ get_peer_info()
|
|||
|
||||
``get_peer_info()`` takes a reference to a vector that will be cleared and filled
|
||||
with one entry for each peer connected to this torrent, given the handle is valid. If the
|
||||
``torrent_handle`` is invalid, it will throw ``invalid_handle`` exception. Each entry in
|
||||
torrent_handle_ is invalid, it will throw ``invalid_handle`` exception. Each entry in
|
||||
the vector contains information about that particular peer. It contains the following
|
||||
fields::
|
||||
|
||||
|
@ -747,8 +762,8 @@ get_torrent_info()
|
|||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Returns a const reference to the ``torrent_info`` object associated with this torrent.
|
||||
This reference is valid as long as the ``torrent_handle`` is valid, no longer. If the
|
||||
``torrent_handle`` is invalid, ``invalid_handle`` exception will be thrown.
|
||||
This reference is valid as long as the torrent_handle_ is valid, no longer. If the
|
||||
torrent_handle_ is invalid, invalid_handle_ exception will be thrown.
|
||||
|
||||
|
||||
is_valid()
|
||||
|
@ -976,7 +991,7 @@ here's a complete list with description.
|
|||
invalid_handle
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This exception is thrown when querying information from a ``torrent_handle`` that hasn't
|
||||
This exception is thrown when querying information from a torrent_handle_ that hasn't
|
||||
been initialized or that has become invalid.
|
||||
|
||||
::
|
||||
|
@ -1162,6 +1177,43 @@ This is a simple client. It doesn't have much output to keep it simple::
|
|||
}
|
||||
|
||||
|
||||
fast resume
|
||||
-----------
|
||||
|
||||
The fast resume mechanism is a way to remember which pieces are downloaded and where they
|
||||
are put between sessions. You can generate fast resume data by calling
|
||||
``torrent_handle::write_resume_data()`` on torrent_handle_. You can then save this data
|
||||
to disk and use it when resuming the torrent. libtorrent will not check the piece hashes
|
||||
then, and rely on the information given in the fast-resume data. The fast-resume data
|
||||
also contains information about which bocks in the unfinished pieces were downloaded, so
|
||||
it will not have to start from scratch on the partially downloaded pieces.
|
||||
|
||||
To use the fast-resume data you simply give it to ``session::add_torrent()``, and it
|
||||
will skip the time consuming checks. It may have to do the checking anyway, if the
|
||||
fast-resume data is corrupt or doesn't fit the storage for that torrent, then it will
|
||||
not trust the fast-resume data and just do the checking.
|
||||
|
||||
file format
|
||||
~~~~~~~~~~~
|
||||
|
||||
The format of the fast-resume data is as follows, given that all
|
||||
4-byte integers are stored as big-endian::
|
||||
|
||||
20 bytes, the info_hash for the torrent
|
||||
4 bytes, the number of allocated slots in the storage
|
||||
for each slot
|
||||
4 bytes, piece index in this slot,
|
||||
-1 means there's no storage for the slot
|
||||
-2 means there's no piece at this slot, it's free
|
||||
4 bytes, the number of blocks per piece.
|
||||
this must be piece_size / 16k or 1 if piece_size is < 16k
|
||||
and can be 128 at max.
|
||||
4 bytes, the number of unfinished pieces
|
||||
for each unfinished piece
|
||||
4 bytes, index of the unfinished piece
|
||||
blocks_per_piece / 32 bytes, the bitmask describing which
|
||||
blocks are finished in this piece.
|
||||
|
||||
Feedback
|
||||
========
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace libtorrent
|
|||
// reads an integer from a byte stream
|
||||
// in big endian byte order and converts
|
||||
// it to native endianess
|
||||
template<class InIt>
|
||||
template <class InIt>
|
||||
unsigned int read_uint(InIt& start)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
@ -90,15 +90,23 @@ namespace libtorrent
|
|||
return val;
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
template <class InIt>
|
||||
inline int read_int(InIt& start)
|
||||
{
|
||||
return static_cast<int>(read_uint(start));
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
inline unsigned char read_uchar(InIt& start)
|
||||
{
|
||||
unsigned char ret = static_cast<unsigned char>(*start);
|
||||
++start;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// reads an integer to a byte stream
|
||||
// and converts it from native endianess
|
||||
template<class OutIt>
|
||||
template <class OutIt>
|
||||
void write_uint(unsigned int val, OutIt& start)
|
||||
{
|
||||
*start = static_cast<unsigned char>((val >> 24) & 0xff); ++start;
|
||||
|
@ -107,10 +115,17 @@ namespace libtorrent
|
|||
*start = static_cast<unsigned char>((val) & 0xff); ++start;
|
||||
}
|
||||
|
||||
template<class OutIt>
|
||||
template <class OutIt>
|
||||
inline void write_int(int val, OutIt& start)
|
||||
{
|
||||
write_uint(reinterpret_cast<unsigned int&>(val), start);
|
||||
write_uint(static_cast<unsigned int>(val), start);
|
||||
}
|
||||
|
||||
template <class OutIt>
|
||||
inline void write_uchar(unsigned char val, OutIt& start)
|
||||
{
|
||||
*start = static_cast<char>(val);
|
||||
++start;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ namespace libtorrent
|
|||
|
||||
detail::session_impl* m_ses;
|
||||
detail::checker_impl* m_chk;
|
||||
sha1_hash m_info_hash; // should be replaced with a torrent*?
|
||||
sha1_hash m_info_hash;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -894,12 +894,16 @@ namespace libtorrent
|
|||
|
||||
const std::vector<char>& data = *rd;
|
||||
|
||||
if (data.size() < 3 * 4) return;
|
||||
if (data.size() < 20 + 3 * 4) return;
|
||||
std::vector<char>::const_iterator ptr = data.begin();
|
||||
|
||||
sha1_hash info_hash;
|
||||
for (int i = 0; i < 20; ++i) info_hash[i] = read_uchar(ptr);
|
||||
if (info.info_hash() != info_hash) return;
|
||||
|
||||
int num_slots = detail::read_int(ptr);
|
||||
if (num_slots < 0) return;
|
||||
if (data.size() < (3 + num_slots) * 4) return;
|
||||
if (data.size() < 20 + (3 + num_slots) * 4) return;
|
||||
|
||||
tmp_pieces.reserve(num_slots);
|
||||
for (int i = 0; i < num_slots; ++i)
|
||||
|
@ -911,12 +915,12 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
int num_blocks_per_piece = read_int(ptr);
|
||||
if (num_blocks_per_piece > 128 || num_blocks_per_piece < 0)
|
||||
if (num_blocks_per_piece > 128 || num_blocks_per_piece < 1)
|
||||
return;
|
||||
|
||||
int num_unfinished = read_int(ptr);
|
||||
if (num_unfinished < 0) return;
|
||||
if (data.size() != (1 + num_slots + 2 + num_unfinished * (num_blocks_per_piece / 32 + 1)) * 4)
|
||||
if (data.size() != 20 + (1 + num_slots + 2 + num_unfinished * (num_blocks_per_piece / 32 + 1)) * 4)
|
||||
return;
|
||||
|
||||
tmp_unfinished.reserve(num_unfinished);
|
||||
|
|
|
@ -186,7 +186,13 @@ namespace libtorrent
|
|||
|
||||
// TODO: write file header
|
||||
// TODO: write modification-dates for all files
|
||||
// TODO: write info hash
|
||||
|
||||
for (sha1_hash::const_iterator i = m_info_hash.begin();
|
||||
i != m_info_hash.end();
|
||||
++i)
|
||||
{
|
||||
detail::write_uchar(*i, out);
|
||||
}
|
||||
|
||||
// number of slots
|
||||
int num_slots = piece_index.size();
|
||||
|
|
Loading…
Reference in New Issue