forked from premiere/premiere-libtorrent
*** empty log message ***
This commit is contained in:
parent
5ac9f67f23
commit
c432c9ad68
1
Jamfile
1
Jamfile
|
@ -1,5 +1,6 @@
|
|||
SOURCES =
|
||||
entry.cpp
|
||||
identify_client.cpp
|
||||
peer_connection.cpp
|
||||
piece_picker.cpp
|
||||
policy.cpp
|
||||
|
|
176
docs/index.html
176
docs/index.html
|
@ -44,23 +44,24 @@
|
|||
<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="#fingerprint" id="id24" name="id24">fingerprint</a></li>
|
||||
<li><a class="reference" href="#exceptions" id="id25" name="id25">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id26" name="id26">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id27" name="id27">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id28" name="id28">invalid_encoding</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>
|
||||
<li><a class="reference" href="#alert" id="id25" name="id25">alert</a></li>
|
||||
<li><a class="reference" href="#exceptions" id="id26" name="id26">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id27" name="id27">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id28" name="id28">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id29" name="id29">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id30" name="id30">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id31" name="id31">invalid_torrent_file</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#example-usage" id="id31" name="id31">example usage</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id32" name="id32">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id33" name="id33">simple client</a></li>
|
||||
<li><a class="reference" href="#example-usage" id="id32" name="id32">example usage</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id33" name="id33">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id34" name="id34">simple client</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#feedback" id="id34" name="id34">Feedback</a></li>
|
||||
<li><a class="reference" href="#aknowledgements" id="id35" name="id35">Aknowledgements</a></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>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
|
@ -98,8 +99,7 @@ download to peers as free upload. To maintain a global 1:1 ratio.</li>
|
|||
<p>Functions that are yet to be implemented:</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>more generous optimistic unchoke</li>
|
||||
<li>better choke/unchoke algorithm</li>
|
||||
<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>
|
||||
|
@ -174,6 +174,10 @@ class session: public boost::noncopyable
|
|||
|
||||
void set_http_settings(const http_settings& settings);
|
||||
void set_upload_rate_limit(int bytes_per_second);
|
||||
|
||||
std::auto_ptr<alert> pop_alert();
|
||||
void set_severity_level(alert::severity_t s);
|
||||
|
||||
};
|
||||
</pre>
|
||||
<p>Once it's created, it will spawn the main thread that will do all the work.
|
||||
|
@ -208,6 +212,89 @@ about the torrent's progress, its peers etc. It is also used to abort a torrent.
|
|||
increase the port number by one and try again. If it still fails it will continue
|
||||
increasing the port number until it succeeds or has failed 9 ports. <em>This will
|
||||
change in the future to give more control of the listen-port.</em></p>
|
||||
<p>The <tt class="literal"><span class="pre">pop_alert()</span></tt> function is the interface for retrieving alerts, warnings and
|
||||
errors from libtorrent. If there hasn't occured any errors (matching your severity
|
||||
level) <tt class="literal"><span class="pre">pop_alert()</span></tt> will return a zero pointer. If there has been some error, it will
|
||||
return a pointer to an alert object describing it. You can then use the query the
|
||||
<a class="reference" href="#alert">alert</a> object for information about the error or message. To retrieve any alerts, you
|
||||
have to select a severity level using <tt class="literal"><span class="pre">set_severity_level()</span></tt>. It defaults to
|
||||
<tt class="literal"><span class="pre">alert::none</span></tt>, which means that you don't get any messages at all, ever. You have
|
||||
the following levels to select among:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="19%" />
|
||||
<col width="81%" />
|
||||
</colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">none</span></tt></td>
|
||||
<td>No alert will ever have this severity level, which
|
||||
effectively filters all messages.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">fatal</span></tt></td>
|
||||
<td>Fatal errors will have this severity level. Examples can
|
||||
be disk full or something else that will make it
|
||||
impossible to continue normal execution.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">critical</span></tt></td>
|
||||
<td>Signals errors that requires user interaction.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">warning</span></tt></td>
|
||||
<td>Messages with the warning severity can be a tracker that
|
||||
times out or responds with invalid data. It will be
|
||||
retried automatically, and the possible next tracker in
|
||||
a multitracker sequence will be tried. It does not
|
||||
require any user interaction.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">info</span></tt></td>
|
||||
<td>Events that can be considered normal, but still deserves
|
||||
an event. This could be a piece hash that fails.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">debug</span></tt></td>
|
||||
<td>This will include alot of debug events that can be used
|
||||
both for debugging libtorrent but also when debugging
|
||||
other clients that are connected to libtorrent. It will
|
||||
report strange behaviors among the connected peers.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>When setting a severity level, you will receive messages of that severity and all
|
||||
messages that are more sever. If you set <tt class="literal"><span class="pre">alert::none</span></tt> (the default) you will not recieve
|
||||
any events at all.</p>
|
||||
<p>When you get an alert, you can use <tt class="literal"><span class="pre">typeid()</span></tt> or <tt class="literal"><span class="pre">dynamic_cast<></span></tt> to get more detailed
|
||||
information on exactly which type it is. i.e. what kind of error it is. You can also use a
|
||||
dispatcher mechanism that's available in libtorrent.</p>
|
||||
<p>TODO: describe the type dispatching mechanism</p>
|
||||
<p>The currently available alert types are:</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>tracker_alert</li>
|
||||
<li>hash_failed_alert</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>You can try a <tt class="literal"><span class="pre">dynamic_cast</span></tt> to these types to get more message-pecific information. Here
|
||||
are their definitions:</p>
|
||||
<pre class="literal-block">
|
||||
struct tracker_alert: alert
|
||||
{
|
||||
tracker_alert(const torrent_handle& h, const std::string& msg);
|
||||
virtual std::auto_ptr<alert> clone() const;
|
||||
|
||||
torrent_handle handle;
|
||||
};
|
||||
|
||||
struct hash_failed_alert: alert
|
||||
{
|
||||
hash_failed_alert(
|
||||
const torrent_handle& h
|
||||
, int index
|
||||
, const std::string& msg);
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const;
|
||||
|
||||
torrent_handle handle;
|
||||
int piece_index;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="parsing-torrent-files">
|
||||
<h2><a class="toc-backref" href="#id11" name="parsing-torrent-files">parsing torrent files</a></h2>
|
||||
|
@ -451,6 +538,7 @@ struct torrent_status
|
|||
invalid_handle,
|
||||
queued_for_checking,
|
||||
checking_files,
|
||||
connecting_to_tracker,
|
||||
downloading,
|
||||
seeding
|
||||
};
|
||||
|
@ -458,10 +546,16 @@ struct torrent_status
|
|||
state_t state;
|
||||
float progress;
|
||||
boost::posix_time::time_duration next_announce;
|
||||
|
||||
std::size_t total_download;
|
||||
std::size_t total_upload;
|
||||
|
||||
std::size_t total_payload_download;
|
||||
std::size_t total_payload_upload;
|
||||
|
||||
float download_rate;
|
||||
float upload_rate;
|
||||
|
||||
std::vector<bool> pieces;
|
||||
std::size_t total_done;
|
||||
};
|
||||
|
@ -471,8 +565,8 @@ torrent's current task. It may be checking files or downloading. The torrent's
|
|||
current task is in the <tt class="literal"><span class="pre">state</span></tt> member, it will be one of the following:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="28%" />
|
||||
<col width="72%" />
|
||||
<col width="31%" />
|
||||
<col width="69%" />
|
||||
</colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">queued_for_checking</span></tt></td>
|
||||
|
@ -484,6 +578,10 @@ This torrent will wait for its turn.</td>
|
|||
<td>The torrent has not started its download yet, and is
|
||||
currently checking existing files.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">connecting_to_tracker</span></tt></td>
|
||||
<td>The torrent has sent a request to the tracker and is
|
||||
currently waiting for a response</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">downloading</span></tt></td>
|
||||
<td>The torrent is being downloaded. This is the state
|
||||
most torrents will be in most of the time. The progress
|
||||
|
@ -499,6 +597,9 @@ is a pure seeder.</td>
|
|||
<p><tt class="literal"><span class="pre">next_announce</span></tt> is the time until the torrent will announce itself to the tracker.</p>
|
||||
<p><tt class="literal"><span class="pre">total_download</span></tt> and <tt class="literal"><span class="pre">total_upload</span></tt> is the number of bytes downloaded and
|
||||
uploaded to all peers, accumulated, <em>this session</em> only.</p>
|
||||
<p><tt class="literal"><span class="pre">total_payload_download</span></tt> and <tt class="literal"><span class="pre">total_payload_upload</span></tt> counts the amount of bytes
|
||||
send and received this session, but only the actual oayload data (i.e the interesting
|
||||
data), these counters ignore any protocol overhead.</p>
|
||||
<p><tt class="literal"><span class="pre">pieces</span></tt> is the bitmask that representw which pieces we have (set to true) and
|
||||
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
|
||||
|
@ -792,12 +893,35 @@ sure not to clash with anybody else. Here are some taken id's:</p>
|
|||
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="alert">
|
||||
<h2><a class="toc-backref" href="#id25" name="alert">alert</a></h2>
|
||||
<p>The <tt class="literal"><span class="pre">alert</span></tt> class is used to pass messages of events from the libtorrent code
|
||||
to the user. It is a base class that specific messages are derived from. This
|
||||
is its synopsis:</p>
|
||||
<pre class="literal-block">
|
||||
class alert
|
||||
{
|
||||
public:
|
||||
|
||||
enum severity_t { debug, info, warning, critital, fatal, none };
|
||||
|
||||
alert(severity_t severity, const std::string& msg);
|
||||
|
||||
virtual ~alert() {}
|
||||
|
||||
const std::string& msg() const;
|
||||
severity_t severity() const;
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const = 0;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="exceptions">
|
||||
<h2><a class="toc-backref" href="#id25" name="exceptions">exceptions</a></h2>
|
||||
<h2><a class="toc-backref" href="#id26" name="exceptions">exceptions</a></h2>
|
||||
<p>There are a number of exceptions that can be thrown from different places in libtorrent,
|
||||
here's a complete list with description.</p>
|
||||
<div class="section" id="invalid-handle">
|
||||
<h3><a class="toc-backref" href="#id26" name="invalid-handle">invalid_handle</a></h3>
|
||||
<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
|
||||
been initialized or that has become invalid.</p>
|
||||
<pre class="literal-block">
|
||||
|
@ -808,7 +932,7 @@ struct invalid_handle: std::exception
|
|||
</pre>
|
||||
</div>
|
||||
<div class="section" id="duplicate-torrent">
|
||||
<h3><a class="toc-backref" href="#id27" name="duplicate-torrent">duplicate_torrent</a></h3>
|
||||
<h3><a class="toc-backref" href="#id28" 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
|
||||
the session.</p>
|
||||
<pre class="literal-block">
|
||||
|
@ -819,7 +943,7 @@ struct duplicate_torrent: std::exception
|
|||
</pre>
|
||||
</div>
|
||||
<div class="section" id="invalid-encoding">
|
||||
<h3><a class="toc-backref" href="#id28" name="invalid-encoding">invalid_encoding</a></h3>
|
||||
<h3><a class="toc-backref" href="#id29" 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>
|
||||
<pre class="literal-block">
|
||||
struct invalid_encoding: std::exception
|
||||
|
@ -829,7 +953,7 @@ struct invalid_encoding: std::exception
|
|||
</pre>
|
||||
</div>
|
||||
<div class="section" id="type-error">
|
||||
<h3><a class="toc-backref" href="#id29" name="type-error">type_error</a></h3>
|
||||
<h3><a class="toc-backref" href="#id30" 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
|
||||
match the type you want to extract from it.</p>
|
||||
<pre class="literal-block">
|
||||
|
@ -840,7 +964,7 @@ struct type_error: std::runtime_error
|
|||
</pre>
|
||||
</div>
|
||||
<div class="section" id="invalid-torrent-file">
|
||||
<h3><a class="toc-backref" href="#id30" name="invalid-torrent-file">invalid_torrent_file</a></h3>
|
||||
<h3><a class="toc-backref" href="#id31" 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
|
||||
doesn't meet the requirements on what information has to be present in a torrent file.</p>
|
||||
<pre class="literal-block">
|
||||
|
@ -852,9 +976,9 @@ struct invalid_torrent_file: std::exception
|
|||
</div>
|
||||
</div>
|
||||
<div class="section" id="example-usage">
|
||||
<h2><a class="toc-backref" href="#id31" name="example-usage">example usage</a></h2>
|
||||
<h2><a class="toc-backref" href="#id32" name="example-usage">example usage</a></h2>
|
||||
<div class="section" id="dump-torrent">
|
||||
<h3><a class="toc-backref" href="#id32" name="dump-torrent">dump_torrent</a></h3>
|
||||
<h3><a class="toc-backref" href="#id33" 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
|
||||
print information about it to std out:</p>
|
||||
<pre class="literal-block">
|
||||
|
@ -918,7 +1042,7 @@ int main(int argc, char* argv[])
|
|||
</pre>
|
||||
</div>
|
||||
<div class="section" id="simple-client">
|
||||
<h3><a class="toc-backref" href="#id33" name="simple-client">simple client</a></h3>
|
||||
<h3><a class="toc-backref" href="#id34" name="simple-client">simple client</a></h3>
|
||||
<p>This is a simple client. It doesn't have much output to keep it simple:</p>
|
||||
<pre class="literal-block">
|
||||
#include <iostream>
|
||||
|
@ -971,12 +1095,12 @@ int main(int argc, char* argv[])
|
|||
</div>
|
||||
</div>
|
||||
<div class="section" id="feedback">
|
||||
<h1><a class="toc-backref" href="#id34" name="feedback">Feedback</a></h1>
|
||||
<h1><a class="toc-backref" href="#id35" 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="#id35" name="aknowledgements">Aknowledgements</a></h1>
|
||||
<h1><a class="toc-backref" href="#id36" 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>
|
||||
|
|
162
docs/index.rst
162
docs/index.rst
|
@ -49,8 +49,7 @@ __ http://home.elp.rr.com/tur/multitracker-spec.txt
|
|||
|
||||
Functions that are yet to be implemented:
|
||||
|
||||
* more generous optimistic unchoke
|
||||
* better choke/unchoke algorithm
|
||||
* choke/unchoke policy for seed-mode
|
||||
* fast resume
|
||||
* number of connections limit
|
||||
* better handling of peers that send bad data
|
||||
|
@ -139,6 +138,10 @@ The ``session`` class has the following synopsis::
|
|||
|
||||
void set_http_settings(const http_settings& settings);
|
||||
void set_upload_rate_limit(int bytes_per_second);
|
||||
|
||||
std::auto_ptr<alert> pop_alert();
|
||||
void set_severity_level(alert::severity_t s);
|
||||
|
||||
};
|
||||
|
||||
Once it's created, it will spawn the main thread that will do all the work.
|
||||
|
@ -182,6 +185,84 @@ increase the port number by one and try again. If it still fails it will continu
|
|||
increasing the port number until it succeeds or has failed 9 ports. *This will
|
||||
change in the future to give more control of the listen-port.*
|
||||
|
||||
The ``pop_alert()`` function is the interface for retrieving alerts, warnings and
|
||||
errors from libtorrent. If there hasn't occured any errors (matching your severity
|
||||
level) ``pop_alert()`` will return a zero pointer. If there has been some error, it will
|
||||
return a pointer to an alert object describing it. You can then use the query the
|
||||
alert_ object for information about the error or message. To retrieve any alerts, you
|
||||
have to select a severity level using ``set_severity_level()``. It defaults to
|
||||
``alert::none``, which means that you don't get any messages at all, ever. You have
|
||||
the following levels to select among:
|
||||
|
||||
+--------------+----------------------------------------------------------+
|
||||
| ``none`` | No alert will ever have this severity level, which |
|
||||
| | effectively filters all messages. |
|
||||
| | |
|
||||
+--------------+----------------------------------------------------------+
|
||||
| ``fatal`` | Fatal errors will have this severity level. Examples can |
|
||||
| | be disk full or something else that will make it |
|
||||
| | impossible to continue normal execution. |
|
||||
| | |
|
||||
+--------------+----------------------------------------------------------+
|
||||
| ``critical`` | Signals errors that requires user interaction. |
|
||||
| | |
|
||||
+--------------+----------------------------------------------------------+
|
||||
| ``warning`` | Messages with the warning severity can be a tracker that |
|
||||
| | times out or responds with invalid data. It will be |
|
||||
| | retried automatically, and the possible next tracker in |
|
||||
| | a multitracker sequence will be tried. It does not |
|
||||
| | require any user interaction. |
|
||||
| | |
|
||||
+--------------+----------------------------------------------------------+
|
||||
| ``info`` | Events that can be considered normal, but still deserves |
|
||||
| | an event. This could be a piece hash that fails. |
|
||||
| | |
|
||||
+--------------+----------------------------------------------------------+
|
||||
| ``debug`` | This will include alot of debug events that can be used |
|
||||
| | both for debugging libtorrent but also when debugging |
|
||||
| | other clients that are connected to libtorrent. It will |
|
||||
| | report strange behaviors among the connected peers. |
|
||||
| | |
|
||||
+--------------+----------------------------------------------------------+
|
||||
|
||||
When setting a severity level, you will receive messages of that severity and all
|
||||
messages that are more sever. If you set ``alert::none`` (the default) you will not recieve
|
||||
any events at all.
|
||||
|
||||
When you get an alert, you can use ``typeid()`` or ``dynamic_cast<>`` to get more detailed
|
||||
information on exactly which type it is. i.e. what kind of error it is. You can also use a
|
||||
dispatcher mechanism that's available in libtorrent.
|
||||
|
||||
TODO: describe the type dispatching mechanism
|
||||
|
||||
The currently available alert types are:
|
||||
|
||||
* tracker_alert
|
||||
* hash_failed_alert
|
||||
|
||||
You can try a ``dynamic_cast`` to these types to get more message-pecific information. Here
|
||||
are their definitions::
|
||||
|
||||
struct tracker_alert: alert
|
||||
{
|
||||
tracker_alert(const torrent_handle& h, const std::string& msg);
|
||||
virtual std::auto_ptr<alert> clone() const;
|
||||
|
||||
torrent_handle handle;
|
||||
};
|
||||
|
||||
struct hash_failed_alert: alert
|
||||
{
|
||||
hash_failed_alert(
|
||||
const torrent_handle& h
|
||||
, int index
|
||||
, const std::string& msg);
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const;
|
||||
|
||||
torrent_handle handle;
|
||||
int piece_index;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -471,6 +552,7 @@ It contains the following fields::
|
|||
invalid_handle,
|
||||
queued_for_checking,
|
||||
checking_files,
|
||||
connecting_to_tracker,
|
||||
downloading,
|
||||
seeding
|
||||
};
|
||||
|
@ -478,10 +560,16 @@ It contains the following fields::
|
|||
state_t state;
|
||||
float progress;
|
||||
boost::posix_time::time_duration next_announce;
|
||||
|
||||
std::size_t total_download;
|
||||
std::size_t total_upload;
|
||||
|
||||
std::size_t total_payload_download;
|
||||
std::size_t total_payload_upload;
|
||||
|
||||
float download_rate;
|
||||
float upload_rate;
|
||||
|
||||
std::vector<bool> pieces;
|
||||
std::size_t total_done;
|
||||
};
|
||||
|
@ -490,28 +578,40 @@ It contains the following fields::
|
|||
torrent's current task. It may be checking files or downloading. The torrent's
|
||||
current task is in the ``state`` member, it will be one of the following:
|
||||
|
||||
+-----------------------+----------------------------------------------------------+
|
||||
|``queued_for_checking``|The torrent is in the queue for being checked. But there |
|
||||
| |currently is another torrent that are being checked. |
|
||||
| |This torrent will wait for its turn. |
|
||||
+-----------------------+----------------------------------------------------------+
|
||||
|``checking_files`` |The torrent has not started its download yet, and is |
|
||||
| |currently checking existing files. |
|
||||
+-----------------------+----------------------------------------------------------+
|
||||
|``downloading`` |The torrent is being downloaded. This is the state |
|
||||
| |most torrents will be in most of the time. The progress |
|
||||
| |meter will tell how much of the files that has been |
|
||||
| |downloaded. |
|
||||
+-----------------------+----------------------------------------------------------+
|
||||
|``seeding`` |In this state the torrent has finished downloading and |
|
||||
| |is a pure seeder. |
|
||||
+-----------------------+----------------------------------------------------------+
|
||||
+--------------------------+----------------------------------------------------------+
|
||||
|``queued_for_checking`` |The torrent is in the queue for being checked. But there |
|
||||
| |currently is another torrent that are being checked. |
|
||||
| |This torrent will wait for its turn. |
|
||||
| | |
|
||||
+--------------------------+----------------------------------------------------------+
|
||||
|``checking_files`` |The torrent has not started its download yet, and is |
|
||||
| |currently checking existing files. |
|
||||
| | |
|
||||
+--------------------------+----------------------------------------------------------+
|
||||
|``connecting_to_tracker`` |The torrent has sent a request to the tracker and is |
|
||||
| |currently waiting for a response |
|
||||
| | |
|
||||
+--------------------------+----------------------------------------------------------+
|
||||
|``downloading`` |The torrent is being downloaded. This is the state |
|
||||
| |most torrents will be in most of the time. The progress |
|
||||
| |meter will tell how much of the files that has been |
|
||||
| |downloaded. |
|
||||
| | |
|
||||
+--------------------------+----------------------------------------------------------+
|
||||
|``seeding`` |In this state the torrent has finished downloading and |
|
||||
| |is a pure seeder. |
|
||||
| | |
|
||||
+--------------------------+----------------------------------------------------------+
|
||||
|
||||
``next_announce`` is the time until the torrent will announce itself to the tracker.
|
||||
|
||||
``total_download`` and ``total_upload`` is the number of bytes downloaded and
|
||||
uploaded to all peers, accumulated, *this session* only.
|
||||
|
||||
``total_payload_download`` and ``total_payload_upload`` counts the amount of bytes
|
||||
send and received this session, but only the actual oayload data (i.e the interesting
|
||||
data), these counters ignore any protocol overhead.
|
||||
|
||||
``pieces`` is the bitmask that representw which pieces we have (set to true) and
|
||||
the pieces we don't have.
|
||||
|
||||
|
@ -840,6 +940,32 @@ version of your client. All these numbers must be within the range [0, 9].
|
|||
|
||||
``to_string()`` will generate the actual string put in the peer-id, and return it.
|
||||
|
||||
alert
|
||||
-----
|
||||
|
||||
The ``alert`` class is used to pass messages of events from the libtorrent code
|
||||
to the user. It is a base class that specific messages are derived from. This
|
||||
is its synopsis::
|
||||
|
||||
class alert
|
||||
{
|
||||
public:
|
||||
|
||||
enum severity_t { debug, info, warning, critital, fatal, none };
|
||||
|
||||
alert(severity_t severity, const std::string& msg);
|
||||
|
||||
virtual ~alert() {}
|
||||
|
||||
const std::string& msg() const;
|
||||
severity_t severity() const;
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
exceptions
|
||||
----------
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/http_settings.hpp"
|
||||
#include "libtorrent/identify_client.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
|
@ -181,15 +182,18 @@ int main(int argc, char* argv[])
|
|||
// settings.proxy_password = "foobar";
|
||||
settings.user_agent = "example";
|
||||
|
||||
std::deque<std::string> events;
|
||||
|
||||
try
|
||||
{
|
||||
std::vector<torrent_handle> handles;
|
||||
session s(6881);
|
||||
session ses(6881);
|
||||
|
||||
// limit upload rate to 100 kB/s
|
||||
s.set_upload_rate_limit(100 * 1024);
|
||||
ses.set_upload_rate_limit(100 * 1024);
|
||||
ses.set_http_settings(settings);
|
||||
ses.set_severity_level(alert::info);
|
||||
|
||||
s.set_http_settings(settings);
|
||||
for (int i = 0; i < argc-1; ++i)
|
||||
{
|
||||
try
|
||||
|
@ -199,8 +203,8 @@ int main(int argc, char* argv[])
|
|||
entry e = bdecode(std::istream_iterator<char>(in), std::istream_iterator<char>());
|
||||
torrent_info t(e);
|
||||
t.print(std::cout);
|
||||
handles.push_back(s.add_torrent(t, ""));
|
||||
handles.back().set_max_uploads(20);
|
||||
handles.push_back(ses.add_torrent(t, ""));
|
||||
handles.back().set_max_uploads(40);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -219,6 +223,15 @@ int main(int argc, char* argv[])
|
|||
if (c == 'q') break;
|
||||
}
|
||||
|
||||
std::auto_ptr<alert> a;
|
||||
a = ses.pop_alert();
|
||||
while (a.get())
|
||||
{
|
||||
if (events.size() >= 6) events.pop_front();
|
||||
events.push_front(a->msg());
|
||||
a = ses.pop_alert();
|
||||
}
|
||||
|
||||
std::stringstream out;
|
||||
for (std::vector<torrent_handle>::iterator i = handles.begin();
|
||||
i != handles.end();
|
||||
|
@ -234,15 +247,17 @@ int main(int argc, char* argv[])
|
|||
case torrent_status::checking_files:
|
||||
out << "checking ";
|
||||
break;
|
||||
case torrent_status::connecting_to_tracker:
|
||||
out << "connecting to tracker ";
|
||||
break;
|
||||
case torrent_status::downloading:
|
||||
out << "dloading ";
|
||||
out << "downloading ";
|
||||
break;
|
||||
case torrent_status::seeding:
|
||||
out << "seeding ";
|
||||
break;
|
||||
};
|
||||
|
||||
// calculate download and upload speeds
|
||||
i->get_peer_info(peers);
|
||||
float down = s.download_rate;
|
||||
float up = s.upload_rate;
|
||||
|
@ -334,6 +349,13 @@ int main(int argc, char* argv[])
|
|||
|
||||
}
|
||||
|
||||
for (std::deque<std::string>::iterator i = events.begin();
|
||||
i != events.end();
|
||||
++i)
|
||||
{
|
||||
out << *i << "\n";
|
||||
}
|
||||
|
||||
clear();
|
||||
set_cursor(0, 0);
|
||||
std::cout << out.str();
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace libtorrent {
|
|||
class alert
|
||||
{
|
||||
public:
|
||||
enum severity_t { info, warning, critital, fatal };
|
||||
enum severity_t { debug, info, warning, critital, fatal, none };
|
||||
|
||||
alert(severity_t severity, const std::string& msg)
|
||||
: m_msg(msg)
|
||||
|
@ -88,6 +88,8 @@ namespace libtorrent {
|
|||
std::auto_ptr<alert> get();
|
||||
|
||||
void set_severity(alert::severity_t severity);
|
||||
bool should_post(alert::severity_t severity) const
|
||||
{ return severity >= m_severity; }
|
||||
|
||||
private:
|
||||
std::queue<alert*> m_alerts;
|
||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_FINGERPRINT_HPP_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2003, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
|
||||
#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
std::string identify_client(const peer_id& p);
|
||||
|
||||
}
|
||||
|
||||
#endif // TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
|
|
@ -241,8 +241,8 @@ namespace libtorrent
|
|||
int share_diff() const
|
||||
{
|
||||
return m_free_upload
|
||||
+ m_statistics.total_download()
|
||||
- m_statistics.total_upload();
|
||||
+ m_statistics.total_payload_download()
|
||||
- m_statistics.total_payload_upload();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -171,6 +171,12 @@ namespace libtorrent
|
|||
// handles delayed alerts
|
||||
alert_manager m_alerts;
|
||||
|
||||
// is false by default and set to true when
|
||||
// the first incoming connection is established
|
||||
// this is used to know if the client is behind
|
||||
// NAT or not.
|
||||
bool m_incoming_connection;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void assert_invariant();
|
||||
boost::shared_ptr<logger> create_log(std::string name);
|
||||
|
@ -182,8 +188,6 @@ namespace libtorrent
|
|||
|
||||
struct http_settings;
|
||||
|
||||
std::string identify_client(const peer_id& p);
|
||||
|
||||
class session: public boost::noncopyable, detail::eh_initializer
|
||||
{
|
||||
public:
|
||||
|
@ -202,7 +206,10 @@ namespace libtorrent
|
|||
void set_http_settings(const http_settings& s);
|
||||
void set_upload_rate_limit(int bytes_per_second);
|
||||
|
||||
// TODO: add a session_status that contain
|
||||
|
||||
std::auto_ptr<alert> pop_alert();
|
||||
void set_severity_level(alert::severity_t s);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -45,12 +45,12 @@ namespace libtorrent
|
|||
public:
|
||||
|
||||
stat()
|
||||
: m_downloaded(0)
|
||||
, m_uploaded(0)
|
||||
: m_downloaded_payload(0)
|
||||
, m_uploaded_payload(0)
|
||||
, m_downloaded_protocol(0)
|
||||
, m_uploaded_protocol(0)
|
||||
, m_total_download(0)
|
||||
, m_total_upload(0)
|
||||
, m_total_download_payload(0)
|
||||
, m_total_upload_payload(0)
|
||||
, m_total_download_protocol(0)
|
||||
, m_total_upload_protocol(0)
|
||||
, m_peak_downloaded_per_second(0)
|
||||
|
@ -64,29 +64,29 @@ namespace libtorrent
|
|||
|
||||
void operator+=(const stat& s)
|
||||
{
|
||||
m_downloaded += s.m_downloaded;
|
||||
m_total_download += s.m_downloaded;
|
||||
m_downloaded_payload += s.m_downloaded_payload;
|
||||
m_total_download_payload += s.m_downloaded_payload;
|
||||
m_downloaded_protocol += s.m_downloaded_protocol;
|
||||
m_total_download_protocol += s.m_downloaded_protocol;
|
||||
|
||||
m_uploaded += s.m_uploaded;
|
||||
m_total_upload += s.m_uploaded;
|
||||
m_uploaded_payload += s.m_uploaded_payload;
|
||||
m_total_upload_payload += s.m_uploaded_payload;
|
||||
m_uploaded_protocol += s.m_uploaded_protocol;
|
||||
m_total_upload_protocol += s.m_uploaded_protocol;
|
||||
}
|
||||
|
||||
void received_bytes(int bytes_payload, int bytes_protocol)
|
||||
{
|
||||
m_downloaded += bytes_payload;
|
||||
m_total_download += bytes_payload;
|
||||
m_downloaded_payload += bytes_payload;
|
||||
m_total_download_payload += bytes_payload;
|
||||
|
||||
m_downloaded_protocol += bytes_protocol;
|
||||
m_total_download_protocol += bytes_protocol;
|
||||
}
|
||||
void sent_bytes(int bytes_payload, int bytes_protocol)
|
||||
{
|
||||
m_uploaded += bytes_payload;
|
||||
m_total_upload += bytes_payload;
|
||||
m_uploaded_payload += bytes_payload;
|
||||
m_total_upload_payload += bytes_payload;
|
||||
|
||||
m_uploaded_protocol += bytes_protocol;
|
||||
m_total_upload_protocol += bytes_protocol;
|
||||
|
@ -102,8 +102,11 @@ namespace libtorrent
|
|||
float down_peak() const { return m_peak_downloaded_per_second; }
|
||||
float up_peak() const { return m_peak_uploaded_per_second; }
|
||||
|
||||
unsigned int total_upload() const { return m_total_upload; }
|
||||
unsigned int total_download() const { return m_total_download; }
|
||||
unsigned int total_payload_upload() const { return m_total_upload_payload; }
|
||||
unsigned int total_payload_download() const { return m_total_download_payload; }
|
||||
|
||||
unsigned int total_protocol_upload() const { return m_total_upload_protocol; }
|
||||
unsigned int total_protocol_download() const { return m_total_download_protocol; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -116,8 +119,8 @@ namespace libtorrent
|
|||
// the accumulators we are adding the downloads/upploads
|
||||
// to this second. This only counts the actual payload
|
||||
// and ignores the bytes sent as protocol chatter.
|
||||
unsigned int m_downloaded;
|
||||
unsigned int m_uploaded;
|
||||
unsigned int m_downloaded_payload;
|
||||
unsigned int m_uploaded_payload;
|
||||
|
||||
// the accumulators we are adding the downloads/upploads
|
||||
// to this second. This only counts the protocol
|
||||
|
@ -127,8 +130,8 @@ namespace libtorrent
|
|||
|
||||
// total download/upload counters
|
||||
// only counting payload data
|
||||
unsigned int m_total_download;
|
||||
unsigned int m_total_upload;
|
||||
unsigned int m_total_download_payload;
|
||||
unsigned int m_total_upload_payload;
|
||||
|
||||
// total download/upload counters
|
||||
// only counting protocol chatter
|
||||
|
|
|
@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/storage.hpp"
|
||||
#include "libtorrent/url_handler.hpp"
|
||||
#include "libtorrent/stat.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -58,6 +59,38 @@ namespace libtorrent
|
|||
struct logger;
|
||||
#endif
|
||||
|
||||
struct tracker_alert: alert
|
||||
{
|
||||
tracker_alert(const torrent_handle& h
|
||||
, const std::string& msg)
|
||||
: alert(alert::warning, msg)
|
||||
, handle(h)
|
||||
{}
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new tracker_alert(*this)); }
|
||||
|
||||
torrent_handle handle;
|
||||
};
|
||||
|
||||
struct hash_failed_alert: alert
|
||||
{
|
||||
hash_failed_alert(
|
||||
const torrent_handle& h
|
||||
, int index
|
||||
, const std::string& msg)
|
||||
: alert(alert::info, msg)
|
||||
, handle(h)
|
||||
, piece_index(index)
|
||||
{}
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new hash_failed_alert(*this)); }
|
||||
|
||||
torrent_handle handle;
|
||||
int piece_index;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct session_impl;
|
||||
|
@ -150,33 +183,9 @@ namespace libtorrent
|
|||
|
||||
// this is a callback called by the tracker_connection class
|
||||
// when this torrent got a response from its tracker request
|
||||
void tracker_response(const entry& e);
|
||||
|
||||
void tracker_request_timed_out()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_log("*** tracker timed out");
|
||||
#endif
|
||||
// TODO: increase the retry_delay for
|
||||
// each failed attempt on the same tracker!
|
||||
// maybe we should add a counter that keeps
|
||||
// track of how many times a specific tracker
|
||||
// has timed out?
|
||||
try_next_tracker();
|
||||
}
|
||||
|
||||
// TODO: this function should also take the
|
||||
// HTTP-response code as an argument
|
||||
// with some codes, we should just consider
|
||||
// the tracker as a failure and not retry
|
||||
// it anymore
|
||||
void tracker_request_error(const char* str)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_log(std::string("*** tracker error: ") + str);
|
||||
#endif
|
||||
try_next_tracker();
|
||||
}
|
||||
virtual void tracker_response(const entry& e);
|
||||
virtual void tracker_request_timed_out();
|
||||
virtual void tracker_request_error(const char* str);
|
||||
|
||||
// generates a request string for sending
|
||||
// to the tracker
|
||||
|
@ -324,6 +333,11 @@ namespace libtorrent
|
|||
// std::accumulate(m_have_pieces.begin(),
|
||||
// m_have_pieces.end(), 0)
|
||||
int m_num_pieces;
|
||||
|
||||
// is false by default and set to
|
||||
// true when the first tracker reponse
|
||||
// is received
|
||||
bool m_got_tracker_response;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -63,10 +63,23 @@ namespace libtorrent
|
|||
|
||||
struct torrent_status
|
||||
{
|
||||
torrent_status()
|
||||
: state(queued_for_checking)
|
||||
, progress(0.f)
|
||||
, total_download(0)
|
||||
, total_upload(0)
|
||||
, total_payload_download(0)
|
||||
, total_payload_upload(0)
|
||||
, download_rate(0)
|
||||
, upload_rate(0)
|
||||
, total_done(0)
|
||||
{}
|
||||
|
||||
enum state_t
|
||||
{
|
||||
queued_for_checking,
|
||||
checking_files,
|
||||
connecting_to_tracker,
|
||||
downloading,
|
||||
seeding
|
||||
};
|
||||
|
@ -76,17 +89,23 @@ namespace libtorrent
|
|||
boost::posix_time::time_duration next_announce;
|
||||
|
||||
// transferred this session!
|
||||
// total, payload plus protocol
|
||||
std::size_t total_download;
|
||||
std::size_t total_upload;
|
||||
|
||||
// payload only
|
||||
std::size_t total_payload_download;
|
||||
std::size_t total_payload_upload;
|
||||
|
||||
// current transfer rate
|
||||
// payload plus protocol
|
||||
float download_rate;
|
||||
float upload_rate;
|
||||
|
||||
std::vector<bool> pieces;
|
||||
|
||||
// the number of bytes of the file we have
|
||||
std::size_t total_done;
|
||||
|
||||
// TODO: add flag that says if there have
|
||||
// been any incoming connections
|
||||
};
|
||||
|
||||
struct partial_piece_info
|
||||
|
@ -103,6 +122,8 @@ namespace libtorrent
|
|||
struct torrent_handle
|
||||
{
|
||||
friend class session;
|
||||
friend class torrent;
|
||||
|
||||
torrent_handle(): m_ses(0) {}
|
||||
|
||||
void get_peer_info(std::vector<peer_info>& v) const;
|
||||
|
|
|
@ -35,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent {
|
||||
|
||||
alert_manager::alert_manager()
|
||||
: m_severity(alert::warning)
|
||||
: m_severity(alert::none)
|
||||
{}
|
||||
|
||||
alert_manager::~alert_manager()
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2003, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <cctype>
|
||||
|
||||
#include "libtorrent/identify_client.hpp"
|
||||
#include "libtorrent/fingerprint.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// 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\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\0"))
|
||||
{
|
||||
return "Experimental 3.1";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 12, "\0\0\0\0\0\0\0\0\0\0\0\0"))
|
||||
{
|
||||
return "Generic";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/peer_connection.hpp"
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/identify_client.hpp"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define for if (false) {} else for
|
||||
|
@ -381,7 +382,6 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|||
{
|
||||
m_have_piece[index] = true;
|
||||
|
||||
// TODO: maybe this if-statement should be moved into the policy
|
||||
m_torrent->peer_has(index);
|
||||
if (!m_torrent->have_piece(index) && !is_interesting())
|
||||
m_torrent->get_policy().peer_is_interesting(*this);
|
||||
|
@ -859,12 +859,12 @@ void libtorrent::peer_connection::second_tick()
|
|||
int bias = 0;
|
||||
if (diff > -2*m_torrent->block_size())
|
||||
{
|
||||
bias = m_statistics.download_rate() * .5;
|
||||
bias = m_statistics.download_rate() / 2;
|
||||
if (bias < 10*1024) bias = 10*1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
bias = -m_statistics.download_rate() * .5;
|
||||
bias = -m_statistics.download_rate() / 2;
|
||||
}
|
||||
m_send_quota_limit = m_statistics.download_rate() + bias;
|
||||
// the maximum send_quota given our download rate from this peer
|
||||
|
@ -1030,6 +1030,16 @@ void libtorrent::peer_connection::receive_data()
|
|||
if (m_recv_pos < m_packet_size) break;
|
||||
assert(m_recv_pos == m_packet_size);
|
||||
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
peer_id tmp;
|
||||
std::copy(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (char*)tmp.begin());
|
||||
std::stringstream s;
|
||||
s << "received peer_id: " << tmp << " client: " << identify_client(tmp) << "\n";
|
||||
(*m_logger) << s.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_active)
|
||||
{
|
||||
// verify peer_id
|
||||
|
@ -1052,7 +1062,7 @@ void libtorrent::peer_connection::receive_data()
|
|||
if (m_torrent->has_peer(m_peer_id))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << m_socket->sender().as_string() << " duplicate connection, closing\n";
|
||||
(*m_logger) << " duplicate connection, closing\n";
|
||||
#endif
|
||||
throw network_error(0);
|
||||
}
|
||||
|
@ -1066,9 +1076,7 @@ void libtorrent::peer_connection::receive_data()
|
|||
m_packet_size = 4;
|
||||
m_recv_pos = 0;
|
||||
m_recv_buffer.resize(4);
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << m_socket->sender().as_string() << " received peer_id\n";
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1234,7 +1242,7 @@ void libtorrent::peer_connection::send_data()
|
|||
, amount_to_send);
|
||||
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << m_socket->sender().as_string() << " ==> SENT [ length: " << sent << " ]\n";
|
||||
// (*m_logger) << m_socket->sender().as_string() << " ==> SENT [ length: " << sent << " ]\n";
|
||||
#endif
|
||||
|
||||
if (sent > 0)
|
||||
|
|
|
@ -593,8 +593,8 @@ namespace libtorrent
|
|||
assert(i != m_peers.end());
|
||||
|
||||
i->connected = boost::posix_time::second_clock::local_time();
|
||||
i->prev_amount_download += c.statistics().total_download();
|
||||
i->prev_amount_upload += c.statistics().total_upload();
|
||||
i->prev_amount_download += c.statistics().total_payload_download();
|
||||
i->prev_amount_upload += c.statistics().total_payload_upload();
|
||||
if (!i->connection->is_choked() && !m_torrent->is_aborted())
|
||||
{
|
||||
--m_num_unchoked;
|
||||
|
@ -651,7 +651,7 @@ namespace libtorrent
|
|||
int policy::peer::total_download() const
|
||||
{
|
||||
if (connection != 0)
|
||||
return connection->statistics().total_download()
|
||||
return connection->statistics().total_payload_download()
|
||||
+ prev_amount_download;
|
||||
else
|
||||
return prev_amount_download;
|
||||
|
@ -660,7 +660,7 @@ namespace libtorrent
|
|||
int policy::peer::total_upload() const
|
||||
{
|
||||
if (connection != 0)
|
||||
return connection->statistics().total_upload()
|
||||
return connection->statistics().total_payload_upload()
|
||||
+ prev_amount_upload;
|
||||
else
|
||||
return prev_amount_upload;
|
||||
|
|
204
src/session.cpp
204
src/session.cpp
|
@ -337,6 +337,7 @@ namespace libtorrent
|
|||
, m_tracker_manager(m_settings)
|
||||
, m_listen_port(listen_port)
|
||||
, m_upload_rate(-1)
|
||||
, m_incoming_connection(false)
|
||||
{
|
||||
|
||||
// ---- generate a peer id ----
|
||||
|
@ -462,6 +463,7 @@ namespace libtorrent
|
|||
if (s)
|
||||
{
|
||||
// we got a connection request!
|
||||
m_incoming_connection = true;
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << s->sender().as_string() << " <== INCOMING CONNECTION\n";
|
||||
#endif
|
||||
|
@ -864,203 +866,15 @@ namespace libtorrent
|
|||
|
||||
std::auto_ptr<alert> session::pop_alert()
|
||||
{
|
||||
return m_impl.m_alerts.get();
|
||||
if (m_impl.m_alerts.pending())
|
||||
return m_impl.m_alerts.get();
|
||||
else
|
||||
return std::auto_ptr<alert>(0);
|
||||
}
|
||||
|
||||
namespace
|
||||
void session::set_severity_level(alert::severity_t s)
|
||||
{
|
||||
|
||||
// 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";
|
||||
}
|
||||
m_impl.m_alerts.set_severity(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,10 +51,10 @@ void libtorrent::stat::second_tick()
|
|||
m_upload_per_second_history+history-1,
|
||||
m_upload_per_second_history+1);
|
||||
|
||||
m_download_per_second_history[0] = m_downloaded + m_downloaded_protocol;
|
||||
m_upload_per_second_history[0] = m_uploaded + m_uploaded_protocol;
|
||||
m_downloaded = 0;
|
||||
m_uploaded = 0;
|
||||
m_download_per_second_history[0] = m_downloaded_payload + m_downloaded_protocol;
|
||||
m_upload_per_second_history[0] = m_uploaded_payload + m_uploaded_protocol;
|
||||
m_downloaded_payload = 0;
|
||||
m_uploaded_payload = 0;
|
||||
m_downloaded_protocol = 0;
|
||||
m_uploaded_protocol = 0;
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/peer.hpp"
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/identify_client.hpp"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
namespace std
|
||||
|
@ -177,6 +179,7 @@ namespace libtorrent
|
|||
, m_time_scaler(0)
|
||||
, m_priority(.5)
|
||||
, m_num_pieces(0)
|
||||
, m_got_tracker_response(false)
|
||||
{
|
||||
assert(torrent_file.begin_files() != torrent_file.end_files());
|
||||
m_have_pieces.resize(torrent_file.num_pieces(), false);
|
||||
|
@ -250,6 +253,7 @@ namespace libtorrent
|
|||
tracker_request_error(e.what());
|
||||
}
|
||||
|
||||
m_got_tracker_response = true;
|
||||
}
|
||||
|
||||
bool torrent::has_peer(const peer_id& id) const
|
||||
|
@ -282,6 +286,13 @@ namespace libtorrent
|
|||
|
||||
void torrent::piece_failed(int index)
|
||||
{
|
||||
if (m_ses.m_alerts.should_post(alert::info))
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "hash for piece " << index << " failed";
|
||||
torrent_handle self(&m_ses, 0, m_torrent_file.info_hash());
|
||||
m_ses.m_alerts.post_alert(hash_failed_alert(self, index, s.str()));
|
||||
}
|
||||
std::vector<peer_id> downloaders;
|
||||
m_picker.get_downloaders(downloaders, index);
|
||||
|
||||
|
@ -365,10 +376,10 @@ namespace libtorrent
|
|||
request += boost::lexical_cast<std::string>(port);
|
||||
|
||||
request += "&uploaded=";
|
||||
request += boost::lexical_cast<std::string>(m_stat.total_upload());
|
||||
request += boost::lexical_cast<std::string>(m_stat.total_payload_upload());
|
||||
|
||||
request += "&downloaded=";
|
||||
request += boost::lexical_cast<std::string>(m_stat.total_download());
|
||||
request += boost::lexical_cast<std::string>(m_stat.total_payload_download());
|
||||
|
||||
request += "&left=";
|
||||
request += boost::lexical_cast<std::string>(bytes_left());
|
||||
|
@ -450,7 +461,7 @@ namespace libtorrent
|
|||
m_connections.erase(i);
|
||||
|
||||
#ifndef NDEBUG
|
||||
m_picker.integrity_check(this);
|
||||
// m_picker.integrity_check(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -628,10 +639,20 @@ namespace libtorrent
|
|||
- blocks_per_piece;
|
||||
}
|
||||
|
||||
st.total_download = m_stat.total_download();
|
||||
st.total_upload = m_stat.total_upload();
|
||||
// payload transfer
|
||||
st.total_payload_download = m_stat.total_payload_download();
|
||||
st.total_payload_upload = m_stat.total_payload_upload();
|
||||
|
||||
// total transfer
|
||||
st.total_download = m_stat.total_payload_download()
|
||||
+ m_stat.total_protocol_download();
|
||||
st.total_upload = m_stat.total_payload_upload()
|
||||
+ m_stat.total_protocol_upload();
|
||||
|
||||
// transfer rate
|
||||
st.download_rate = m_stat.download_rate();
|
||||
st.upload_rate = m_stat.upload_rate();
|
||||
|
||||
st.progress = (blocks_we_have + unverified_blocks)
|
||||
/ static_cast<float>(total_blocks);
|
||||
|
||||
|
@ -644,7 +665,9 @@ namespace libtorrent
|
|||
st.total_done = (blocks_we_have + unverified_blocks) * m_block_size;
|
||||
st.pieces = m_have_pieces;
|
||||
|
||||
if (m_num_pieces == p.size())
|
||||
if (m_got_tracker_response == false)
|
||||
st.state = torrent_status::connecting_to_tracker;
|
||||
else if (m_num_pieces == p.size())
|
||||
st.state = torrent_status::seeding;
|
||||
else
|
||||
st.state = torrent_status::downloading;
|
||||
|
@ -652,6 +675,53 @@ namespace libtorrent
|
|||
return st;
|
||||
}
|
||||
|
||||
void torrent::tracker_request_timed_out()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_log("*** tracker timed out");
|
||||
#endif
|
||||
if (m_ses.m_alerts.should_post(alert::warning))
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "tracker: \""
|
||||
<< m_torrent_file.trackers()[m_currently_trying_tracker].url
|
||||
<< "\" timed out";
|
||||
torrent_handle self(&m_ses, 0, m_torrent_file.info_hash());
|
||||
m_ses.m_alerts.post_alert(tracker_alert( self, s.str()));
|
||||
}
|
||||
// TODO: increase the retry_delay for
|
||||
// each failed attempt on the same tracker!
|
||||
// maybe we should add a counter that keeps
|
||||
// track of how many times a specific tracker
|
||||
// has timed out?
|
||||
try_next_tracker();
|
||||
}
|
||||
|
||||
// TODO: this function should also take the
|
||||
// HTTP-response code as an argument
|
||||
// with some codes, we should just consider
|
||||
// the tracker as a failure and not retry
|
||||
// it anymore
|
||||
void torrent::tracker_request_error(const char* str)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_log(std::string("*** tracker error: ") + str);
|
||||
#endif
|
||||
if (m_ses.m_alerts.should_post(alert::warning))
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "tracker: \""
|
||||
<< m_torrent_file.trackers()[m_currently_trying_tracker].url
|
||||
<< "\" " << str;
|
||||
torrent_handle self(&m_ses, 0, m_torrent_file.info_hash());
|
||||
m_ses.m_alerts.post_alert(tracker_alert(self, s.str()));
|
||||
}
|
||||
|
||||
|
||||
try_next_tracker();
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
void torrent::debug_log(const std::string& line)
|
||||
{
|
||||
|
|
|
@ -68,7 +68,6 @@ namespace libtorrent
|
|||
{
|
||||
if (m_ses == 0) throw invalid_handle();
|
||||
|
||||
assert(m_chk != 0);
|
||||
{
|
||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
||||
torrent* t = m_ses->find_torrent(m_info_hash);
|
||||
|
@ -80,6 +79,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
|
||||
if (m_chk)
|
||||
{
|
||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||
|
||||
|
@ -97,13 +97,13 @@ namespace libtorrent
|
|||
{
|
||||
if (m_ses == 0) throw invalid_handle();
|
||||
|
||||
assert(m_chk != 0);
|
||||
{
|
||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
||||
torrent* t = m_ses->find_torrent(m_info_hash);
|
||||
if (t != 0) return t->status();
|
||||
}
|
||||
|
||||
if (m_chk)
|
||||
{
|
||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||
|
||||
|
@ -111,10 +111,7 @@ namespace libtorrent
|
|||
if (d != 0)
|
||||
{
|
||||
torrent_status st;
|
||||
st.total_download = 0;
|
||||
st.total_upload = 0;
|
||||
st.download_rate = 0.f;
|
||||
st.upload_rate = 0.f;
|
||||
|
||||
if (d == &m_chk->m_torrents.front())
|
||||
st.state = torrent_status::checking_files;
|
||||
else
|
||||
|
@ -123,7 +120,6 @@ namespace libtorrent
|
|||
st.next_announce = boost::posix_time::time_duration();
|
||||
st.pieces.clear();
|
||||
st.pieces.resize(d->torrent_ptr->torrent_file().num_pieces(), false);
|
||||
st.total_done = 0;
|
||||
return st;
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +137,7 @@ namespace libtorrent
|
|||
if (t != 0) return t->torrent_file();
|
||||
}
|
||||
|
||||
if (m_chk)
|
||||
{
|
||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
||||
|
@ -160,6 +157,7 @@ namespace libtorrent
|
|||
if (t != 0) return true;
|
||||
}
|
||||
|
||||
if (m_chk)
|
||||
{
|
||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
||||
|
@ -190,6 +188,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
if (m_chk)
|
||||
{
|
||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
||||
|
@ -207,7 +206,6 @@ namespace libtorrent
|
|||
{
|
||||
v.clear();
|
||||
if (m_ses == 0) throw invalid_handle();
|
||||
assert(m_chk != 0);
|
||||
|
||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
||||
|
||||
|
@ -235,8 +233,8 @@ namespace libtorrent
|
|||
|
||||
// TODO: add the prev_amount_downloaded and prev_amount_uploaded
|
||||
// from the peer list in the policy
|
||||
p.total_download = statistics.total_download();
|
||||
p.total_upload = statistics.total_upload();
|
||||
p.total_download = statistics.total_payload_download();
|
||||
p.total_upload = statistics.total_payload_upload();
|
||||
|
||||
p.upload_limit = peer->send_quota();
|
||||
p.upload_ceiling = peer->send_quota_limit();
|
||||
|
@ -274,7 +272,6 @@ namespace libtorrent
|
|||
queue.clear();
|
||||
|
||||
if (m_ses == 0) throw invalid_handle();
|
||||
assert(m_chk != 0);
|
||||
|
||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
||||
torrent* t = m_ses->find_torrent(m_info_hash);
|
||||
|
|
Loading…
Reference in New Issue