*** empty log message ***
This commit is contained in:
15
Jamfile
15
Jamfile
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
SOURCES =
|
SOURCES =
|
||||||
entry.cpp
|
entry.cpp
|
||||||
peer_connection.cpp
|
peer_connection.cpp
|
||||||
@@ -16,15 +14,18 @@ SOURCES =
|
|||||||
sha1.c
|
sha1.c
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
lib torrent
|
lib torrent
|
||||||
: src/$(SOURCES)
|
: src/$(SOURCES)
|
||||||
zlib//zlib
|
# <lib>zlib/zlib
|
||||||
$(BOOST_ROOT)/libs/filesystem/build//boost_filesystem
|
# zlib//zlib
|
||||||
$(BOOST_ROOT)/libs/thread/build//boost_thread
|
# <file>boost_filesystem.lib
|
||||||
|
# <file>boost_date_time.lib
|
||||||
|
# <file>boost_thread.dll
|
||||||
: <include>$(BOOST_ROOT)
|
: <include>$(BOOST_ROOT)
|
||||||
<sysinclude>$(BOOST_ROOT)
|
<sysinclude>$(BOOST_ROOT)
|
||||||
<include>./include
|
<include>./include
|
||||||
<include>./
|
<include>./zlib
|
||||||
<threading>multi
|
<threading>multi
|
||||||
<link>static
|
<link>static
|
||||||
: debug release
|
: debug release
|
||||||
@@ -33,7 +34,7 @@ lib torrent
|
|||||||
|
|
||||||
exe client_test
|
exe client_test
|
||||||
: examples/client_test.cpp
|
: examples/client_test.cpp
|
||||||
torrent
|
<lib>torrent
|
||||||
: <include>$(BOOST_ROOT)
|
: <include>$(BOOST_ROOT)
|
||||||
<sysinclude>$(BOOST_ROOT)
|
<sysinclude>$(BOOST_ROOT)
|
||||||
<include>./include
|
<include>./include
|
||||||
|
126
docs/index.html
126
docs/index.html
@@ -43,23 +43,24 @@
|
|||||||
<li><a class="reference" href="#http-settings" id="id21" name="id21">http_settings</a></li>
|
<li><a class="reference" href="#http-settings" id="id21" name="id21">http_settings</a></li>
|
||||||
<li><a class="reference" href="#big-number" id="id22" name="id22">big_number</a></li>
|
<li><a class="reference" href="#big-number" id="id22" name="id22">big_number</a></li>
|
||||||
<li><a class="reference" href="#hasher" id="id23" name="id23">hasher</a></li>
|
<li><a class="reference" href="#hasher" id="id23" name="id23">hasher</a></li>
|
||||||
<li><a class="reference" href="#exceptions" id="id24" name="id24">exceptions</a><ul>
|
<li><a class="reference" href="#fingerprint" id="id24" name="id24">fingerprint</a></li>
|
||||||
<li><a class="reference" href="#invalid-handle" id="id25" name="id25">invalid_handle</a></li>
|
<li><a class="reference" href="#exceptions" id="id25" name="id25">exceptions</a><ul>
|
||||||
<li><a class="reference" href="#duplicate-torrent" id="id26" name="id26">duplicate_torrent</a></li>
|
<li><a class="reference" href="#invalid-handle" id="id26" name="id26">invalid_handle</a></li>
|
||||||
<li><a class="reference" href="#invalid-encoding" id="id27" name="id27">invalid_encoding</a></li>
|
<li><a class="reference" href="#duplicate-torrent" id="id27" name="id27">duplicate_torrent</a></li>
|
||||||
<li><a class="reference" href="#type-error" id="id28" name="id28">type_error</a></li>
|
<li><a class="reference" href="#invalid-encoding" id="id28" name="id28">invalid_encoding</a></li>
|
||||||
<li><a class="reference" href="#invalid-torrent-file" id="id29" name="id29">invalid_torrent_file</a></li>
|
<li><a class="reference" href="#type-error" id="id29" name="id29">type_error</a></li>
|
||||||
|
<li><a class="reference" href="#invalid-torrent-file" id="id30" name="id30">invalid_torrent_file</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference" href="#example-usage" id="id30" name="id30">example usage</a><ul>
|
<li><a class="reference" href="#example-usage" id="id31" name="id31">example usage</a><ul>
|
||||||
<li><a class="reference" href="#dump-torrent" id="id31" name="id31">dump_torrent</a></li>
|
<li><a class="reference" href="#dump-torrent" id="id32" name="id32">dump_torrent</a></li>
|
||||||
<li><a class="reference" href="#simple-client" id="id32" name="id32">simple client</a></li>
|
<li><a class="reference" href="#simple-client" id="id33" name="id33">simple client</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference" href="#feedback" id="id33" name="id33">Feedback</a></li>
|
<li><a class="reference" href="#feedback" id="id34" name="id34">Feedback</a></li>
|
||||||
<li><a class="reference" href="#aknowledgements" id="id34" name="id34">Aknowledgements</a></li>
|
<li><a class="reference" href="#aknowledgements" id="id35" name="id35">Aknowledgements</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="introduction">
|
<div class="section" id="introduction">
|
||||||
@@ -88,9 +89,10 @@ The current state includes the following features:</p>
|
|||||||
<li>queues torrents for file check, instead of checking all of them in parallel.</li>
|
<li>queues torrents for file check, instead of checking all of them in parallel.</li>
|
||||||
<li>uses separate threads for checking files and for main downloader, with a fool-proof
|
<li>uses separate threads for checking files and for main downloader, with a fool-proof
|
||||||
thread-safe library interface. (i.e. There's no way for the user to cause a deadlock).</li>
|
thread-safe library interface. (i.e. There's no way for the user to cause a deadlock).</li>
|
||||||
<li>can limit the upload bandwidth usage</li>
|
<li>can limit the upload bandwidth usage and the maximum number of unchoked peers</li>
|
||||||
<li>piece-wise file allocation</li>
|
<li>piece-wise file allocation</li>
|
||||||
<li>upload rate limit, balanced depending on download speed and upload bandwidth</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>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p>Functions that are yet to be implemented:</p>
|
<p>Functions that are yet to be implemented:</p>
|
||||||
@@ -115,6 +117,12 @@ boost.filesystem boost.date_time and various other boost libraries and zlib.</p>
|
|||||||
<li>Linux x86 (debian) GCC 3.0</li>
|
<li>Linux x86 (debian) GCC 3.0</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
<p>It does not compile on</p>
|
||||||
|
<blockquote>
|
||||||
|
<ul class="simple">
|
||||||
|
<li>GCC 2.95</li>
|
||||||
|
</ul>
|
||||||
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="building">
|
<div class="section" id="building">
|
||||||
<h1><a class="toc-backref" href="#id8" name="building">building</a></h1>
|
<h1><a class="toc-backref" href="#id8" name="building">building</a></h1>
|
||||||
@@ -158,7 +166,8 @@ the <tt class="literal"><span class="pre">session</span></tt>, it contains the m
|
|||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
class session: public boost::noncopyable
|
class session: public boost::noncopyable
|
||||||
{
|
{
|
||||||
session(int listen_port, const std::string& fingerprint = std::string());
|
session(int listen_port, const fingerprint& print);
|
||||||
|
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);
|
||||||
void remove_torrent(const torrent_handle& h);
|
void remove_torrent(const torrent_handle& h);
|
||||||
@@ -179,9 +188,11 @@ 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
|
<p>If the torrent you are trying to add already exists in the session (is either queued
|
||||||
for checking, being checked or downloading) <tt class="literal"><span class="pre">add_torrent()</span></tt> will throw
|
for checking, being checked or downloading) <tt class="literal"><span class="pre">add_torrent()</span></tt> will throw
|
||||||
<tt class="literal"><span class="pre">duplicate_torrent</span></tt> which derives from <tt class="literal"><span class="pre">std::exception</span></tt>.</p>
|
<tt class="literal"><span class="pre">duplicate_torrent</span></tt> which derives from <tt class="literal"><span class="pre">std::exception</span></tt>.</p>
|
||||||
<p><tt class="literal"><span class="pre">fingerprint</span></tt> is a short string that will be used in the peer_id to
|
<p>The difference between the two constructors is that one of them takes a fingerprint
|
||||||
identify the client. If the string is longer than 7 characters it will
|
as argument. If this is ommited, the client will get a default fingerprint stating
|
||||||
be trimmed down to 7 characters. The default is an empty string.</p>
|
the version of libtorrent. The fingerprint is a short string that will be used in
|
||||||
|
the peer-id to identify the client and the client's version. For more details see the
|
||||||
|
fingerprint class.</p>
|
||||||
<p><tt class="literal"><span class="pre">set_upload_rate_limit()</span></tt> set the maximum number of bytes allowed to be
|
<p><tt class="literal"><span class="pre">set_upload_rate_limit()</span></tt> set the maximum number of bytes allowed to be
|
||||||
sent to peers per second. This bandwidth is distributed among all the peers. If
|
sent to peers per second. This bandwidth is distributed among all the peers. If
|
||||||
you don't want to limit upload rate, you can set this to -1 (the default).</p>
|
you don't want to limit upload rate, you can set this to -1 (the default).</p>
|
||||||
@@ -555,6 +566,8 @@ struct peer_info
|
|||||||
int upload_limit;
|
int upload_limit;
|
||||||
int upload_ceiling;
|
int upload_ceiling;
|
||||||
|
|
||||||
|
int load_balancing;
|
||||||
|
|
||||||
int downloading_piece_index;
|
int downloading_piece_index;
|
||||||
int downloading_block_index;
|
int downloading_block_index;
|
||||||
int downloading_progress;
|
int downloading_progress;
|
||||||
@@ -586,6 +599,11 @@ should sum up to the upload limit set by <tt class="literal"><span class="pre">s
|
|||||||
<p><tt class="literal"><span class="pre">upload_ceiling</span></tt> is the current maximum allowed upload rate given the cownload
|
<p><tt class="literal"><span class="pre">upload_ceiling</span></tt> is the current maximum allowed upload rate given the cownload
|
||||||
rate and share ratio. If the global upload rate is inlimited, the <tt class="literal"><span class="pre">upload_limit</span></tt>
|
rate and share ratio. If the global upload rate is inlimited, the <tt class="literal"><span class="pre">upload_limit</span></tt>
|
||||||
for every peer will be the same as their <tt class="literal"><span class="pre">upload_ceiling</span></tt>.</p>
|
for every peer will be the same as their <tt class="literal"><span class="pre">upload_ceiling</span></tt>.</p>
|
||||||
|
<p><tt class="literal"><span class="pre">load_balancing</span></tt> is a measurment of the balancing of free download (that we get)
|
||||||
|
and free upload that we give. Every peer gets a certain amount of free upload, but
|
||||||
|
this member says how much <em>extra</em> free upload this peer has got. If it is a negative
|
||||||
|
number it means that this was a peer from which we have got this amount of free
|
||||||
|
download.</p>
|
||||||
<p>You can know which piece, and which part of that piece, that is currently being
|
<p>You can know which piece, and which part of that piece, that is currently being
|
||||||
downloaded from a specific peer by looking at the next four members.
|
downloaded from a specific peer by looking at the next four members.
|
||||||
<tt class="literal"><span class="pre">downloading_piece_index</span></tt> is the index of the piece that is currently being downloaded.
|
<tt class="literal"><span class="pre">downloading_piece_index</span></tt> is the index of the piece that is currently being downloaded.
|
||||||
@@ -725,12 +743,61 @@ call <tt class="literal"><span class="pre">reset()</span></tt> to reinitialize i
|
|||||||
<p>The sha1-algorithm used was implemented by Steve Reid and released as public domain.
|
<p>The sha1-algorithm used was implemented by Steve Reid and released as public domain.
|
||||||
For more info, see <tt class="literal"><span class="pre">src/sha1.c</span></tt>.</p>
|
For more info, see <tt class="literal"><span class="pre">src/sha1.c</span></tt>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section" id="fingerprint">
|
||||||
|
<h2><a class="toc-backref" href="#id24" name="fingerprint">fingerprint</a></h2>
|
||||||
|
<p>The fingerprint class represents information about a client and its version. It is used
|
||||||
|
to encode this information into the client's peer id.</p>
|
||||||
|
<p>This is the class declaration:</p>
|
||||||
|
<pre class="literal-block">
|
||||||
|
struct fingerprint
|
||||||
|
{
|
||||||
|
fingerprint(const char* id_string, int major, int minor, int revision, int tag);
|
||||||
|
|
||||||
|
std::string to_string() const;
|
||||||
|
|
||||||
|
char id[2];
|
||||||
|
char major_version;
|
||||||
|
char minor_version;
|
||||||
|
char revision_version;
|
||||||
|
char tag_version;
|
||||||
|
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
<p>The constructor takes a <tt class="literal"><span class="pre">const</span> <span class="pre">char*</span></tt> that should point to a string constant containing
|
||||||
|
exactly two characters. These are the characters that should be unique for your client. Make
|
||||||
|
sure not to clash with anybody else. Here are some taken id's:</p>
|
||||||
|
<table border class="table">
|
||||||
|
<colgroup>
|
||||||
|
<col width="30%" />
|
||||||
|
<col width="70%" />
|
||||||
|
</colgroup>
|
||||||
|
<thead valign="bottom">
|
||||||
|
<tr><th>id chars</th>
|
||||||
|
<th>client</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody valign="top">
|
||||||
|
<tr><td>'AZ'</td>
|
||||||
|
<td>Azureus</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td>'LT'</td>
|
||||||
|
<td>libtorrent (default)</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td>'BX'</td>
|
||||||
|
<td>BittorrentX</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>The <tt class="literal"><span class="pre">major</span></tt>, <tt class="literal"><span class="pre">minor</span></tt>, <tt class="literal"><span class="pre">revision</span></tt> and <tt class="literal"><span class="pre">tag</span></tt> parameters are used to identify the
|
||||||
|
version of your client. All these numbers must be within the range [0, 9].</p>
|
||||||
|
<p><tt class="literal"><span class="pre">to_string()</span></tt> will generate the actual string put in the peer-id, and return it.</p>
|
||||||
|
</div>
|
||||||
<div class="section" id="exceptions">
|
<div class="section" id="exceptions">
|
||||||
<h2><a class="toc-backref" href="#id24" name="exceptions">exceptions</a></h2>
|
<h2><a class="toc-backref" href="#id25" name="exceptions">exceptions</a></h2>
|
||||||
<p>There are a number of exceptions that can be thrown from different places in libtorrent,
|
<p>There are a number of exceptions that can be thrown from different places in libtorrent,
|
||||||
here's a complete list with description.</p>
|
here's a complete list with description.</p>
|
||||||
<div class="section" id="invalid-handle">
|
<div class="section" id="invalid-handle">
|
||||||
<h3><a class="toc-backref" href="#id25" name="invalid-handle">invalid_handle</a></h3>
|
<h3><a class="toc-backref" href="#id26" 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 <tt class="literal"><span class="pre">torrent_handle</span></tt> that hasn't
|
||||||
been initialized or that has become invalid.</p>
|
been initialized or that has become invalid.</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
@@ -741,7 +808,7 @@ struct invalid_handle: std::exception
|
|||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="duplicate-torrent">
|
<div class="section" id="duplicate-torrent">
|
||||||
<h3><a class="toc-backref" href="#id26" name="duplicate-torrent">duplicate_torrent</a></h3>
|
<h3><a class="toc-backref" href="#id27" name="duplicate-torrent">duplicate_torrent</a></h3>
|
||||||
<p>This is thrown by <tt class="literal"><span class="pre">session::add_torrent()</span></tt> if the torrent already has been added to
|
<p>This is thrown by <tt class="literal"><span class="pre">session::add_torrent()</span></tt> if the torrent already has been added to
|
||||||
the session.</p>
|
the session.</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
@@ -752,7 +819,7 @@ struct duplicate_torrent: std::exception
|
|||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="invalid-encoding">
|
<div class="section" id="invalid-encoding">
|
||||||
<h3><a class="toc-backref" href="#id27" name="invalid-encoding">invalid_encoding</a></h3>
|
<h3><a class="toc-backref" href="#id28" name="invalid-encoding">invalid_encoding</a></h3>
|
||||||
<p>This is thrown by <tt class="literal"><span class="pre">bdecode()</span></tt> if the input data is not a valid bencoding.</p>
|
<p>This is thrown by <tt class="literal"><span class="pre">bdecode()</span></tt> if the input data is not a valid bencoding.</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
struct invalid_encoding: std::exception
|
struct invalid_encoding: std::exception
|
||||||
@@ -762,7 +829,7 @@ struct invalid_encoding: std::exception
|
|||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="type-error">
|
<div class="section" id="type-error">
|
||||||
<h3><a class="toc-backref" href="#id28" name="type-error">type_error</a></h3>
|
<h3><a class="toc-backref" href="#id29" name="type-error">type_error</a></h3>
|
||||||
<p>This is thrown from the accessors of <tt class="literal"><span class="pre">entry</span></tt> if the data type of the <tt class="literal"><span class="pre">entry</span></tt> doesn't
|
<p>This is thrown from the accessors of <tt class="literal"><span class="pre">entry</span></tt> if the data type of the <tt class="literal"><span class="pre">entry</span></tt> doesn't
|
||||||
match the type you want to extract from it.</p>
|
match the type you want to extract from it.</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
@@ -773,7 +840,7 @@ struct type_error: std::runtime_error
|
|||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="invalid-torrent-file">
|
<div class="section" id="invalid-torrent-file">
|
||||||
<h3><a class="toc-backref" href="#id29" name="invalid-torrent-file">invalid_torrent_file</a></h3>
|
<h3><a class="toc-backref" href="#id30" name="invalid-torrent-file">invalid_torrent_file</a></h3>
|
||||||
<p>This exception is thrown from the constructor of <tt class="literal"><span class="pre">torrent_info</span></tt> if the given bencoded information
|
<p>This exception is thrown from the constructor of <tt class="literal"><span class="pre">torrent_info</span></tt> if the given bencoded information
|
||||||
doesn't meet the requirements on what information has to be present in a torrent file.</p>
|
doesn't meet the requirements on what information has to be present in a torrent file.</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
@@ -785,9 +852,9 @@ struct invalid_torrent_file: std::exception
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="example-usage">
|
<div class="section" id="example-usage">
|
||||||
<h2><a class="toc-backref" href="#id30" name="example-usage">example usage</a></h2>
|
<h2><a class="toc-backref" href="#id31" name="example-usage">example usage</a></h2>
|
||||||
<div class="section" id="dump-torrent">
|
<div class="section" id="dump-torrent">
|
||||||
<h3><a class="toc-backref" href="#id31" name="dump-torrent">dump_torrent</a></h3>
|
<h3><a class="toc-backref" href="#id32" name="dump-torrent">dump_torrent</a></h3>
|
||||||
<p>This is an example of a program that will take a torrent-file as a parameter and
|
<p>This is an example of a program that will take a torrent-file as a parameter and
|
||||||
print information about it to std out:</p>
|
print information about it to std out:</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
@@ -851,7 +918,7 @@ int main(int argc, char* argv[])
|
|||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="simple-client">
|
<div class="section" id="simple-client">
|
||||||
<h3><a class="toc-backref" href="#id32" name="simple-client">simple client</a></h3>
|
<h3><a class="toc-backref" href="#id33" name="simple-client">simple client</a></h3>
|
||||||
<p>This is a simple client. It doesn't have much output to keep it simple:</p>
|
<p>This is a simple client. It doesn't have much output to keep it simple:</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -880,7 +947,7 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
session s(6881, "E\x1");
|
session s(6881);
|
||||||
|
|
||||||
std::ifstream in(argv[1], std::ios_base::binary);
|
std::ifstream in(argv[1], std::ios_base::binary);
|
||||||
in.unsetf(std::ios_base::skipws);
|
in.unsetf(std::ios_base::skipws);
|
||||||
@@ -904,14 +971,15 @@ int main(int argc, char* argv[])
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="feedback">
|
<div class="section" id="feedback">
|
||||||
<h1><a class="toc-backref" href="#id33" name="feedback">Feedback</a></h1>
|
<h1><a class="toc-backref" href="#id34" 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>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>
|
<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>
|
||||||
<div class="section" id="aknowledgements">
|
<div class="section" id="aknowledgements">
|
||||||
<h1><a class="toc-backref" href="#id34" name="aknowledgements">Aknowledgements</a></h1>
|
<h1><a class="toc-backref" href="#id35" name="aknowledgements">Aknowledgements</a></h1>
|
||||||
<p>Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003</p>
|
<p>Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003</p>
|
||||||
<p>Contributions by Magnus Jonsson</p>
|
<p>Contributions by Magnus Jonsson</p>
|
||||||
|
<p>Thanks to Reimond Retz for bugfixes, suggestions and testing</p>
|
||||||
<p>Project is hosted by sourceforge.</p>
|
<p>Project is hosted by sourceforge.</p>
|
||||||
<p><a class="reference" href="http://sourceforge.net"><img alt="sf_logo" src="http://sourceforge.net/sflogo.php?group_id=7994" /></a></p>
|
<p><a class="reference" href="http://sourceforge.net"><img alt="sf_logo" src="http://sourceforge.net/sflogo.php?group_id=7994" /></a></p>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -832,6 +832,8 @@ sure not to clash with anybody else. Here are some taken id's:
|
|||||||
+----------+-----------------------+
|
+----------+-----------------------+
|
||||||
| 'LT' | libtorrent (default) |
|
| 'LT' | libtorrent (default) |
|
||||||
+----------+-----------------------+
|
+----------+-----------------------+
|
||||||
|
| 'BX' | BittorrentX |
|
||||||
|
+----------+-----------------------+
|
||||||
|
|
||||||
The ``major``, ``minor``, ``revision`` and ``tag`` parameters are used to identify the
|
The ``major``, ``minor``, ``revision`` and ``tag`` parameters are used to identify the
|
||||||
version of your client. All these numbers must be within the range [0, 9].
|
version of your client. All these numbers must be within the range [0, 9].
|
||||||
|
@@ -302,8 +302,13 @@ int main(int argc, char* argv[])
|
|||||||
if (progress > j) out << "#";
|
if (progress > j) out << "#";
|
||||||
else out << "-";
|
else out << "-";
|
||||||
}
|
}
|
||||||
out << "\n";
|
out << " ";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 19; ++i) out << " ";
|
||||||
|
}
|
||||||
|
out << identify_client(i->id) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "___________________________________\n";
|
out << "___________________________________\n";
|
||||||
|
@@ -65,6 +65,12 @@ namespace libtorrent
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char& operator[](int i)
|
||||||
|
{ assert(i >= 0 && i < number_size); return m_number[i]; }
|
||||||
|
|
||||||
|
unsigned char operator[](int i) const
|
||||||
|
{ assert(i >= 0 && i < number_size); return m_number[i]; }
|
||||||
|
|
||||||
typedef const unsigned char* const_iterator;
|
typedef const unsigned char* const_iterator;
|
||||||
typedef unsigned char* iterator;
|
typedef unsigned char* iterator;
|
||||||
|
|
||||||
|
@@ -182,7 +182,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
struct http_settings;
|
struct http_settings;
|
||||||
|
|
||||||
std::string extract_fingerprint(const peer_id& p);
|
std::string identify_client(const peer_id& p);
|
||||||
|
|
||||||
class session: public boost::noncopyable, detail::eh_initializer
|
class session: public boost::noncopyable, detail::eh_initializer
|
||||||
{
|
{
|
||||||
|
@@ -84,6 +84,9 @@ namespace libtorrent
|
|||||||
|
|
||||||
// the number of bytes of the file we have
|
// the number of bytes of the file we have
|
||||||
std::size_t total_done;
|
std::size_t total_done;
|
||||||
|
|
||||||
|
// TODO: add flag that says if there have
|
||||||
|
// been any incoming connections
|
||||||
};
|
};
|
||||||
|
|
||||||
struct partial_piece_info
|
struct partial_piece_info
|
||||||
|
@@ -485,6 +485,7 @@ namespace libtorrent
|
|||||||
// this means we're already connected
|
// this means we're already connected
|
||||||
// to this peer. don't connect to
|
// to this peer. don't connect to
|
||||||
// it again.
|
// it again.
|
||||||
|
assert(i->connection->associated_torrent() == m_torrent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
231
src/session.cpp
231
src/session.cpp
@@ -62,6 +62,8 @@ namespace std
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: enable floating point exceptions in debug mode!
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -486,6 +488,10 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
// (*m_logger) << "readable: " << p->first->sender().as_string() << "\n";
|
// (*m_logger) << "readable: " << p->first->sender().as_string() << "\n";
|
||||||
p->second->receive_data();
|
p->second->receive_data();
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
assert_invariant();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch(std::exception& e)
|
catch(std::exception& e)
|
||||||
{
|
{
|
||||||
@@ -684,7 +690,19 @@ namespace libtorrent
|
|||||||
i != m_connections.end();
|
i != m_connections.end();
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
assert(i->second->has_data() == m_selector.is_writability_monitored(i->first));
|
if (i->second->has_data() != m_selector.is_writability_monitored(i->first))
|
||||||
|
{
|
||||||
|
std::ofstream error_log("error.log", std::ios_base::app);
|
||||||
|
boost::shared_ptr<peer_connection> p = i->second;
|
||||||
|
error_log << "session_imple::assert_invariant()\n"
|
||||||
|
"peer_connection::has_data() != is_writability_monitored()\n";
|
||||||
|
error_log << "peer_connection::has_data() " << p->has_data() << "\n";
|
||||||
|
error_log << "peer_connection::send_quota_left " << p->send_quota_left() << "\n";
|
||||||
|
error_log << "peer_connection::send_quota " << p->send_quota() << "\n";
|
||||||
|
error_log << "peer_connection::get_peer_id " << p->get_peer_id() << "\n";
|
||||||
|
error_log.flush();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
if (i->second->associated_torrent())
|
if (i->second->associated_torrent())
|
||||||
{
|
{
|
||||||
assert(i->second->associated_torrent()
|
assert(i->second->associated_torrent()
|
||||||
@@ -849,25 +867,200 @@ namespace libtorrent
|
|||||||
return m_impl.m_alerts.get();
|
return m_impl.m_alerts.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: document
|
namespace
|
||||||
// TODO: if the first 4 charachters are printable
|
|
||||||
// maybe they should be considered a fingerprint?
|
|
||||||
std::string extract_fingerprint(const peer_id& p)
|
|
||||||
{
|
{
|
||||||
std::string ret;
|
|
||||||
const unsigned char* c = p.begin();
|
|
||||||
while (c != p.end() && *c != 0)
|
|
||||||
{
|
|
||||||
if (std::isprint(*c))
|
|
||||||
ret += *c;
|
|
||||||
else if (*c <= 9)
|
|
||||||
ret += '0'+ *c;
|
|
||||||
else
|
|
||||||
return std::string();
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
if (c == p.end()) return std::string();
|
|
||||||
|
|
||||||
return ret;
|
// takes a peer id and returns a valid boost::optional
|
||||||
|
// object if the peer id matched the azureus style encoding
|
||||||
|
// the returned fingerprint contains information about the
|
||||||
|
// client's id
|
||||||
|
boost::optional<fingerprint> parse_az_style(const peer_id& id)
|
||||||
|
{
|
||||||
|
fingerprint ret("..", 0, 0, 0, 0);
|
||||||
|
peer_id::const_iterator i = id.begin();
|
||||||
|
|
||||||
|
if (*i != '-') return boost::optional<fingerprint>();
|
||||||
|
++i;
|
||||||
|
|
||||||
|
for (int j = 0; j < 2; ++j)
|
||||||
|
{
|
||||||
|
if (!std::isprint(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.id[j] = *i;
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!std::isdigit(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.major_version = *i - '0';
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (!std::isdigit(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.minor_version = *i - '0';
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (!std::isdigit(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.revision_version = *i - '0';
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (!std::isdigit(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.tag_version = *i - '0';
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (*i != '-') return boost::optional<fingerprint>();
|
||||||
|
|
||||||
|
return boost::optional<fingerprint>(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if a peer id can possibly contain a shadow-style
|
||||||
|
// identification
|
||||||
|
boost::optional<fingerprint> parse_shadow_style(const peer_id& id)
|
||||||
|
{
|
||||||
|
fingerprint ret("..", 0, 0, 0, 0);
|
||||||
|
peer_id::const_iterator i = id.begin();
|
||||||
|
|
||||||
|
if (!std::isprint(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.id[0] = *i;
|
||||||
|
ret.id[1] = 0;
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (id[8] == 45)
|
||||||
|
{
|
||||||
|
if (!std::isdigit(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.major_version = *i - '0';
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (!std::isdigit(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.minor_version = *i - '0';
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (!std::isdigit(*i)) return boost::optional<fingerprint>();
|
||||||
|
ret.revision_version = *i - '0';
|
||||||
|
}
|
||||||
|
else if (id[0] == 0)
|
||||||
|
{
|
||||||
|
if (*i > 127) return boost::optional<fingerprint>();
|
||||||
|
ret.major_version = *i;
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (*i > 127) return boost::optional<fingerprint>();
|
||||||
|
ret.minor_version = *i;
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (*i > 127) return boost::optional<fingerprint>();
|
||||||
|
ret.revision_version = *i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return boost::optional<fingerprint>();
|
||||||
|
|
||||||
|
|
||||||
|
ret.tag_version = 0;
|
||||||
|
return boost::optional<fingerprint>(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace unnamed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: document
|
||||||
|
std::string identify_client(const peer_id& p)
|
||||||
|
{
|
||||||
|
peer_id::const_iterator PID = p.begin();
|
||||||
|
boost::optional<fingerprint> f;
|
||||||
|
|
||||||
|
|
||||||
|
// look for azureus style id
|
||||||
|
f = parse_az_style(p);
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
std::stringstream identity;
|
||||||
|
|
||||||
|
// azureus
|
||||||
|
if (std::equal(f->id, f->id+2, "AZ"))
|
||||||
|
identity << "Azureus ";
|
||||||
|
|
||||||
|
// BittorrentX
|
||||||
|
else if (std::equal(f->id, f->id+2, "BX"))
|
||||||
|
identity << "BittorrentX ";
|
||||||
|
|
||||||
|
// libtorrent
|
||||||
|
else if (std::equal(f->id, f->id+2, "LT"))
|
||||||
|
identity << "libtorrent ";
|
||||||
|
|
||||||
|
// unknown client
|
||||||
|
else
|
||||||
|
identity << std::string(f->id, f->id+2) << " ";
|
||||||
|
|
||||||
|
identity << (int)f->major_version
|
||||||
|
<< "." << (int)f->minor_version
|
||||||
|
<< "." << (int)f->revision_version
|
||||||
|
<< "." << (int)f->tag_version;
|
||||||
|
|
||||||
|
return identity.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// look for shadow style id
|
||||||
|
f = parse_shadow_style(p);
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
std::stringstream identity;
|
||||||
|
|
||||||
|
// Shadow
|
||||||
|
if (std::equal(f->id, f->id+1, "S"))
|
||||||
|
identity << "Shadow ";
|
||||||
|
|
||||||
|
// UPnP
|
||||||
|
else if (std::equal(f->id, f->id+1, "U"))
|
||||||
|
identity << "UPnP ";
|
||||||
|
|
||||||
|
// unknown client
|
||||||
|
else
|
||||||
|
identity << std::string(f->id, f->id+1) << " ";
|
||||||
|
|
||||||
|
identity << (int)f->major_version
|
||||||
|
<< "." << (int)f->minor_version
|
||||||
|
<< "." << (int)f->revision_version;
|
||||||
|
|
||||||
|
return identity.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// non standard encodings
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
|
||||||
|
if (std::equal(PID + 5, PID + 5 + 8, "Azureus"))
|
||||||
|
{
|
||||||
|
return "Azureus 2.0.3.2";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (std::equal(PID, PID + 11, "DansClient"))
|
||||||
|
{
|
||||||
|
return "XanTorrent";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::equal(PID, PID + 7, "btfans"))
|
||||||
|
{
|
||||||
|
return "BitComet";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::equal(PID, PID + 8, "turbobt"))
|
||||||
|
{
|
||||||
|
return "TurboBT";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\x97"))
|
||||||
|
{
|
||||||
|
return "Experimental 3.2.1b2";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0"))
|
||||||
|
{
|
||||||
|
return "Experimental 3.1";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Generic";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -466,6 +466,8 @@ namespace libtorrent {
|
|||||||
m_pimpl->write(buf, piece_index, offset, size);
|
m_pimpl->write(buf, piece_index, offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: must handle the case where some hashes are identical
|
||||||
|
// correctly
|
||||||
void piece_manager::impl::check_pieces(
|
void piece_manager::impl::check_pieces(
|
||||||
boost::mutex& mutex
|
boost::mutex& mutex
|
||||||
, detail::piece_checker_data& data
|
, detail::piece_checker_data& data
|
||||||
@@ -612,6 +614,8 @@ namespace libtorrent {
|
|||||||
|
|
||||||
int found_piece = -1;
|
int found_piece = -1;
|
||||||
|
|
||||||
|
// TODO: there's still potential problems if some
|
||||||
|
// pieces have the same hash
|
||||||
for (int i = current_slot; i < m_info.num_pieces(); ++i)
|
for (int i = current_slot; i < m_info.num_pieces(); ++i)
|
||||||
{
|
{
|
||||||
if (pieces[i] && i != current_slot) continue;
|
if (pieces[i] && i != current_slot) continue;
|
||||||
@@ -620,7 +624,10 @@ namespace libtorrent {
|
|||||||
i == m_info.num_pieces() - 1]->get();
|
i == m_info.num_pieces() - 1]->get();
|
||||||
|
|
||||||
if (hash == m_info.hash_for_piece(i))
|
if (hash == m_info.hash_for_piece(i))
|
||||||
|
{
|
||||||
found_piece = i;
|
found_piece = i;
|
||||||
|
if (i == current_slot) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_piece != -1)
|
if (found_piece != -1)
|
||||||
|
@@ -73,8 +73,22 @@ namespace
|
|||||||
|
|
||||||
int calculate_block_size(const torrent_info& i)
|
int calculate_block_size(const torrent_info& i)
|
||||||
{
|
{
|
||||||
// TODO: if blocks_per_piece > 128 increase block-size
|
const int default_block_size = 16 * 1024;
|
||||||
return 16*1024;
|
|
||||||
|
// if pieces are too small, adjust the block size
|
||||||
|
if (i.piece_length() < default_block_size)
|
||||||
|
{
|
||||||
|
return i.piece_length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if pieces are too large, adjust the block size
|
||||||
|
if (i.piece_length() / default_block_size > 128)
|
||||||
|
{
|
||||||
|
return i.piece_length() / 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, go with the default
|
||||||
|
return default_block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -199,7 +213,7 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
std::cout << " " << std::setfill(' ') << std::setw(16) << i->ip
|
std::cout << " " << std::setfill(' ') << std::setw(16) << i->ip
|
||||||
<< " " << std::setw(5) << std::dec << i->port << " "
|
<< " " << std::setw(5) << std::dec << i->port << " "
|
||||||
<< i->id << " " << extract_fingerprint(i->id) << "\n";
|
<< i->id << " " << identify_client(i->id) << "\n";
|
||||||
}
|
}
|
||||||
std::cout << std::setfill(' ');
|
std::cout << std::setfill(' ');
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user