merged back encryption branch to trunk
This commit is contained in:
parent
41cf912501
commit
273f8bd921
1
AUTHORS
1
AUTHORS
@ -6,6 +6,7 @@ Massaroddel
|
||||
Tianhao Qiu.
|
||||
|
||||
Contributions by:
|
||||
Shyam
|
||||
Magnus Jonsson
|
||||
Daniel Wallin
|
||||
Cory Nelson
|
||||
|
@ -1,3 +1,4 @@
|
||||
* added encryption support
|
||||
* added parole mode for peers whose data fails the hash check.
|
||||
* optimized heap usage in piece-picker and web seed downloader.
|
||||
* fixed bug in DHT where older write tokens weren't accepted.
|
||||
|
15
Jamfile
15
Jamfile
@ -28,6 +28,10 @@ feature dht-support : on off logging : composite propagated symmetric link-incom
|
||||
feature.compose <dht-support>off : <define>TORRENT_DISABLE_DHT ;
|
||||
feature.compose <dht-support>logging : <define>TORRENT_DHT_VERBOSE_LOGGING ;
|
||||
|
||||
feature pe-support : on off : composite propagated symmetric ;
|
||||
feature.compose <pe-support>on : ;
|
||||
feature.compose <pe-support>off : <define>TORRENT_DISABLE_ENCRYPTION ;
|
||||
|
||||
feature openssl : off on : composite propagated symmetric link-incompatible ;
|
||||
feature.compose <openssl>on : <define>TORRENT_USE_OPENSSL ;
|
||||
|
||||
@ -37,6 +41,8 @@ feature.compose <resolve-countries>off : <define>TORRENT_DISABLE_RESOLVE_COUNTRI
|
||||
feature character-set : ansi unicode : composite propagated link-incompatible ;
|
||||
feature.compose <character-set>unicode : <define>_UNICODE <define>UNICODE ;
|
||||
|
||||
feature zlib : shipped system : composite ;
|
||||
|
||||
feature statistics : off on : composite propagated symmetric link-incompatible ;
|
||||
feature.compose <statistics>on : <define>TORRENT_STATS ;
|
||||
|
||||
@ -136,7 +142,7 @@ project torrent
|
||||
|
||||
<include>./include
|
||||
<include>./include/libtorrent
|
||||
<include>./zlib
|
||||
<zlib>shipped:<include>./zlib
|
||||
<include>$(BOOST_ROOT)
|
||||
<variant>release:<define>NDEBUG
|
||||
<define>BOOST_ALL_NO_LIB
|
||||
@ -179,13 +185,16 @@ project torrent
|
||||
lib torrent
|
||||
:
|
||||
src/$(SOURCES).cpp
|
||||
zlib/$(ZLIB_SOURCES).c
|
||||
$(LIBS)
|
||||
# pch
|
||||
:
|
||||
<dht-support>on:<source>src/$(KADEMLIA_SOURCES).cpp
|
||||
<dht-support>logging:<source>src/$(KADEMLIA_SOURCES).cpp
|
||||
<openssl>off:<source>src/sha1.cpp
|
||||
<zlib>shipped:<source>zlib/$(ZLIB_SOURCES).c
|
||||
<zlib>system:<library>z
|
||||
<pe-support>on:<source>src/pe_crypto.cpp
|
||||
<pe-support>on:<library>crypt
|
||||
<openssl>on:<library>crypt
|
||||
<openssl>off,<pe-support>off:<source>src/sha1.cpp
|
||||
;
|
||||
|
||||
|
@ -206,6 +206,24 @@ logging of the DHT protocol traffic.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">zlib</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">system</span></tt> - links against the zlib supplied
|
||||
with your operating system.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">shipped</span></tt> - links against the zlib bundled
|
||||
with the libtorrent package.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">pe-support</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - turns on support for encrypted
|
||||
connections. requires openssl (libcrypto)</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - turns off support for encrypted
|
||||
connections. openssl is not linked in.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">link</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">static</span></tt> - builds libtorrent as a static
|
||||
@ -273,7 +291,8 @@ boost.program-options symbols.</p>
|
||||
sure all build variants will actually compile), you can invoke this command:</p>
|
||||
<pre class="literal-block">
|
||||
bjam debug release link=shared link=static logging=verbose logging=default \
|
||||
logging=none dht-support=on dht-support=logging dht-support=off
|
||||
logging=none dht-support=on dht-support=logging dht-support=off pe-support=on \
|
||||
pe-support=off zlib=shipped zlib=system
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -208,6 +208,16 @@ Build features:
|
||||
| | logging of the DHT protocol traffic. |
|
||||
| | * ``off`` - build without DHT support. |
|
||||
+------------------------+----------------------------------------------------+
|
||||
| ``zlib`` | * ``system`` - links against the zlib supplied |
|
||||
| | with your operating system. |
|
||||
| | * ``shipped`` - links against the zlib bundled |
|
||||
| | with the libtorrent package. |
|
||||
+------------------------+----------------------------------------------------+
|
||||
| ``pe-support`` | * ``on`` - turns on support for encrypted |
|
||||
| | connections. requires openssl (libcrypto) |
|
||||
| | * ``off`` - turns off support for encrypted |
|
||||
| | connections. openssl is not linked in. |
|
||||
+------------------------+----------------------------------------------------+
|
||||
| ``link`` | * ``static`` - builds libtorrent as a static |
|
||||
| | library (.a / .lib) |
|
||||
| | * ``shared`` - builds libtorrent as a shared |
|
||||
@ -261,7 +271,9 @@ To build all possible variants of libtorrent (good for testing when making
|
||||
sure all build variants will actually compile), you can invoke this command::
|
||||
|
||||
bjam debug release link=shared link=static logging=verbose logging=default \
|
||||
logging=none dht-support=on dht-support=logging dht-support=off
|
||||
logging=none dht-support=on dht-support=logging dht-support=off pe-support=on \
|
||||
pe-support=off zlib=shipped zlib=system openssl=on openssl=off \
|
||||
character-set=ansi character-set=unicode
|
||||
|
||||
building with autotools
|
||||
-----------------------
|
||||
@ -472,6 +484,12 @@ defines you can use to control the build.
|
||||
| ``TORRENT_DHT_VERBOSE_LOGGING`` | This will enable verbose logging of the DHT |
|
||||
| | protocol traffic. |
|
||||
+---------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_ENCRYPTION`` | This will disable any encryption support and |
|
||||
| | the openssl dependency that comes with it. |
|
||||
| | Encryption support is the peer connection |
|
||||
| | encrypted supported by clients such as |
|
||||
| | uTorrent, Azureus and KTorrent. |
|
||||
+---------------------------------+-------------------------------------------------+
|
||||
|
||||
|
||||
If you experience that libtorrent uses unreasonable amounts of cpu, it will
|
||||
|
@ -19,11 +19,11 @@
|
||||
<td>Arvid Norberg, <a class="last reference" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="mainline-dht-extensions">
|
||||
<h1>Mainline DHT extensions</h1>
|
||||
<div class="section">
|
||||
<h1><a id="mainline-dht-extensions" name="mainline-dht-extensions">Mainline DHT extensions</a></h1>
|
||||
<p>libtorrent implements a few extensions to the Mainline DHT protocol.</p>
|
||||
<div class="section" id="client-identification">
|
||||
<h2>client identification</h2>
|
||||
<div class="section">
|
||||
<h2><a id="client-identification" name="client-identification">client identification</a></h2>
|
||||
<p>In each DHT packet, an extra key is inserted named "v". This is a string
|
||||
describing the client and version used. This can help alot when debugging
|
||||
and finding errors in client implementations. The string is encoded as four
|
||||
@ -51,8 +51,8 @@ as a binary number describing the client version.</p>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="ipv6-support">
|
||||
<h2>IPv6 support</h2>
|
||||
<div class="section">
|
||||
<h2><a id="ipv6-support" name="ipv6-support">IPv6 support</a></h2>
|
||||
<p>The DHT messages that don't support IPv6 are the <tt class="docutils literal"><span class="pre">nodes</span></tt> replies.
|
||||
They encode all the contacts as 6 bytes packed together in sequence in a
|
||||
string. The problem is that IPv6 endpoints cannot be encoded as 6 bytes, but
|
||||
|
@ -20,16 +20,16 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title first">Table of contents</p>
|
||||
<p class="topic-title first"><a name="table-of-contents">Table of contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#introduction" id="id4">introduction</a></li>
|
||||
<li><a class="reference" href="#features" id="id5">features</a></li>
|
||||
<li><a class="reference" href="#portability" id="id6">portability</a></li>
|
||||
<li><a class="reference" href="#license" id="id7">license</a></li>
|
||||
<li><a class="reference" href="#introduction" id="id6" name="id6">introduction</a></li>
|
||||
<li><a class="reference" href="#features" id="id7" name="id7">features</a></li>
|
||||
<li><a class="reference" href="#portability" id="id8" name="id8">portability</a></li>
|
||||
<li><a class="reference" href="#license" id="id9" name="id9">license</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
<h1>introduction</h1>
|
||||
<div class="section">
|
||||
<h1><a id="introduction" name="introduction">introduction</a></h1>
|
||||
<p>libtorrent is a C++ library that aims to be a good alternative to all the
|
||||
other bittorrent implementations around. It is a
|
||||
library and not a full featured client, although it comes with a working
|
||||
@ -41,8 +41,8 @@ example client.</p>
|
||||
<li>to be very easy to use</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="features">
|
||||
<h1>features</h1>
|
||||
<div class="section">
|
||||
<h1><a id="features" name="features">features</a></h1>
|
||||
<p>libtorrent is still being developed, however it is stable. It is an ongoing
|
||||
project (including this documentation). The current state includes the
|
||||
following features:</p>
|
||||
@ -67,7 +67,7 @@ as well as all local peers in a separate fast-resume file.</li>
|
||||
This means it can download parts of the same piece from different peers.
|
||||
It will also prefer to download whole pieces from single peers if the
|
||||
download speed is high enough from that particular peer.</li>
|
||||
<li>supports the <a class="reference" href="udp_tracker_protocol.html">udp-tracker protocol</a> by Olaf van der Spek.</li>
|
||||
<li>supports the <a class="reference" href="extension_protocol.html">udp-tracker protocol</a> by Olaf van der Spek.</li>
|
||||
<li>queues torrents for file check, instead of checking all of them in parallel.</li>
|
||||
<li>supports http proxies and basic proxy authentication</li>
|
||||
<li>gzipped tracker-responses</li>
|
||||
@ -76,7 +76,7 @@ unchoked peers</li>
|
||||
<li>implements fair trade. User settable trade-ratio, must at least be 1:1,
|
||||
but one can choose to trade 1 for 2 or any other ratio that isn't unfair
|
||||
to the other party.</li>
|
||||
<li>supports an <a class="reference" href="extension_protocol.html">extension protocol</a>. See <a class="reference" href="manual.html#extensions">extensions</a>.</li>
|
||||
<li>supports an <a class="reference" href="udp_tracker_protocol.html">extension protocol</a>. See <a class="reference" href="manual.html#extensions">extensions</a>.</li>
|
||||
<li>supports the <tt class="docutils literal"><span class="pre">no_peer_id=1</span></tt> extension that will ease the load off trackers.</li>
|
||||
<li>possibility to limit the number of connections.</li>
|
||||
<li>delays have messages if there's no other outgoing traffic to the peer, and
|
||||
@ -91,8 +91,8 @@ want to download.</li>
|
||||
being connected</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="portability">
|
||||
<h1>portability</h1>
|
||||
<div class="section">
|
||||
<h1><a id="portability" name="portability">portability</a></h1>
|
||||
<p>libtorrent is portable at least among Windows, MacOS X and other UNIX-systems.
|
||||
It uses Boost.Thread, Boost.Filesystem, Boost.Date_time and various other
|
||||
boost libraries as well as <a class="reference" href="http://www.zlib.org">zlib</a> (shipped) and <a class="reference" href="http://asio.sf.net">asio</a> (shipped). At least version
|
||||
@ -114,8 +114,8 @@ epoll on linux and kqueue on MacOS X and BSD.</p>
|
||||
<li>msvc6</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="license">
|
||||
<h1>license</h1>
|
||||
<div class="section">
|
||||
<h1><a id="license" name="license">license</a></h1>
|
||||
<p>libtorrent is released under the <a class="reference" href="http://www.opensource.org/licenses/bsd-license.php">BSD-license</a>.</p>
|
||||
<p>This means that you can use the library in your project without having to
|
||||
release its source code. The only requirement is that you give credit
|
||||
|
836
docs/manual.html
836
docs/manual.html
File diff suppressed because it is too large
Load Diff
@ -92,8 +92,8 @@ The ``session`` class has the following synopsis::
|
||||
torrent_handle find_torrent(sha_hash const& ih);
|
||||
std::vector<torrent_handle> get_torrents() const;
|
||||
|
||||
void set_settings(
|
||||
session_settings const& settings);
|
||||
void set_settings(session_settings const& settings);
|
||||
void set_pe_settings(pe_settings const& settings);
|
||||
|
||||
void set_upload_rate_limit(int bytes_per_second);
|
||||
int upload_rate_limit() const;
|
||||
@ -250,9 +250,9 @@ about the torrent's progress, its peers etc. It is also used to abort a torrent.
|
||||
The second overload that takes a tracker url and an info-hash instead of metadata
|
||||
(``torrent_info``) can be used with torrents where (at least some) peers support
|
||||
the metadata extension. For the overload to be available, libtorrent must be built
|
||||
with extensions enabled (``TORRENT_ENABLE_EXTENSIONS`` defined). It also takes an
|
||||
optional ``name`` argument. This may be 0 in case no name should be assigned to the
|
||||
torrent. In case it's not 0, the name is used for the torrent as long as it doesn't
|
||||
with extensions enabled (``TORRENT_DISABLE_EXTENSIONS`` must not be defined). It also
|
||||
takes an optional ``name`` argument. This may be 0 in case no name should be assigned
|
||||
to the torrent. In case it's not 0, the name is used for the torrent as long as it doesn't
|
||||
have metadata. See ``torrent_handle::name``.
|
||||
|
||||
remove_torrent() find_torrent() get_torrents()
|
||||
@ -515,6 +515,19 @@ e.g.
|
||||
|
||||
.. _`libtorrent plugins`: libtorrent_plugins.html
|
||||
|
||||
set_settings() set_pe_settings()
|
||||
--------------------------------
|
||||
|
||||
::
|
||||
|
||||
void set_settings(session_settings const& settings);
|
||||
void set_pe_settings(pe_settings const& settings);
|
||||
|
||||
Sets the session settings and the packet encryption settings respectively.
|
||||
See session_settings_ and pe_settings_ for more information on available
|
||||
options.
|
||||
|
||||
|
||||
set_peer_proxy() set_web_seed_proxy() set_tracker_proxy() set_dht_proxy()
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
@ -556,6 +569,7 @@ These functions returns references to their respective current settings.
|
||||
|
||||
The ``dht_proxy`` is not available when DHT is disabled.
|
||||
|
||||
|
||||
start_dht() stop_dht() set_dht_settings() dht_state()
|
||||
-----------------------------------------------------
|
||||
|
||||
@ -2310,6 +2324,66 @@ Default is 10 minutes
|
||||
all trackers in its tracker list has failed. Either by an explicit error
|
||||
message or a time out.
|
||||
|
||||
pe_settings
|
||||
===========
|
||||
|
||||
The ``pe_settings`` structure is used to control the settings related
|
||||
to peer protocol encryption::
|
||||
|
||||
struct pe_settings
|
||||
{
|
||||
pe_settings();
|
||||
|
||||
enum enc_policy
|
||||
{
|
||||
forced,
|
||||
enabled,
|
||||
disabled
|
||||
};
|
||||
|
||||
enum enc_level
|
||||
{
|
||||
plaintext,
|
||||
rc4,
|
||||
both
|
||||
};
|
||||
|
||||
enc_policy out_enc_policy;
|
||||
enc_policy in_enc_policy;
|
||||
enc_level allowed_enc_level;
|
||||
bool prefer_rc4;
|
||||
};
|
||||
|
||||
|
||||
``in_enc_policy`` and ``out_enc_policy`` control the settings for incoming
|
||||
and outgoing connections respectively. The settings for these are:
|
||||
|
||||
* ``forced`` - Only encrypted connections are allowed. Incoming connections
|
||||
that are not encrypted are closed and if the encrypted outgoing connection
|
||||
fails, a non-encrypted retry will not be made.
|
||||
|
||||
* ``enabled`` - encrypted connections are enabled, but non-encrypted
|
||||
connections are allowed. An incoming non-encrypted connection will
|
||||
be accepted, and if an outgoing encrypted connection fails, a non-
|
||||
encrypted connection will be tried.
|
||||
|
||||
* ``disabled`` - only non-encrypted connections are allowed.
|
||||
|
||||
``allowed_enc_level`` determines the encryption level of the
|
||||
connections. This setting will adjust which encryption scheme is
|
||||
offered to the other peer, as well as which encryption scheme is
|
||||
selected by the client. The settings are:
|
||||
|
||||
* ``plaintext`` - only the handshake is encrypted, the bulk of the traffic
|
||||
remains unchanged.
|
||||
|
||||
* ``rc4`` - the entire stream is encrypted with RC4
|
||||
|
||||
* ``both`` - both RC4 and plaintext connections are allowed.
|
||||
|
||||
``prefer_rc4`` can be set to true if you want to prefer the RC4 encrypted stream.
|
||||
|
||||
|
||||
proxy_settings
|
||||
==============
|
||||
|
||||
|
@ -297,7 +297,11 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
|
||||
<< ((i->flags & peer_info::local_connection)?'l':'r')
|
||||
<< ((i->flags & peer_info::seed)?'s':'.')
|
||||
<< ((i->flags & peer_info::on_parole)?'p':'.')
|
||||
<< " "
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
<< ((i->flags & peer_info::rc4_encrypted)?'E':
|
||||
(i->flags & peer_info::plaintext_encrypted)?'e':'.')
|
||||
#endif
|
||||
<< " "
|
||||
<< ((i->source & peer_info::tracker)?"T":"_")
|
||||
<< ((i->source & peer_info::pex)?"P":"_")
|
||||
<< ((i->source & peer_info::dht)?"D":"_")
|
||||
|
@ -27,6 +27,7 @@ libtorrent/peer.hpp \
|
||||
libtorrent/peer_connection.hpp \
|
||||
libtorrent/bt_peer_connection.hpp \
|
||||
libtorrent/web_peer_connection.hpp \
|
||||
libtorrent/pe_crypto.hpp \
|
||||
libtorrent/natpmp.hpp \
|
||||
libtorrent/pch.hpp \
|
||||
libtorrent/peer_id.hpp \
|
||||
|
@ -217,6 +217,11 @@ namespace libtorrent
|
||||
entry dht_state() const;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
void set_pe_settings(pe_settings const& settings);
|
||||
pe_settings const& get_pe_settings() const { return m_pe_settings; }
|
||||
#endif
|
||||
|
||||
// called when a port mapping is successful, or a router returns
|
||||
// a failure to map a port
|
||||
void on_port_mapping(int tcp_port, int udp_port, std::string const& errmsg);
|
||||
@ -429,6 +434,11 @@ namespace libtorrent
|
||||
// but for the udp port used by the DHT.
|
||||
int m_external_udp_port;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
pe_settings m_pe_settings;
|
||||
#endif
|
||||
|
||||
boost::shared_ptr<natpmp> m_natpmp;
|
||||
boost::shared_ptr<upnp> m_upnp;
|
||||
boost::shared_ptr<lsd> m_lsd;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2003, Arvid Norberg
|
||||
Copyright (c) 2003 - 2006, Arvid Norberg
|
||||
Copyright (c) 2007, Arvid Norberg, Un Shyam
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -68,6 +69,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/pe_crypto.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
@ -102,6 +104,11 @@ namespace libtorrent
|
||||
, policy::peer* peerinfo);
|
||||
|
||||
~bt_peer_connection();
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
bool supports_encryption() const
|
||||
{ return m_encrypted; }
|
||||
#endif
|
||||
|
||||
enum message_type
|
||||
{
|
||||
@ -213,19 +220,76 @@ namespace libtorrent
|
||||
// will be invalid.
|
||||
boost::optional<piece_block_progress> downloading_piece_progress() const;
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
|
||||
// if (is_local()), we are 'a' otherwise 'b'
|
||||
//
|
||||
// 1. a -> b dhkey, pad
|
||||
// 2. b -> a dhkey, pad
|
||||
// 3. a -> b sync, payload
|
||||
// 4. b -> a sync, payload
|
||||
// 5. a -> b payload
|
||||
|
||||
void write_pe1_2_dhkey();
|
||||
void write_pe3_sync();
|
||||
void write_pe4_sync(int crypto_select);
|
||||
|
||||
void write_pe_vc_cryptofield(buffer::interval& write_buf,
|
||||
int crypto_field, int pad_size);
|
||||
|
||||
// stream key (info hash of attached torrent)
|
||||
// secret is the DH shared secret
|
||||
// initializes m_RC4_handler
|
||||
void init_pe_RC4_handler(char const* secret, sha1_hash const& stream_key);
|
||||
|
||||
// these functions encrypt the send buffer if m_rc4_encrypted
|
||||
// is true, otherwise it passes the call to the
|
||||
// peer_connection functions of the same names
|
||||
void send_buffer(char* begin, char* end);
|
||||
buffer::interval allocate_send_buffer(int size);
|
||||
void setup_send();
|
||||
|
||||
// Returns offset at which bytestream (src, src + src_size)
|
||||
// matches bytestream(target, target + target_size).
|
||||
// If no sync found, return -1
|
||||
int get_syncoffset(char const* src, int src_size,
|
||||
char const* target, int target_size) const;
|
||||
#endif
|
||||
|
||||
enum state
|
||||
{
|
||||
read_protocol_length = 0,
|
||||
read_protocol_string,
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
read_pe_dhkey = 0,
|
||||
read_pe_syncvc,
|
||||
read_pe_synchash,
|
||||
read_pe_skey_vc,
|
||||
read_pe_cryptofield,
|
||||
read_pe_pad,
|
||||
read_pe_ia,
|
||||
init_bt_handshake,
|
||||
read_protocol_identifier,
|
||||
#else
|
||||
read_protocol_identifier = 0,
|
||||
#endif
|
||||
read_info_hash,
|
||||
read_peer_id,
|
||||
|
||||
// handshake complete
|
||||
read_packet_size,
|
||||
read_packet
|
||||
};
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
enum
|
||||
{
|
||||
handshake_len = 68,
|
||||
dh_key_len = 96
|
||||
};
|
||||
#endif
|
||||
|
||||
std::string m_client_version;
|
||||
|
||||
// state of on_receive
|
||||
state m_state;
|
||||
|
||||
// the timeout in seconds
|
||||
@ -262,6 +326,44 @@ namespace libtorrent
|
||||
#endif
|
||||
bool m_supports_dht_port;
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
// this is set to true after the encryption method has been
|
||||
// succesfully negotiated (either plaintext or rc4), to signal
|
||||
// automatic encryption/decryption.
|
||||
bool m_encrypted;
|
||||
|
||||
// true if rc4, false if plaintext
|
||||
bool m_rc4_encrypted;
|
||||
|
||||
// used to disconnect peer if sync points are not found within
|
||||
// the maximum number of bytes
|
||||
int m_sync_bytes_read;
|
||||
|
||||
// hold information about latest allocated send buffer
|
||||
// need to check for non zero (begin, end) for operations with this
|
||||
buffer::interval m_enc_send_buffer;
|
||||
|
||||
// initialized during write_pe1_2_dhkey, and destroyed on
|
||||
// creation of m_RC4_handler. Cannot reinitialize once
|
||||
// initialized.
|
||||
boost::scoped_ptr<DH_key_exchange> m_DH_key_exchange;
|
||||
|
||||
// if RC4 is negotiated, this is used for
|
||||
// encryption/decryption during the entire session. Destroyed
|
||||
// if plaintext is selected
|
||||
boost::scoped_ptr<RC4_handler> m_RC4_handler;
|
||||
|
||||
// (outgoing only) synchronize verification constant with
|
||||
// remote peer, this will hold RC4_decrypt(vc). Destroyed
|
||||
// after the sync step.
|
||||
boost::scoped_array<char> m_sync_vc;
|
||||
|
||||
// (incoming only) synchronize hash with remote peer, holds
|
||||
// the sync hash (hash("req1",secret)). Destroyed after the
|
||||
// sync step.
|
||||
boost::scoped_ptr<sha1_hash> m_sync_hash;
|
||||
#endif // #ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
|
||||
#ifndef NDEBUG
|
||||
// this is set to true when the client's
|
||||
// bitfield is sent to this peer
|
||||
@ -269,6 +371,7 @@ namespace libtorrent
|
||||
|
||||
bool m_in_constructor;
|
||||
#endif
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,12 @@ public:
|
||||
return begin[index];
|
||||
}
|
||||
|
||||
bool operator==(const const_interval& p_interval)
|
||||
{
|
||||
return (begin == p_interval.begin
|
||||
&& end == p_interval.end);
|
||||
}
|
||||
|
||||
int left() const { assert(end >= begin); return end - begin; }
|
||||
|
||||
char const* begin;
|
||||
|
125
include/libtorrent/pe_crypto.hpp
Normal file
125
include/libtorrent/pe_crypto.hpp
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2007, Un Shyam
|
||||
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_DISABLE_ENCRYPTION
|
||||
|
||||
#ifndef TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||
#define TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/rc4.h>
|
||||
|
||||
#include "peer_id.hpp" // For sha1_hash
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
class DH_key_exchange
|
||||
{
|
||||
public:
|
||||
DH_key_exchange ();
|
||||
~DH_key_exchange ();
|
||||
|
||||
// Get local public key, always 96 bytes
|
||||
char const* get_local_key (void) const;
|
||||
|
||||
// read remote_pubkey, generate and store shared secret in
|
||||
// m_dh_secret
|
||||
void compute_secret (const char* remote_pubkey);
|
||||
|
||||
const char* get_secret (void) const;
|
||||
|
||||
private:
|
||||
int get_local_key_size () const
|
||||
{
|
||||
assert (m_DH);
|
||||
return BN_num_bytes (m_DH->pub_key);
|
||||
}
|
||||
|
||||
DH* m_DH;
|
||||
static const unsigned char m_dh_prime[96];
|
||||
static const unsigned char m_dh_generator[1];
|
||||
|
||||
char m_dh_local_key[96];
|
||||
char m_dh_secret[96];
|
||||
};
|
||||
|
||||
class RC4_handler // Non copyable
|
||||
{
|
||||
public:
|
||||
// Input longkeys must be 20 bytes
|
||||
RC4_handler (const sha1_hash& rc4_local_longkey,
|
||||
const sha1_hash& rc4_remote_longkey)
|
||||
|
||||
{
|
||||
RC4_set_key (&m_local_key, 20,
|
||||
reinterpret_cast<unsigned char const*>(rc4_local_longkey.begin()));
|
||||
RC4_set_key (&m_remote_key, 20,
|
||||
reinterpret_cast<unsigned char const*>(rc4_remote_longkey.begin()));
|
||||
|
||||
// Discard first 1024 bytes
|
||||
char buf[1024];
|
||||
encrypt (buf, 1024);
|
||||
decrypt (buf, 1024);
|
||||
};
|
||||
|
||||
~RC4_handler () {};
|
||||
|
||||
void encrypt (char* pos, int len)
|
||||
{
|
||||
assert (len >= 0);
|
||||
assert (pos);
|
||||
|
||||
RC4 (&m_local_key, len, reinterpret_cast<unsigned char const*>(pos),
|
||||
reinterpret_cast<unsigned char*>(pos));
|
||||
}
|
||||
|
||||
void decrypt (char* pos, int len)
|
||||
{
|
||||
assert (len >= 0);
|
||||
assert (pos);
|
||||
|
||||
RC4 (&m_remote_key, len, reinterpret_cast<unsigned char const*>(pos),
|
||||
reinterpret_cast<unsigned char*>(pos));
|
||||
}
|
||||
|
||||
private:
|
||||
RC4_KEY m_local_key; // Key to encrypt outgoing data
|
||||
RC4_KEY m_remote_key; // Key to decrypt incoming data
|
||||
};
|
||||
|
||||
} // namespace libtorrent
|
||||
|
||||
#endif // TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||
#endif // TORRENT_DISABLE_ENCRYPTION
|
@ -395,6 +395,14 @@ namespace libtorrent
|
||||
- m_write_pos;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
buffer::interval wr_recv_buffer()
|
||||
{
|
||||
return buffer::interval(&m_recv_buffer[0]
|
||||
, &m_recv_buffer[0] + m_recv_pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer::const_interval receive_buffer() const
|
||||
{
|
||||
return buffer::const_interval(&m_recv_buffer[0]
|
||||
@ -408,7 +416,6 @@ namespace libtorrent
|
||||
|
||||
bool packet_finished() const
|
||||
{
|
||||
assert(m_recv_pos <= m_packet_size);
|
||||
return m_packet_size <= m_recv_pos;
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,13 @@ namespace libtorrent
|
||||
return *this;
|
||||
}
|
||||
|
||||
big_number& operator ^= (big_number const& n)
|
||||
{
|
||||
for (int i = 0; i< number_size; ++i)
|
||||
m_number[i] ^= n.m_number[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned char& operator[](int i)
|
||||
{ assert(i >= 0 && i < number_size); return m_number[i]; }
|
||||
|
||||
|
@ -57,6 +57,10 @@ namespace libtorrent
|
||||
queued = 0x100,
|
||||
on_parole = 0x200,
|
||||
seed = 0x400
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
, rc4_encrypted = 0x800,
|
||||
plaintext_encrypted = 0x1000
|
||||
#endif
|
||||
};
|
||||
|
||||
unsigned int flags;
|
||||
|
@ -135,6 +135,17 @@ namespace libtorrent
|
||||
tcp::endpoint ip;
|
||||
connection_type type;
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
// Hints encryption support of peer. Only effective for
|
||||
// and when the outgoing encryption policy allows both
|
||||
// encrypted and non encrypted connections
|
||||
// (pe_settings::out_enc_policy == enabled). The initial
|
||||
// state of this flag determines the initial connection
|
||||
// attempt type (true = encrypted, false = standard).
|
||||
// This will be toggled everytime either an encrypted or
|
||||
// non-encrypted handshake fails.
|
||||
bool pe_support;
|
||||
#endif
|
||||
// the number of failed connection attempts this peer has
|
||||
int failcount;
|
||||
|
||||
|
@ -178,6 +178,11 @@ namespace libtorrent
|
||||
void add_dht_router(std::pair<std::string, int> const& node);
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
void set_pe_settings(pe_settings const& settings);
|
||||
pe_settings const& get_pe_settings() const;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext);
|
||||
#endif
|
||||
|
@ -269,6 +269,42 @@ namespace libtorrent
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
|
||||
struct pe_settings
|
||||
{
|
||||
pe_settings()
|
||||
: out_enc_policy(enabled)
|
||||
, in_enc_policy(enabled)
|
||||
, allowed_enc_level(both)
|
||||
, prefer_rc4(false)
|
||||
{}
|
||||
|
||||
enum enc_policy
|
||||
{
|
||||
forced, // disallow non encrypted connections
|
||||
enabled, // allow encrypted and non encrypted connections
|
||||
disabled // disallow encrypted connections
|
||||
};
|
||||
|
||||
enum enc_level
|
||||
{
|
||||
plaintext, // use only plaintext encryption
|
||||
rc4, // use only rc4 encryption
|
||||
both // allow both
|
||||
};
|
||||
|
||||
enc_policy out_enc_policy;
|
||||
enc_policy in_enc_policy;
|
||||
|
||||
enc_level allowed_enc_level;
|
||||
// if the allowed encryption level is both, setting this to
|
||||
// true will prefer rc4 if both methods are offered, plaintext
|
||||
// otherwise
|
||||
bool prefer_rc4;
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -16,7 +16,7 @@ libtorrent_la_SOURCES = allocate_resources.cpp \
|
||||
bandwidth_manager.cpp entry.cpp escape_string.cpp \
|
||||
peer_connection.cpp bt_peer_connection.cpp web_peer_connection.cpp \
|
||||
natpmp.cpp piece_picker.cpp policy.cpp session.cpp session_impl.cpp sha1.cpp \
|
||||
stat.cpp storage.cpp torrent.cpp torrent_handle.cpp \
|
||||
stat.cpp storage.cpp torrent.cpp torrent_handle.cpp pe_crypto.cpp \
|
||||
torrent_info.cpp tracker_manager.cpp http_connection.cpp \
|
||||
http_tracker_connection.cpp udp_tracker_connection.cpp \
|
||||
alert.cpp identify_client.cpp ip_filter.cpp file.cpp metadata_transfer.cpp \
|
||||
@ -59,6 +59,7 @@ $(top_srcdir)/include/libtorrent/peer.hpp \
|
||||
$(top_srcdir)/include/libtorrent/peer_connection.hpp \
|
||||
$(top_srcdir)/include/libtorrent/bt_peer_connection.hpp \
|
||||
$(top_srcdir)/include/libtorrent/web_peer_connection.hpp \
|
||||
$(top_srcdir)/include/libtorrent/pe_crypto.hpp \
|
||||
$(top_srcdir)/include/libtorrent/natpmp.hpp \
|
||||
$(top_srcdir)/include/libtorrent/pch.hpp \
|
||||
$(top_srcdir)/include/libtorrent/peer_id.hpp \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -412,6 +412,10 @@ namespace libtorrent
|
||||
m_send_buffer += '&';
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
m_send_buffer += "supportcrypto=1&";
|
||||
#endif
|
||||
|
||||
// extension that tells the tracker that
|
||||
// we don't need any peer_id's in the response
|
||||
if (!url_has_argument(request, "no_peer_id"))
|
||||
|
122
src/pe_crypto.cpp
Normal file
122
src/pe_crypto.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2007, Un Shyam
|
||||
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_DISABLE_ENCRYPTION
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#include "libtorrent/pe_crypto.hpp"
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
|
||||
// Set the prime P and the generator, generate local public key
|
||||
DH_key_exchange::DH_key_exchange ()
|
||||
{
|
||||
m_DH = DH_new ();
|
||||
|
||||
m_DH->p = BN_bin2bn (m_dh_prime, sizeof(m_dh_prime), NULL);
|
||||
m_DH->g = BN_bin2bn (m_dh_generator, sizeof(m_dh_generator), NULL);
|
||||
|
||||
assert (sizeof(m_dh_prime) == DH_size(m_DH));
|
||||
|
||||
DH_generate_key (m_DH); // TODO Check != 0
|
||||
|
||||
assert (m_DH->pub_key);
|
||||
|
||||
// DH can generate key sizes that are smaller than the size of
|
||||
// P with exponentially decreasing probability, in which case
|
||||
// the msb's of m_dh_local_key need to be zeroed
|
||||
// appropriately.
|
||||
int key_size = get_local_key_size();
|
||||
int len_dh = sizeof(m_dh_prime); // must equal DH_size(m_DH)
|
||||
if (key_size != len_dh)
|
||||
{
|
||||
assert(key_size > 0 && key_size < len_dh);
|
||||
|
||||
int pad_zero_size = len_dh - key_size;
|
||||
std::fill(m_dh_local_key, m_dh_local_key + pad_zero_size, 0);
|
||||
BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key + pad_zero_size);
|
||||
}
|
||||
else
|
||||
BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key); // TODO Check return value
|
||||
}
|
||||
|
||||
DH_key_exchange::~DH_key_exchange ()
|
||||
{
|
||||
assert (m_DH);
|
||||
DH_free (m_DH);
|
||||
}
|
||||
|
||||
char const* DH_key_exchange::get_local_key () const
|
||||
{
|
||||
return m_dh_local_key;
|
||||
}
|
||||
|
||||
|
||||
// compute shared secret given remote public key
|
||||
void DH_key_exchange::compute_secret (char const* remote_pubkey)
|
||||
{
|
||||
assert (remote_pubkey);
|
||||
BIGNUM* bn_remote_pubkey = BN_bin2bn ((unsigned char*)remote_pubkey, 96, NULL);
|
||||
|
||||
int ret =
|
||||
DH_compute_key ( (unsigned char*)m_dh_secret, bn_remote_pubkey, m_DH); // TODO Check for errors
|
||||
|
||||
BN_free (bn_remote_pubkey);
|
||||
}
|
||||
|
||||
char const* DH_key_exchange::get_secret () const
|
||||
{
|
||||
return m_dh_secret;
|
||||
}
|
||||
|
||||
const unsigned char DH_key_exchange::m_dh_prime[96] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x3A, 0x36, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, 0x63
|
||||
};
|
||||
|
||||
const unsigned char DH_key_exchange::m_dh_generator[1] = { 2 };
|
||||
|
||||
} // namespace libtorrent
|
||||
|
||||
#endif // #ifndef TORRENT_DISABLE_ENCRYPTION
|
@ -336,6 +336,9 @@ namespace libtorrent
|
||||
|
||||
void peer_connection::announce_piece(int index)
|
||||
{
|
||||
// dont announce during handshake
|
||||
if (in_handshake()) return;
|
||||
|
||||
// optimization, don't send have messages
|
||||
// to peers that already have the piece
|
||||
if (!m_ses.settings().send_redundant_have
|
||||
@ -1769,8 +1772,9 @@ namespace libtorrent
|
||||
assert(int(m_recv_buffer.size()) >= size);
|
||||
assert(int(m_recv_buffer.size()) >= m_recv_pos);
|
||||
assert(m_recv_pos >= size);
|
||||
|
||||
std::memmove(&m_recv_buffer[0], &m_recv_buffer[0] + size, m_recv_pos - size);
|
||||
|
||||
if (size > 0)
|
||||
std::memmove(&m_recv_buffer[0], &m_recv_buffer[0] + size, m_recv_pos - size);
|
||||
|
||||
m_recv_pos -= size;
|
||||
|
||||
@ -1869,6 +1873,8 @@ namespace libtorrent
|
||||
}
|
||||
}
|
||||
|
||||
m_statistics.second_tick(tick_interval);
|
||||
|
||||
// If the client sends more data
|
||||
// we send it data faster, otherwise, slower.
|
||||
// It will also depend on how much data the
|
||||
@ -2071,7 +2077,7 @@ namespace libtorrent
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!can_write()) return;
|
||||
|
||||
assert(!m_writing);
|
||||
@ -2145,7 +2151,6 @@ namespace libtorrent
|
||||
|
||||
assert(m_recv_pos >= 0);
|
||||
assert(m_packet_size > 0);
|
||||
assert(max_receive > 0);
|
||||
|
||||
assert(can_read());
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
@ -2169,7 +2174,7 @@ namespace libtorrent
|
||||
if (int(m_recv_buffer.size()) < m_packet_size)
|
||||
m_recv_buffer.resize(m_packet_size);
|
||||
}
|
||||
|
||||
|
||||
void peer_connection::send_buffer(char const* begin, char const* end)
|
||||
{
|
||||
std::vector<char>& buf = m_send_buffer[m_current_send_buffer];
|
||||
@ -2213,10 +2218,11 @@ namespace libtorrent
|
||||
assert(m_reading);
|
||||
m_reading = false;
|
||||
|
||||
|
||||
if (error)
|
||||
{
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << "**ERROR**: " << error.message() << "\n";
|
||||
(*m_logger) << "**ERROR**: " << error.message() << "[in peer_connection::on_receive_data]\n";
|
||||
#endif
|
||||
on_receive(error, bytes_transferred);
|
||||
throw std::runtime_error(error.message());
|
||||
@ -2300,7 +2306,7 @@ namespace libtorrent
|
||||
// all exceptions should derive from std::exception
|
||||
assert(false);
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(m_socket, remote(), "connection failed for unkown reason");
|
||||
m_ses.connection_failed(m_socket, remote(), "connection failed for unknown reason");
|
||||
}
|
||||
|
||||
bool peer_connection::can_write() const
|
||||
@ -2428,10 +2434,11 @@ namespace libtorrent
|
||||
|
||||
m_write_pos += bytes_transferred;
|
||||
|
||||
|
||||
if (error)
|
||||
{
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << "**ERROR**: " << error.message() << "\n";
|
||||
(*m_logger) << "**ERROR**: " << error.message() << " [in peer_connection::on_send_data]\n";
|
||||
#endif
|
||||
throw std::runtime_error(error.message());
|
||||
}
|
||||
@ -2480,7 +2487,7 @@ namespace libtorrent
|
||||
// all exceptions should derive from std::exception
|
||||
assert(false);
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(m_socket, remote(), "connection failed for unkown reason");
|
||||
m_ses.connection_failed(m_socket, remote(), "connection failed for unknown reason");
|
||||
}
|
||||
|
||||
|
||||
@ -2633,9 +2640,19 @@ namespace libtorrent
|
||||
time_duration d;
|
||||
d = time_now() - m_last_sent;
|
||||
if (total_seconds(d) < m_timeout / 2) return;
|
||||
|
||||
|
||||
if (m_connecting) return;
|
||||
if (in_handshake()) return;
|
||||
|
||||
// if the last send has not completed yet, do not send a keep
|
||||
// alive
|
||||
if (m_writing) return;
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
using namespace boost::posix_time;
|
||||
(*m_logger) << time_now_string() << " ==> KEEPALIVE\n";
|
||||
#endif
|
||||
|
||||
write_keepalive();
|
||||
}
|
||||
|
||||
|
@ -1021,7 +1021,10 @@ namespace libtorrent
|
||||
// the iterator is invalid
|
||||
// because of the push_back()
|
||||
i = boost::prior(m_peers.end());
|
||||
if (flags & 0x02) p.seed = true;
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
if (flags & 0x01) p.pe_support = true;
|
||||
#endif
|
||||
if (flags & 0x02) i->seed = true;
|
||||
|
||||
// try to send a DHT ping to this peer
|
||||
// as well, to figure out if it supports
|
||||
@ -1408,6 +1411,9 @@ namespace libtorrent
|
||||
policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src)
|
||||
: ip(ip_)
|
||||
, type(t)
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
, pe_support(true)
|
||||
#endif
|
||||
, failcount(0)
|
||||
, hashfails(0)
|
||||
, seed(false)
|
||||
|
@ -252,6 +252,18 @@ namespace libtorrent
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
void session::set_pe_settings(pe_settings const& settings)
|
||||
{
|
||||
m_impl->set_pe_settings(settings);
|
||||
}
|
||||
|
||||
pe_settings const& session::get_pe_settings() const
|
||||
{
|
||||
return m_impl->get_pe_settings();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool session::is_listening() const
|
||||
{
|
||||
return m_impl->is_listening();
|
||||
|
@ -1755,6 +1755,14 @@ namespace libtorrent { namespace detail
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
void session_impl::set_pe_settings(pe_settings const& settings)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
m_pe_settings = settings;
|
||||
}
|
||||
#endif
|
||||
|
||||
void session_impl::set_download_rate_limit(int bytes_per_second)
|
||||
{
|
||||
assert(bytes_per_second > 0 || bytes_per_second == -1);
|
||||
|
@ -117,14 +117,21 @@ namespace libtorrent { namespace
|
||||
if (di == dropped.end())
|
||||
{
|
||||
// don't write too big of a package
|
||||
if (num_added >= max_peer_entries) continue;
|
||||
if (num_added >= max_peer_entries) break;
|
||||
|
||||
// only send proper bittorrent peers
|
||||
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(i->second);
|
||||
if (!p) continue;
|
||||
|
||||
// i->first was added since the last time
|
||||
detail::write_endpoint(i->first, pla_out);
|
||||
// no supported flags to set yet
|
||||
// 0x01 - peer supports encryption
|
||||
// 0x02 - peer is a seed
|
||||
int flags = i->second->is_seed() ? 2 : 0;
|
||||
int flags = p->is_seed() ? 2 : 0;
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
flags |= p->supports_encryption() ? 1 : 0;
|
||||
#endif
|
||||
detail::write_uint8(flags, plf_out);
|
||||
++num_added;
|
||||
}
|
||||
@ -280,14 +287,21 @@ namespace libtorrent { namespace
|
||||
if (!send_peer(*i->second)) continue;
|
||||
|
||||
// don't write too big of a package
|
||||
if (num_added >= max_peer_entries) continue;
|
||||
if (num_added >= max_peer_entries) break;
|
||||
|
||||
// only send proper bittorrent peers
|
||||
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(i->second);
|
||||
if (!p) continue;
|
||||
|
||||
// i->first was added since the last time
|
||||
detail::write_endpoint(i->first, pla_out);
|
||||
// no supported flags to set yet
|
||||
// 0x01 - peer supports encryption
|
||||
// 0x02 - peer is a seed
|
||||
int flags = i->second->is_seed() ? 2 : 0;
|
||||
int flags = p->is_seed() ? 2 : 0;
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
flags |= p->supports_encryption() ? 1 : 0;
|
||||
#endif
|
||||
detail::write_uint8(flags, plf_out);
|
||||
++num_added;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ test-suite libtorrent :
|
||||
[ run test_storage.cpp ]
|
||||
[ run test_piece_picker.cpp ]
|
||||
# [ run test_entry.cpp ]
|
||||
[ run test_pe_crypto.cpp ]
|
||||
[ run test_bencoding.cpp ]
|
||||
[ run test_primitives.cpp ]
|
||||
[ run test_ip_filter.cpp ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
noinst_PROGRAMS = test_hasher test_bencoding test_ip_filter test_piece_picker test_storage test_metadata_extension test_buffer test_allocate_resources
|
||||
noinst_PROGRAMS = test_hasher test_bencoding test_ip_filter test_piece_picker test_storage test_metadata_extension test_buffer test_allocate_resources test_pe_crypto
|
||||
EXTRA_DIST = Jamfile
|
||||
|
||||
test_hasher_SOURCES = main.cpp test_hasher.cpp
|
||||
@ -25,6 +25,9 @@ test_allocate_resources_LDADD = $(top_builddir)/src/libtorrent.la
|
||||
test_metadata_extension_SOURCES = main.cpp setup_transfer.cpp test_metadata_extension.cpp
|
||||
test_metadata_extension_LDADD = $(top_builddir)/src/libtorrent.la
|
||||
|
||||
test_pe_crypto_SOURCES = main.cpp test_pe_crypto.cpp
|
||||
test_pe_crypto_LDADD = $(top_builddir)/src/libtorrent.la $(top_builddir)/test/setup_transfer.o
|
||||
|
||||
noinst_HEADERS = test.hpp setup_transfer.hpp
|
||||
|
||||
AM_CXXFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include -I$(top_srcdir)/include/libtorrent @DEBUGFLAGS@ @PTHREAD_CFLAGS@
|
||||
|
@ -22,7 +22,7 @@ void sleep(int msec)
|
||||
using namespace libtorrent;
|
||||
|
||||
boost::tuple<torrent_handle, torrent_handle> setup_transfer(
|
||||
session& ses1, session& ses2, bool clear_files)
|
||||
session& ses1, session& ses2, bool clear_files, bool use_metadata_transfer)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
|
||||
@ -59,8 +59,12 @@ boost::tuple<torrent_handle, torrent_handle> setup_transfer(
|
||||
// file pool will complain if two torrents are trying to
|
||||
// use the same files
|
||||
torrent_handle tor1 = ses1.add_torrent(t, "./tmp1");
|
||||
torrent_handle tor2 = ses2.add_torrent(tracker_url
|
||||
torrent_handle tor2;
|
||||
if (use_metadata_transfer)
|
||||
tor2 = ses2.add_torrent(tracker_url
|
||||
, t.info_hash(), 0, "./tmp2");
|
||||
else
|
||||
tor2 = ses2.add_torrent(t, "./tmp2");
|
||||
|
||||
sleep(100);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
void sleep(int msec);
|
||||
boost::tuple<libtorrent::torrent_handle, libtorrent::torrent_handle>
|
||||
setup_transfer(libtorrent::session& ses1, libtorrent::session& ses2
|
||||
, bool clear_files);
|
||||
, bool clear_files, bool use_metadata_transfer = true);
|
||||
|
||||
#endif
|
||||
|
||||
|
194
test/test_pe_crypto.cpp
Normal file
194
test/test_pe_crypto.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2007, Un Shyam
|
||||
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 <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/pe_crypto.hpp"
|
||||
#include "libtorrent/session.hpp"
|
||||
|
||||
#include "setup_transfer.hpp"
|
||||
#include "test.hpp"
|
||||
|
||||
void display_pe_policy(libtorrent::pe_settings::enc_policy policy)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using std::cerr;
|
||||
|
||||
if (policy == pe_settings::disabled) cerr << "disabled ";
|
||||
else if (policy == pe_settings::enabled) cerr << "enabled ";
|
||||
else if (policy == pe_settings::forced) cerr << "forced ";
|
||||
}
|
||||
|
||||
void display_pe_settings(libtorrent::pe_settings s)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using std::cerr;
|
||||
|
||||
cerr << "out_enc_policy - ";
|
||||
display_pe_policy(s.out_enc_policy);
|
||||
cerr << "\tin_enc_policy - ";
|
||||
display_pe_policy(s.in_enc_policy);
|
||||
|
||||
cerr << "\nenc_level - ";
|
||||
if (s.allowed_enc_level == pe_settings::plaintext) cerr << "plaintext ";
|
||||
else if (s.allowed_enc_level == pe_settings::rc4) cerr << "rc4 ";
|
||||
else if (s.allowed_enc_level == pe_settings::both) cerr << "both ";
|
||||
|
||||
cerr << "\t\tprefer_rc4 - ";
|
||||
(s.prefer_rc4) ? cerr << "true" : cerr << "false";
|
||||
cerr << "\n\n";
|
||||
}
|
||||
|
||||
void test_transfer(libtorrent::pe_settings::enc_policy policy,
|
||||
libtorrent::pe_settings::enc_level level = libtorrent::pe_settings::both,
|
||||
bool pref_rc4 = false)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using std::cerr;
|
||||
|
||||
session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48000, 49000));
|
||||
session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49000, 50000));
|
||||
pe_settings s;
|
||||
|
||||
s.out_enc_policy = libtorrent::pe_settings::enabled;
|
||||
s.in_enc_policy = libtorrent::pe_settings::enabled;
|
||||
|
||||
s.allowed_enc_level = pe_settings::both;
|
||||
ses2.set_pe_settings(s);
|
||||
|
||||
s.out_enc_policy = policy;
|
||||
s.in_enc_policy = policy;
|
||||
s.allowed_enc_level = level;
|
||||
s.prefer_rc4 = pref_rc4;
|
||||
ses1.set_pe_settings(s);
|
||||
|
||||
// s = ses1.get_pe_settings();
|
||||
// cerr << " Session1 \n";
|
||||
// display_pe_settings(s);
|
||||
// s = ses2.get_pe_settings();
|
||||
// cerr << " Session2 \n";
|
||||
// display_pe_settings(s);
|
||||
|
||||
torrent_handle tor1;
|
||||
torrent_handle tor2;
|
||||
|
||||
boost::tie(tor1, tor2) = setup_transfer(ses1, ses2, true, false);
|
||||
|
||||
std::cerr << "waiting for transfer to complete\n";
|
||||
|
||||
for (int i = 0; i < 50; ++i)
|
||||
{
|
||||
tor2.status();
|
||||
std::auto_ptr<alert> a;
|
||||
a = ses1.pop_alert();
|
||||
if (a.get())
|
||||
std::cerr << "ses1: " << a->msg() << "\n";
|
||||
|
||||
a = ses2.pop_alert();
|
||||
if (a.get())
|
||||
std::cerr << "ses2: " << a->msg() << "\n";
|
||||
|
||||
if (tor2.is_seed()) break;
|
||||
sleep(100);
|
||||
}
|
||||
|
||||
TEST_CHECK(tor2.is_seed());
|
||||
if (tor2.is_seed()) std::cerr << "done\n";
|
||||
}
|
||||
|
||||
|
||||
int test_main()
|
||||
{
|
||||
using namespace libtorrent;
|
||||
int repcount = 64;
|
||||
|
||||
for (int rep = 0; rep < repcount; ++rep)
|
||||
{
|
||||
DH_key_exchange DH1, DH2;
|
||||
|
||||
DH1.compute_secret(DH2.get_local_key());
|
||||
DH2.compute_secret(DH1.get_local_key());
|
||||
|
||||
TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
|
||||
}
|
||||
|
||||
DH_key_exchange DH1, DH2;
|
||||
DH1.compute_secret(DH2.get_local_key());
|
||||
DH2.compute_secret(DH1.get_local_key());
|
||||
|
||||
TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
|
||||
|
||||
sha1_hash test1_key = hasher("test1_key",8).final();
|
||||
sha1_hash test2_key = hasher("test2_key",8).final();
|
||||
|
||||
RC4_handler RC41 (test2_key, test1_key);
|
||||
RC4_handler RC42 (test1_key, test2_key);
|
||||
|
||||
for (int rep = 0; rep < repcount; ++rep)
|
||||
{
|
||||
std::size_t buf_len = rand() % (512 * 1024);
|
||||
char* buf = new char[buf_len];
|
||||
char* zero_buf = new char[buf_len];
|
||||
|
||||
std::fill(buf, buf + buf_len, 0);
|
||||
std::fill(zero_buf, zero_buf + buf_len, 0);
|
||||
|
||||
RC41.encrypt(buf, buf_len);
|
||||
RC42.decrypt(buf, buf_len);
|
||||
TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));
|
||||
|
||||
RC42.encrypt(buf, buf_len);
|
||||
RC41.decrypt(buf, buf_len);
|
||||
TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));
|
||||
|
||||
delete[] buf;
|
||||
delete[] zero_buf;
|
||||
}
|
||||
|
||||
|
||||
test_transfer(pe_settings::disabled);
|
||||
|
||||
test_transfer(pe_settings::forced, pe_settings::plaintext);
|
||||
test_transfer(pe_settings::forced, pe_settings::rc4);
|
||||
test_transfer(pe_settings::forced, pe_settings::both, false);
|
||||
test_transfer(pe_settings::forced, pe_settings::both, true);
|
||||
|
||||
test_transfer(pe_settings::enabled, pe_settings::plaintext);
|
||||
test_transfer(pe_settings::enabled, pe_settings::rc4);
|
||||
test_transfer(pe_settings::enabled, pe_settings::both, false);
|
||||
test_transfer(pe_settings::enabled, pe_settings::both, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user