landed ssl branch back into trunk
This commit is contained in:
parent
cbe02221cd
commit
4a40e68a82
|
@ -1,3 +1,4 @@
|
||||||
|
* improve SSL torrent support by using SNI and a single SSL listen socket
|
||||||
* improved peer exchange performance by sharing incoming connections which advertize listen port
|
* improved peer exchange performance by sharing incoming connections which advertize listen port
|
||||||
* deprecate set_ratio(), and per-peer rate limits
|
* deprecate set_ratio(), and per-peer rate limits
|
||||||
* add web seed support for torrents with pad files
|
* add web seed support for torrents with pad files
|
||||||
|
|
4
Jamfile
4
Jamfile
|
@ -65,7 +65,7 @@ rule linking ( properties * )
|
||||||
}
|
}
|
||||||
|
|
||||||
# gcrypt libraries, if enabled
|
# gcrypt libraries, if enabled
|
||||||
if <encryption>gcrypt in $(properties)
|
if <encryption>gcrypt in $(properties) || <encryption>openssl in $(properties)
|
||||||
{
|
{
|
||||||
# on mac os x, adding the /opt/local/include path
|
# on mac os x, adding the /opt/local/include path
|
||||||
# would include openssl headers incompatible with
|
# would include openssl headers incompatible with
|
||||||
|
@ -371,7 +371,7 @@ lib boost_system : : <name>boost_system ;
|
||||||
lib gcrypt : : <name>gcrypt <link>shared <search>/opt/local/lib ;
|
lib gcrypt : : <name>gcrypt <link>shared <search>/opt/local/lib ;
|
||||||
lib z : : <link>shared <name>z <search>/lib ;
|
lib z : : <link>shared <name>z <search>/lib ;
|
||||||
lib crypto : : <name>crypto <search>/lib <use>z ;
|
lib crypto : : <name>crypto <search>/lib <use>z ;
|
||||||
lib ssl : : <name>ssl <link>shared <use>crypto ;
|
lib ssl : : <name>ssl <link>shared <use>crypto <search>/opt/local/lib ;
|
||||||
lib dl : : <link>shared <name>dl ;
|
lib dl : : <link>shared <name>dl ;
|
||||||
|
|
||||||
# time functions used on linux require librt
|
# time functions used on linux require librt
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript">
|
|
||||||
/* <![CDATA[ */
|
|
||||||
(function() {
|
|
||||||
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
|
||||||
|
|
||||||
s.type = 'text/javascript';
|
|
||||||
s.async = true;
|
|
||||||
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
|
||||||
|
|
||||||
t.parentNode.insertBefore(s, t);
|
|
||||||
})();
|
|
||||||
/* ]]> */
|
|
||||||
</script>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||||
<title></title>
|
<title></title>
|
||||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* <![CDATA[ */
|
||||||
|
(function() {
|
||||||
|
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
||||||
|
s.type = 'text/javascript';
|
||||||
|
s.async = true;
|
||||||
|
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
||||||
|
t.parentNode.insertBefore(s, t);
|
||||||
|
})();
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* Hides from IE-mac \*/
|
/* Hides from IE-mac \*/
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript">
|
|
||||||
/* <![CDATA[ */
|
|
||||||
(function() {
|
|
||||||
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
|
||||||
|
|
||||||
s.type = 'text/javascript';
|
|
||||||
s.async = true;
|
|
||||||
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
|
||||||
|
|
||||||
t.parentNode.insertBefore(s, t);
|
|
||||||
})();
|
|
||||||
/* ]]> */
|
|
||||||
</script>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||||
<title></title>
|
<title></title>
|
||||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com Ludvig Strigeus, ludde@utorrent.com" />
|
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com Ludvig Strigeus, ludde@utorrent.com" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* <![CDATA[ */
|
||||||
|
(function() {
|
||||||
|
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
||||||
|
s.type = 'text/javascript';
|
||||||
|
s.async = true;
|
||||||
|
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
||||||
|
t.parentNode.insertBefore(s, t);
|
||||||
|
})();
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* Hides from IE-mac \*/
|
/* Hides from IE-mac \*/
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript">
|
|
||||||
/* <![CDATA[ */
|
|
||||||
(function() {
|
|
||||||
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
|
||||||
|
|
||||||
s.type = 'text/javascript';
|
|
||||||
s.async = true;
|
|
||||||
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
|
||||||
|
|
||||||
t.parentNode.insertBefore(s, t);
|
|
||||||
})();
|
|
||||||
/* ]]> */
|
|
||||||
</script>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||||
<title></title>
|
<title></title>
|
||||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* <![CDATA[ */
|
||||||
|
(function() {
|
||||||
|
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
||||||
|
s.type = 'text/javascript';
|
||||||
|
s.async = true;
|
||||||
|
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
||||||
|
t.parentNode.insertBefore(s, t);
|
||||||
|
})();
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* Hides from IE-mac \*/
|
/* Hides from IE-mac \*/
|
||||||
|
|
|
@ -75,8 +75,9 @@
|
||||||
<li><a class="reference internal" href="#add-url-seed-add-http-seed" id="id17">add_url_seed() add_http_seed()</a></li>
|
<li><a class="reference internal" href="#add-url-seed-add-http-seed" id="id17">add_url_seed() add_http_seed()</a></li>
|
||||||
<li><a class="reference internal" href="#add-node" id="id18">add_node()</a></li>
|
<li><a class="reference internal" href="#add-node" id="id18">add_node()</a></li>
|
||||||
<li><a class="reference internal" href="#add-tracker" id="id19">add_tracker()</a></li>
|
<li><a class="reference internal" href="#add-tracker" id="id19">add_tracker()</a></li>
|
||||||
<li><a class="reference internal" href="#set-priv-priv" id="id20">set_priv() priv()</a></li>
|
<li><a class="reference internal" href="#set-root-cert" id="id20">set_root_cert()</a></li>
|
||||||
<li><a class="reference internal" href="#merkle-tree" id="id21">merkle_tree()</a></li>
|
<li><a class="reference internal" href="#set-priv-priv" id="id21">set_priv() priv()</a></li>
|
||||||
|
<li><a class="reference internal" href="#merkle-tree" id="id22">merkle_tree()</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -345,6 +346,7 @@ struct create_torrent
|
||||||
void add_http_seed(std::string const& url);
|
void add_http_seed(std::string const& url);
|
||||||
void add_node(std::pair<std::string, int> const& node);
|
void add_node(std::pair<std::string, int> const& node);
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
void add_tracker(std::string const& url, int tier = 0);
|
||||||
|
void set_root_cert(std::string const& pem);
|
||||||
void set_priv(bool p);
|
void set_priv(bool p);
|
||||||
|
|
||||||
int num_pieces() const;
|
int num_pieces() const;
|
||||||
|
@ -530,6 +532,18 @@ info-hash. The tier is the fallback priority of the tracker. All trackers with t
|
||||||
tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
|
tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
|
||||||
fail, trackers with tier 2 are tried, and so on.</p>
|
fail, trackers with tier 2 are tried, and so on.</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section" id="set-root-cert">
|
||||||
|
<h2>set_root_cert()</h2>
|
||||||
|
<blockquote>
|
||||||
|
<pre class="literal-block">
|
||||||
|
void set_root_cert(std::string const& pem);
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
<p>This function sets an X.509 certificate in PEM format to the torrent. This makes the
|
||||||
|
torrent an <em>SSL torrent</em>. An SSL torrent requires that each peer has a valid certificate
|
||||||
|
signed by this root certificate. For SSL torrents, all peers are connecting over SSL
|
||||||
|
connections. For more information on SSL torrents, see the <a class="reference external" href="manual.html#ssl-torrents">manual</a>.</p>
|
||||||
|
</div>
|
||||||
<div class="section" id="set-priv-priv">
|
<div class="section" id="set-priv-priv">
|
||||||
<h2>set_priv() priv()</h2>
|
<h2>set_priv() priv()</h2>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
|
|
@ -288,6 +288,7 @@ The ``create_torrent`` class has the following synopsis::
|
||||||
void add_http_seed(std::string const& url);
|
void add_http_seed(std::string const& url);
|
||||||
void add_node(std::pair<std::string, int> const& node);
|
void add_node(std::pair<std::string, int> const& node);
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
void add_tracker(std::string const& url, int tier = 0);
|
||||||
|
void set_root_cert(std::string const& pem);
|
||||||
void set_priv(bool p);
|
void set_priv(bool p);
|
||||||
|
|
||||||
int num_pieces() const;
|
int num_pieces() const;
|
||||||
|
@ -482,6 +483,20 @@ info-hash. The tier is the fallback priority of the tracker. All trackers with t
|
||||||
tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
|
tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
|
||||||
fail, trackers with tier 2 are tried, and so on.
|
fail, trackers with tier 2 are tried, and so on.
|
||||||
|
|
||||||
|
set_root_cert()
|
||||||
|
---------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
void set_root_cert(std::string const& pem);
|
||||||
|
|
||||||
|
This function sets an X.509 certificate in PEM format to the torrent. This makes the
|
||||||
|
torrent an *SSL torrent*. An SSL torrent requires that each peer has a valid certificate
|
||||||
|
signed by this root certificate. For SSL torrents, all peers are connecting over SSL
|
||||||
|
connections. For more information on SSL torrents, see the manual_.
|
||||||
|
|
||||||
|
.. _manual: manual.html#ssl-torrents
|
||||||
|
|
||||||
set_priv() priv()
|
set_priv() priv()
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
464
docs/manual.html
464
docs/manual.html
|
@ -138,210 +138,208 @@
|
||||||
<li><a class="reference internal" href="#scrape-tracker" id="id87">scrape_tracker()</a></li>
|
<li><a class="reference internal" href="#scrape-tracker" id="id87">scrape_tracker()</a></li>
|
||||||
<li><a class="reference internal" href="#connect-peer" id="id88">connect_peer()</a></li>
|
<li><a class="reference internal" href="#connect-peer" id="id88">connect_peer()</a></li>
|
||||||
<li><a class="reference internal" href="#name" id="id89">name()</a></li>
|
<li><a class="reference internal" href="#name" id="id89">name()</a></li>
|
||||||
<li><a class="reference internal" href="#set-ratio" id="id90">set_ratio()</a></li>
|
<li><a class="reference internal" href="#set-upload-limit-set-download-limit-upload-limit-download-limit" id="id90">set_upload_limit() set_download_limit() upload_limit() download_limit()</a></li>
|
||||||
<li><a class="reference internal" href="#set-upload-limit-set-download-limit-upload-limit-download-limit" id="id91">set_upload_limit() set_download_limit() upload_limit() download_limit()</a></li>
|
<li><a class="reference internal" href="#set-sequential-download" id="id91">set_sequential_download()</a></li>
|
||||||
<li><a class="reference internal" href="#set-sequential-download" id="id92">set_sequential_download()</a></li>
|
<li><a class="reference internal" href="#pause-resume" id="id92">pause() resume()</a></li>
|
||||||
<li><a class="reference internal" href="#get-peer-download-limit-get-peer-upload-limit-set-peer-upload-limit-set-peer-download-limit" id="id93">get_peer_download_limit() get_peer_upload_limit() set_peer_upload_limit() set_peer_download_limit()</a></li>
|
<li><a class="reference internal" href="#flush-cache" id="id93">flush_cache()</a></li>
|
||||||
<li><a class="reference internal" href="#pause-resume" id="id94">pause() resume()</a></li>
|
<li><a class="reference internal" href="#force-recheck" id="id94">force_recheck()</a></li>
|
||||||
<li><a class="reference internal" href="#flush-cache" id="id95">flush_cache()</a></li>
|
<li><a class="reference internal" href="#clear-error" id="id95">clear_error()</a></li>
|
||||||
<li><a class="reference internal" href="#force-recheck" id="id96">force_recheck()</a></li>
|
<li><a class="reference internal" href="#set-upload-mode" id="id96">set_upload_mode()</a></li>
|
||||||
<li><a class="reference internal" href="#clear-error" id="id97">clear_error()</a></li>
|
<li><a class="reference internal" href="#set-share-mode" id="id97">set_share_mode()</a></li>
|
||||||
<li><a class="reference internal" href="#set-upload-mode" id="id98">set_upload_mode()</a></li>
|
<li><a class="reference internal" href="#apply-ip-filter" id="id98">apply_ip_filter()</a></li>
|
||||||
<li><a class="reference internal" href="#set-share-mode" id="id99">set_share_mode()</a></li>
|
<li><a class="reference internal" href="#resolve-countries" id="id99">resolve_countries()</a></li>
|
||||||
<li><a class="reference internal" href="#apply-ip-filter" id="id100">apply_ip_filter()</a></li>
|
<li><a class="reference internal" href="#is-seed" id="id100">is_seed()</a></li>
|
||||||
<li><a class="reference internal" href="#resolve-countries" id="id101">resolve_countries()</a></li>
|
<li><a class="reference internal" href="#auto-managed" id="id101">auto_managed()</a></li>
|
||||||
<li><a class="reference internal" href="#is-seed" id="id102">is_seed()</a></li>
|
<li><a class="reference internal" href="#set-metadata" id="id102">set_metadata()</a></li>
|
||||||
<li><a class="reference internal" href="#auto-managed" id="id103">auto_managed()</a></li>
|
<li><a class="reference internal" href="#set-tracker-login" id="id103">set_tracker_login()</a></li>
|
||||||
<li><a class="reference internal" href="#set-metadata" id="id104">set_metadata()</a></li>
|
<li><a class="reference internal" href="#trackers-replace-trackers-add-tracker" id="id104">trackers() replace_trackers() add_tracker()</a></li>
|
||||||
<li><a class="reference internal" href="#set-tracker-login" id="id105">set_tracker_login()</a></li>
|
<li><a class="reference internal" href="#add-url-seed-remove-url-seed-url-seeds" id="id105">add_url_seed() remove_url_seed() url_seeds()</a></li>
|
||||||
<li><a class="reference internal" href="#trackers-replace-trackers-add-tracker" id="id106">trackers() replace_trackers() add_tracker()</a></li>
|
<li><a class="reference internal" href="#add-http-seed-remove-http-seed-http-seeds" id="id106">add_http_seed() remove_http_seed() http_seeds()</a></li>
|
||||||
<li><a class="reference internal" href="#add-url-seed-remove-url-seed-url-seeds" id="id107">add_url_seed() remove_url_seed() url_seeds()</a></li>
|
<li><a class="reference internal" href="#queue-position-queue-position-up-queue-position-down-queue-position-top-queue-position-bottom" id="id107">queue_position() queue_position_up() queue_position_down() queue_position_top() queue_position_bottom()</a></li>
|
||||||
<li><a class="reference internal" href="#add-http-seed-remove-http-seed-http-seeds" id="id108">add_http_seed() remove_http_seed() http_seeds()</a></li>
|
<li><a class="reference internal" href="#set-priority" id="id108">set_priority()</a></li>
|
||||||
<li><a class="reference internal" href="#queue-position-queue-position-up-queue-position-down-queue-position-top-queue-position-bottom" id="id109">queue_position() queue_position_up() queue_position_down() queue_position_top() queue_position_bottom()</a></li>
|
<li><a class="reference internal" href="#use-interface" id="id109">use_interface()</a></li>
|
||||||
<li><a class="reference internal" href="#set-priority" id="id110">set_priority()</a></li>
|
<li><a class="reference internal" href="#info-hash" id="id110">info_hash()</a></li>
|
||||||
<li><a class="reference internal" href="#use-interface" id="id111">use_interface()</a></li>
|
<li><a class="reference internal" href="#set-max-uploads-max-uploads" id="id111">set_max_uploads() max_uploads()</a></li>
|
||||||
<li><a class="reference internal" href="#info-hash" id="id112">info_hash()</a></li>
|
<li><a class="reference internal" href="#set-max-connections-max-connections" id="id112">set_max_connections() max_connections()</a></li>
|
||||||
<li><a class="reference internal" href="#set-max-uploads-max-uploads" id="id113">set_max_uploads() max_uploads()</a></li>
|
<li><a class="reference internal" href="#save-resume-data" id="id113">save_resume_data()</a></li>
|
||||||
<li><a class="reference internal" href="#set-max-connections-max-connections" id="id114">set_max_connections() max_connections()</a></li>
|
<li><a class="reference internal" href="#need-save-resume-data" id="id114">need_save_resume_data()</a></li>
|
||||||
<li><a class="reference internal" href="#save-resume-data" id="id115">save_resume_data()</a></li>
|
<li><a class="reference internal" href="#id5" id="id115">status()</a></li>
|
||||||
<li><a class="reference internal" href="#need-save-resume-data" id="id116">need_save_resume_data()</a></li>
|
<li><a class="reference internal" href="#get-download-queue" id="id116">get_download_queue()</a></li>
|
||||||
<li><a class="reference internal" href="#id5" id="id117">status()</a></li>
|
<li><a class="reference internal" href="#get-peer-info" id="id117">get_peer_info()</a></li>
|
||||||
<li><a class="reference internal" href="#get-download-queue" id="id118">get_download_queue()</a></li>
|
<li><a class="reference internal" href="#get-torrent-info" id="id118">get_torrent_info()</a></li>
|
||||||
<li><a class="reference internal" href="#get-peer-info" id="id119">get_peer_info()</a></li>
|
<li><a class="reference internal" href="#is-valid" id="id119">is_valid()</a></li>
|
||||||
<li><a class="reference internal" href="#get-torrent-info" id="id120">get_torrent_info()</a></li>
|
<li><a class="reference internal" href="#set-ssl-certificate" id="id120">set_ssl_certificate()</a></li>
|
||||||
<li><a class="reference internal" href="#is-valid" id="id121">is_valid()</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-ssl-certificate" id="id122">set_ssl_certificate()</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#torrent-status" id="id123">torrent_status</a></li>
|
<li><a class="reference internal" href="#torrent-status" id="id121">torrent_status</a></li>
|
||||||
<li><a class="reference internal" href="#peer-info" id="id124">peer_info</a></li>
|
<li><a class="reference internal" href="#peer-info" id="id122">peer_info</a></li>
|
||||||
<li><a class="reference internal" href="#feed-handle" id="id125">feed_handle</a><ul>
|
<li><a class="reference internal" href="#feed-handle" id="id123">feed_handle</a><ul>
|
||||||
<li><a class="reference internal" href="#update-feed" id="id126">update_feed()</a></li>
|
<li><a class="reference internal" href="#update-feed" id="id124">update_feed()</a></li>
|
||||||
<li><a class="reference internal" href="#get-feed-status" id="id127">get_feed_status()</a></li>
|
<li><a class="reference internal" href="#get-feed-status" id="id125">get_feed_status()</a></li>
|
||||||
<li><a class="reference internal" href="#set-settings-settings" id="id128">set_settings() settings()</a></li>
|
<li><a class="reference internal" href="#set-settings-settings" id="id126">set_settings() settings()</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#feed-item" id="id129">feed_item</a></li>
|
<li><a class="reference internal" href="#feed-item" id="id127">feed_item</a></li>
|
||||||
<li><a class="reference internal" href="#session-customization" id="id130">session customization</a><ul>
|
<li><a class="reference internal" href="#session-customization" id="id128">session customization</a><ul>
|
||||||
<li><a class="reference internal" href="#presets" id="id131">presets</a></li>
|
<li><a class="reference internal" href="#presets" id="id129">presets</a></li>
|
||||||
<li><a class="reference internal" href="#session-settings" id="id132">session_settings</a></li>
|
<li><a class="reference internal" href="#session-settings" id="id130">session_settings</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#pe-settings" id="id133">pe_settings</a></li>
|
<li><a class="reference internal" href="#pe-settings" id="id131">pe_settings</a></li>
|
||||||
<li><a class="reference internal" href="#proxy-settings" id="id134">proxy_settings</a></li>
|
<li><a class="reference internal" href="#proxy-settings" id="id132">proxy_settings</a></li>
|
||||||
<li><a class="reference internal" href="#ip-filter" id="id135">ip_filter</a><ul>
|
<li><a class="reference internal" href="#ip-filter" id="id133">ip_filter</a><ul>
|
||||||
<li><a class="reference internal" href="#id8" id="id136">ip_filter()</a></li>
|
<li><a class="reference internal" href="#id8" id="id134">ip_filter()</a></li>
|
||||||
<li><a class="reference internal" href="#add-rule" id="id137">add_rule()</a></li>
|
<li><a class="reference internal" href="#add-rule" id="id135">add_rule()</a></li>
|
||||||
<li><a class="reference internal" href="#access" id="id138">access()</a></li>
|
<li><a class="reference internal" href="#access" id="id136">access()</a></li>
|
||||||
<li><a class="reference internal" href="#export-filter" id="id139">export_filter()</a></li>
|
<li><a class="reference internal" href="#export-filter" id="id137">export_filter()</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#big-number" id="id140">big_number</a></li>
|
<li><a class="reference internal" href="#big-number" id="id138">big_number</a></li>
|
||||||
<li><a class="reference internal" href="#bitfield" id="id141">bitfield</a></li>
|
<li><a class="reference internal" href="#bitfield" id="id139">bitfield</a></li>
|
||||||
<li><a class="reference internal" href="#hasher" id="id142">hasher</a></li>
|
<li><a class="reference internal" href="#hasher" id="id140">hasher</a></li>
|
||||||
<li><a class="reference internal" href="#fingerprint" id="id143">fingerprint</a></li>
|
<li><a class="reference internal" href="#fingerprint" id="id141">fingerprint</a></li>
|
||||||
<li><a class="reference internal" href="#upnp-and-nat-pmp" id="id144">UPnP and NAT-PMP</a><ul>
|
<li><a class="reference internal" href="#upnp-and-nat-pmp" id="id142">UPnP and NAT-PMP</a><ul>
|
||||||
<li><a class="reference internal" href="#add-mapping" id="id145">add_mapping()</a></li>
|
<li><a class="reference internal" href="#add-mapping" id="id143">add_mapping()</a></li>
|
||||||
<li><a class="reference internal" href="#delete-mapping" id="id146">delete_mapping()</a></li>
|
<li><a class="reference internal" href="#delete-mapping" id="id144">delete_mapping()</a></li>
|
||||||
<li><a class="reference internal" href="#router-model" id="id147">router_model()</a></li>
|
<li><a class="reference internal" href="#router-model" id="id145">router_model()</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#free-functions" id="id148">free functions</a><ul>
|
<li><a class="reference internal" href="#free-functions" id="id146">free functions</a><ul>
|
||||||
<li><a class="reference internal" href="#identify-client" id="id149">identify_client()</a></li>
|
<li><a class="reference internal" href="#identify-client" id="id147">identify_client()</a></li>
|
||||||
<li><a class="reference internal" href="#client-fingerprint" id="id150">client_fingerprint()</a></li>
|
<li><a class="reference internal" href="#client-fingerprint" id="id148">client_fingerprint()</a></li>
|
||||||
<li><a class="reference internal" href="#lazy-bdecode" id="id151">lazy_bdecode()</a></li>
|
<li><a class="reference internal" href="#lazy-bdecode" id="id149">lazy_bdecode()</a></li>
|
||||||
<li><a class="reference internal" href="#bdecode-bencode" id="id152">bdecode() bencode()</a></li>
|
<li><a class="reference internal" href="#bdecode-bencode" id="id150">bdecode() bencode()</a></li>
|
||||||
<li><a class="reference internal" href="#add-magnet-uri" id="id153">add_magnet_uri()</a></li>
|
<li><a class="reference internal" href="#add-magnet-uri" id="id151">add_magnet_uri()</a></li>
|
||||||
<li><a class="reference internal" href="#make-magnet-uri" id="id154">make_magnet_uri()</a></li>
|
<li><a class="reference internal" href="#make-magnet-uri" id="id152">make_magnet_uri()</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#alerts" id="id155">alerts</a><ul>
|
<li><a class="reference internal" href="#alerts" id="id153">alerts</a><ul>
|
||||||
<li><a class="reference internal" href="#torrent-added-alert" id="id156">torrent_added_alert</a></li>
|
<li><a class="reference internal" href="#torrent-added-alert" id="id154">torrent_added_alert</a></li>
|
||||||
<li><a class="reference internal" href="#add-torrent-alert" id="id157">add_torrent_alert</a></li>
|
<li><a class="reference internal" href="#add-torrent-alert" id="id155">add_torrent_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-removed-alert" id="id158">torrent_removed_alert</a></li>
|
<li><a class="reference internal" href="#torrent-removed-alert" id="id156">torrent_removed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#read-piece-alert" id="id159">read_piece_alert</a></li>
|
<li><a class="reference internal" href="#read-piece-alert" id="id157">read_piece_alert</a></li>
|
||||||
<li><a class="reference internal" href="#external-ip-alert" id="id160">external_ip_alert</a></li>
|
<li><a class="reference internal" href="#external-ip-alert" id="id158">external_ip_alert</a></li>
|
||||||
<li><a class="reference internal" href="#listen-failed-alert" id="id161">listen_failed_alert</a></li>
|
<li><a class="reference internal" href="#listen-failed-alert" id="id159">listen_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#listen-succeeded-alert" id="id162">listen_succeeded_alert</a></li>
|
<li><a class="reference internal" href="#listen-succeeded-alert" id="id160">listen_succeeded_alert</a></li>
|
||||||
<li><a class="reference internal" href="#portmap-error-alert" id="id163">portmap_error_alert</a></li>
|
<li><a class="reference internal" href="#portmap-error-alert" id="id161">portmap_error_alert</a></li>
|
||||||
<li><a class="reference internal" href="#portmap-alert" id="id164">portmap_alert</a></li>
|
<li><a class="reference internal" href="#portmap-alert" id="id162">portmap_alert</a></li>
|
||||||
<li><a class="reference internal" href="#portmap-log-alert" id="id165">portmap_log_alert</a></li>
|
<li><a class="reference internal" href="#portmap-log-alert" id="id163">portmap_log_alert</a></li>
|
||||||
<li><a class="reference internal" href="#file-error-alert" id="id166">file_error_alert</a></li>
|
<li><a class="reference internal" href="#file-error-alert" id="id164">file_error_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-error-alert" id="id167">torrent_error_alert</a></li>
|
<li><a class="reference internal" href="#torrent-error-alert" id="id165">torrent_error_alert</a></li>
|
||||||
<li><a class="reference internal" href="#file-renamed-alert" id="id168">file_renamed_alert</a></li>
|
<li><a class="reference internal" href="#file-renamed-alert" id="id166">file_renamed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#file-rename-failed-alert" id="id169">file_rename_failed_alert</a></li>
|
<li><a class="reference internal" href="#file-rename-failed-alert" id="id167">file_rename_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#tracker-announce-alert" id="id170">tracker_announce_alert</a></li>
|
<li><a class="reference internal" href="#tracker-announce-alert" id="id168">tracker_announce_alert</a></li>
|
||||||
<li><a class="reference internal" href="#tracker-error-alert" id="id171">tracker_error_alert</a></li>
|
<li><a class="reference internal" href="#tracker-error-alert" id="id169">tracker_error_alert</a></li>
|
||||||
<li><a class="reference internal" href="#tracker-reply-alert" id="id172">tracker_reply_alert</a></li>
|
<li><a class="reference internal" href="#tracker-reply-alert" id="id170">tracker_reply_alert</a></li>
|
||||||
<li><a class="reference internal" href="#tracker-warning-alert" id="id173">tracker_warning_alert</a></li>
|
<li><a class="reference internal" href="#tracker-warning-alert" id="id171">tracker_warning_alert</a></li>
|
||||||
<li><a class="reference internal" href="#scrape-reply-alert" id="id174">scrape_reply_alert</a></li>
|
<li><a class="reference internal" href="#scrape-reply-alert" id="id172">scrape_reply_alert</a></li>
|
||||||
<li><a class="reference internal" href="#scrape-failed-alert" id="id175">scrape_failed_alert</a></li>
|
<li><a class="reference internal" href="#scrape-failed-alert" id="id173">scrape_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#url-seed-alert" id="id176">url_seed_alert</a></li>
|
<li><a class="reference internal" href="#url-seed-alert" id="id174">url_seed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#hash-failed-alert" id="id177">hash_failed_alert</a></li>
|
<li><a class="reference internal" href="#hash-failed-alert" id="id175">hash_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-alert" id="id178">peer_alert</a></li>
|
<li><a class="reference internal" href="#peer-alert" id="id176">peer_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-connect-alert" id="id179">peer_connect_alert</a></li>
|
<li><a class="reference internal" href="#peer-connect-alert" id="id177">peer_connect_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-ban-alert" id="id180">peer_ban_alert</a></li>
|
<li><a class="reference internal" href="#peer-ban-alert" id="id178">peer_ban_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-snubbed-alert" id="id181">peer_snubbed_alert</a></li>
|
<li><a class="reference internal" href="#peer-snubbed-alert" id="id179">peer_snubbed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-unsnubbed-alert" id="id182">peer_unsnubbed_alert</a></li>
|
<li><a class="reference internal" href="#peer-unsnubbed-alert" id="id180">peer_unsnubbed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-error-alert" id="id183">peer_error_alert</a></li>
|
<li><a class="reference internal" href="#peer-error-alert" id="id181">peer_error_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-connected-alert" id="id184">peer_connected_alert</a></li>
|
<li><a class="reference internal" href="#peer-connected-alert" id="id182">peer_connected_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-disconnected-alert" id="id185">peer_disconnected_alert</a></li>
|
<li><a class="reference internal" href="#peer-disconnected-alert" id="id183">peer_disconnected_alert</a></li>
|
||||||
<li><a class="reference internal" href="#invalid-request-alert" id="id186">invalid_request_alert</a></li>
|
<li><a class="reference internal" href="#invalid-request-alert" id="id184">invalid_request_alert</a></li>
|
||||||
<li><a class="reference internal" href="#request-dropped-alert" id="id187">request_dropped_alert</a></li>
|
<li><a class="reference internal" href="#request-dropped-alert" id="id185">request_dropped_alert</a></li>
|
||||||
<li><a class="reference internal" href="#block-timeout-alert" id="id188">block_timeout_alert</a></li>
|
<li><a class="reference internal" href="#block-timeout-alert" id="id186">block_timeout_alert</a></li>
|
||||||
<li><a class="reference internal" href="#block-finished-alert" id="id189">block_finished_alert</a></li>
|
<li><a class="reference internal" href="#block-finished-alert" id="id187">block_finished_alert</a></li>
|
||||||
<li><a class="reference internal" href="#lsd-peer-alert" id="id190">lsd_peer_alert</a></li>
|
<li><a class="reference internal" href="#lsd-peer-alert" id="id188">lsd_peer_alert</a></li>
|
||||||
<li><a class="reference internal" href="#file-completed-alert" id="id191">file_completed_alert</a></li>
|
<li><a class="reference internal" href="#file-completed-alert" id="id189">file_completed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#block-downloading-alert" id="id192">block_downloading_alert</a></li>
|
<li><a class="reference internal" href="#block-downloading-alert" id="id190">block_downloading_alert</a></li>
|
||||||
<li><a class="reference internal" href="#unwanted-block-alert" id="id193">unwanted_block_alert</a></li>
|
<li><a class="reference internal" href="#unwanted-block-alert" id="id191">unwanted_block_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-delete-failed-alert" id="id194">torrent_delete_failed_alert</a></li>
|
<li><a class="reference internal" href="#torrent-delete-failed-alert" id="id192">torrent_delete_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-deleted-alert" id="id195">torrent_deleted_alert</a></li>
|
<li><a class="reference internal" href="#torrent-deleted-alert" id="id193">torrent_deleted_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-finished-alert" id="id196">torrent_finished_alert</a></li>
|
<li><a class="reference internal" href="#torrent-finished-alert" id="id194">torrent_finished_alert</a></li>
|
||||||
<li><a class="reference internal" href="#performance-alert" id="id197">performance_alert</a></li>
|
<li><a class="reference internal" href="#performance-alert" id="id195">performance_alert</a></li>
|
||||||
<li><a class="reference internal" href="#state-changed-alert" id="id198">state_changed_alert</a></li>
|
<li><a class="reference internal" href="#state-changed-alert" id="id196">state_changed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#metadata-failed-alert" id="id199">metadata_failed_alert</a></li>
|
<li><a class="reference internal" href="#metadata-failed-alert" id="id197">metadata_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#metadata-received-alert" id="id200">metadata_received_alert</a></li>
|
<li><a class="reference internal" href="#metadata-received-alert" id="id198">metadata_received_alert</a></li>
|
||||||
<li><a class="reference internal" href="#fastresume-rejected-alert" id="id201">fastresume_rejected_alert</a></li>
|
<li><a class="reference internal" href="#fastresume-rejected-alert" id="id199">fastresume_rejected_alert</a></li>
|
||||||
<li><a class="reference internal" href="#peer-blocked-alert" id="id202">peer_blocked_alert</a></li>
|
<li><a class="reference internal" href="#peer-blocked-alert" id="id200">peer_blocked_alert</a></li>
|
||||||
<li><a class="reference internal" href="#storage-moved-alert" id="id203">storage_moved_alert</a></li>
|
<li><a class="reference internal" href="#storage-moved-alert" id="id201">storage_moved_alert</a></li>
|
||||||
<li><a class="reference internal" href="#storage-moved-failed-alert" id="id204">storage_moved_failed_alert</a></li>
|
<li><a class="reference internal" href="#storage-moved-failed-alert" id="id202">storage_moved_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-paused-alert" id="id205">torrent_paused_alert</a></li>
|
<li><a class="reference internal" href="#torrent-paused-alert" id="id203">torrent_paused_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-resumed-alert" id="id206">torrent_resumed_alert</a></li>
|
<li><a class="reference internal" href="#torrent-resumed-alert" id="id204">torrent_resumed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#save-resume-data-alert" id="id207">save_resume_data_alert</a></li>
|
<li><a class="reference internal" href="#save-resume-data-alert" id="id205">save_resume_data_alert</a></li>
|
||||||
<li><a class="reference internal" href="#save-resume-data-failed-alert" id="id208">save_resume_data_failed_alert</a></li>
|
<li><a class="reference internal" href="#save-resume-data-failed-alert" id="id206">save_resume_data_failed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#stats-alert" id="id209">stats_alert</a></li>
|
<li><a class="reference internal" href="#stats-alert" id="id207">stats_alert</a></li>
|
||||||
<li><a class="reference internal" href="#cache-flushed-alert" id="id210">cache_flushed_alert</a></li>
|
<li><a class="reference internal" href="#cache-flushed-alert" id="id208">cache_flushed_alert</a></li>
|
||||||
<li><a class="reference internal" href="#torrent-need-cert-alert" id="id211">torrent_need_cert_alert</a></li>
|
<li><a class="reference internal" href="#torrent-need-cert-alert" id="id209">torrent_need_cert_alert</a></li>
|
||||||
<li><a class="reference internal" href="#dht-announce-alert" id="id212">dht_announce_alert</a></li>
|
<li><a class="reference internal" href="#dht-announce-alert" id="id210">dht_announce_alert</a></li>
|
||||||
<li><a class="reference internal" href="#dht-get-peers-alert" id="id213">dht_get_peers_alert</a></li>
|
<li><a class="reference internal" href="#dht-get-peers-alert" id="id211">dht_get_peers_alert</a></li>
|
||||||
<li><a class="reference internal" href="#dht-reply-alert" id="id214">dht_reply_alert</a></li>
|
<li><a class="reference internal" href="#dht-reply-alert" id="id212">dht_reply_alert</a></li>
|
||||||
<li><a class="reference internal" href="#dht-bootstrap-alert" id="id215">dht_bootstrap_alert</a></li>
|
<li><a class="reference internal" href="#dht-bootstrap-alert" id="id213">dht_bootstrap_alert</a></li>
|
||||||
<li><a class="reference internal" href="#anonymous-mode-alert" id="id216">anonymous_mode_alert</a></li>
|
<li><a class="reference internal" href="#anonymous-mode-alert" id="id214">anonymous_mode_alert</a></li>
|
||||||
<li><a class="reference internal" href="#rss-alert" id="id217">rss_alert</a></li>
|
<li><a class="reference internal" href="#rss-alert" id="id215">rss_alert</a></li>
|
||||||
<li><a class="reference internal" href="#incoming-connection-alert" id="id218">incoming_connection_alert</a></li>
|
<li><a class="reference internal" href="#incoming-connection-alert" id="id216">incoming_connection_alert</a></li>
|
||||||
<li><a class="reference internal" href="#state-update-alert" id="id219">state_update_alert</a></li>
|
<li><a class="reference internal" href="#state-update-alert" id="id217">state_update_alert</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#alert-dispatcher" id="id220">alert dispatcher</a></li>
|
<li><a class="reference internal" href="#alert-dispatcher" id="id218">alert dispatcher</a></li>
|
||||||
<li><a class="reference internal" href="#exceptions" id="id221">exceptions</a><ul>
|
<li><a class="reference internal" href="#exceptions" id="id219">exceptions</a><ul>
|
||||||
<li><a class="reference internal" href="#libtorrent-exception" id="id222">libtorrent_exception</a></li>
|
<li><a class="reference internal" href="#libtorrent-exception" id="id220">libtorrent_exception</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#error-code" id="id223">error_code</a><ul>
|
<li><a class="reference internal" href="#error-code" id="id221">error_code</a><ul>
|
||||||
<li><a class="reference internal" href="#translating-error-codes" id="id224">translating error codes</a></li>
|
<li><a class="reference internal" href="#translating-error-codes" id="id222">translating error codes</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#storage-interface" id="id225">storage_interface</a><ul>
|
<li><a class="reference internal" href="#storage-interface" id="id223">storage_interface</a><ul>
|
||||||
<li><a class="reference internal" href="#initialize" id="id226">initialize()</a></li>
|
<li><a class="reference internal" href="#initialize" id="id224">initialize()</a></li>
|
||||||
<li><a class="reference internal" href="#has-any-file" id="id227">has_any_file()</a></li>
|
<li><a class="reference internal" href="#has-any-file" id="id225">has_any_file()</a></li>
|
||||||
<li><a class="reference internal" href="#hint-read" id="id228">hint_read()</a></li>
|
<li><a class="reference internal" href="#hint-read" id="id226">hint_read()</a></li>
|
||||||
<li><a class="reference internal" href="#readv-writev" id="id229">readv() writev()</a></li>
|
<li><a class="reference internal" href="#readv-writev" id="id227">readv() writev()</a></li>
|
||||||
<li><a class="reference internal" href="#sparse-end" id="id230">sparse_end()</a></li>
|
<li><a class="reference internal" href="#sparse-end" id="id228">sparse_end()</a></li>
|
||||||
<li><a class="reference internal" href="#id10" id="id231">move_storage()</a></li>
|
<li><a class="reference internal" href="#id10" id="id229">move_storage()</a></li>
|
||||||
<li><a class="reference internal" href="#verify-resume-data" id="id232">verify_resume_data()</a></li>
|
<li><a class="reference internal" href="#verify-resume-data" id="id230">verify_resume_data()</a></li>
|
||||||
<li><a class="reference internal" href="#write-resume-data" id="id233">write_resume_data()</a></li>
|
<li><a class="reference internal" href="#write-resume-data" id="id231">write_resume_data()</a></li>
|
||||||
<li><a class="reference internal" href="#move-slot" id="id234">move_slot()</a></li>
|
<li><a class="reference internal" href="#move-slot" id="id232">move_slot()</a></li>
|
||||||
<li><a class="reference internal" href="#swap-slots" id="id235">swap_slots()</a></li>
|
<li><a class="reference internal" href="#swap-slots" id="id233">swap_slots()</a></li>
|
||||||
<li><a class="reference internal" href="#swap-slots3" id="id236">swap_slots3()</a></li>
|
<li><a class="reference internal" href="#swap-slots3" id="id234">swap_slots3()</a></li>
|
||||||
<li><a class="reference internal" href="#id11" id="id237">rename_file()</a></li>
|
<li><a class="reference internal" href="#id11" id="id235">rename_file()</a></li>
|
||||||
<li><a class="reference internal" href="#release-files" id="id238">release_files()</a></li>
|
<li><a class="reference internal" href="#release-files" id="id236">release_files()</a></li>
|
||||||
<li><a class="reference internal" href="#delete-files" id="id239">delete_files()</a></li>
|
<li><a class="reference internal" href="#delete-files" id="id237">delete_files()</a></li>
|
||||||
<li><a class="reference internal" href="#finalize-file" id="id240">finalize_file()</a></li>
|
<li><a class="reference internal" href="#finalize-file" id="id238">finalize_file()</a></li>
|
||||||
<li><a class="reference internal" href="#example" id="id241">example</a></li>
|
<li><a class="reference internal" href="#example" id="id239">example</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#magnet-links" id="id242">magnet links</a></li>
|
<li><a class="reference internal" href="#magnet-links" id="id240">magnet links</a></li>
|
||||||
<li><a class="reference internal" href="#queuing" id="id243">queuing</a><ul>
|
<li><a class="reference internal" href="#queuing" id="id241">queuing</a><ul>
|
||||||
<li><a class="reference internal" href="#downloading" id="id244">downloading</a></li>
|
<li><a class="reference internal" href="#downloading" id="id242">downloading</a></li>
|
||||||
<li><a class="reference internal" href="#seeding" id="id245">seeding</a></li>
|
<li><a class="reference internal" href="#seeding" id="id243">seeding</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#fast-resume" id="id246">fast resume</a><ul>
|
<li><a class="reference internal" href="#fast-resume" id="id244">fast resume</a><ul>
|
||||||
<li><a class="reference internal" href="#file-format" id="id247">file format</a></li>
|
<li><a class="reference internal" href="#file-format" id="id245">file format</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#storage-allocation" id="id248">storage allocation</a><ul>
|
<li><a class="reference internal" href="#storage-allocation" id="id246">storage allocation</a><ul>
|
||||||
<li><a class="reference internal" href="#sparse-allocation" id="id249">sparse allocation</a></li>
|
<li><a class="reference internal" href="#sparse-allocation" id="id247">sparse allocation</a></li>
|
||||||
<li><a class="reference internal" href="#full-allocation" id="id250">full allocation</a></li>
|
<li><a class="reference internal" href="#full-allocation" id="id248">full allocation</a></li>
|
||||||
<li><a class="reference internal" href="#compact-allocation" id="id251">compact allocation</a></li>
|
<li><a class="reference internal" href="#compact-allocation" id="id249">compact allocation</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#extensions" id="id252">extensions</a><ul>
|
<li><a class="reference internal" href="#extensions" id="id250">extensions</a><ul>
|
||||||
<li><a class="reference internal" href="#metadata-from-peers" id="id253">metadata from peers</a></li>
|
<li><a class="reference internal" href="#metadata-from-peers" id="id251">metadata from peers</a></li>
|
||||||
<li><a class="reference internal" href="#dont-have" id="id254">dont_have</a></li>
|
<li><a class="reference internal" href="#dont-have" id="id252">dont_have</a></li>
|
||||||
<li><a class="reference internal" href="#http-seeding" id="id255">HTTP seeding</a></li>
|
<li><a class="reference internal" href="#http-seeding" id="id253">HTTP seeding</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#piece-picker" id="id256">piece picker</a><ul>
|
<li><a class="reference internal" href="#piece-picker" id="id254">piece picker</a><ul>
|
||||||
<li><a class="reference internal" href="#internal-representation" id="id257">internal representation</a></li>
|
<li><a class="reference internal" href="#internal-representation" id="id255">internal representation</a></li>
|
||||||
<li><a class="reference internal" href="#picker-strategy" id="id258">picker strategy</a></li>
|
<li><a class="reference internal" href="#picker-strategy" id="id256">picker strategy</a></li>
|
||||||
<li><a class="reference internal" href="#reverse-order" id="id259">reverse order</a></li>
|
<li><a class="reference internal" href="#reverse-order" id="id257">reverse order</a></li>
|
||||||
<li><a class="reference internal" href="#parole-mode" id="id260">parole mode</a></li>
|
<li><a class="reference internal" href="#parole-mode" id="id258">parole mode</a></li>
|
||||||
<li><a class="reference internal" href="#prioritize-partial-pieces" id="id261">prioritize partial pieces</a></li>
|
<li><a class="reference internal" href="#prioritize-partial-pieces" id="id259">prioritize partial pieces</a></li>
|
||||||
<li><a class="reference internal" href="#prefer-whole-pieces" id="id262">prefer whole pieces</a></li>
|
<li><a class="reference internal" href="#prefer-whole-pieces" id="id260">prefer whole pieces</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#ssl-torrents" id="id263">SSL torrents</a></li>
|
<li><a class="reference internal" href="#ssl-torrents" id="id261">SSL torrents</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="overview">
|
<div class="section" id="overview">
|
||||||
|
@ -2402,7 +2400,6 @@ struct torrent_handle
|
||||||
void remove_http_seed(std::string const& url);
|
void remove_http_seed(std::string const& url);
|
||||||
std::set<std::string> http_seeds() const;
|
std::set<std::string> http_seeds() const;
|
||||||
|
|
||||||
void set_ratio(float ratio) const;
|
|
||||||
int max_uploads() const;
|
int max_uploads() const;
|
||||||
void set_max_uploads(int max_uploads) const;
|
void set_max_uploads(int max_uploads) const;
|
||||||
void set_max_connections(int max_connections) const;
|
void set_max_connections(int max_connections) const;
|
||||||
|
@ -2414,11 +2411,6 @@ struct torrent_handle
|
||||||
void set_sequential_download(bool sd) const;
|
void set_sequential_download(bool sd) const;
|
||||||
bool is_sequential_download() const;
|
bool is_sequential_download() const;
|
||||||
|
|
||||||
int get_peer_upload_limit(tcp::endpoint ip);
|
|
||||||
int get_peer_download_limit(tcp::endpoint ip);
|
|
||||||
void set_peer_upload_limit(asio::ip::tcp::endpoint ip, int limit) const;
|
|
||||||
void set_peer_download_limit(asio::ip::tcp::endpoint ip, int limit) const;
|
|
||||||
|
|
||||||
int queue_position() const;
|
int queue_position() const;
|
||||||
void queue_position_up() const;
|
void queue_position_up() const;
|
||||||
void queue_position_down() const;
|
void queue_position_down() const;
|
||||||
|
@ -2790,21 +2782,6 @@ std::string name() const;
|
||||||
case the torrent was started without metadata, and hasn't completely received it yet,
|
case the torrent was started without metadata, and hasn't completely received it yet,
|
||||||
it returns the name given to it when added to the session. See <tt class="docutils literal"><span class="pre">session::add_torrent</span></tt>.</p>
|
it returns the name given to it when added to the session. See <tt class="docutils literal"><span class="pre">session::add_torrent</span></tt>.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="set-ratio">
|
|
||||||
<h2>set_ratio()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void set_ratio(float ratio) const;
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p><tt class="docutils literal"><span class="pre">set_ratio()</span></tt> sets the desired download / upload ratio. If set to 0, it is considered being
|
|
||||||
infinite. i.e. the client will always upload as much as it can, no matter how much it gets back
|
|
||||||
in return. With this setting it will work much like the standard clients.</p>
|
|
||||||
<p>Besides 0, the ratio can be set to any number greater than or equal to 1. It means how much to
|
|
||||||
attempt to upload in return for each download. e.g. if set to 2, the client will try to upload
|
|
||||||
2 bytes for every byte received. The default setting for this is 0, which will make it work
|
|
||||||
as a standard client.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-upload-limit-set-download-limit-upload-limit-download-limit">
|
<div class="section" id="set-upload-limit-set-download-limit-upload-limit-download-limit">
|
||||||
<h2>set_upload_limit() set_download_limit() upload_limit() download_limit()</h2>
|
<h2>set_upload_limit() set_download_limit() upload_limit() download_limit()</h2>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
@ -2836,20 +2813,6 @@ picker will pick pieces in sequence instead of rarest first.</p>
|
||||||
<p>Enabling sequential download will affect the piece distribution negatively in the swarm. It should be
|
<p>Enabling sequential download will affect the piece distribution negatively in the swarm. It should be
|
||||||
used sparingly.</p>
|
used sparingly.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="get-peer-download-limit-get-peer-upload-limit-set-peer-upload-limit-set-peer-download-limit">
|
|
||||||
<h2>get_peer_download_limit() get_peer_upload_limit() set_peer_upload_limit() set_peer_download_limit()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
int get_peer_upload_limit(tcp::endpoint ip);
|
|
||||||
int get_peer_download_limit(tcp::endpoint ip);
|
|
||||||
void set_peer_upload_limit(asio::ip::tcp::endpoint ip, int limit) const;
|
|
||||||
void set_peer_download_limit(asio::ip::tcp::endpoint ip, int limit) const;
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Works like <tt class="docutils literal"><span class="pre">get_upload_limit</span></tt>, <tt class="docutils literal"><span class="pre">get_download_limit</span></tt>, <tt class="docutils literal"><span class="pre">set_upload_limit</span></tt> and
|
|
||||||
<tt class="docutils literal"><span class="pre">set_download_limit</span></tt> respectively, but controls individual peer instead of the
|
|
||||||
whole torrent.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="pause-resume">
|
<div class="section" id="pause-resume">
|
||||||
<h2>pause() resume()</h2>
|
<h2>pause() resume()</h2>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
@ -4516,8 +4479,6 @@ struct session_settings
|
||||||
bool report_true_downloaded;
|
bool report_true_downloaded;
|
||||||
bool strict_end_game_mode;
|
bool strict_end_game_mode;
|
||||||
|
|
||||||
int default_peer_upload_rate;
|
|
||||||
int default_peer_download_rate;
|
|
||||||
bool broadcast_lsd;
|
bool broadcast_lsd;
|
||||||
|
|
||||||
bool enable_outgoing_utp;
|
bool enable_outgoing_utp;
|
||||||
|
@ -4574,6 +4535,8 @@ struct session_settings
|
||||||
int read_job_every;
|
int read_job_every;
|
||||||
bool use_disk_read_ahead;
|
bool use_disk_read_ahead;
|
||||||
bool lock_files;
|
bool lock_files;
|
||||||
|
|
||||||
|
int ssl_listen;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
<p><tt class="docutils literal"><span class="pre">version</span></tt> is automatically set to the libtorrent version you're using
|
<p><tt class="docutils literal"><span class="pre">version</span></tt> is automatically set to the libtorrent version you're using
|
||||||
|
@ -5124,12 +5087,6 @@ sometimes, but it may also avoid downloading a lot of redundant bytes.
|
||||||
If this is <tt class="docutils literal"><span class="pre">false</span></tt>, libtorrent attempts to use each peer connection
|
If this is <tt class="docutils literal"><span class="pre">false</span></tt>, libtorrent attempts to use each peer connection
|
||||||
to its max, by always requesting something, even if it means requesting
|
to its max, by always requesting something, even if it means requesting
|
||||||
something that has been requested from another peer already.</p>
|
something that has been requested from another peer already.</p>
|
||||||
<p><tt class="docutils literal"><span class="pre">default_peer_upload_rate</span></tt> and <tt class="docutils literal"><span class="pre">default_peer_download_rate</span></tt> specifies
|
|
||||||
the default upload and download rate limits for peers, respectively. These
|
|
||||||
default to 0, which means unlimited. These settings affect the rate limits
|
|
||||||
set on new peer connections (not existing ones). The peer rate limits can
|
|
||||||
be changed individually later using
|
|
||||||
<a class="reference internal" href="#get-peer-download-limit-get-peer-upload-limit-set-peer-upload-limit-set-peer-download-limit">get_peer_download_limit() get_peer_upload_limit() set_peer_upload_limit() set_peer_download_limit()</a>.</p>
|
|
||||||
<p>if <tt class="docutils literal"><span class="pre">broadcast_lsd</span></tt> is set to true, the local peer discovery
|
<p>if <tt class="docutils literal"><span class="pre">broadcast_lsd</span></tt> is set to true, the local peer discovery
|
||||||
(or Local Service Discovery) will not only use IP multicast, but also
|
(or Local Service Discovery) will not only use IP multicast, but also
|
||||||
broadcast its messages. This can be useful when running on networks
|
broadcast its messages. This can be useful when running on networks
|
||||||
|
@ -5301,6 +5258,11 @@ in the disk job queue. This gives a significant performance boost for seeding.</
|
||||||
to or seeding from. This is implemented using <tt class="docutils literal"><span class="pre">fcntl(F_SETLK)</span></tt> on unix systems and
|
to or seeding from. This is implemented using <tt class="docutils literal"><span class="pre">fcntl(F_SETLK)</span></tt> on unix systems and
|
||||||
by not passing in <tt class="docutils literal"><span class="pre">SHARE_READ</span></tt> and <tt class="docutils literal"><span class="pre">SHARE_WRITE</span></tt> on windows. This might prevent
|
by not passing in <tt class="docutils literal"><span class="pre">SHARE_READ</span></tt> and <tt class="docutils literal"><span class="pre">SHARE_WRITE</span></tt> on windows. This might prevent
|
||||||
3rd party processes from corrupting the files under libtorrent's feet.</p>
|
3rd party processes from corrupting the files under libtorrent's feet.</p>
|
||||||
|
<p><tt class="docutils literal"><span class="pre">ssl_listen</span></tt> sets the listen port for SSL connections. If this is set to 0,
|
||||||
|
no SSL listen port is opened. Otherwise a socket is opened on this port. This
|
||||||
|
setting is only taken into account when opening the regular listen port, and
|
||||||
|
won't re-open the listen socket simply by changing this setting.</p>
|
||||||
|
<p>It defaults to port 4433.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="pe-settings">
|
<div class="section" id="pe-settings">
|
||||||
|
@ -6501,7 +6463,7 @@ struct peer_disconnected_alert: peer_alert
|
||||||
<div class="section" id="invalid-request-alert">
|
<div class="section" id="invalid-request-alert">
|
||||||
<h2>invalid_request_alert</h2>
|
<h2>invalid_request_alert</h2>
|
||||||
<p>This is a debug alert that is generated by an incoming invalid piece request.
|
<p>This is a debug alert that is generated by an incoming invalid piece request.
|
||||||
<tt class="docutils literal"><span class="pre">Ïp</span></tt> is the address of the peer and the <tt class="docutils literal"><span class="pre">request</span></tt> is the actual incoming
|
<tt class="docutils literal"><span class="pre">ìp</span></tt> is the address of the peer and the <tt class="docutils literal"><span class="pre">request</span></tt> is the actual incoming
|
||||||
request from the peer.</p>
|
request from the peer.</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
struct invalid_request_alert: peer_alert
|
struct invalid_request_alert: peer_alert
|
||||||
|
@ -7667,6 +7629,16 @@ metadata, and also torrents added by URL.</td>
|
||||||
message is an extension to allow peers to advertise that the
|
message is an extension to allow peers to advertise that the
|
||||||
no longer has a piece they previously had.</td>
|
no longer has a piece they previously had.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr><td>111</td>
|
||||||
|
<td>requires_ssl_connection</td>
|
||||||
|
<td>The peer tried to connect to an SSL torrent without connecting
|
||||||
|
over SSL.</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td>112</td>
|
||||||
|
<td>invalid_ssl_cert</td>
|
||||||
|
<td>The peer tried to connect to a torrent with a certificate
|
||||||
|
for a different torrent.</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p>NAT-PMP errors:</p>
|
<p>NAT-PMP errors:</p>
|
||||||
|
@ -8054,13 +8026,13 @@ std::string error_code_to_string(boost::system::error_code const& ec)
|
||||||
static const char const* swedish[] =
|
static const char const* swedish[] =
|
||||||
{
|
{
|
||||||
"inget fel",
|
"inget fel",
|
||||||
"en fil i torrenten kolliderar med en fil frÂn en annan torrent",
|
"en fil i torrenten kolliderar med en fil från en annan torrent",
|
||||||
"hash check misslyckades",
|
"hash check misslyckades",
|
||||||
"torrent filen ‰r inte en dictionary",
|
"torrent filen är inte en dictionary",
|
||||||
"'info'-nyckeln saknas eller ‰r korrupt i torrentfilen",
|
"'info'-nyckeln saknas eller är korrupt i torrentfilen",
|
||||||
"'info'-f‰ltet ‰r inte en dictionary",
|
"'info'-fältet är inte en dictionary",
|
||||||
"'piece length' f‰ltet saknas eller ‰r korrupt i torrentfilen",
|
"'piece length' fältet saknas eller är korrupt i torrentfilen",
|
||||||
"torrentfilen saknar namnf‰ltet",
|
"torrentfilen saknar namnfältet",
|
||||||
"ogiltigt namn i torrentfilen (kan vara en attack)",
|
"ogiltigt namn i torrentfilen (kan vara en attack)",
|
||||||
// ... more strings here
|
// ... more strings here
|
||||||
};
|
};
|
||||||
|
@ -8712,7 +8684,7 @@ as much space as has been downloaded.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="full-allocation">
|
<div class="section" id="full-allocation">
|
||||||
<h2>full allocation</h2>
|
<h2>full allocation</h2>
|
||||||
<p>When a torrent is started in full allocation mode, the disk-io thread (see <a href="#id264"><span class="problematic" id="id265">threads_</span></a>)
|
<p>When a torrent is started in full allocation mode, the disk-io thread (see <a href="#id262"><span class="problematic" id="id263">threads_</span></a>)
|
||||||
will make sure that the entire storage is allocated, and fill any gaps with zeros.
|
will make sure that the entire storage is allocated, and fill any gaps with zeros.
|
||||||
This will be skipped if the filesystem supports sparse files or automatic zero filling.
|
This will be skipped if the filesystem supports sparse files or automatic zero filling.
|
||||||
It will of course still check for existing pieces and fast resume data. The main
|
It will of course still check for existing pieces and fast resume data. The main
|
||||||
|
@ -9089,22 +9061,46 @@ The protocols are layered like this:</p>
|
||||||
+-----------+-----------+
|
+-----------+-----------+
|
||||||
</pre>
|
</pre>
|
||||||
<p>During the SSL handshake, both peers need to authenticate by providing a certificate
|
<p>During the SSL handshake, both peers need to authenticate by providing a certificate
|
||||||
that is signed by the private counterpart of the CA certificate found in the
|
that is signed by the CA certificate found in the .torrent file. These peer
|
||||||
.torrent file. These peer certificates are expected to be privided to peers through
|
certificates are expected to be privided to peers through some other means than
|
||||||
some other means than bittorrent. Typically by a peer generating a certificate request
|
bittorrent. Typically by a peer generating a certificate request which is sent to
|
||||||
which is sent to the publisher of the torrent, and the publisher returning a signed
|
the publisher of the torrent, and the publisher returning a signed certificate.</p>
|
||||||
certificate.</p>
|
|
||||||
<p>In libtorrent, <a class="reference internal" href="#set-ssl-certificate">set_ssl_certificate()</a> in <a class="reference internal" href="#torrent-handle">torrent_handle</a> is used to tell libtorrent where
|
<p>In libtorrent, <a class="reference internal" href="#set-ssl-certificate">set_ssl_certificate()</a> in <a class="reference internal" href="#torrent-handle">torrent_handle</a> is used to tell libtorrent where
|
||||||
to find the peer certificate and the private key for it. When an SSL torrent is loaded,
|
to find the peer certificate and the private key for it. When an SSL torrent is loaded,
|
||||||
the <a class="reference internal" href="#torrent-need-cert-alert">torrent_need_cert_alert</a> is posted to remind the user to provide a certificate.</p>
|
the <a class="reference internal" href="#torrent-need-cert-alert">torrent_need_cert_alert</a> is posted to remind the user to provide a certificate.</p>
|
||||||
<p>In order for the client to know which torrent an incoming connection belongs to, in order
|
<p>A peer connecting to an SSL torrent MUST provide the <em>SNI</em> TLS extension (server name
|
||||||
to provide the correct certificate, each SSL torrent opens their own dedicated listen socket.</p>
|
indication). The server name is the hex encoded info-hash of the torrent to connect to.
|
||||||
|
This is required for the client accepting the connection to know which certificate to
|
||||||
|
present.</p>
|
||||||
|
<p>SSL connections are accepted on a separate socket from normal bittorrent connections. To
|
||||||
|
pick which port the SSL socket should bind to, set <tt class="docutils literal"><span class="pre">session_settings::ssl_listen</span></tt> to a
|
||||||
|
different port. It defaults to port 4433. This setting is only taken into account when the
|
||||||
|
normal listen socket is opened (i.e. just changing this setting won't necessarily close
|
||||||
|
and re-open the SSL socket). To not listen on an SSL socket at all, set <tt class="docutils literal"><span class="pre">ssl_listen</span></tt> to 0.</p>
|
||||||
<p>This feature is only available if libtorrent is build with openssl support (<tt class="docutils literal"><span class="pre">TORRENT_USE_OPENSSL</span></tt>).</p>
|
<p>This feature is only available if libtorrent is build with openssl support (<tt class="docutils literal"><span class="pre">TORRENT_USE_OPENSSL</span></tt>).</p>
|
||||||
|
<p>To test incoming SSL connections to an SSL torrent, one can use the following <em>openssl</em> command:</p>
|
||||||
|
<pre class="literal-block">
|
||||||
|
openssl s_client -cert <peer-certificate>.pem -key <peer-private-key>.pem -CAfile <torrent-cert>.pem -debug -connect 127.0.0.1:4433 -tls1 -servername <info-hash>
|
||||||
|
</pre>
|
||||||
|
<p>To create a root certificate, the Distinguished Name (<em>DN</em>) is not taken into account
|
||||||
|
by bittorrent peers. You still need to specify something, but from libtorrent's point of
|
||||||
|
view, it doesn't matter what it is. libtorrent only makes sure the peer certificates are
|
||||||
|
signed by the correct root certificate.</p>
|
||||||
|
<p>One way to create the certificates is to use the <tt class="docutils literal"><span class="pre">CA.sh</span></tt> script that comes with openssl, like thisi (don't forget to enter a common Name for the certificate):</p>
|
||||||
|
<pre class="literal-block">
|
||||||
|
CA.sh -newca
|
||||||
|
CA.sh -newreq
|
||||||
|
CA.sh -sign
|
||||||
|
</pre>
|
||||||
|
<p>The torrent certificate is located in <tt class="docutils literal"><span class="pre">./demoCA/private/demoCA/cacert.pem</span></tt>, this is
|
||||||
|
the pem file to include in the .torrent file.</p>
|
||||||
|
<p>The peer's certificate is located in <tt class="docutils literal"><span class="pre">./newcert.pem</span></tt> and the certificate's
|
||||||
|
private key in <tt class="docutils literal"><span class="pre">./newkey.pem</span></tt>.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="system-messages section">
|
<div class="system-messages section">
|
||||||
<h1>Docutils System Messages</h1>
|
<h1>Docutils System Messages</h1>
|
||||||
<div class="system-message" id="id264">
|
<div class="system-message" id="id262">
|
||||||
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">manual.rst</tt>, line 8717); <em><a href="#id265">backlink</a></em></p>
|
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">manual.rst</tt>, line 8686); <em><a href="#id263">backlink</a></em></p>
|
||||||
Unknown target name: "threads".</div>
|
Unknown target name: "threads".</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4535,6 +4535,8 @@ session_settings
|
||||||
int read_job_every;
|
int read_job_every;
|
||||||
bool use_disk_read_ahead;
|
bool use_disk_read_ahead;
|
||||||
bool lock_files;
|
bool lock_files;
|
||||||
|
|
||||||
|
int ssl_listen;
|
||||||
};
|
};
|
||||||
|
|
||||||
``version`` is automatically set to the libtorrent version you're using
|
``version`` is automatically set to the libtorrent version you're using
|
||||||
|
@ -5403,6 +5405,13 @@ to or seeding from. This is implemented using ``fcntl(F_SETLK)`` on unix systems
|
||||||
by not passing in ``SHARE_READ`` and ``SHARE_WRITE`` on windows. This might prevent
|
by not passing in ``SHARE_READ`` and ``SHARE_WRITE`` on windows. This might prevent
|
||||||
3rd party processes from corrupting the files under libtorrent's feet.
|
3rd party processes from corrupting the files under libtorrent's feet.
|
||||||
|
|
||||||
|
``ssl_listen`` sets the listen port for SSL connections. If this is set to 0,
|
||||||
|
no SSL listen port is opened. Otherwise a socket is opened on this port. This
|
||||||
|
setting is only taken into account when opening the regular listen port, and
|
||||||
|
won't re-open the listen socket simply by changing this setting.
|
||||||
|
|
||||||
|
It defaults to port 4433.
|
||||||
|
|
||||||
pe_settings
|
pe_settings
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
@ -7779,6 +7788,12 @@ code symbol description
|
||||||
110 invalid_dont_have The peer sent an invalid ``dont_have`` message. The dont have
|
110 invalid_dont_have The peer sent an invalid ``dont_have`` message. The dont have
|
||||||
message is an extension to allow peers to advertise that the
|
message is an extension to allow peers to advertise that the
|
||||||
no longer has a piece they previously had.
|
no longer has a piece they previously had.
|
||||||
|
------ ----------------------------------------- -----------------------------------------------------------------
|
||||||
|
111 requires_ssl_connection The peer tried to connect to an SSL torrent without connecting
|
||||||
|
over SSL.
|
||||||
|
------ ----------------------------------------- -----------------------------------------------------------------
|
||||||
|
112 invalid_ssl_cert The peer tried to connect to a torrent with a certificate
|
||||||
|
for a different torrent.
|
||||||
====== ========================================= =================================================================
|
====== ========================================= =================================================================
|
||||||
|
|
||||||
NAT-PMP errors:
|
NAT-PMP errors:
|
||||||
|
@ -9022,18 +9037,46 @@ The protocols are layered like this::
|
||||||
+-----------+-----------+
|
+-----------+-----------+
|
||||||
|
|
||||||
During the SSL handshake, both peers need to authenticate by providing a certificate
|
During the SSL handshake, both peers need to authenticate by providing a certificate
|
||||||
that is signed by the private counterpart of the CA certificate found in the
|
that is signed by the CA certificate found in the .torrent file. These peer
|
||||||
.torrent file. These peer certificates are expected to be privided to peers through
|
certificates are expected to be privided to peers through some other means than
|
||||||
some other means than bittorrent. Typically by a peer generating a certificate request
|
bittorrent. Typically by a peer generating a certificate request which is sent to
|
||||||
which is sent to the publisher of the torrent, and the publisher returning a signed
|
the publisher of the torrent, and the publisher returning a signed certificate.
|
||||||
certificate.
|
|
||||||
|
|
||||||
In libtorrent, `set_ssl_certificate()`_ in torrent_handle_ is used to tell libtorrent where
|
In libtorrent, `set_ssl_certificate()`_ in torrent_handle_ is used to tell libtorrent where
|
||||||
to find the peer certificate and the private key for it. When an SSL torrent is loaded,
|
to find the peer certificate and the private key for it. When an SSL torrent is loaded,
|
||||||
the torrent_need_cert_alert_ is posted to remind the user to provide a certificate.
|
the torrent_need_cert_alert_ is posted to remind the user to provide a certificate.
|
||||||
|
|
||||||
In order for the client to know which torrent an incoming connection belongs to, in order
|
A peer connecting to an SSL torrent MUST provide the *SNI* TLS extension (server name
|
||||||
to provide the correct certificate, each SSL torrent opens their own dedicated listen socket.
|
indication). The server name is the hex encoded info-hash of the torrent to connect to.
|
||||||
|
This is required for the client accepting the connection to know which certificate to
|
||||||
|
present.
|
||||||
|
|
||||||
|
SSL connections are accepted on a separate socket from normal bittorrent connections. To
|
||||||
|
pick which port the SSL socket should bind to, set ``session_settings::ssl_listen`` to a
|
||||||
|
different port. It defaults to port 4433. This setting is only taken into account when the
|
||||||
|
normal listen socket is opened (i.e. just changing this setting won't necessarily close
|
||||||
|
and re-open the SSL socket). To not listen on an SSL socket at all, set ``ssl_listen`` to 0.
|
||||||
|
|
||||||
This feature is only available if libtorrent is build with openssl support (``TORRENT_USE_OPENSSL``).
|
This feature is only available if libtorrent is build with openssl support (``TORRENT_USE_OPENSSL``).
|
||||||
|
|
||||||
|
To test incoming SSL connections to an SSL torrent, one can use the following *openssl* command::
|
||||||
|
|
||||||
|
openssl s_client -cert <peer-certificate>.pem -key <peer-private-key>.pem -CAfile <torrent-cert>.pem -debug -connect 127.0.0.1:4433 -tls1 -servername <info-hash>
|
||||||
|
|
||||||
|
To create a root certificate, the Distinguished Name (*DN*) is not taken into account
|
||||||
|
by bittorrent peers. You still need to specify something, but from libtorrent's point of
|
||||||
|
view, it doesn't matter what it is. libtorrent only makes sure the peer certificates are
|
||||||
|
signed by the correct root certificate.
|
||||||
|
|
||||||
|
One way to create the certificates is to use the ``CA.sh`` script that comes with openssl, like thisi (don't forget to enter a common Name for the certificate)::
|
||||||
|
|
||||||
|
CA.sh -newca
|
||||||
|
CA.sh -newreq
|
||||||
|
CA.sh -sign
|
||||||
|
|
||||||
|
The torrent certificate is located in ``./demoCA/private/demoCA/cacert.pem``, this is
|
||||||
|
the pem file to include in the .torrent file.
|
||||||
|
|
||||||
|
The peer's certificate is located in ``./newcert.pem`` and the certificate's
|
||||||
|
private key in ``./newkey.pem``.
|
||||||
|
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript">
|
|
||||||
/* <![CDATA[ */
|
|
||||||
(function() {
|
|
||||||
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
|
||||||
|
|
||||||
s.type = 'text/javascript';
|
|
||||||
s.async = true;
|
|
||||||
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
|
||||||
|
|
||||||
t.parentNode.insertBefore(s, t);
|
|
||||||
})();
|
|
||||||
/* ]]> */
|
|
||||||
</script>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||||
<title>libtorrent manual</title>
|
<title>libtorrent manual</title>
|
||||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* <![CDATA[ */
|
||||||
|
(function() {
|
||||||
|
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
||||||
|
s.type = 'text/javascript';
|
||||||
|
s.async = true;
|
||||||
|
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
||||||
|
t.parentNode.insertBefore(s, t);
|
||||||
|
})();
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* Hides from IE-mac \*/
|
/* Hides from IE-mac \*/
|
||||||
|
|
|
@ -669,6 +669,9 @@ bool seed_mode = false;
|
||||||
bool share_mode = false;
|
bool share_mode = false;
|
||||||
bool disable_storage = false;
|
bool disable_storage = false;
|
||||||
|
|
||||||
|
// if non-empty, a peer that will be added to all torrents
|
||||||
|
std::string peer;
|
||||||
|
|
||||||
using boost::bind;
|
using boost::bind;
|
||||||
|
|
||||||
// monitored_dir is true if this torrent is added because
|
// monitored_dir is true if this torrent is added because
|
||||||
|
@ -871,7 +874,7 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
||||||
snprintf(msg, sizeof(msg), "loaded certificate %s and key %s\n", cert.c_str(), priv.c_str());
|
snprintf(msg, sizeof(msg), "loaded certificate %s and key %s\n", cert.c_str(), priv.c_str());
|
||||||
if (g_log_file) fprintf(g_log_file, "[%s] %s\n", time_now_string(), msg);
|
if (g_log_file) fprintf(g_log_file, "[%s] %s\n", time_now_string(), msg);
|
||||||
|
|
||||||
h.set_ssl_certificate(cert, priv, "certificates/dhparams.pem", "test");
|
h.set_ssl_certificate(cert, priv, "certificates/dhparams.pem", "1234");
|
||||||
h.resume();
|
h.resume();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -905,6 +908,20 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
||||||
h.resolve_countries(true);
|
h.resolve_countries(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// if we have a peer specified, connect to it
|
||||||
|
if (!peer.empty())
|
||||||
|
{
|
||||||
|
char* port = (char*) strrchr((char*)peer.c_str(), ':');
|
||||||
|
if (port > 0)
|
||||||
|
{
|
||||||
|
*port++ = 0;
|
||||||
|
char const* ip = peer.c_str();
|
||||||
|
int peer_port = atoi(port);
|
||||||
|
if (peer_port > 0)
|
||||||
|
h.connect_peer(tcp::endpoint(address::from_string(ip), peer_port));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boost::unordered_set<torrent_status>::iterator j
|
boost::unordered_set<torrent_status>::iterator j
|
||||||
= all_handles.insert(h.status()).first;
|
= all_handles.insert(h.status()).first;
|
||||||
if (show_torrent(*j, torrent_filter, counters))
|
if (show_torrent(*j, torrent_filter, counters))
|
||||||
|
@ -1086,6 +1103,7 @@ int main(int argc, char* argv[])
|
||||||
" -B <seconds> sets the peer timeout\n"
|
" -B <seconds> sets the peer timeout\n"
|
||||||
" -Q enables share mode. Share mode attempts to maximize\n"
|
" -Q enables share mode. Share mode attempts to maximize\n"
|
||||||
" share ratio rather than downloading\n"
|
" share ratio rather than downloading\n"
|
||||||
|
" -r <IP:port> connect to specified peer\n"
|
||||||
" -e force encrypted bittorrent connections\n"
|
" -e force encrypted bittorrent connections\n"
|
||||||
"\n QUEING OPTIONS\n"
|
"\n QUEING OPTIONS\n"
|
||||||
" -v <limit> Set the max number of active downloads\n"
|
" -v <limit> Set the max number of active downloads\n"
|
||||||
|
@ -1310,6 +1328,7 @@ int main(int argc, char* argv[])
|
||||||
case 'O': settings.allow_reordered_disk_operations = false; --i; break;
|
case 'O': settings.allow_reordered_disk_operations = false; --i; break;
|
||||||
case 'M': settings.mixed_mode_algorithm = session_settings::prefer_tcp; --i; break;
|
case 'M': settings.mixed_mode_algorithm = session_settings::prefer_tcp; --i; break;
|
||||||
case 'y': settings.enable_outgoing_tcp = false; settings.enable_incoming_tcp = false; --i; break;
|
case 'y': settings.enable_outgoing_tcp = false; settings.enable_incoming_tcp = false; --i; break;
|
||||||
|
case 'r': peer = arg; break;
|
||||||
case 'P':
|
case 'P':
|
||||||
{
|
{
|
||||||
char* port = (char*) strrchr(arg, ':');
|
char* port = (char*) strrchr(arg, ':');
|
||||||
|
|
|
@ -121,7 +121,7 @@ namespace libtorrent
|
||||||
|
|
||||||
struct listen_socket_t
|
struct listen_socket_t
|
||||||
{
|
{
|
||||||
listen_socket_t(): external_port(0) {}
|
listen_socket_t(): external_port(0), ssl(false) {}
|
||||||
|
|
||||||
// this is typically empty but can be set
|
// this is typically empty but can be set
|
||||||
// to the WAN IP address of NAT-PMP or UPnP router
|
// to the WAN IP address of NAT-PMP or UPnP router
|
||||||
|
@ -136,6 +136,9 @@ namespace libtorrent
|
||||||
// the client is reachable through.
|
// the client is reachable through.
|
||||||
int external_port;
|
int external_port;
|
||||||
|
|
||||||
|
// set to true if this is an SSL listen socket
|
||||||
|
bool ssl;
|
||||||
|
|
||||||
// the actual socket
|
// the actual socket
|
||||||
boost::shared_ptr<socket_acceptor> sock;
|
boost::shared_ptr<socket_acceptor> sock;
|
||||||
};
|
};
|
||||||
|
@ -230,9 +233,9 @@ namespace libtorrent
|
||||||
tcp::endpoint get_ipv6_interface() const;
|
tcp::endpoint get_ipv6_interface() const;
|
||||||
tcp::endpoint get_ipv4_interface() const;
|
tcp::endpoint get_ipv4_interface() const;
|
||||||
|
|
||||||
void async_accept(boost::shared_ptr<socket_acceptor> const& listener);
|
void async_accept(boost::shared_ptr<socket_acceptor> const& listener, bool ssl);
|
||||||
void on_accept_connection(boost::shared_ptr<socket_type> const& s
|
void on_accept_connection(boost::shared_ptr<socket_type> const& s
|
||||||
, boost::weak_ptr<socket_acceptor> listener, error_code const& e);
|
, boost::weak_ptr<socket_acceptor> listener, error_code const& e, bool ssl);
|
||||||
void on_socks_accept(boost::shared_ptr<socket_type> const& s
|
void on_socks_accept(boost::shared_ptr<socket_type> const& s
|
||||||
, error_code const& e);
|
, error_code const& e);
|
||||||
|
|
||||||
|
@ -373,7 +376,8 @@ namespace libtorrent
|
||||||
void set_peer_id(peer_id const& id);
|
void set_peer_id(peer_id const& id);
|
||||||
void set_key(int key);
|
void set_key(int key);
|
||||||
address listen_address() const;
|
address listen_address() const;
|
||||||
unsigned short listen_port() const;
|
boost::uint16_t listen_port() const;
|
||||||
|
boost::uint16_t ssl_listen_port() const;
|
||||||
|
|
||||||
void abort();
|
void abort();
|
||||||
|
|
||||||
|
@ -585,6 +589,8 @@ namespace libtorrent
|
||||||
mutable io_service m_io_service;
|
mutable io_service m_io_service;
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
// this is a generic SSL context used when talking to
|
||||||
|
// unauthenticated HTTPS servers
|
||||||
asio::ssl::context m_ssl_ctx;
|
asio::ssl::context m_ssl_ctx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -699,6 +705,10 @@ namespace libtorrent
|
||||||
// we might need more than one listen socket
|
// we might need more than one listen socket
|
||||||
std::list<listen_socket_t> m_listen_sockets;
|
std::list<listen_socket_t> m_listen_sockets;
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
void ssl_handshake(error_code const& ec, boost::shared_ptr<socket_type> s);
|
||||||
|
#endif
|
||||||
|
|
||||||
// when as a socks proxy is used for peers, also
|
// when as a socks proxy is used for peers, also
|
||||||
// listen for incoming connections on a socks connection
|
// listen for incoming connections on a socks connection
|
||||||
boost::shared_ptr<socket_type> m_socks_listen_socket;
|
boost::shared_ptr<socket_type> m_socks_listen_socket;
|
||||||
|
@ -859,9 +869,17 @@ namespace libtorrent
|
||||||
boost::intrusive_ptr<upnp> m_upnp;
|
boost::intrusive_ptr<upnp> m_upnp;
|
||||||
boost::intrusive_ptr<lsd> m_lsd;
|
boost::intrusive_ptr<lsd> m_lsd;
|
||||||
|
|
||||||
|
// mask is a bitmask of which protocols to remap on:
|
||||||
|
// 1: NAT-PMP
|
||||||
|
// 2: UPnP
|
||||||
|
void remap_tcp_ports(boost::uint32_t mask, int tcp_port, int ssl_port);
|
||||||
|
|
||||||
// 0 is natpmp 1 is upnp
|
// 0 is natpmp 1 is upnp
|
||||||
int m_tcp_mapping[2];
|
int m_tcp_mapping[2];
|
||||||
int m_udp_mapping[2];
|
int m_udp_mapping[2];
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
int m_ssl_mapping[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
// the timer used to fire the tick
|
// the timer used to fire the tick
|
||||||
deadline_timer m_timer;
|
deadline_timer m_timer;
|
||||||
|
|
|
@ -168,8 +168,8 @@ namespace libtorrent
|
||||||
too_frequent_pex,
|
too_frequent_pex,
|
||||||
no_metadata,
|
no_metadata,
|
||||||
invalid_dont_have,
|
invalid_dont_have,
|
||||||
reserved111,
|
requires_ssl_connection,
|
||||||
reserved112,
|
invalid_ssl_cert,
|
||||||
reserved113,
|
reserved113,
|
||||||
reserved114,
|
reserved114,
|
||||||
reserved115,
|
reserved115,
|
||||||
|
|
|
@ -268,6 +268,7 @@ namespace libtorrent
|
||||||
, read_job_every(10)
|
, read_job_every(10)
|
||||||
, use_disk_read_ahead(true)
|
, use_disk_read_ahead(true)
|
||||||
, lock_files(false)
|
, lock_files(false)
|
||||||
|
, ssl_listen(4433)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// libtorrent version. Used for forward binary compatibility
|
// libtorrent version. Used for forward binary compatibility
|
||||||
|
@ -1075,6 +1076,9 @@ namespace libtorrent
|
||||||
// if set to true, files will be locked when opened.
|
// if set to true, files will be locked when opened.
|
||||||
// preventing any other process from modifying them
|
// preventing any other process from modifying them
|
||||||
bool lock_files;
|
bool lock_files;
|
||||||
|
|
||||||
|
// open an ssl listen socket for ssl torrents on this port
|
||||||
|
int ssl_listen;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
|
@ -62,6 +62,11 @@ public:
|
||||||
typedef typename Stream::endpoint_type endpoint_type;
|
typedef typename Stream::endpoint_type endpoint_type;
|
||||||
typedef typename Stream::protocol_type protocol_type;
|
typedef typename Stream::protocol_type protocol_type;
|
||||||
|
|
||||||
|
void set_host_name(std::string name)
|
||||||
|
{ SSL_set_tlsext_host_name(m_sock.native_handle(), name.c_str()); }
|
||||||
|
|
||||||
|
SSL* native_handle() { return m_sock.native_handle(); }
|
||||||
|
|
||||||
typedef boost::function<void(error_code const&)> handler_type;
|
typedef boost::function<void(error_code const&)> handler_type;
|
||||||
|
|
||||||
template <class Handler>
|
template <class Handler>
|
||||||
|
@ -97,8 +102,7 @@ public:
|
||||||
template <class Handler>
|
template <class Handler>
|
||||||
void async_shutdown(Handler const& handler)
|
void async_shutdown(Handler const& handler)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<handler_type> h(new handler_type(handler));
|
m_sock.async_shutdown(handler);
|
||||||
m_sock.async_shutdown( boost::bind(&ssl_stream::on_shutdown, this, _1, h));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown(error_code& ec)
|
void shutdown(error_code& ec)
|
||||||
|
|
|
@ -945,26 +945,8 @@ namespace libtorrent
|
||||||
piece_manager* m_storage;
|
piece_manager* m_storage;
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
// TODO: in order to save space, stick the ssl context
|
|
||||||
// and the listen_socket_t in a single struct and have
|
|
||||||
// a shared_pointer to that (or intrusive_ptr even)
|
|
||||||
|
|
||||||
boost::shared_ptr<asio::ssl::context> m_ssl_ctx;
|
boost::shared_ptr<asio::ssl::context> m_ssl_ctx;
|
||||||
|
|
||||||
// listen socket used to accept incoming ssl connections
|
|
||||||
boost::shared_ptr<listen_socket_t> m_ssl_acceptor;
|
|
||||||
|
|
||||||
// SSL torrents have their own listen socket, so that
|
|
||||||
// we know which certificate to use for incoming connections
|
|
||||||
// these function are used for handling the torrent specific
|
|
||||||
// listen socket
|
|
||||||
void async_accept(boost::shared_ptr<socket_acceptor> const& listener);
|
|
||||||
|
|
||||||
void on_accept_ssl_connection(boost::shared_ptr<socket_type> const& s
|
|
||||||
, boost::weak_ptr<socket_acceptor> listen_socket, error_code const& e);
|
|
||||||
|
|
||||||
void ssl_handshake(error_code const& ec, boost::shared_ptr<socket_type> s);
|
|
||||||
|
|
||||||
void init_ssl(std::string const& cert);
|
void init_ssl(std::string const& cert);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -160,8 +160,8 @@ namespace libtorrent
|
||||||
"pex messages sent too frequent (possible attack)",
|
"pex messages sent too frequent (possible attack)",
|
||||||
"torrent has no metadata",
|
"torrent has no metadata",
|
||||||
"invalid dont-have message",
|
"invalid dont-have message",
|
||||||
"",
|
"SSL connection required",
|
||||||
"",
|
"invalid SSL certificate",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -1179,16 +1179,6 @@ namespace libtorrent
|
||||||
t.reset();
|
t.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
|
||||||
if (t && t->is_ssl_torrent())
|
|
||||||
{
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
|
||||||
peer_log("*** can't attach to an ssl torrent");
|
|
||||||
#endif
|
|
||||||
t.reset();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
// we couldn't find the torrent!
|
// we couldn't find the torrent!
|
||||||
|
@ -2021,7 +2011,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(t);
|
TORRENT_ASSERT(t);
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING
|
||||||
peer_log("<== REQUEST [ piece: %d s: %d l: ]"
|
peer_log("<== REQUEST [ piece: %d s: %d l: %d ]"
|
||||||
, r.piece, r.start, r.length);
|
, r.piece, r.start, r.length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3454,6 +3444,12 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close_socket(boost::shared_ptr<socket_type> const& s)
|
||||||
|
{
|
||||||
|
error_code ec;
|
||||||
|
s->close(ec);
|
||||||
|
}
|
||||||
|
|
||||||
// the error argument defaults to 0, which means deliberate disconnect
|
// the error argument defaults to 0, which means deliberate disconnect
|
||||||
// 1 means unexpected disconnect/error
|
// 1 means unexpected disconnect/error
|
||||||
// 2 protocol error (client sent something invalid)
|
// 2 protocol error (client sent something invalid)
|
||||||
|
@ -3618,7 +3614,23 @@ namespace libtorrent
|
||||||
|
|
||||||
m_disconnecting = true;
|
m_disconnecting = true;
|
||||||
error_code e;
|
error_code e;
|
||||||
m_socket->close(e);
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
// for SSL connections, first do an async_shutdown, before closing the socket
|
||||||
|
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
|
||||||
|
m_socket->get<ssl_stream<t> >()->async_shutdown(boost::bind(&close_socket, m_socket)); \
|
||||||
|
break;
|
||||||
|
switch(m_socket->type())
|
||||||
|
{
|
||||||
|
CASE(stream_socket)
|
||||||
|
CASE(socks5_stream)
|
||||||
|
CASE(http_stream)
|
||||||
|
CASE(utp_stream)
|
||||||
|
default: m_socket->close(e); break;
|
||||||
|
}
|
||||||
|
#undef CASE
|
||||||
|
#endif // TORRENT_USE_OPENSSL
|
||||||
|
|
||||||
m_ses.close_connection(this, ec);
|
m_ses.close_connection(this, ec);
|
||||||
|
|
||||||
// we should only disconnect while we still have
|
// we should only disconnect while we still have
|
||||||
|
@ -4529,7 +4541,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING
|
||||||
peer_log("==> PIECE [ piece: %d s: %d l: ]"
|
peer_log("==> PIECE [ piece: %d s: %d l: %d ]"
|
||||||
, r.piece, r.start, r.length);
|
, r.piece, r.start, r.length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -537,6 +537,44 @@ namespace aux {
|
||||||
int session_impl::logging_allocator::allocated_bytes = 0;
|
int session_impl::logging_allocator::allocated_bytes = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
// when running bittorrent over SSL, the SNI (server name indication)
|
||||||
|
// extension is used to know which torrent the incoming connection is
|
||||||
|
// trying to connect to. The 40 first bytes in the name is expected to
|
||||||
|
// be the hex encoded info-hash
|
||||||
|
int servername_callback(SSL *s, int *ad, void *arg)
|
||||||
|
{
|
||||||
|
session_impl* ses = (session_impl*)arg;
|
||||||
|
const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
|
||||||
|
|
||||||
|
if (!servername || strlen(servername) < 40)
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
|
||||||
|
sha1_hash info_hash;
|
||||||
|
bool valid = from_hex(servername, 40, (char*)&info_hash[0]);
|
||||||
|
|
||||||
|
// the server name is not a valid hex-encoded info-hash
|
||||||
|
if (!valid)
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
|
||||||
|
// see if there is a torrent with this info-hash
|
||||||
|
boost::shared_ptr<torrent> t = ses->find_torrent(info_hash).lock();
|
||||||
|
|
||||||
|
// if there isn't, fail
|
||||||
|
if (!t) return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
|
||||||
|
// if the torrent we found isn't an SSL torrent, also fail.
|
||||||
|
// the torrent doesn't have an SSL context and should not allow
|
||||||
|
// incoming SSL connections
|
||||||
|
if (!t->is_ssl_torrent()) return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
|
||||||
|
// use this torrent's certificate
|
||||||
|
SSL_set_SSL_CTX(s, t->ssl_ctx()->native_handle());
|
||||||
|
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
session_impl::session_impl(
|
session_impl::session_impl(
|
||||||
std::pair<int, int> listen_port_range
|
std::pair<int, int> listen_port_range
|
||||||
, fingerprint const& cl_fprint
|
, fingerprint const& cl_fprint
|
||||||
|
@ -556,7 +594,7 @@ namespace aux {
|
||||||
, m_files(40)
|
, m_files(40)
|
||||||
, m_io_service()
|
, m_io_service()
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
, m_ssl_ctx(m_io_service, asio::ssl::context::sslv23_client)
|
, m_ssl_ctx(m_io_service, asio::ssl::context::sslv23)
|
||||||
#endif
|
#endif
|
||||||
, m_alerts(m_io_service, m_settings.alert_queue_size, alert_mask)
|
, m_alerts(m_io_service, m_settings.alert_queue_size, alert_mask)
|
||||||
, m_disk_thread(m_io_service, boost::bind(&session_impl::on_disk_queue, this), m_files)
|
, m_disk_thread(m_io_service, boost::bind(&session_impl::on_disk_queue, this), m_files)
|
||||||
|
@ -646,6 +684,8 @@ namespace aux {
|
||||||
error_code ec;
|
error_code ec;
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
m_ssl_ctx.set_verify_mode(asio::ssl::context::verify_none, ec);
|
m_ssl_ctx.set_verify_mode(asio::ssl::context::verify_none, ec);
|
||||||
|
SSL_CTX_set_tlsext_servername_callback(m_ssl_ctx.native_handle(), servername_callback);
|
||||||
|
SSL_CTX_set_tlsext_servername_arg(m_ssl_ctx.native_handle(), this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
@ -663,6 +703,10 @@ namespace aux {
|
||||||
m_tcp_mapping[1] = -1;
|
m_tcp_mapping[1] = -1;
|
||||||
m_udp_mapping[0] = -1;
|
m_udp_mapping[0] = -1;
|
||||||
m_udp_mapping[1] = -1;
|
m_udp_mapping[1] = -1;
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
m_ssl_mapping[0] = -1;
|
||||||
|
m_ssl_mapping[1] = -1;
|
||||||
|
#endif
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// windows XP has a limit on the number of
|
// windows XP has a limit on the number of
|
||||||
// simultaneous half-open TCP connections
|
// simultaneous half-open TCP connections
|
||||||
|
@ -2050,6 +2094,11 @@ namespace aux {
|
||||||
m_ipv6_interface = tcp::endpoint();
|
m_ipv6_interface = tcp::endpoint();
|
||||||
m_ipv4_interface = tcp::endpoint();
|
m_ipv4_interface = tcp::endpoint();
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
tcp::endpoint ssl_interface = m_listen_interface;
|
||||||
|
ssl_interface.port(m_settings.ssl_listen);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (is_any(m_listen_interface.address()))
|
if (is_any(m_listen_interface.address()))
|
||||||
{
|
{
|
||||||
// this means we should open two listen sockets
|
// this means we should open two listen sockets
|
||||||
|
@ -2064,12 +2113,27 @@ namespace aux {
|
||||||
// update the listen_interface member with the
|
// update the listen_interface member with the
|
||||||
// actual port we ended up listening on, so that the other
|
// actual port we ended up listening on, so that the other
|
||||||
// sockets can be bound to the same one
|
// sockets can be bound to the same one
|
||||||
m_listen_interface.port(s.sock->local_endpoint(ec).port());
|
m_listen_interface.port(s.external_port);
|
||||||
|
|
||||||
m_listen_sockets.push_back(s);
|
m_listen_sockets.push_back(s);
|
||||||
async_accept(s.sock);
|
async_accept(s.sock, s.ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (m_settings.ssl_listen)
|
||||||
|
{
|
||||||
|
listen_socket_t s;
|
||||||
|
s.ssl = true;
|
||||||
|
setup_listener(&s, ssl_interface, 10, false, flags, ec);
|
||||||
|
|
||||||
|
if (s.sock)
|
||||||
|
{
|
||||||
|
m_listen_sockets.push_back(s);
|
||||||
|
async_accept(s.sock, s.ssl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if TORRENT_USE_IPV6
|
#if TORRENT_USE_IPV6
|
||||||
// only try to open the IPv6 port if IPv6 is installed
|
// only try to open the IPv6 port if IPv6 is installed
|
||||||
if (supports_ipv6())
|
if (supports_ipv6())
|
||||||
|
@ -2080,8 +2144,24 @@ namespace aux {
|
||||||
if (s.sock)
|
if (s.sock)
|
||||||
{
|
{
|
||||||
m_listen_sockets.push_back(s);
|
m_listen_sockets.push_back(s);
|
||||||
async_accept(s.sock);
|
async_accept(s.sock, s.ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (m_settings.ssl_listen)
|
||||||
|
{
|
||||||
|
listen_socket_t s;
|
||||||
|
s.ssl = true;
|
||||||
|
setup_listener(&s, tcp::endpoint(address_v6::any(), ssl_interface.port())
|
||||||
|
, 10, false, flags, ec);
|
||||||
|
|
||||||
|
if (s.sock)
|
||||||
|
{
|
||||||
|
m_listen_sockets.push_back(s);
|
||||||
|
async_accept(s.sock, s.ssl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // TORRENT_USE_OPENSSL
|
||||||
}
|
}
|
||||||
#endif // TORRENT_USE_IPV6
|
#endif // TORRENT_USE_IPV6
|
||||||
|
|
||||||
|
@ -2109,13 +2189,28 @@ namespace aux {
|
||||||
if (s.sock)
|
if (s.sock)
|
||||||
{
|
{
|
||||||
m_listen_sockets.push_back(s);
|
m_listen_sockets.push_back(s);
|
||||||
async_accept(s.sock);
|
async_accept(s.sock, s.ssl);
|
||||||
|
|
||||||
if (m_listen_interface.address().is_v6())
|
if (m_listen_interface.address().is_v6())
|
||||||
m_ipv6_interface = m_listen_interface;
|
m_ipv6_interface = m_listen_interface;
|
||||||
else
|
else
|
||||||
m_ipv4_interface = m_listen_interface;
|
m_ipv4_interface = m_listen_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (m_settings.ssl_listen)
|
||||||
|
{
|
||||||
|
listen_socket_t s;
|
||||||
|
s.ssl = true;
|
||||||
|
setup_listener(&s, ssl_interface, 10, false, flags, ec);
|
||||||
|
|
||||||
|
if (s.sock)
|
||||||
|
{
|
||||||
|
m_listen_sockets.push_back(s);
|
||||||
|
async_accept(s.sock, s.ssl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
m_udp_socket.bind(udp::endpoint(m_listen_interface.address(), m_listen_interface.port()), ec);
|
m_udp_socket.bind(udp::endpoint(m_listen_interface.address(), m_listen_interface.port()), ec);
|
||||||
|
@ -2145,21 +2240,7 @@ namespace aux {
|
||||||
if (!m_listen_sockets.empty())
|
if (!m_listen_sockets.empty())
|
||||||
{
|
{
|
||||||
tcp::endpoint local = m_listen_sockets.front().sock->local_endpoint(ec);
|
tcp::endpoint local = m_listen_sockets.front().sock->local_endpoint(ec);
|
||||||
if (!ec)
|
if (!ec) remap_tcp_ports(3, local.port(), ssl_listen_port());
|
||||||
{
|
|
||||||
if (m_natpmp.get())
|
|
||||||
{
|
|
||||||
if (m_tcp_mapping[0] != -1) m_natpmp->delete_mapping(m_tcp_mapping[0]);
|
|
||||||
m_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp
|
|
||||||
, local.port(), local.port());
|
|
||||||
}
|
|
||||||
if (m_upnp.get())
|
|
||||||
{
|
|
||||||
if (m_tcp_mapping[1] != -1) m_upnp->delete_mapping(m_tcp_mapping[1]);
|
|
||||||
m_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp
|
|
||||||
, local.port(), local.port());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||||
|
@ -2167,6 +2248,28 @@ namespace aux {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void session_impl::remap_tcp_ports(boost::uint32_t mask, int tcp_port, int ssl_port)
|
||||||
|
{
|
||||||
|
if ((mask & 1) && m_natpmp.get())
|
||||||
|
{
|
||||||
|
if (m_tcp_mapping[0] != -1) m_natpmp->delete_mapping(m_tcp_mapping[0]);
|
||||||
|
m_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp, tcp_port, tcp_port);
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (m_ssl_mapping[0] != -1) m_natpmp->delete_mapping(m_ssl_mapping[0]);
|
||||||
|
m_ssl_mapping[0] = m_natpmp->add_mapping(natpmp::tcp, ssl_port, ssl_port);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if ((mask & 2) && m_upnp.get())
|
||||||
|
{
|
||||||
|
if (m_tcp_mapping[1] != -1) m_upnp->delete_mapping(m_tcp_mapping[1]);
|
||||||
|
m_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp, tcp_port, tcp_port);
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (m_ssl_mapping[1] != -1) m_upnp->delete_mapping(m_ssl_mapping[1]);
|
||||||
|
m_ssl_mapping[1] = m_upnp->add_mapping(upnp::tcp, ssl_port, ssl_port);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void session_impl::open_new_incoming_socks_connection()
|
void session_impl::open_new_incoming_socks_connection()
|
||||||
{
|
{
|
||||||
if (m_proxy.type != proxy_settings::socks5
|
if (m_proxy.type != proxy_settings::socks5
|
||||||
|
@ -2298,21 +2401,40 @@ namespace aux {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::async_accept(boost::shared_ptr<socket_acceptor> const& listener)
|
void session_impl::async_accept(boost::shared_ptr<socket_acceptor> const& listener, bool ssl)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(!m_abort);
|
TORRENT_ASSERT(!m_abort);
|
||||||
shared_ptr<socket_type> c(new socket_type(m_io_service));
|
shared_ptr<socket_type> c(new socket_type(m_io_service));
|
||||||
c->instantiate<stream_socket>(m_io_service);
|
stream_socket* str = 0;
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (ssl)
|
||||||
|
{
|
||||||
|
// accept connections initializing the SSL connection to
|
||||||
|
// use the generic m_ssl_ctx context. However, since it has
|
||||||
|
// the servername callback set on it, we will switch away from
|
||||||
|
// this context into a specific torrent once we start handshaking
|
||||||
|
c->instantiate<ssl_stream<stream_socket> >(m_io_service, &m_ssl_ctx);
|
||||||
|
str = &c->get<ssl_stream<stream_socket> >()->next_layer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
c->instantiate<stream_socket>(m_io_service);
|
||||||
|
str = c->get<stream_socket>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined TORRENT_ASIO_DEBUGGING
|
#if defined TORRENT_ASIO_DEBUGGING
|
||||||
add_outstanding_async("session_impl::on_accept_connection");
|
add_outstanding_async("session_impl::on_accept_connection");
|
||||||
#endif
|
#endif
|
||||||
listener->async_accept(*c->get<stream_socket>()
|
listener->async_accept(*str
|
||||||
, boost::bind(&session_impl::on_accept_connection, this, c
|
, boost::bind(&session_impl::on_accept_connection, this, c
|
||||||
, boost::weak_ptr<socket_acceptor>(listener), _1));
|
, boost::weak_ptr<socket_acceptor>(listener), _1, ssl));
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::on_accept_connection(shared_ptr<socket_type> const& s
|
void session_impl::on_accept_connection(shared_ptr<socket_type> const& s
|
||||||
, weak_ptr<socket_acceptor> listen_socket, error_code const& e)
|
, weak_ptr<socket_acceptor> listen_socket, error_code const& e, bool ssl)
|
||||||
{
|
{
|
||||||
#if defined TORRENT_ASIO_DEBUGGING
|
#if defined TORRENT_ASIO_DEBUGGING
|
||||||
complete_async("session_impl::on_accept_connection");
|
complete_async("session_impl::on_accept_connection");
|
||||||
|
@ -2342,7 +2464,7 @@ namespace aux {
|
||||||
// non-fatal and we have to do another async_accept.
|
// non-fatal and we have to do another async_accept.
|
||||||
if (e.value() == ERROR_SEM_TIMEOUT)
|
if (e.value() == ERROR_SEM_TIMEOUT)
|
||||||
{
|
{
|
||||||
async_accept(listener);
|
async_accept(listener, ssl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2351,7 +2473,7 @@ namespace aux {
|
||||||
// non-fatal and we have to do another async_accept.
|
// non-fatal and we have to do another async_accept.
|
||||||
if (e.value() == EINVAL)
|
if (e.value() == EINVAL)
|
||||||
{
|
{
|
||||||
async_accept(listener);
|
async_accept(listener, ssl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2377,17 +2499,63 @@ namespace aux {
|
||||||
m_settings.connections_limit = m_connections.size();
|
m_settings.connections_limit = m_connections.size();
|
||||||
}
|
}
|
||||||
// try again, but still alert the user of the problem
|
// try again, but still alert the user of the problem
|
||||||
async_accept(listener);
|
async_accept(listener, ssl);
|
||||||
}
|
}
|
||||||
if (m_alerts.should_post<listen_failed_alert>())
|
if (m_alerts.should_post<listen_failed_alert>())
|
||||||
m_alerts.post_alert(listen_failed_alert(ep, e));
|
m_alerts.post_alert(listen_failed_alert(ep, e));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
async_accept(listener);
|
async_accept(listener, ssl);
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (ssl)
|
||||||
|
{
|
||||||
|
// for SSL connections, incoming_connection() is called
|
||||||
|
// after the handshake is done
|
||||||
|
s->get<ssl_stream<stream_socket> >()->async_accept_handshake(
|
||||||
|
boost::bind(&session_impl::ssl_handshake, this, _1, s));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
incoming_connection(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
|
||||||
|
// to test SSL connections, one can use this openssl command template:
|
||||||
|
//
|
||||||
|
// openssl s_client -cert <client-cert>.pem -key <client-private-key>.pem \
|
||||||
|
// -CAfile <torrent-cert>.pem -debug -connect 127.0.0.1:4433 -tls1 \
|
||||||
|
// -servername <hex-encoded-info-hash>
|
||||||
|
|
||||||
|
void session_impl::ssl_handshake(error_code const& ec, boost::shared_ptr<socket_type> s)
|
||||||
|
{
|
||||||
|
error_code e;
|
||||||
|
tcp::endpoint endp = s->remote_endpoint(e);
|
||||||
|
if (e) return;
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << time_now_string() << " *** peer SSL handshake done [ ip: "
|
||||||
|
<< endp << " ec: " << ec.message() << "]\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
if (m_alerts.should_post<peer_error_alert>())
|
||||||
|
{
|
||||||
|
m_alerts.post_alert(peer_error_alert(torrent_handle(), endp
|
||||||
|
, peer_id(), ec));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
incoming_connection(s);
|
incoming_connection(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // TORRENT_USE_OPENSSL
|
||||||
|
|
||||||
void session_impl::incoming_connection(boost::shared_ptr<socket_type> const& s)
|
void session_impl::incoming_connection(boost::shared_ptr<socket_type> const& s)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_network_thread());
|
TORRENT_ASSERT(is_network_thread());
|
||||||
|
@ -4701,7 +4869,7 @@ namespace aux {
|
||||||
return address();
|
return address();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short session_impl::listen_port() const
|
boost::uint16_t session_impl::listen_port() const
|
||||||
{
|
{
|
||||||
// if peer connections are set up to be received over a socks
|
// if peer connections are set up to be received over a socks
|
||||||
// proxy, and it's the same one as we're using for the tracker
|
// proxy, and it's the same one as we're using for the tracker
|
||||||
|
@ -4718,6 +4886,30 @@ namespace aux {
|
||||||
return m_listen_sockets.front().external_port;
|
return m_listen_sockets.front().external_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::uint16_t session_impl::ssl_listen_port() const
|
||||||
|
{
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
// if peer connections are set up to be received over a socks
|
||||||
|
// proxy, and it's the same one as we're using for the tracker
|
||||||
|
// just tell the tracker the socks5 port we're listening on
|
||||||
|
if (m_socks_listen_socket && m_socks_listen_socket->is_open()
|
||||||
|
&& m_proxy.hostname == m_proxy.hostname)
|
||||||
|
return m_socks_listen_port;
|
||||||
|
|
||||||
|
// if not, don't tell the tracker anything if we're in anonymous
|
||||||
|
// mode. We don't want to leak our listen port since it can
|
||||||
|
// potentially identify us if it is leaked elsewere
|
||||||
|
if (m_settings.anonymous_mode) return 0;
|
||||||
|
if (m_listen_sockets.empty()) return 0;
|
||||||
|
for (std::list<listen_socket_t>::const_iterator i = m_listen_sockets.begin()
|
||||||
|
, end(m_listen_sockets.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
if (i->ssl) return i->external_port;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void session_impl::announce_lsd(sha1_hash const& ih, int port, bool broadcast)
|
void session_impl::announce_lsd(sha1_hash const& ih, int port, bool broadcast)
|
||||||
{
|
{
|
||||||
// use internal listen port for local peers
|
// use internal listen port for local peers
|
||||||
|
@ -5354,8 +5546,7 @@ namespace aux {
|
||||||
|
|
||||||
if (m_listen_interface.port() > 0)
|
if (m_listen_interface.port() > 0)
|
||||||
{
|
{
|
||||||
m_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp
|
remap_tcp_ports(1, m_listen_interface.port(), ssl_listen_port());
|
||||||
, m_listen_interface.port(), m_listen_interface.port());
|
|
||||||
}
|
}
|
||||||
if (m_udp_socket.is_open())
|
if (m_udp_socket.is_open())
|
||||||
{
|
{
|
||||||
|
@ -5387,10 +5578,9 @@ namespace aux {
|
||||||
m_upnp = u;
|
m_upnp = u;
|
||||||
|
|
||||||
m_upnp->discover_device();
|
m_upnp->discover_device();
|
||||||
if (m_listen_interface.port() > 0)
|
if (m_listen_interface.port() > 0 || ssl_listen_port() > 0)
|
||||||
{
|
{
|
||||||
m_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp
|
remap_tcp_ports(2, m_listen_interface.port(), ssl_listen_port());
|
||||||
, m_listen_interface.port(), m_listen_interface.port());
|
|
||||||
}
|
}
|
||||||
if (m_udp_socket.is_open())
|
if (m_udp_socket.is_open())
|
||||||
{
|
{
|
||||||
|
@ -5421,6 +5611,9 @@ namespace aux {
|
||||||
m_upnp->close();
|
m_upnp->close();
|
||||||
m_udp_mapping[1] = -1;
|
m_udp_mapping[1] = -1;
|
||||||
m_tcp_mapping[1] = -1;
|
m_tcp_mapping[1] = -1;
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
m_ssl_mapping[1] = -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
m_upnp = 0;
|
m_upnp = 0;
|
||||||
}
|
}
|
||||||
|
|
261
src/torrent.cpp
261
src/torrent.cpp
|
@ -1288,7 +1288,7 @@ namespace libtorrent
|
||||||
/*
|
/*
|
||||||
bool verify_function(bool preverified, boost::asio::ssl::verify_context& ctx)
|
bool verify_function(bool preverified, boost::asio::ssl::verify_context& ctx)
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1334,7 +1334,7 @@ namespace libtorrent
|
||||||
// this is used for debugging
|
// this is used for debugging
|
||||||
/*
|
/*
|
||||||
#error there's a bug where the async_handshake on the ssl_stream always succeeds, regardless of the certificate failing. It's not a trivial bug in asio, that's been tested with a small repro program.
|
#error there's a bug where the async_handshake on the ssl_stream always succeeds, regardless of the certificate failing. It's not a trivial bug in asio, that's been tested with a small repro program.
|
||||||
ctx->set_verify_callback(verify_function, ec);
|
ctx->set_verify_callback(verify_function, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
{
|
{
|
||||||
set_error(ec, "SSL verify callback");
|
set_error(ec, "SSL verify callback");
|
||||||
|
@ -1343,7 +1343,6 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
SSL_CTX* ssl_ctx = ctx->impl();
|
SSL_CTX* ssl_ctx = ctx->impl();
|
||||||
|
|
||||||
// create a new x.509 certificate store
|
// create a new x.509 certificate store
|
||||||
X509_STORE* cert_store = X509_STORE_new();
|
X509_STORE* cert_store = X509_STORE_new();
|
||||||
if (!cert_store)
|
if (!cert_store)
|
||||||
|
@ -1388,186 +1387,9 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
|
|
||||||
// tell the client we need a cert for this torrent
|
// tell the client we need a cert for this torrent
|
||||||
alerts().post_alert(torrent_need_cert_alert(get_handle()));
|
alerts().post_alert(torrent_need_cert_alert(get_handle()));
|
||||||
|
|
||||||
m_ssl_acceptor.reset(new listen_socket_t);
|
|
||||||
m_ses.setup_listener(m_ssl_acceptor.get()
|
|
||||||
, tcp::endpoint(address_v4::any(), m_ses.m_listen_interface.port())
|
|
||||||
, m_ses.m_listen_port_retries + 10, false, 0, ec);
|
|
||||||
if (!m_ssl_acceptor->sock)
|
|
||||||
{
|
|
||||||
set_error(ec, "ssl listen port");
|
|
||||||
pause();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: issue UPnP and NAT-PMP for this socket
|
|
||||||
|
|
||||||
async_accept(m_ssl_acceptor->sock);
|
|
||||||
|
|
||||||
set_allow_peers(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::async_accept(boost::shared_ptr<socket_acceptor> const& listener)
|
#endif // TORRENT_OPENSSL
|
||||||
{
|
|
||||||
boost::shared_ptr<socket_type> c(new socket_type(m_ses.m_io_service));
|
|
||||||
c->instantiate<ssl_stream<stream_socket> >(m_ses.m_io_service, m_ssl_ctx.get());
|
|
||||||
|
|
||||||
#if defined TORRENT_ASIO_DEBUGGING
|
|
||||||
add_outstanding_async("torrent::on_accept_ssl_connection");
|
|
||||||
#endif
|
|
||||||
listener->async_accept(c->get<ssl_stream<stream_socket> >()->next_layer()
|
|
||||||
, boost::bind(&torrent::on_accept_ssl_connection, shared_from_this(), c
|
|
||||||
, boost::weak_ptr<socket_acceptor>(listener), _1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void torrent::on_accept_ssl_connection(boost::shared_ptr<socket_type> const& s
|
|
||||||
, boost::weak_ptr<socket_acceptor> listen_socket, error_code const& e)
|
|
||||||
{
|
|
||||||
#if defined TORRENT_ASIO_DEBUGGING
|
|
||||||
complete_async("torrent::on_accept_ssl_connection");
|
|
||||||
#endif
|
|
||||||
// TODO: there's some code duplication with session_impl::on_accept_connection
|
|
||||||
|
|
||||||
boost::shared_ptr<socket_acceptor> listener = listen_socket.lock();
|
|
||||||
if (!listener) return;
|
|
||||||
|
|
||||||
if (e == asio::error::operation_aborted) return;
|
|
||||||
|
|
||||||
if (m_abort) return;
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
if (e)
|
|
||||||
{
|
|
||||||
tcp::endpoint ep = listener->local_endpoint(ec);
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
std::string msg = "error accepting connection on '"
|
|
||||||
+ print_endpoint(ep) + "' " + e.message();
|
|
||||||
(*m_ses.m_logger) << msg << "\n";
|
|
||||||
#endif
|
|
||||||
#ifdef TORRENT_WINDOWS
|
|
||||||
// Windows sometimes generates this error. It seems to be
|
|
||||||
// non-fatal and we have to do another async_accept.
|
|
||||||
if (e.value() == ERROR_SEM_TIMEOUT)
|
|
||||||
{
|
|
||||||
async_accept(listener);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef TORRENT_BSD
|
|
||||||
// Leopard sometimes generates an "invalid argument" error. It seems to be
|
|
||||||
// non-fatal and we have to do another async_accept.
|
|
||||||
if (e.value() == EINVAL)
|
|
||||||
{
|
|
||||||
async_accept(listener);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (alerts().should_post<listen_failed_alert>())
|
|
||||||
alerts().post_alert(listen_failed_alert(ep, e));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
async_accept(listener);
|
|
||||||
|
|
||||||
if (is_paused()) return;
|
|
||||||
|
|
||||||
// we got a connection request!
|
|
||||||
tcp::endpoint endp = s->remote_endpoint(ec);
|
|
||||||
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_ses.m_logger) << endp << " <== INCOMING CONNECTION FAILED, could "
|
|
||||||
"not retrieve remote endpoint " << ec.message() << "\n";
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alerts().should_post<incoming_connection_alert>())
|
|
||||||
{
|
|
||||||
alerts().post_alert(incoming_connection_alert(s->type(), endp));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!settings().enable_incoming_tcp)
|
|
||||||
{
|
|
||||||
if (alerts().should_post<peer_blocked_alert>())
|
|
||||||
alerts().post_alert(peer_blocked_alert(torrent_handle(), endp.address()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_apply_ip_filter
|
|
||||||
&& m_ses.m_ip_filter.access(endp.address()) & ip_filter::blocked)
|
|
||||||
{
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_ses.m_logger) << "filtered blocked ip\n";
|
|
||||||
#endif
|
|
||||||
if (alerts().should_post<peer_blocked_alert>())
|
|
||||||
alerts().post_alert(peer_blocked_alert(get_handle(), endp.address()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_connections.size() >= m_max_connections)
|
|
||||||
{
|
|
||||||
if (alerts().should_post<peer_disconnected_alert>())
|
|
||||||
{
|
|
||||||
alerts().post_alert(
|
|
||||||
peer_disconnected_alert(get_handle(), endp, peer_id()
|
|
||||||
, error_code(errors::too_many_connections, get_libtorrent_category())));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ses.setup_socket_buffers(*s);
|
|
||||||
|
|
||||||
s->get<ssl_stream<stream_socket> >()->async_accept_handshake(boost::bind(&torrent::ssl_handshake
|
|
||||||
, shared_from_this(), _1, s));
|
|
||||||
}
|
|
||||||
|
|
||||||
void torrent::ssl_handshake(error_code const& ec, boost::shared_ptr<socket_type> s)
|
|
||||||
{
|
|
||||||
error_code e;
|
|
||||||
tcp::endpoint endp = s->remote_endpoint(e);
|
|
||||||
if (e) return;
|
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_ses.m_logger) << time_now_string() << " *** peer SSL handshake done [ ip: "
|
|
||||||
<< endp << " ec: " << ec.message() << "]\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
if (alerts().should_post<peer_error_alert>())
|
|
||||||
{
|
|
||||||
alerts().post_alert(peer_error_alert(get_handle(), endp
|
|
||||||
, peer_id(), ec));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::intrusive_ptr<peer_connection> c(
|
|
||||||
new bt_peer_connection(m_ses, shared_from_this(), s, endp, 0, false));
|
|
||||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
|
||||||
c->m_in_constructor = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (c->is_disconnecting()) return;
|
|
||||||
|
|
||||||
if (!m_policy.new_connection(*c, m_ses.session_time()))
|
|
||||||
{
|
|
||||||
#if defined TORRENT_LOGGING
|
|
||||||
(*m_ses.m_logger) << time_now_string() << " CLOSING CONNECTION "
|
|
||||||
<< c->remote() << " policy::new_connection returned false (i.e. peer list full)\n";
|
|
||||||
#endif
|
|
||||||
c->disconnect(errors::too_many_connections);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the newly connected peer to this torrent's peer list
|
|
||||||
m_connections.insert(boost::get_pointer(c));
|
|
||||||
m_ses.m_connections.insert(c);
|
|
||||||
c->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// this may not be called from a constructor because of the call to
|
// this may not be called from a constructor because of the call to
|
||||||
// shared_from_this()
|
// shared_from_this()
|
||||||
|
@ -2190,7 +2012,7 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
if (is_paused()) return;
|
if (is_paused()) return;
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
int port = is_ssl_torrent() ? m_ssl_acceptor->external_port : m_ses.listen_port();
|
int port = is_ssl_torrent() ? m_ses.ssl_listen_port() : m_ses.listen_port();
|
||||||
#else
|
#else
|
||||||
int port = m_ses.listen_port();
|
int port = m_ses.listen_port();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2212,7 +2034,7 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
TORRENT_ASSERT(m_allow_peers);
|
TORRENT_ASSERT(m_allow_peers);
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
int port = is_ssl_torrent() ? m_ssl_acceptor->external_port : m_ses.listen_port();
|
int port = is_ssl_torrent() ? m_ses.ssl_listen_port() : m_ses.listen_port();
|
||||||
#else
|
#else
|
||||||
int port = m_ses.listen_port();
|
int port = m_ses.listen_port();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2311,7 +2133,7 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
// TODO: this pattern is repeated in a few places. Factor this into
|
// TODO: this pattern is repeated in a few places. Factor this into
|
||||||
// a function and generalize the concept of a torrent having a
|
// a function and generalize the concept of a torrent having a
|
||||||
// dedicated listen port
|
// dedicated listen port
|
||||||
if (is_ssl_torrent()) req.listen_port = m_ssl_acceptor->external_port;
|
if (is_ssl_torrent()) req.listen_port = m_ses.ssl_listen_port();
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
req.listen_port = m_ses.listen_port();
|
req.listen_port = m_ses.listen_port();
|
||||||
|
@ -3461,12 +3283,6 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
m_ses.m_encrypted_torrents.erase(shared_from_this());
|
m_ses.m_encrypted_torrents.erase(shared_from_this());
|
||||||
m_in_encrypted_list = false;
|
m_in_encrypted_list = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ssl_acceptor && m_ssl_acceptor->sock)
|
|
||||||
{
|
|
||||||
error_code ec;
|
|
||||||
m_ssl_acceptor->sock->close(ec);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_abort = true;
|
m_abort = true;
|
||||||
|
@ -5530,6 +5346,26 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
bool ret = instantiate_connection(m_ses.m_io_service, m_ses.proxy(), *s, userdata, sm, true);
|
bool ret = instantiate_connection(m_ses.m_io_service, m_ses.proxy(), *s, userdata, sm, true);
|
||||||
(void)ret;
|
(void)ret;
|
||||||
TORRENT_ASSERT(ret);
|
TORRENT_ASSERT(ret);
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (is_ssl_torrent())
|
||||||
|
{
|
||||||
|
// for ssl sockets, set the hostname
|
||||||
|
std::string host_name = to_hex(m_torrent_file->info_hash().to_string());
|
||||||
|
|
||||||
|
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
|
||||||
|
s->get<ssl_stream<t> >()->set_host_name(host_name); break;
|
||||||
|
|
||||||
|
switch (s->type())
|
||||||
|
{
|
||||||
|
CASE(stream_socket)
|
||||||
|
CASE(socks5_stream)
|
||||||
|
CASE(http_stream)
|
||||||
|
CASE(utp_stream)
|
||||||
|
default: break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ses.setup_socket_buffers(*s);
|
m_ses.setup_socket_buffers(*s);
|
||||||
|
@ -5649,6 +5485,49 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
{
|
{
|
||||||
// INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
if (is_ssl_torrent())
|
||||||
|
{
|
||||||
|
// if this is an SSL torrent, don't allow non SSL peers on it
|
||||||
|
boost::shared_ptr<socket_type> s = p->get_socket();
|
||||||
|
|
||||||
|
//
|
||||||
|
#define SSL(t) socket_type_int_impl<ssl_stream<t> >::value: \
|
||||||
|
ssl_conn = s->get<ssl_stream<t> >()->native_handle(); \
|
||||||
|
break;
|
||||||
|
|
||||||
|
SSL* ssl_conn = 0;
|
||||||
|
|
||||||
|
switch (s->type())
|
||||||
|
{
|
||||||
|
case SSL(stream_socket)
|
||||||
|
case SSL(socks5_stream)
|
||||||
|
case SSL(http_stream)
|
||||||
|
case SSL(utp_stream)
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef SSL
|
||||||
|
|
||||||
|
if (ssl_conn == 0)
|
||||||
|
{
|
||||||
|
// don't allow non SSL peers on SSL torrents
|
||||||
|
p->disconnect(errors::requires_ssl_connection);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SSL_get_SSL_CTX(ssl_conn) != m_ssl_ctx->native_handle())
|
||||||
|
{
|
||||||
|
// if the SSL_CTX associated with this connection is
|
||||||
|
// not the one belonging to this torrent, the SSL handshake
|
||||||
|
// connected to one torrent, and the BitTorrent protocol
|
||||||
|
// to a different one. This is probably an attempt to circumvent
|
||||||
|
// access control. Don't allow it.
|
||||||
|
p->disconnect(errors::invalid_ssl_cert);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // TORRENT_USE_OPENSSL
|
||||||
|
|
||||||
TORRENT_ASSERT(p != 0);
|
TORRENT_ASSERT(p != 0);
|
||||||
TORRENT_ASSERT(!p->is_local());
|
TORRENT_ASSERT(!p->is_local());
|
||||||
|
|
||||||
|
@ -8053,7 +7932,7 @@ ctx->set_verify_callback(verify_function, ec);
|
||||||
|
|
||||||
st->listen_port = 0;
|
st->listen_port = 0;
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
if (is_ssl_torrent() && m_ssl_acceptor) st->listen_port = m_ssl_acceptor->external_port;
|
if (is_ssl_torrent()) st->listen_port = m_ses.ssl_listen_port();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
st->has_incoming = m_has_incoming;
|
st->has_incoming = m_has_incoming;
|
||||||
|
|
Loading…
Reference in New Issue