added a setting for max outstanding requests, and a limit for BitComet since it's known to have a very low limit, also added an extension header to specify it. Fixed another unnecessary delay spotted by Tianhao Qiu. Cleaned up the logging class a bit. Fixed a bug that would cause an assert when removing a torrent queued for checking.
This commit is contained in:
parent
73b1c5c9b8
commit
0b529e8f96
|
@ -3,10 +3,130 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.9: http://docutils.sourceforge.net/" />
|
||||
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
|
||||
<title></title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com Ludvig Strigeus, ludde@utorrent.com" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
|
||||
body
|
||||
{
|
||||
background-color: white;
|
||||
color: black;
|
||||
margin: 1em 2em 1em 2em;
|
||||
}
|
||||
|
||||
h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; font-size: 140%; }
|
||||
h2 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; font-size: 110%; }
|
||||
h3 { font-family: "courier new", courier, monospace; font-weight: bold; text-align: left; font-size: 100%; }
|
||||
|
||||
pre
|
||||
{
|
||||
border: gray 1pt solid;
|
||||
padding: 2pt;
|
||||
|
||||
display: block;
|
||||
font-family: "courier new", courier, monospace;
|
||||
background-color: #eeeeee;
|
||||
color: black;
|
||||
font-size: small
|
||||
}
|
||||
|
||||
code
|
||||
{
|
||||
white-space: pre;
|
||||
border: gray 1pt solid;
|
||||
padding: 2pt;
|
||||
|
||||
display: block;
|
||||
font-family: "courier new", courier, monospace;
|
||||
color: black;
|
||||
font-size: small
|
||||
}
|
||||
|
||||
tt
|
||||
{
|
||||
display: inline;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
|
||||
p
|
||||
{
|
||||
text-align: justify;
|
||||
font-family: Georgia, "Times New Roman", Times, serif
|
||||
}
|
||||
|
||||
ul
|
||||
{
|
||||
font-family: Georgia, "Times New Roman", Times, serif
|
||||
}
|
||||
|
||||
ol
|
||||
{
|
||||
font-family: Georgia, "Times New Roman", Times, serif
|
||||
}
|
||||
|
||||
a:link
|
||||
{
|
||||
font-weight: bold;
|
||||
color: #003366;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:visited
|
||||
{
|
||||
font-weight: bold;
|
||||
color: #003366;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
table
|
||||
{
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table td
|
||||
{
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
table th
|
||||
{
|
||||
border: 3px solid black;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
table.menu
|
||||
{
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
table.menu td
|
||||
{
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
|
||||
td
|
||||
{
|
||||
border: 1px solid black
|
||||
}
|
||||
|
||||
div.warning, div.note, div.important {
|
||||
width: 80%;
|
||||
margin: 1.5em auto;
|
||||
background: #C1E5F6;
|
||||
background: #F1FFF5;
|
||||
border: solid 1px #D1DFD5;
|
||||
padding: 5px 10px 5px 10px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
|
@ -19,8 +139,8 @@
|
|||
Ludvig Strigeus, <a class="last reference" href="mailto:ludde@utorrent.com">ludde@utorrent.com</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="extension-protocol-for-bittorrent">
|
||||
<h1><a name="extension-protocol-for-bittorrent">extension protocol for bittorrent</a></h1>
|
||||
<div class="section">
|
||||
<h1><a id="extension-protocol-for-bittorrent" name="extension-protocol-for-bittorrent">extension protocol for bittorrent</a></h1>
|
||||
<p>The intention of this protocol is to provide a simple and thin transport
|
||||
for extensions to the bittorrent protocol. Supporting this protocol makes
|
||||
it easy to add new extensions without interfering with the standard
|
||||
|
@ -88,8 +208,8 @@ message as specified by the handshake.</td>
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="handshake-message">
|
||||
<h2><a name="handshake-message">handshake message</a></h2>
|
||||
<div class="section">
|
||||
<h2><a id="handshake-message" name="handshake-message">handshake message</a></h2>
|
||||
<p>The payload of the handshake message is a bencoded dictionary. All items
|
||||
in the dictionary are optional. Any unknown names should be ignored
|
||||
by the client. All parts of the dictionary are case sensitive.
|
||||
|
@ -140,6 +260,11 @@ known.</td>
|
|||
This is a much more reliable way of identifying the
|
||||
client than relying on the peer id encoding.</td>
|
||||
</tr>
|
||||
<tr><td>reqq</td>
|
||||
<td>An integer, the number of outstanding request messages
|
||||
this client supports without dropping any. The default in
|
||||
in libtorrent is 250.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The handshake dictionary could also include extended handshake
|
||||
|
@ -214,8 +339,8 @@ for the actual extensions to the bittorrent protocol and the extensions
|
|||
named in the example above (such as <tt class="docutils literal"><span class="pre">p</span></tt>) are just examples of possible
|
||||
extensions.</p>
|
||||
</div>
|
||||
<div class="section" id="rationale">
|
||||
<h2><a name="rationale">rationale</a></h2>
|
||||
<div class="section">
|
||||
<h2><a id="rationale" name="rationale">rationale</a></h2>
|
||||
<p>The reason why the extension messages' IDs would be defined in the handshake
|
||||
is to avoid having a global registry somewhere, where ID's are assigned
|
||||
global identifiers. Now the extensions have unique names.</p>
|
||||
|
|
|
@ -87,6 +87,10 @@ Here are two other items that an implementation may choose to support:
|
|||
| | This is a much more reliable way of identifying the |
|
||||
| | client than relying on the peer id encoding. |
|
||||
+-------+-----------------------------------------------------------+
|
||||
| reqq | An integer, the number of outstanding request messages |
|
||||
| | this client supports without dropping any. The default in |
|
||||
| | in libtorrent is 250. |
|
||||
+-------+-----------------------------------------------------------+
|
||||
|
||||
The handshake dictionary could also include extended handshake
|
||||
information, such as support for encrypted headers or anything
|
||||
|
|
|
@ -229,60 +229,61 @@ div.warning, div.note, div.important {
|
|||
<li><a class="reference" href="#fingerprint" id="id96" name="id96">fingerprint</a></li>
|
||||
<li><a class="reference" href="#free-functions" id="id97" name="id97">free functions</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id98" name="id98">identify_client()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id99" name="id99">bdecode() bencode()</a></li>
|
||||
<li><a class="reference" href="#client-fingerprint" id="id99" name="id99">client_fingerprint()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id100" name="id100">bdecode() bencode()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#alerts" id="id100" name="id100">alerts</a><ul>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id101" name="id101">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id102" name="id102">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id103" name="id103">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id104" name="id104">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id105" name="id105">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id106" name="id106">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id107" name="id107">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id108" name="id108">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id109" name="id109">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id110" name="id110">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id111" name="id111">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id112" name="id112">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id113" name="id113">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id114" name="id114">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id115" name="id115">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id116" name="id116">dispatcher</a></li>
|
||||
<li><a class="reference" href="#alerts" id="id101" name="id101">alerts</a><ul>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id102" name="id102">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id103" name="id103">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id104" name="id104">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id105" name="id105">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id106" name="id106">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id107" name="id107">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id108" name="id108">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id109" name="id109">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id110" name="id110">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id111" name="id111">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id112" name="id112">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id113" name="id113">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id114" name="id114">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id115" name="id115">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id116" name="id116">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id117" name="id117">dispatcher</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#exceptions" id="id117" name="id117">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id118" name="id118">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id119" name="id119">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id120" name="id120">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id121" name="id121">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id122" name="id122">invalid_torrent_file</a></li>
|
||||
<li><a class="reference" href="#exceptions" id="id118" name="id118">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id119" name="id119">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id120" name="id120">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id121" name="id121">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id122" name="id122">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id123" name="id123">invalid_torrent_file</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#examples" id="id123" name="id123">examples</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id124" name="id124">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id125" name="id125">simple client</a></li>
|
||||
<li><a class="reference" href="#make-torrent" id="id126" name="id126">make_torrent</a></li>
|
||||
<li><a class="reference" href="#examples" id="id124" name="id124">examples</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id125" name="id125">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id126" name="id126">simple client</a></li>
|
||||
<li><a class="reference" href="#make-torrent" id="id127" name="id127">make_torrent</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#fast-resume" id="id127" name="id127">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id128" name="id128">file format</a></li>
|
||||
<li><a class="reference" href="#fast-resume" id="id128" name="id128">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id129" name="id129">file format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#threads" id="id129" name="id129">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id130" name="id130">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#full-allocation" id="id131" name="id131">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id132" name="id132">compact allocation</a></li>
|
||||
<li><a class="reference" href="#threads" id="id130" name="id130">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id131" name="id131">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#full-allocation" id="id132" name="id132">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id133" name="id133">compact allocation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#extensions" id="id133" name="id133">extensions</a><ul>
|
||||
<li><a class="reference" href="#chat-messages" id="id134" name="id134">chat messages</a></li>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id135" name="id135">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id136" name="id136">HTTP seeding</a></li>
|
||||
<li><a class="reference" href="#extensions" id="id134" name="id134">extensions</a><ul>
|
||||
<li><a class="reference" href="#chat-messages" id="id135" name="id135">chat messages</a></li>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id136" name="id136">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id137" name="id137">HTTP seeding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#filename-checks" id="id137" name="id137">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgements" id="id138" name="id138">acknowledgements</a></li>
|
||||
<li><a class="reference" href="#filename-checks" id="id138" name="id138">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgements" id="id139" name="id139">acknowledgements</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
|
@ -2459,6 +2460,18 @@ to extract a string describing a client version from its peer-id. It will recogn
|
|||
that have this kind of identification in the peer-id.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="client-fingerprint" name="client-fingerprint">client_fingerprint()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
boost::optional<fingerprint> client_fingerprint(peer_id const& p);
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Returns an optional fingerprint if any can be identified from the peer id. This can be used
|
||||
to automate the identification of clients. It will not be able to identifiy peers with non-
|
||||
standard encodings. Only Azureus style, Shadow's style and Mainline style. This function is
|
||||
declared in the header <tt class="docutils literal"><span class="pre"><libtorrent/identify_client.hpp></span></tt>.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="bdecode-bencode" name="bdecode-bencode">bdecode() bencode()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
|
|
|
@ -2346,6 +2346,20 @@ This function is declared in the header ``<libtorrent/identify_client.hpp>``. It
|
|||
to extract a string describing a client version from its peer-id. It will recognize most clients
|
||||
that have this kind of identification in the peer-id.
|
||||
|
||||
|
||||
client_fingerprint()
|
||||
--------------------
|
||||
|
||||
::
|
||||
|
||||
boost::optional<fingerprint> client_fingerprint(peer_id const& p);
|
||||
|
||||
Returns an optional fingerprint if any can be identified from the peer id. This can be used
|
||||
to automate the identification of clients. It will not be able to identifiy peers with non-
|
||||
standard encodings. Only Azureus style, Shadow's style and Mainline style. This function is
|
||||
declared in the header ``<libtorrent/identify_client.hpp>``.
|
||||
|
||||
|
||||
bdecode() bencode()
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -67,63 +67,22 @@ namespace libtorrent
|
|||
|
||||
struct logger
|
||||
{
|
||||
logger& operator<<(const char* t)
|
||||
{ assert(t); log(t); return *this; }
|
||||
logger& operator<<(const std::string& t)
|
||||
{ log(t.c_str()); return *this; }
|
||||
logger& operator<<(int i)
|
||||
{
|
||||
log(boost::lexical_cast<std::string>(i).c_str());
|
||||
return *this;
|
||||
}
|
||||
logger& operator<<(unsigned int i)
|
||||
{
|
||||
log(boost::lexical_cast<std::string>(i).c_str());
|
||||
return *this;
|
||||
}
|
||||
logger& operator<<(float i)
|
||||
{
|
||||
log(boost::lexical_cast<std::string>(i).c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
logger& operator<<(char i)
|
||||
{
|
||||
char c[2];
|
||||
c[0] = i;
|
||||
c[1] = 0;
|
||||
log(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void log(const char*) = 0;
|
||||
virtual ~logger() {}
|
||||
};
|
||||
|
||||
struct null_logger: libtorrent::logger
|
||||
{
|
||||
public:
|
||||
virtual void log(const char*) {}
|
||||
};
|
||||
|
||||
struct cout_logger: libtorrent::logger
|
||||
{
|
||||
public:
|
||||
virtual void log(const char* text) { std::cout << text; }
|
||||
};
|
||||
|
||||
struct file_logger: libtorrent::logger
|
||||
{
|
||||
public:
|
||||
file_logger(boost::filesystem::path const& filename, bool append = true)
|
||||
logger(boost::filesystem::path const& filename, bool append = true)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
path dir(complete("libtorrent_logs"));
|
||||
if (!exists(dir)) create_directories(dir);
|
||||
m_file.open(dir / filename, std::ios_base::out | (append ? std::ios_base::app : std::ios_base::out));
|
||||
log("\n\n\n*** starting log ***\n");
|
||||
*this << "\n\n\n*** starting log ***\n";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
logger& operator<<(T const& v)
|
||||
{
|
||||
m_file << v;
|
||||
m_file.flush();
|
||||
return *this;
|
||||
}
|
||||
virtual void log(const char* text) { assert(text); m_file << text; m_file.flush(); }
|
||||
|
||||
boost::filesystem::ofstream m_file;
|
||||
};
|
||||
|
|
|
@ -34,12 +34,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/fingerprint.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
TORRENT_EXPORT std::string identify_client(const peer_id& p);
|
||||
TORRENT_EXPORT boost::optional<fingerprint> client_fingerprint(peer_id const& p);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -261,6 +261,7 @@ namespace libtorrent
|
|||
// adds a block to the request queue
|
||||
void add_request(piece_block const& b);
|
||||
void cancel_request(piece_block const& b);
|
||||
void send_block_requests();
|
||||
|
||||
// how much bandwidth we're using, how much we want,
|
||||
// and how much we are allowed to use.
|
||||
|
@ -360,10 +361,16 @@ namespace libtorrent
|
|||
void on_receive_data(asio::error const& error
|
||||
, std::size_t bytes_transferred);
|
||||
|
||||
// this is the limit on the number of outstanding requests
|
||||
// we have to this peer. This is initialized to the settings
|
||||
// in the session_settings structure. But it may be lowered
|
||||
// if the peer is known to require a smaller limit (like BitComet).
|
||||
// or if the extended handshake sets a limit.
|
||||
int m_max_out_request_queue;
|
||||
|
||||
private:
|
||||
|
||||
void fill_send_buffer();
|
||||
void send_block_requests();
|
||||
|
||||
// the timeout in seconds
|
||||
int m_timeout;
|
||||
|
@ -386,7 +393,6 @@ namespace libtorrent
|
|||
// buffer, the other is used to write data to
|
||||
// be queued up.
|
||||
std::vector<char> m_send_buffer[2];
|
||||
// buffer m_send_buffer[2];
|
||||
// the current send buffer is the one to write to.
|
||||
// (m_current_send_buffer + 1) % 2 is the
|
||||
// buffer we're currently waiting for.
|
||||
|
@ -394,7 +400,7 @@ namespace libtorrent
|
|||
|
||||
// if the sending buffer doesn't finish in one send
|
||||
// operation, this is the position within that buffer
|
||||
// wher the next operation should continue
|
||||
// where the next operation should continue
|
||||
int m_write_pos;
|
||||
|
||||
// timeouts
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace libtorrent
|
|||
// the number of bytes of the number
|
||||
enum { number_size = 20 };
|
||||
public:
|
||||
enum { size = number_size };
|
||||
|
||||
big_number() {}
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ namespace libtorrent
|
|||
enum
|
||||
{
|
||||
// the limits of the download queue size
|
||||
max_request_queue = 48,
|
||||
min_request_queue = 2,
|
||||
|
||||
// the amount of free upload allowed before
|
||||
|
|
|
@ -42,8 +42,10 @@ namespace libtorrent
|
|||
: piece_timeout(120)
|
||||
, request_queue_time(3.f)
|
||||
, sequenced_download_threshold(7)
|
||||
, max_allowed_request_queue(200)
|
||||
{}
|
||||
, max_allowed_in_request_queue(250)
|
||||
, max_out_request_queue(200)
|
||||
, whole_pieces_threshold(20)
|
||||
{}
|
||||
|
||||
// the number of seconds from a request is sent until
|
||||
// it times out if no piece response is returned.
|
||||
|
@ -70,7 +72,20 @@ namespace libtorrent
|
|||
// been sent) the last request will be dropped.
|
||||
// the higher this is, the faster upload speeds the
|
||||
// client can get to a single peer.
|
||||
int max_allowed_request_queue;
|
||||
int max_allowed_in_request_queue;
|
||||
|
||||
// the maximum number of outstanding requests to
|
||||
// send to a peer. This limit takes precedence over
|
||||
// request_queue_time.
|
||||
int max_out_request_queue;
|
||||
|
||||
// if a whole piece can be downloaded in this number
|
||||
// of seconds, or less, the peer_connection will prefer
|
||||
// to request whole pieces at a time from this peer.
|
||||
// The benefit of this is to better utilize disk caches by
|
||||
// doing localized accesses and also to make it easier
|
||||
// to identify bad peers if a piece fails the hash check.
|
||||
int whole_pieces_threshold;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,8 @@ namespace libtorrent
|
|||
// by the checker thread.
|
||||
bool is_allocating() const;
|
||||
|
||||
session_settings const& settings() const;
|
||||
|
||||
// is called every second by session. This will
|
||||
// caclulate the upload/download and number
|
||||
// of connections this torrent needs. And prepare
|
||||
|
|
|
@ -724,6 +724,14 @@ namespace libtorrent
|
|||
if (client_info->type() == entry::string_t)
|
||||
m_client_version = client_info->string();
|
||||
}
|
||||
|
||||
if (entry* reqq = root.find_key("reqq"))
|
||||
{
|
||||
if (reqq->type() == entry::int_t)
|
||||
m_max_out_request_queue = reqq->integer();
|
||||
if (m_max_out_request_queue < 1)
|
||||
m_max_out_request_queue = 1;
|
||||
}
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
{
|
||||
|
@ -1113,6 +1121,7 @@ namespace libtorrent
|
|||
handshake["m"] = extension_list;
|
||||
handshake["p"] = m_ses.m_listen_interface.port();
|
||||
handshake["v"] = m_ses.m_http_settings.user_agent;
|
||||
handshake["reqq"] = m_ses.m_settings.max_allowed_in_request_queue;
|
||||
|
||||
std::vector<char> msg;
|
||||
bencode(std::back_inserter(msg), handshake);
|
||||
|
@ -1395,12 +1404,18 @@ namespace libtorrent
|
|||
set_pid(pid);
|
||||
|
||||
m_client_version = identify_client(pid);
|
||||
boost::optional<fingerprint> f = client_fingerprint(pid);
|
||||
if (f && std::equal(f->name, f->name + 2, "BC"))
|
||||
{
|
||||
// if this is a bitcomet client, lower the request queue size limit
|
||||
if (m_max_out_request_queue > 50) m_max_out_request_queue = 50;
|
||||
}
|
||||
|
||||
// disconnect if the peer has the same peer-id as ourself
|
||||
// since it most likely is ourself then
|
||||
if (pid == m_ses.get_peer_id())
|
||||
throw std::runtime_error("closing connection to ourself");
|
||||
|
||||
|
||||
if (m_supports_extensions) write_extensions();
|
||||
/*
|
||||
if (!m_active)
|
||||
|
|
|
@ -247,6 +247,7 @@ namespace libtorrent
|
|||
{
|
||||
throw_exception("file::seek");
|
||||
}
|
||||
return offs.QuadPart;
|
||||
}
|
||||
|
||||
size_type tell()
|
||||
|
@ -264,8 +265,8 @@ namespace libtorrent
|
|||
throw_exception("file::tell");
|
||||
}
|
||||
|
||||
size_type pos=offs.QuadPart;
|
||||
assert(pos>=0);
|
||||
size_type pos = offs.QuadPart;
|
||||
assert(pos >= 0);
|
||||
return pos;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -226,7 +226,24 @@ namespace
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
std::string identify_client(const peer_id& p)
|
||||
boost::optional<fingerprint> client_fingerprint(peer_id const& p)
|
||||
{
|
||||
// look for azureus style id
|
||||
boost::optional<fingerprint> f;
|
||||
f = parse_az_style(p);
|
||||
if (f) return f;
|
||||
|
||||
// look for shadow style id
|
||||
f = parse_shadow_style(p);
|
||||
if (f) return f;
|
||||
|
||||
// look for mainline style id
|
||||
f = parse_mainline_style(p);
|
||||
if (f) return f;
|
||||
return f;
|
||||
}
|
||||
|
||||
std::string identify_client(peer_id const& p)
|
||||
{
|
||||
peer_id::const_iterator PID = p.begin();
|
||||
boost::optional<fingerprint> f;
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace libtorrent
|
|||
,
|
||||
#endif
|
||||
m_ses(ses)
|
||||
, m_max_out_request_queue(m_ses.m_settings.max_out_request_queue)
|
||||
, m_timeout(120)
|
||||
, m_last_piece(second_clock::universal_time())
|
||||
, m_packet_size(0)
|
||||
|
@ -172,6 +173,7 @@ namespace libtorrent
|
|||
,
|
||||
#endif
|
||||
m_ses(ses)
|
||||
, m_max_out_request_queue(m_ses.m_settings.max_out_request_queue)
|
||||
, m_timeout(120)
|
||||
, m_last_piece(second_clock::universal_time())
|
||||
, m_packet_size(0)
|
||||
|
@ -792,7 +794,7 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
if (int(m_requests.size()) > m_ses.m_settings.max_allowed_request_queue)
|
||||
if (int(m_requests.size()) > m_ses.m_settings.max_allowed_in_request_queue)
|
||||
{
|
||||
// don't allow clients to abuse our
|
||||
// memory consumption.
|
||||
|
@ -830,7 +832,7 @@ namespace libtorrent
|
|||
return;
|
||||
|
||||
m_requests.push_back(r);
|
||||
setup_send();
|
||||
fill_send_buffer();
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
using namespace boost::posix_time;
|
||||
(*m_logger) << to_simple_string(second_clock::universal_time())
|
||||
|
@ -1093,7 +1095,6 @@ namespace libtorrent
|
|||
|
||||
t->picker().mark_as_downloading(block, m_remote);
|
||||
m_request_queue.push_back(block);
|
||||
send_block_requests();
|
||||
}
|
||||
|
||||
void peer_connection::cancel_request(piece_block const& block)
|
||||
|
@ -1410,10 +1411,10 @@ namespace libtorrent
|
|||
|
||||
m_desired_queue_size = static_cast<int>(queue_time
|
||||
* statistics().download_rate() / block_size);
|
||||
if (m_desired_queue_size > max_request_queue) m_desired_queue_size
|
||||
= max_request_queue;
|
||||
if (m_desired_queue_size < min_request_queue) m_desired_queue_size
|
||||
= min_request_queue;
|
||||
if (m_desired_queue_size > m_max_out_request_queue)
|
||||
m_desired_queue_size = m_max_out_request_queue;
|
||||
if (m_desired_queue_size < min_request_queue)
|
||||
m_desired_queue_size = min_request_queue;
|
||||
|
||||
if (!m_download_queue.empty()
|
||||
&& now - m_last_piece > seconds(m_ses.m_settings.piece_timeout))
|
||||
|
@ -1550,8 +1551,6 @@ namespace libtorrent
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!can_write()) return;
|
||||
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
if (!t) return;
|
||||
|
||||
|
@ -1778,8 +1777,7 @@ namespace libtorrent
|
|||
|
||||
// if we have requests or pending data to be sent or announcements to be made
|
||||
// we want to send data
|
||||
return ((!m_requests.empty() && !m_choked)
|
||||
|| !m_send_buffer[m_current_send_buffer].empty()
|
||||
return (!m_send_buffer[m_current_send_buffer].empty()
|
||||
|| !m_send_buffer[(m_current_send_buffer + 1) & 1].empty())
|
||||
&& m_ul_bandwidth_quota.left() > 0
|
||||
&& !m_connecting;
|
||||
|
|
|
@ -94,7 +94,8 @@ namespace
|
|||
// for this peer. If we're downloading one piece in 20 seconds
|
||||
// then use this mode.
|
||||
// TODO: 20 seconds has to be customizable
|
||||
bool prefer_whole_pieces = c.statistics().download_payload_rate() * 20.f
|
||||
bool prefer_whole_pieces = c.statistics().download_payload_rate()
|
||||
* t.settings().whole_pieces_threshold
|
||||
> t.torrent_file().piece_length();
|
||||
|
||||
// if we prefer whole pieces, the piece picker will pick at least
|
||||
|
@ -131,6 +132,8 @@ namespace
|
|||
num_requests--;
|
||||
}
|
||||
|
||||
c.send_block_requests();
|
||||
|
||||
// in this case, we could not find any blocks
|
||||
// that was free. If we couldn't find any busy
|
||||
// blocks as well, we cannot download anything
|
||||
|
@ -222,6 +225,7 @@ namespace
|
|||
|
||||
if (weight <= min_weight) break;
|
||||
}
|
||||
c.send_block_requests();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -372,6 +372,7 @@ namespace libtorrent { namespace detail
|
|||
for (std::deque<boost::shared_ptr<piece_checker_data> >::iterator i
|
||||
= m_processing.begin(); i != m_processing.end(); ++i)
|
||||
{
|
||||
|
||||
if ((*i)->info_hash == info_hash) return i->get();
|
||||
}
|
||||
|
||||
|
@ -390,6 +391,17 @@ namespace libtorrent { namespace detail
|
|||
return;
|
||||
}
|
||||
}
|
||||
for (std::deque<boost::shared_ptr<piece_checker_data> >::iterator i
|
||||
= m_processing.begin(); i != m_processing.end(); ++i)
|
||||
{
|
||||
if ((*i)->info_hash == info_hash)
|
||||
{
|
||||
assert((*i)->processing == false);
|
||||
m_torrents.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
@ -839,6 +851,9 @@ namespace libtorrent { namespace detail
|
|||
for (std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i
|
||||
= m_torrents.begin(); i != m_torrents.end(); ++i)
|
||||
{
|
||||
#ifndef DEBUG
|
||||
i->second->check_invariant();
|
||||
#endif
|
||||
i->second->distribute_resources();
|
||||
}
|
||||
}
|
||||
|
@ -955,7 +970,7 @@ namespace libtorrent { namespace detail
|
|||
boost::shared_ptr<logger> session_impl::create_log(std::string const& name, bool append)
|
||||
{
|
||||
// current options are file_logger, cout_logger and null_logger
|
||||
return boost::shared_ptr<logger>(new file_logger(name + ".log", append));
|
||||
return boost::shared_ptr<logger>(new logger(name + ".log", append));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1322,7 +1322,10 @@ namespace libtorrent
|
|||
return torrent_handle(&m_ses, 0, m_torrent_file.info_hash());
|
||||
}
|
||||
|
||||
|
||||
session_settings const& torrent::settings() const
|
||||
{
|
||||
return m_ses.m_settings;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void torrent::check_invariant() const
|
||||
|
@ -1599,6 +1602,7 @@ namespace libtorrent
|
|||
{
|
||||
bencode(std::back_inserter(m_metadata)
|
||||
, m_torrent_file.create_info_metadata());
|
||||
|
||||
assert(hasher(&m_metadata[0], m_metadata.size()).final()
|
||||
== m_torrent_file.info_hash());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue