*** empty log message ***
This commit is contained in:
1
Jamfile
1
Jamfile
@@ -1,5 +1,6 @@
|
|||||||
SOURCES =
|
SOURCES =
|
||||||
entry.cpp
|
entry.cpp
|
||||||
|
identify_client.cpp
|
||||||
peer_connection.cpp
|
peer_connection.cpp
|
||||||
piece_picker.cpp
|
piece_picker.cpp
|
||||||
policy.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="#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="#fingerprint" id="id24" name="id24">fingerprint</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="#alert" id="id25" name="id25">alert</a></li>
|
||||||
<li><a class="reference" href="#invalid-handle" id="id26" name="id26">invalid_handle</a></li>
|
<li><a class="reference" href="#exceptions" id="id26" name="id26">exceptions</a><ul>
|
||||||
<li><a class="reference" href="#duplicate-torrent" id="id27" name="id27">duplicate_torrent</a></li>
|
<li><a class="reference" href="#invalid-handle" id="id27" name="id27">invalid_handle</a></li>
|
||||||
<li><a class="reference" href="#invalid-encoding" id="id28" name="id28">invalid_encoding</a></li>
|
<li><a class="reference" href="#duplicate-torrent" id="id28" name="id28">duplicate_torrent</a></li>
|
||||||
<li><a class="reference" href="#type-error" id="id29" name="id29">type_error</a></li>
|
<li><a class="reference" href="#invalid-encoding" id="id29" name="id29">invalid_encoding</a></li>
|
||||||
<li><a class="reference" href="#invalid-torrent-file" id="id30" name="id30">invalid_torrent_file</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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference" href="#example-usage" id="id31" name="id31">example usage</a><ul>
|
<li><a class="reference" href="#example-usage" id="id32" name="id32">example usage</a><ul>
|
||||||
<li><a class="reference" href="#dump-torrent" id="id32" name="id32">dump_torrent</a></li>
|
<li><a class="reference" href="#dump-torrent" id="id33" name="id33">dump_torrent</a></li>
|
||||||
<li><a class="reference" href="#simple-client" id="id33" name="id33">simple client</a></li>
|
<li><a class="reference" href="#simple-client" id="id34" name="id34">simple client</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference" href="#feedback" id="id34" name="id34">Feedback</a></li>
|
<li><a class="reference" href="#feedback" id="id35" name="id35">Feedback</a></li>
|
||||||
<li><a class="reference" href="#aknowledgements" id="id35" name="id35">Aknowledgements</a></li>
|
<li><a class="reference" href="#aknowledgements" id="id36" name="id36">Aknowledgements</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="introduction">
|
<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>
|
<p>Functions that are yet to be implemented:</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
<li>more generous optimistic unchoke</li>
|
<li>choke/unchoke policy for seed-mode</li>
|
||||||
<li>better choke/unchoke algorithm</li>
|
|
||||||
<li>fast resume</li>
|
<li>fast resume</li>
|
||||||
<li>number of connections limit</li>
|
<li>number of connections limit</li>
|
||||||
<li>better handling of peers that send bad data</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_http_settings(const http_settings& settings);
|
||||||
void set_upload_rate_limit(int bytes_per_second);
|
void set_upload_rate_limit(int bytes_per_second);
|
||||||
|
|
||||||
|
std::auto_ptr<alert> pop_alert();
|
||||||
|
void set_severity_level(alert::severity_t s);
|
||||||
|
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
<p>Once it's created, it will spawn the main thread that will do all the work.
|
<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
|
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
|
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>
|
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>
|
||||||
<div class="section" id="parsing-torrent-files">
|
<div class="section" id="parsing-torrent-files">
|
||||||
<h2><a class="toc-backref" href="#id11" name="parsing-torrent-files">parsing torrent files</a></h2>
|
<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,
|
invalid_handle,
|
||||||
queued_for_checking,
|
queued_for_checking,
|
||||||
checking_files,
|
checking_files,
|
||||||
|
connecting_to_tracker,
|
||||||
downloading,
|
downloading,
|
||||||
seeding
|
seeding
|
||||||
};
|
};
|
||||||
@@ -458,10 +546,16 @@ struct torrent_status
|
|||||||
state_t state;
|
state_t state;
|
||||||
float progress;
|
float progress;
|
||||||
boost::posix_time::time_duration next_announce;
|
boost::posix_time::time_duration next_announce;
|
||||||
|
|
||||||
std::size_t total_download;
|
std::size_t total_download;
|
||||||
std::size_t total_upload;
|
std::size_t total_upload;
|
||||||
|
|
||||||
|
std::size_t total_payload_download;
|
||||||
|
std::size_t total_payload_upload;
|
||||||
|
|
||||||
float download_rate;
|
float download_rate;
|
||||||
float upload_rate;
|
float upload_rate;
|
||||||
|
|
||||||
std::vector<bool> pieces;
|
std::vector<bool> pieces;
|
||||||
std::size_t total_done;
|
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>
|
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">
|
<table border class="table">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col width="28%" />
|
<col width="31%" />
|
||||||
<col width="72%" />
|
<col width="69%" />
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<tbody valign="top">
|
<tbody valign="top">
|
||||||
<tr><td><tt class="literal"><span class="pre">queued_for_checking</span></tt></td>
|
<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
|
<td>The torrent has not started its download yet, and is
|
||||||
currently checking existing files.</td>
|
currently checking existing files.</td>
|
||||||
</tr>
|
</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>
|
<tr><td><tt class="literal"><span class="pre">downloading</span></tt></td>
|
||||||
<td>The torrent is being downloaded. This is the state
|
<td>The torrent is being downloaded. This is the state
|
||||||
most torrents will be in most of the time. The progress
|
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">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
|
<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>
|
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
|
<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>
|
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
|
<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>
|
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>
|
<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>
|
||||||
|
<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">
|
<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,
|
<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="#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
|
<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">
|
||||||
@@ -808,7 +932,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="#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
|
<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">
|
||||||
@@ -819,7 +943,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="#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>
|
<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
|
||||||
@@ -829,7 +953,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="#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
|
<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">
|
||||||
@@ -840,7 +964,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="#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
|
<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">
|
||||||
@@ -852,9 +976,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="#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">
|
<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
|
<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">
|
||||||
@@ -918,7 +1042,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="#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>
|
<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>
|
||||||
@@ -971,12 +1095,12 @@ 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="#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>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="#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>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>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:
|
Functions that are yet to be implemented:
|
||||||
|
|
||||||
* more generous optimistic unchoke
|
* choke/unchoke policy for seed-mode
|
||||||
* better choke/unchoke algorithm
|
|
||||||
* fast resume
|
* fast resume
|
||||||
* number of connections limit
|
* number of connections limit
|
||||||
* better handling of peers that send bad data
|
* 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_http_settings(const http_settings& settings);
|
||||||
void set_upload_rate_limit(int bytes_per_second);
|
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.
|
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
|
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.*
|
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,
|
invalid_handle,
|
||||||
queued_for_checking,
|
queued_for_checking,
|
||||||
checking_files,
|
checking_files,
|
||||||
|
connecting_to_tracker,
|
||||||
downloading,
|
downloading,
|
||||||
seeding
|
seeding
|
||||||
};
|
};
|
||||||
@@ -478,10 +560,16 @@ It contains the following fields::
|
|||||||
state_t state;
|
state_t state;
|
||||||
float progress;
|
float progress;
|
||||||
boost::posix_time::time_duration next_announce;
|
boost::posix_time::time_duration next_announce;
|
||||||
|
|
||||||
std::size_t total_download;
|
std::size_t total_download;
|
||||||
std::size_t total_upload;
|
std::size_t total_upload;
|
||||||
|
|
||||||
|
std::size_t total_payload_download;
|
||||||
|
std::size_t total_payload_upload;
|
||||||
|
|
||||||
float download_rate;
|
float download_rate;
|
||||||
float upload_rate;
|
float upload_rate;
|
||||||
|
|
||||||
std::vector<bool> pieces;
|
std::vector<bool> pieces;
|
||||||
std::size_t total_done;
|
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
|
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:
|
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 |
|
|``queued_for_checking`` |The torrent is in the queue for being checked. But there |
|
||||||
| |currently is another torrent that are being checked. |
|
| |currently is another torrent that are being checked. |
|
||||||
| |This torrent will wait for its turn. |
|
| |This torrent will wait for its turn. |
|
||||||
+-----------------------+----------------------------------------------------------+
|
| | |
|
||||||
|``checking_files`` |The torrent has not started its download yet, and is |
|
+--------------------------+----------------------------------------------------------+
|
||||||
| |currently checking existing files. |
|
|``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 |
|
|``connecting_to_tracker`` |The torrent has sent a request to the tracker and is |
|
||||||
| |downloaded. |
|
| |currently waiting for a response |
|
||||||
+-----------------------+----------------------------------------------------------+
|
| | |
|
||||||
|``seeding`` |In this state the torrent has finished downloading and |
|
+--------------------------+----------------------------------------------------------+
|
||||||
| |is a pure seeder. |
|
|``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.
|
``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
|
``total_download`` and ``total_upload`` is the number of bytes downloaded and
|
||||||
uploaded to all peers, accumulated, *this session* only.
|
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
|
``pieces`` is the bitmask that representw which pieces we have (set to true) and
|
||||||
the pieces we don't have.
|
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.
|
``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
|
exceptions
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/bencode.hpp"
|
#include "libtorrent/bencode.hpp"
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
#include "libtorrent/http_settings.hpp"
|
#include "libtorrent/http_settings.hpp"
|
||||||
|
#include "libtorrent/identify_client.hpp"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
@@ -181,15 +182,18 @@ int main(int argc, char* argv[])
|
|||||||
// settings.proxy_password = "foobar";
|
// settings.proxy_password = "foobar";
|
||||||
settings.user_agent = "example";
|
settings.user_agent = "example";
|
||||||
|
|
||||||
|
std::deque<std::string> events;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::vector<torrent_handle> handles;
|
std::vector<torrent_handle> handles;
|
||||||
session s(6881);
|
session ses(6881);
|
||||||
|
|
||||||
// limit upload rate to 100 kB/s
|
// 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)
|
for (int i = 0; i < argc-1; ++i)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -199,8 +203,8 @@ int main(int argc, char* argv[])
|
|||||||
entry e = bdecode(std::istream_iterator<char>(in), std::istream_iterator<char>());
|
entry e = bdecode(std::istream_iterator<char>(in), std::istream_iterator<char>());
|
||||||
torrent_info t(e);
|
torrent_info t(e);
|
||||||
t.print(std::cout);
|
t.print(std::cout);
|
||||||
handles.push_back(s.add_torrent(t, ""));
|
handles.push_back(ses.add_torrent(t, ""));
|
||||||
handles.back().set_max_uploads(20);
|
handles.back().set_max_uploads(40);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
@@ -219,6 +223,15 @@ int main(int argc, char* argv[])
|
|||||||
if (c == 'q') break;
|
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;
|
std::stringstream out;
|
||||||
for (std::vector<torrent_handle>::iterator i = handles.begin();
|
for (std::vector<torrent_handle>::iterator i = handles.begin();
|
||||||
i != handles.end();
|
i != handles.end();
|
||||||
@@ -234,15 +247,17 @@ int main(int argc, char* argv[])
|
|||||||
case torrent_status::checking_files:
|
case torrent_status::checking_files:
|
||||||
out << "checking ";
|
out << "checking ";
|
||||||
break;
|
break;
|
||||||
|
case torrent_status::connecting_to_tracker:
|
||||||
|
out << "connecting to tracker ";
|
||||||
|
break;
|
||||||
case torrent_status::downloading:
|
case torrent_status::downloading:
|
||||||
out << "dloading ";
|
out << "downloading ";
|
||||||
break;
|
break;
|
||||||
case torrent_status::seeding:
|
case torrent_status::seeding:
|
||||||
out << "seeding ";
|
out << "seeding ";
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
// calculate download and upload speeds
|
|
||||||
i->get_peer_info(peers);
|
i->get_peer_info(peers);
|
||||||
float down = s.download_rate;
|
float down = s.download_rate;
|
||||||
float up = s.upload_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();
|
clear();
|
||||||
set_cursor(0, 0);
|
set_cursor(0, 0);
|
||||||
std::cout << out.str();
|
std::cout << out.str();
|
||||||
|
@@ -51,7 +51,7 @@ namespace libtorrent {
|
|||||||
class alert
|
class alert
|
||||||
{
|
{
|
||||||
public:
|
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)
|
alert(severity_t severity, const std::string& msg)
|
||||||
: m_msg(msg)
|
: m_msg(msg)
|
||||||
@@ -88,6 +88,8 @@ namespace libtorrent {
|
|||||||
std::auto_ptr<alert> get();
|
std::auto_ptr<alert> get();
|
||||||
|
|
||||||
void set_severity(alert::severity_t severity);
|
void set_severity(alert::severity_t severity);
|
||||||
|
bool should_post(alert::severity_t severity) const
|
||||||
|
{ return severity >= m_severity; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::queue<alert*> m_alerts;
|
std::queue<alert*> m_alerts;
|
||||||
|
@@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#define TORRENT_FINGERPRINT_HPP_INCLUDED
|
#define TORRENT_FINGERPRINT_HPP_INCLUDED
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
|
||||||
|
45
include/libtorrent/identify_client.hpp
Executable file
45
include/libtorrent/identify_client.hpp
Executable file
@@ -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
|
int share_diff() const
|
||||||
{
|
{
|
||||||
return m_free_upload
|
return m_free_upload
|
||||||
+ m_statistics.total_download()
|
+ m_statistics.total_payload_download()
|
||||||
- m_statistics.total_upload();
|
- m_statistics.total_payload_upload();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@@ -171,6 +171,12 @@ namespace libtorrent
|
|||||||
// handles delayed alerts
|
// handles delayed alerts
|
||||||
alert_manager m_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
|
#ifndef NDEBUG
|
||||||
void assert_invariant();
|
void assert_invariant();
|
||||||
boost::shared_ptr<logger> create_log(std::string name);
|
boost::shared_ptr<logger> create_log(std::string name);
|
||||||
@@ -182,8 +188,6 @@ namespace libtorrent
|
|||||||
|
|
||||||
struct http_settings;
|
struct http_settings;
|
||||||
|
|
||||||
std::string identify_client(const peer_id& p);
|
|
||||||
|
|
||||||
class session: public boost::noncopyable, detail::eh_initializer
|
class session: public boost::noncopyable, detail::eh_initializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -202,7 +206,10 @@ namespace libtorrent
|
|||||||
void set_http_settings(const http_settings& s);
|
void set_http_settings(const http_settings& s);
|
||||||
void set_upload_rate_limit(int bytes_per_second);
|
void set_upload_rate_limit(int bytes_per_second);
|
||||||
|
|
||||||
|
// TODO: add a session_status that contain
|
||||||
|
|
||||||
std::auto_ptr<alert> pop_alert();
|
std::auto_ptr<alert> pop_alert();
|
||||||
|
void set_severity_level(alert::severity_t s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@@ -45,12 +45,12 @@ namespace libtorrent
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
stat()
|
stat()
|
||||||
: m_downloaded(0)
|
: m_downloaded_payload(0)
|
||||||
, m_uploaded(0)
|
, m_uploaded_payload(0)
|
||||||
, m_downloaded_protocol(0)
|
, m_downloaded_protocol(0)
|
||||||
, m_uploaded_protocol(0)
|
, m_uploaded_protocol(0)
|
||||||
, m_total_download(0)
|
, m_total_download_payload(0)
|
||||||
, m_total_upload(0)
|
, m_total_upload_payload(0)
|
||||||
, m_total_download_protocol(0)
|
, m_total_download_protocol(0)
|
||||||
, m_total_upload_protocol(0)
|
, m_total_upload_protocol(0)
|
||||||
, m_peak_downloaded_per_second(0)
|
, m_peak_downloaded_per_second(0)
|
||||||
@@ -64,29 +64,29 @@ namespace libtorrent
|
|||||||
|
|
||||||
void operator+=(const stat& s)
|
void operator+=(const stat& s)
|
||||||
{
|
{
|
||||||
m_downloaded += s.m_downloaded;
|
m_downloaded_payload += s.m_downloaded_payload;
|
||||||
m_total_download += s.m_downloaded;
|
m_total_download_payload += s.m_downloaded_payload;
|
||||||
m_downloaded_protocol += s.m_downloaded_protocol;
|
m_downloaded_protocol += s.m_downloaded_protocol;
|
||||||
m_total_download_protocol += s.m_downloaded_protocol;
|
m_total_download_protocol += s.m_downloaded_protocol;
|
||||||
|
|
||||||
m_uploaded += s.m_uploaded;
|
m_uploaded_payload += s.m_uploaded_payload;
|
||||||
m_total_upload += s.m_uploaded;
|
m_total_upload_payload += s.m_uploaded_payload;
|
||||||
m_uploaded_protocol += s.m_uploaded_protocol;
|
m_uploaded_protocol += s.m_uploaded_protocol;
|
||||||
m_total_upload_protocol += s.m_uploaded_protocol;
|
m_total_upload_protocol += s.m_uploaded_protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
void received_bytes(int bytes_payload, int bytes_protocol)
|
void received_bytes(int bytes_payload, int bytes_protocol)
|
||||||
{
|
{
|
||||||
m_downloaded += bytes_payload;
|
m_downloaded_payload += bytes_payload;
|
||||||
m_total_download += bytes_payload;
|
m_total_download_payload += bytes_payload;
|
||||||
|
|
||||||
m_downloaded_protocol += bytes_protocol;
|
m_downloaded_protocol += bytes_protocol;
|
||||||
m_total_download_protocol += bytes_protocol;
|
m_total_download_protocol += bytes_protocol;
|
||||||
}
|
}
|
||||||
void sent_bytes(int bytes_payload, int bytes_protocol)
|
void sent_bytes(int bytes_payload, int bytes_protocol)
|
||||||
{
|
{
|
||||||
m_uploaded += bytes_payload;
|
m_uploaded_payload += bytes_payload;
|
||||||
m_total_upload += bytes_payload;
|
m_total_upload_payload += bytes_payload;
|
||||||
|
|
||||||
m_uploaded_protocol += bytes_protocol;
|
m_uploaded_protocol += bytes_protocol;
|
||||||
m_total_upload_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 down_peak() const { return m_peak_downloaded_per_second; }
|
||||||
float up_peak() const { return m_peak_uploaded_per_second; }
|
float up_peak() const { return m_peak_uploaded_per_second; }
|
||||||
|
|
||||||
unsigned int total_upload() const { return m_total_upload; }
|
unsigned int total_payload_upload() const { return m_total_upload_payload; }
|
||||||
unsigned int total_download() const { return m_total_download; }
|
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:
|
private:
|
||||||
|
|
||||||
@@ -116,8 +119,8 @@ namespace libtorrent
|
|||||||
// the accumulators we are adding the downloads/upploads
|
// the accumulators we are adding the downloads/upploads
|
||||||
// to this second. This only counts the actual payload
|
// to this second. This only counts the actual payload
|
||||||
// and ignores the bytes sent as protocol chatter.
|
// and ignores the bytes sent as protocol chatter.
|
||||||
unsigned int m_downloaded;
|
unsigned int m_downloaded_payload;
|
||||||
unsigned int m_uploaded;
|
unsigned int m_uploaded_payload;
|
||||||
|
|
||||||
// the accumulators we are adding the downloads/upploads
|
// the accumulators we are adding the downloads/upploads
|
||||||
// to this second. This only counts the protocol
|
// to this second. This only counts the protocol
|
||||||
@@ -127,8 +130,8 @@ namespace libtorrent
|
|||||||
|
|
||||||
// total download/upload counters
|
// total download/upload counters
|
||||||
// only counting payload data
|
// only counting payload data
|
||||||
unsigned int m_total_download;
|
unsigned int m_total_download_payload;
|
||||||
unsigned int m_total_upload;
|
unsigned int m_total_upload_payload;
|
||||||
|
|
||||||
// total download/upload counters
|
// total download/upload counters
|
||||||
// only counting protocol chatter
|
// only counting protocol chatter
|
||||||
|
@@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
#include "libtorrent/url_handler.hpp"
|
#include "libtorrent/url_handler.hpp"
|
||||||
#include "libtorrent/stat.hpp"
|
#include "libtorrent/stat.hpp"
|
||||||
|
#include "libtorrent/alert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
@@ -58,6 +59,38 @@ namespace libtorrent
|
|||||||
struct logger;
|
struct logger;
|
||||||
#endif
|
#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
|
namespace detail
|
||||||
{
|
{
|
||||||
struct session_impl;
|
struct session_impl;
|
||||||
@@ -150,33 +183,9 @@ namespace libtorrent
|
|||||||
|
|
||||||
// this is a callback called by the tracker_connection class
|
// this is a callback called by the tracker_connection class
|
||||||
// when this torrent got a response from its tracker request
|
// when this torrent got a response from its tracker request
|
||||||
void tracker_response(const entry& e);
|
virtual void tracker_response(const entry& e);
|
||||||
|
virtual void tracker_request_timed_out();
|
||||||
void tracker_request_timed_out()
|
virtual void tracker_request_error(const char* str);
|
||||||
{
|
|
||||||
#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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// generates a request string for sending
|
// generates a request string for sending
|
||||||
// to the tracker
|
// to the tracker
|
||||||
@@ -324,6 +333,11 @@ namespace libtorrent
|
|||||||
// std::accumulate(m_have_pieces.begin(),
|
// std::accumulate(m_have_pieces.begin(),
|
||||||
// m_have_pieces.end(), 0)
|
// m_have_pieces.end(), 0)
|
||||||
int m_num_pieces;
|
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
|
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
|
enum state_t
|
||||||
{
|
{
|
||||||
queued_for_checking,
|
queued_for_checking,
|
||||||
checking_files,
|
checking_files,
|
||||||
|
connecting_to_tracker,
|
||||||
downloading,
|
downloading,
|
||||||
seeding
|
seeding
|
||||||
};
|
};
|
||||||
@@ -76,17 +89,23 @@ namespace libtorrent
|
|||||||
boost::posix_time::time_duration next_announce;
|
boost::posix_time::time_duration next_announce;
|
||||||
|
|
||||||
// transferred this session!
|
// transferred this session!
|
||||||
|
// total, payload plus protocol
|
||||||
std::size_t total_download;
|
std::size_t total_download;
|
||||||
std::size_t total_upload;
|
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 download_rate;
|
||||||
float upload_rate;
|
float upload_rate;
|
||||||
|
|
||||||
std::vector<bool> pieces;
|
std::vector<bool> pieces;
|
||||||
|
|
||||||
// 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
|
||||||
@@ -103,6 +122,8 @@ namespace libtorrent
|
|||||||
struct torrent_handle
|
struct torrent_handle
|
||||||
{
|
{
|
||||||
friend class session;
|
friend class session;
|
||||||
|
friend class torrent;
|
||||||
|
|
||||||
torrent_handle(): m_ses(0) {}
|
torrent_handle(): m_ses(0) {}
|
||||||
|
|
||||||
void get_peer_info(std::vector<peer_info>& v) const;
|
void get_peer_info(std::vector<peer_info>& v) const;
|
||||||
|
@@ -35,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
alert_manager::alert_manager()
|
alert_manager::alert_manager()
|
||||||
: m_severity(alert::warning)
|
: m_severity(alert::none)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
alert_manager::~alert_manager()
|
alert_manager::~alert_manager()
|
||||||
|
241
src/identify_client.cpp
Executable file
241
src/identify_client.cpp
Executable file
@@ -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/peer_connection.hpp"
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
|
#include "libtorrent/identify_client.hpp"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define for if (false) {} else for
|
#define for if (false) {} else for
|
||||||
@@ -381,7 +382,6 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|||||||
{
|
{
|
||||||
m_have_piece[index] = true;
|
m_have_piece[index] = true;
|
||||||
|
|
||||||
// TODO: maybe this if-statement should be moved into the policy
|
|
||||||
m_torrent->peer_has(index);
|
m_torrent->peer_has(index);
|
||||||
if (!m_torrent->have_piece(index) && !is_interesting())
|
if (!m_torrent->have_piece(index) && !is_interesting())
|
||||||
m_torrent->get_policy().peer_is_interesting(*this);
|
m_torrent->get_policy().peer_is_interesting(*this);
|
||||||
@@ -859,12 +859,12 @@ void libtorrent::peer_connection::second_tick()
|
|||||||
int bias = 0;
|
int bias = 0;
|
||||||
if (diff > -2*m_torrent->block_size())
|
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;
|
if (bias < 10*1024) bias = 10*1024;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bias = -m_statistics.download_rate() * .5;
|
bias = -m_statistics.download_rate() / 2;
|
||||||
}
|
}
|
||||||
m_send_quota_limit = m_statistics.download_rate() + bias;
|
m_send_quota_limit = m_statistics.download_rate() + bias;
|
||||||
// the maximum send_quota given our download rate from this peer
|
// 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;
|
if (m_recv_pos < m_packet_size) break;
|
||||||
assert(m_recv_pos == m_packet_size);
|
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)
|
if (m_active)
|
||||||
{
|
{
|
||||||
// verify peer_id
|
// verify peer_id
|
||||||
@@ -1052,7 +1062,7 @@ void libtorrent::peer_connection::receive_data()
|
|||||||
if (m_torrent->has_peer(m_peer_id))
|
if (m_torrent->has_peer(m_peer_id))
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
(*m_logger) << m_socket->sender().as_string() << " duplicate connection, closing\n";
|
(*m_logger) << " duplicate connection, closing\n";
|
||||||
#endif
|
#endif
|
||||||
throw network_error(0);
|
throw network_error(0);
|
||||||
}
|
}
|
||||||
@@ -1066,9 +1076,7 @@ void libtorrent::peer_connection::receive_data()
|
|||||||
m_packet_size = 4;
|
m_packet_size = 4;
|
||||||
m_recv_pos = 0;
|
m_recv_pos = 0;
|
||||||
m_recv_buffer.resize(4);
|
m_recv_buffer.resize(4);
|
||||||
#ifndef NDEBUG
|
|
||||||
(*m_logger) << m_socket->sender().as_string() << " received peer_id\n";
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1234,7 +1242,7 @@ void libtorrent::peer_connection::send_data()
|
|||||||
, amount_to_send);
|
, amount_to_send);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#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
|
#endif
|
||||||
|
|
||||||
if (sent > 0)
|
if (sent > 0)
|
||||||
|
@@ -593,8 +593,8 @@ namespace libtorrent
|
|||||||
assert(i != m_peers.end());
|
assert(i != m_peers.end());
|
||||||
|
|
||||||
i->connected = boost::posix_time::second_clock::local_time();
|
i->connected = boost::posix_time::second_clock::local_time();
|
||||||
i->prev_amount_download += c.statistics().total_download();
|
i->prev_amount_download += c.statistics().total_payload_download();
|
||||||
i->prev_amount_upload += c.statistics().total_upload();
|
i->prev_amount_upload += c.statistics().total_payload_upload();
|
||||||
if (!i->connection->is_choked() && !m_torrent->is_aborted())
|
if (!i->connection->is_choked() && !m_torrent->is_aborted())
|
||||||
{
|
{
|
||||||
--m_num_unchoked;
|
--m_num_unchoked;
|
||||||
@@ -651,7 +651,7 @@ namespace libtorrent
|
|||||||
int policy::peer::total_download() const
|
int policy::peer::total_download() const
|
||||||
{
|
{
|
||||||
if (connection != 0)
|
if (connection != 0)
|
||||||
return connection->statistics().total_download()
|
return connection->statistics().total_payload_download()
|
||||||
+ prev_amount_download;
|
+ prev_amount_download;
|
||||||
else
|
else
|
||||||
return prev_amount_download;
|
return prev_amount_download;
|
||||||
@@ -660,7 +660,7 @@ namespace libtorrent
|
|||||||
int policy::peer::total_upload() const
|
int policy::peer::total_upload() const
|
||||||
{
|
{
|
||||||
if (connection != 0)
|
if (connection != 0)
|
||||||
return connection->statistics().total_upload()
|
return connection->statistics().total_payload_upload()
|
||||||
+ prev_amount_upload;
|
+ prev_amount_upload;
|
||||||
else
|
else
|
||||||
return prev_amount_upload;
|
return prev_amount_upload;
|
||||||
|
204
src/session.cpp
204
src/session.cpp
@@ -337,6 +337,7 @@ namespace libtorrent
|
|||||||
, m_tracker_manager(m_settings)
|
, m_tracker_manager(m_settings)
|
||||||
, m_listen_port(listen_port)
|
, m_listen_port(listen_port)
|
||||||
, m_upload_rate(-1)
|
, m_upload_rate(-1)
|
||||||
|
, m_incoming_connection(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
// ---- generate a peer id ----
|
// ---- generate a peer id ----
|
||||||
@@ -462,6 +463,7 @@ namespace libtorrent
|
|||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
// we got a connection request!
|
// we got a connection request!
|
||||||
|
m_incoming_connection = true;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
(*m_logger) << s->sender().as_string() << " <== INCOMING CONNECTION\n";
|
(*m_logger) << s->sender().as_string() << " <== INCOMING CONNECTION\n";
|
||||||
#endif
|
#endif
|
||||||
@@ -864,203 +866,15 @@ namespace libtorrent
|
|||||||
|
|
||||||
std::auto_ptr<alert> session::pop_alert()
|
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)
|
||||||
{
|
{
|
||||||
|
m_impl.m_alerts.set_severity(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";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -51,10 +51,10 @@ void libtorrent::stat::second_tick()
|
|||||||
m_upload_per_second_history+history-1,
|
m_upload_per_second_history+history-1,
|
||||||
m_upload_per_second_history+1);
|
m_upload_per_second_history+1);
|
||||||
|
|
||||||
m_download_per_second_history[0] = m_downloaded + m_downloaded_protocol;
|
m_download_per_second_history[0] = m_downloaded_payload + m_downloaded_protocol;
|
||||||
m_upload_per_second_history[0] = m_uploaded + m_uploaded_protocol;
|
m_upload_per_second_history[0] = m_uploaded_payload + m_uploaded_protocol;
|
||||||
m_downloaded = 0;
|
m_downloaded_payload = 0;
|
||||||
m_uploaded = 0;
|
m_uploaded_payload = 0;
|
||||||
m_downloaded_protocol = 0;
|
m_downloaded_protocol = 0;
|
||||||
m_uploaded_protocol = 0;
|
m_uploaded_protocol = 0;
|
||||||
|
|
||||||
|
@@ -51,6 +51,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/peer.hpp"
|
#include "libtorrent/peer.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
#include "libtorrent/alert.hpp"
|
||||||
|
#include "libtorrent/identify_client.hpp"
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||||
namespace std
|
namespace std
|
||||||
@@ -177,6 +179,7 @@ namespace libtorrent
|
|||||||
, m_time_scaler(0)
|
, m_time_scaler(0)
|
||||||
, m_priority(.5)
|
, m_priority(.5)
|
||||||
, m_num_pieces(0)
|
, m_num_pieces(0)
|
||||||
|
, m_got_tracker_response(false)
|
||||||
{
|
{
|
||||||
assert(torrent_file.begin_files() != torrent_file.end_files());
|
assert(torrent_file.begin_files() != torrent_file.end_files());
|
||||||
m_have_pieces.resize(torrent_file.num_pieces(), false);
|
m_have_pieces.resize(torrent_file.num_pieces(), false);
|
||||||
@@ -250,6 +253,7 @@ namespace libtorrent
|
|||||||
tracker_request_error(e.what());
|
tracker_request_error(e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_got_tracker_response = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool torrent::has_peer(const peer_id& id) const
|
bool torrent::has_peer(const peer_id& id) const
|
||||||
@@ -282,6 +286,13 @@ namespace libtorrent
|
|||||||
|
|
||||||
void torrent::piece_failed(int index)
|
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;
|
std::vector<peer_id> downloaders;
|
||||||
m_picker.get_downloaders(downloaders, index);
|
m_picker.get_downloaders(downloaders, index);
|
||||||
|
|
||||||
@@ -365,10 +376,10 @@ namespace libtorrent
|
|||||||
request += boost::lexical_cast<std::string>(port);
|
request += boost::lexical_cast<std::string>(port);
|
||||||
|
|
||||||
request += "&uploaded=";
|
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 += "&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 += "&left=";
|
||||||
request += boost::lexical_cast<std::string>(bytes_left());
|
request += boost::lexical_cast<std::string>(bytes_left());
|
||||||
@@ -450,7 +461,7 @@ namespace libtorrent
|
|||||||
m_connections.erase(i);
|
m_connections.erase(i);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_picker.integrity_check(this);
|
// m_picker.integrity_check(this);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,10 +639,20 @@ namespace libtorrent
|
|||||||
- blocks_per_piece;
|
- blocks_per_piece;
|
||||||
}
|
}
|
||||||
|
|
||||||
st.total_download = m_stat.total_download();
|
// payload transfer
|
||||||
st.total_upload = m_stat.total_upload();
|
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.download_rate = m_stat.download_rate();
|
||||||
st.upload_rate = m_stat.upload_rate();
|
st.upload_rate = m_stat.upload_rate();
|
||||||
|
|
||||||
st.progress = (blocks_we_have + unverified_blocks)
|
st.progress = (blocks_we_have + unverified_blocks)
|
||||||
/ static_cast<float>(total_blocks);
|
/ static_cast<float>(total_blocks);
|
||||||
|
|
||||||
@@ -644,7 +665,9 @@ namespace libtorrent
|
|||||||
st.total_done = (blocks_we_have + unverified_blocks) * m_block_size;
|
st.total_done = (blocks_we_have + unverified_blocks) * m_block_size;
|
||||||
st.pieces = m_have_pieces;
|
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;
|
st.state = torrent_status::seeding;
|
||||||
else
|
else
|
||||||
st.state = torrent_status::downloading;
|
st.state = torrent_status::downloading;
|
||||||
@@ -652,6 +675,53 @@ namespace libtorrent
|
|||||||
return st;
|
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
|
#ifndef NDEBUG
|
||||||
void torrent::debug_log(const std::string& line)
|
void torrent::debug_log(const std::string& line)
|
||||||
{
|
{
|
||||||
|
@@ -68,7 +68,6 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
if (m_ses == 0) throw invalid_handle();
|
if (m_ses == 0) throw invalid_handle();
|
||||||
|
|
||||||
assert(m_chk != 0);
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
||||||
torrent* t = m_ses->find_torrent(m_info_hash);
|
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);
|
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||||
|
|
||||||
@@ -97,13 +97,13 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
if (m_ses == 0) throw invalid_handle();
|
if (m_ses == 0) throw invalid_handle();
|
||||||
|
|
||||||
assert(m_chk != 0);
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
||||||
torrent* t = m_ses->find_torrent(m_info_hash);
|
torrent* t = m_ses->find_torrent(m_info_hash);
|
||||||
if (t != 0) return t->status();
|
if (t != 0) return t->status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_chk)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||||
|
|
||||||
@@ -111,10 +111,7 @@ namespace libtorrent
|
|||||||
if (d != 0)
|
if (d != 0)
|
||||||
{
|
{
|
||||||
torrent_status st;
|
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())
|
if (d == &m_chk->m_torrents.front())
|
||||||
st.state = torrent_status::checking_files;
|
st.state = torrent_status::checking_files;
|
||||||
else
|
else
|
||||||
@@ -123,7 +120,6 @@ namespace libtorrent
|
|||||||
st.next_announce = boost::posix_time::time_duration();
|
st.next_announce = boost::posix_time::time_duration();
|
||||||
st.pieces.clear();
|
st.pieces.clear();
|
||||||
st.pieces.resize(d->torrent_ptr->torrent_file().num_pieces(), false);
|
st.pieces.resize(d->torrent_ptr->torrent_file().num_pieces(), false);
|
||||||
st.total_done = 0;
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,6 +137,7 @@ namespace libtorrent
|
|||||||
if (t != 0) return t->torrent_file();
|
if (t != 0) return t->torrent_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_chk)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||||
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
||||||
@@ -160,6 +157,7 @@ namespace libtorrent
|
|||||||
if (t != 0) return true;
|
if (t != 0) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_chk)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||||
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
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);
|
boost::mutex::scoped_lock l(m_chk->m_mutex);
|
||||||
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
||||||
@@ -207,7 +206,6 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
v.clear();
|
v.clear();
|
||||||
if (m_ses == 0) throw invalid_handle();
|
if (m_ses == 0) throw invalid_handle();
|
||||||
assert(m_chk != 0);
|
|
||||||
|
|
||||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
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
|
// TODO: add the prev_amount_downloaded and prev_amount_uploaded
|
||||||
// from the peer list in the policy
|
// from the peer list in the policy
|
||||||
p.total_download = statistics.total_download();
|
p.total_download = statistics.total_payload_download();
|
||||||
p.total_upload = statistics.total_upload();
|
p.total_upload = statistics.total_payload_upload();
|
||||||
|
|
||||||
p.upload_limit = peer->send_quota();
|
p.upload_limit = peer->send_quota();
|
||||||
p.upload_ceiling = peer->send_quota_limit();
|
p.upload_ceiling = peer->send_quota_limit();
|
||||||
@@ -274,7 +272,6 @@ namespace libtorrent
|
|||||||
queue.clear();
|
queue.clear();
|
||||||
|
|
||||||
if (m_ses == 0) throw invalid_handle();
|
if (m_ses == 0) throw invalid_handle();
|
||||||
assert(m_chk != 0);
|
|
||||||
|
|
||||||
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
boost::mutex::scoped_lock l(m_ses->m_mutex);
|
||||||
torrent* t = m_ses->find_torrent(m_info_hash);
|
torrent* t = m_ses->find_torrent(m_info_hash);
|
||||||
|
Reference in New Issue
Block a user