added anonymous mode to disable some particular features that might give away the user's and the client's identity

This commit is contained in:
Arvid Norberg 2010-04-13 04:30:34 +00:00
parent 8e3c5f45e3
commit 384bfdec48
16 changed files with 419 additions and 187 deletions

View File

@ -58,72 +58,60 @@ void bind_alert()
} }
class_<torrent_alert, bases<alert>, noncopyable>( class_<torrent_alert, bases<alert>, noncopyable>(
"torrent_alert", no_init "torrent_alert", no_init)
)
.def_readonly("handle", &torrent_alert::handle) .def_readonly("handle", &torrent_alert::handle)
; ;
class_<tracker_alert, bases<torrent_alert>, noncopyable>( class_<tracker_alert, bases<torrent_alert>, noncopyable>(
"tracker_alert", no_init "tracker_alert", no_init)
)
.def_readonly("url", &tracker_alert::url) .def_readonly("url", &tracker_alert::url)
; ;
class_<read_piece_alert, bases<torrent_alert>, noncopyable>( class_<read_piece_alert, bases<torrent_alert>, noncopyable>(
"read_piece_alert", 0, no_init "read_piece_alert", 0, no_init)
)
.add_property("buffer", get_buffer) .add_property("buffer", get_buffer)
.def_readonly("piece", &read_piece_alert::piece) .def_readonly("piece", &read_piece_alert::piece)
.def_readonly("size", &read_piece_alert::size) .def_readonly("size", &read_piece_alert::size)
; ;
class_<peer_alert, bases<torrent_alert>, noncopyable>( class_<peer_alert, bases<torrent_alert>, noncopyable>(
"peer_alert", no_init "peer_alert", no_init)
)
.def_readonly("ip", &peer_alert::ip) .def_readonly("ip", &peer_alert::ip)
.def_readonly("pid", &peer_alert::pid) .def_readonly("pid", &peer_alert::pid)
; ;
class_<tracker_error_alert, bases<tracker_alert>, noncopyable>( class_<tracker_error_alert, bases<tracker_alert>, noncopyable>(
"tracker_error_alert", no_init "tracker_error_alert", no_init)
)
.def_readonly("msg", &tracker_error_alert::msg) .def_readonly("msg", &tracker_error_alert::msg)
.def_readonly("times_in_row", &tracker_error_alert::times_in_row) .def_readonly("times_in_row", &tracker_error_alert::times_in_row)
.def_readonly("status_code", &tracker_error_alert::status_code) .def_readonly("status_code", &tracker_error_alert::status_code)
; ;
class_<tracker_warning_alert, bases<tracker_alert>, noncopyable>( class_<tracker_warning_alert, bases<tracker_alert>, noncopyable>(
"tracker_warning_alert", no_init "tracker_warning_alert", no_init);
);
class_<tracker_reply_alert, bases<tracker_alert>, noncopyable>( class_<tracker_reply_alert, bases<tracker_alert>, noncopyable>(
"tracker_reply_alert", no_init "tracker_reply_alert", no_init)
)
.def_readonly("num_peers", &tracker_reply_alert::num_peers) .def_readonly("num_peers", &tracker_reply_alert::num_peers)
; ;
class_<tracker_announce_alert, bases<tracker_alert>, noncopyable>( class_<tracker_announce_alert, bases<tracker_alert>, noncopyable>(
"tracker_announce_alert", no_init "tracker_announce_alert", no_init)
)
.def_readonly("event", &tracker_announce_alert::event) .def_readonly("event", &tracker_announce_alert::event)
; ;
class_<hash_failed_alert, bases<torrent_alert>, noncopyable>( class_<hash_failed_alert, bases<torrent_alert>, noncopyable>(
"hash_failed_alert", no_init "hash_failed_alert", no_init)
)
.def_readonly("piece_index", &hash_failed_alert::piece_index) .def_readonly("piece_index", &hash_failed_alert::piece_index)
; ;
class_<peer_ban_alert, bases<peer_alert>, noncopyable>( class_<peer_ban_alert, bases<peer_alert>, noncopyable>(
"peer_ban_alert", no_init "peer_ban_alert", no_init);
);
class_<peer_error_alert, bases<peer_alert>, noncopyable>( class_<peer_error_alert, bases<peer_alert>, noncopyable>(
"peer_error_alert", no_init "peer_error_alert", no_init);
);
class_<invalid_request_alert, bases<peer_alert>, noncopyable>( class_<invalid_request_alert, bases<peer_alert>, noncopyable>(
"invalid_request_alert", no_init "invalid_request_alert", no_init)
)
.def_readonly("request", &invalid_request_alert::request) .def_readonly("request", &invalid_request_alert::request)
; ;
@ -135,66 +123,55 @@ void bind_alert()
; ;
class_<torrent_finished_alert, bases<torrent_alert>, noncopyable>( class_<torrent_finished_alert, bases<torrent_alert>, noncopyable>(
"torrent_finished_alert", no_init "torrent_finished_alert", no_init);
);
class_<piece_finished_alert, bases<torrent_alert>, noncopyable>( class_<piece_finished_alert, bases<torrent_alert>, noncopyable>(
"piece_finished_alert", no_init "piece_finished_alert", no_init)
)
.def_readonly("piece_index", &piece_finished_alert::piece_index) .def_readonly("piece_index", &piece_finished_alert::piece_index)
; ;
class_<block_finished_alert, bases<peer_alert>, noncopyable>( class_<block_finished_alert, bases<peer_alert>, noncopyable>(
"block_finished_alert", no_init "block_finished_alert", no_init)
)
.def_readonly("block_index", &block_finished_alert::block_index) .def_readonly("block_index", &block_finished_alert::block_index)
.def_readonly("piece_index", &block_finished_alert::piece_index) .def_readonly("piece_index", &block_finished_alert::piece_index)
; ;
class_<block_downloading_alert, bases<peer_alert>, noncopyable>( class_<block_downloading_alert, bases<peer_alert>, noncopyable>(
"block_downloading_alert", no_init "block_downloading_alert", no_init)
)
.def_readonly("peer_speedmsg", &block_downloading_alert::peer_speedmsg) .def_readonly("peer_speedmsg", &block_downloading_alert::peer_speedmsg)
.def_readonly("block_index", &block_downloading_alert::block_index) .def_readonly("block_index", &block_downloading_alert::block_index)
.def_readonly("piece_index", &block_downloading_alert::piece_index) .def_readonly("piece_index", &block_downloading_alert::piece_index)
; ;
class_<storage_moved_alert, bases<torrent_alert>, noncopyable>( class_<storage_moved_alert, bases<torrent_alert>, noncopyable>(
"storage_moved_alert", no_init "storage_moved_alert", no_init)
)
.def_readonly("path", &storage_moved_alert::path) .def_readonly("path", &storage_moved_alert::path)
; ;
class_<storage_moved_failed_alert, bases<torrent_alert>, noncopyable>( class_<storage_moved_failed_alert, bases<torrent_alert>, noncopyable>(
"storage_moved_failed_alert", no_init "storage_moved_failed_alert", no_init)
)
.def_readonly("error", &storage_moved_failed_alert::error) .def_readonly("error", &storage_moved_failed_alert::error)
; ;
class_<torrent_deleted_alert, bases<torrent_alert>, noncopyable>( class_<torrent_deleted_alert, bases<torrent_alert>, noncopyable>(
"torrent_deleted_alert", no_init "torrent_deleted_alert", no_init)
)
.def_readonly("info_hash", &torrent_deleted_alert::info_hash) .def_readonly("info_hash", &torrent_deleted_alert::info_hash)
; ;
class_<torrent_paused_alert, bases<torrent_alert>, noncopyable>( class_<torrent_paused_alert, bases<torrent_alert>, noncopyable>(
"torrent_paused_alert", no_init "torrent_paused_alert", no_init);
);
class_<torrent_checked_alert, bases<torrent_alert>, noncopyable>( class_<torrent_checked_alert, bases<torrent_alert>, noncopyable>(
"torrent_checked_alert", no_init "torrent_checked_alert", no_init);
);
class_<url_seed_alert, bases<torrent_alert>, noncopyable>( class_<url_seed_alert, bases<torrent_alert>, noncopyable>(
"url_seed_alert", no_init "url_seed_alert", no_init)
)
.def_readonly("url", &url_seed_alert::url) .def_readonly("url", &url_seed_alert::url)
.def_readonly("msg", &url_seed_alert::msg) .def_readonly("msg", &url_seed_alert::msg)
; ;
class_<file_error_alert, bases<torrent_alert>, noncopyable>( class_<file_error_alert, bases<torrent_alert>, noncopyable>(
"file_error_alert", no_init "file_error_alert", no_init)
)
.def_readonly("file", &file_error_alert::file) .def_readonly("file", &file_error_alert::file)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &file_error_alert::msg) .def_readonly("msg", &file_error_alert::msg)
@ -202,29 +179,24 @@ void bind_alert()
; ;
class_<metadata_failed_alert, bases<torrent_alert>, noncopyable>( class_<metadata_failed_alert, bases<torrent_alert>, noncopyable>(
"metadata_failed_alert", no_init "metadata_failed_alert", no_init);
);
class_<metadata_received_alert, bases<torrent_alert>, noncopyable>( class_<metadata_received_alert, bases<torrent_alert>, noncopyable>(
"metadata_received_alert", no_init "metadata_received_alert", no_init);
);
class_<listen_failed_alert, bases<alert>, noncopyable>( class_<listen_failed_alert, bases<alert>, noncopyable>(
"listen_failed_alert", no_init "listen_failed_alert", no_init)
)
.def_readonly("endpoint", &listen_failed_alert::endpoint) .def_readonly("endpoint", &listen_failed_alert::endpoint)
.def_readonly("error", &listen_failed_alert::error) .def_readonly("error", &listen_failed_alert::error)
; ;
class_<listen_succeeded_alert, bases<alert>, noncopyable>( class_<listen_succeeded_alert, bases<alert>, noncopyable>(
"listen_succeeded_alert", no_init "listen_succeeded_alert", no_init)
)
.def_readonly("endpoint", &listen_succeeded_alert::endpoint) .def_readonly("endpoint", &listen_succeeded_alert::endpoint)
; ;
class_<portmap_error_alert, bases<alert>, noncopyable>( class_<portmap_error_alert, bases<alert>, noncopyable>(
"portmap_error_alert", no_init "portmap_error_alert", no_init)
)
.def_readonly("mapping", &portmap_error_alert::mapping) .def_readonly("mapping", &portmap_error_alert::mapping)
.def_readonly("type", &portmap_error_alert::type) .def_readonly("type", &portmap_error_alert::type)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
@ -233,16 +205,14 @@ void bind_alert()
; ;
class_<portmap_alert, bases<alert>, noncopyable>( class_<portmap_alert, bases<alert>, noncopyable>(
"portmap_alert", no_init "portmap_alert", no_init)
)
.def_readonly("mapping", &portmap_alert::mapping) .def_readonly("mapping", &portmap_alert::mapping)
.def_readonly("external_port", &portmap_alert::external_port) .def_readonly("external_port", &portmap_alert::external_port)
.def_readonly("type", &portmap_alert::type) .def_readonly("type", &portmap_alert::type)
; ;
class_<portmap_log_alert, bases<alert>, noncopyable>( class_<portmap_log_alert, bases<alert>, noncopyable>(
"portmap_log_alert", no_init "portmap_log_alert", no_init)
)
.def_readonly("type", &portmap_log_alert::type) .def_readonly("type", &portmap_log_alert::type)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &portmap_log_alert::msg) .def_readonly("msg", &portmap_log_alert::msg)
@ -250,59 +220,50 @@ void bind_alert()
; ;
class_<fastresume_rejected_alert, bases<torrent_alert>, noncopyable>( class_<fastresume_rejected_alert, bases<torrent_alert>, noncopyable>(
"fastresume_rejected_alert", no_init "fastresume_rejected_alert", no_init)
)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &fastresume_rejected_alert::msg) .def_readonly("msg", &fastresume_rejected_alert::msg)
#endif #endif
; ;
class_<peer_blocked_alert, bases<alert>, noncopyable>( class_<peer_blocked_alert, bases<alert>, noncopyable>(
"peer_blocked_alert", no_init "peer_blocked_alert", no_init)
)
.def_readonly("ip", &peer_blocked_alert::ip) .def_readonly("ip", &peer_blocked_alert::ip)
; ;
class_<scrape_reply_alert, bases<tracker_alert>, noncopyable>( class_<scrape_reply_alert, bases<tracker_alert>, noncopyable>(
"scrape_reply_alert", no_init "scrape_reply_alert", no_init)
)
.def_readonly("incomplete", &scrape_reply_alert::incomplete) .def_readonly("incomplete", &scrape_reply_alert::incomplete)
.def_readonly("complete", &scrape_reply_alert::complete) .def_readonly("complete", &scrape_reply_alert::complete)
; ;
class_<scrape_failed_alert, bases<tracker_alert>, noncopyable>( class_<scrape_failed_alert, bases<tracker_alert>, noncopyable>(
"scrape_failed_alert", no_init "scrape_failed_alert", no_init);
);
class_<udp_error_alert, bases<alert>, noncopyable>( class_<udp_error_alert, bases<alert>, noncopyable>(
"udp_error_alert", no_init "udp_error_alert", no_init)
)
.def_readonly("endpoint", &udp_error_alert::endpoint) .def_readonly("endpoint", &udp_error_alert::endpoint)
.def_readonly("error", &udp_error_alert::error) .def_readonly("error", &udp_error_alert::error)
; ;
class_<external_ip_alert, bases<alert>, noncopyable>( class_<external_ip_alert, bases<alert>, noncopyable>(
"external_ip_alert", no_init "external_ip_alert", no_init)
)
.def_readonly("external_address", &external_ip_alert::external_address) .def_readonly("external_address", &external_ip_alert::external_address)
; ;
class_<save_resume_data_alert, bases<torrent_alert>, noncopyable>( class_<save_resume_data_alert, bases<torrent_alert>, noncopyable>(
"save_resume_data_alert", no_init "save_resume_data_alert", no_init)
)
.def_readonly("resume_data", &save_resume_data_alert::resume_data) .def_readonly("resume_data", &save_resume_data_alert::resume_data)
; ;
class_<file_renamed_alert, bases<torrent_alert>, noncopyable>( class_<file_renamed_alert, bases<torrent_alert>, noncopyable>(
"file_renamed_alert", no_init "file_renamed_alert", no_init)
)
.def_readonly("index", &file_renamed_alert::index) .def_readonly("index", &file_renamed_alert::index)
.def_readonly("name", &file_renamed_alert::name) .def_readonly("name", &file_renamed_alert::name)
; ;
class_<file_rename_failed_alert, bases<torrent_alert>, noncopyable>( class_<file_rename_failed_alert, bases<torrent_alert>, noncopyable>(
"file_rename_failed_alert", no_init "file_rename_failed_alert", no_init)
)
.def_readonly("index", &file_rename_failed_alert::index) .def_readonly("index", &file_rename_failed_alert::index)
.def_readonly("error", &file_rename_failed_alert::error) .def_readonly("error", &file_rename_failed_alert::error)
; ;
@ -312,21 +273,18 @@ void bind_alert()
); );
class_<state_changed_alert, bases<torrent_alert>, noncopyable>( class_<state_changed_alert, bases<torrent_alert>, noncopyable>(
"state_changed_alert", no_init "state_changed_alert", no_init)
)
.def_readonly("state", &state_changed_alert::state) .def_readonly("state", &state_changed_alert::state)
.def_readonly("prev_state", &state_changed_alert::prev_state) .def_readonly("prev_state", &state_changed_alert::prev_state)
; ;
class_<dht_reply_alert, bases<tracker_alert>, noncopyable>( class_<dht_reply_alert, bases<tracker_alert>, noncopyable>(
"dht_reply_alert", no_init "dht_reply_alert", no_init)
)
.def_readonly("num_peers", &dht_reply_alert::num_peers) .def_readonly("num_peers", &dht_reply_alert::num_peers)
; ;
class_<dht_announce_alert, bases<alert>, noncopyable>( class_<dht_announce_alert, bases<alert>, noncopyable>(
"dht_announce_alert", no_init "dht_announce_alert", no_init)
)
.def_readonly("ip", &dht_announce_alert::ip) .def_readonly("ip", &dht_announce_alert::ip)
.def_readonly("port", &dht_announce_alert::port) .def_readonly("port", &dht_announce_alert::port)
.def_readonly("info_hash", &dht_announce_alert::info_hash) .def_readonly("info_hash", &dht_announce_alert::info_hash)
@ -351,53 +309,46 @@ void bind_alert()
); );
class_<peer_disconnected_alert, bases<peer_alert>, noncopyable>( class_<peer_disconnected_alert, bases<peer_alert>, noncopyable>(
"peer_disconnected_alert", no_init "peer_disconnected_alert", no_init)
)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &peer_disconnected_alert::msg) .def_readonly("msg", &peer_disconnected_alert::msg)
#endif #endif
; ;
class_<request_dropped_alert, bases<peer_alert>, noncopyable>( class_<request_dropped_alert, bases<peer_alert>, noncopyable>(
"request_dropped_alert", no_init "request_dropped_alert", no_init)
)
.def_readonly("block_index", &request_dropped_alert::block_index) .def_readonly("block_index", &request_dropped_alert::block_index)
.def_readonly("piece_index", &request_dropped_alert::piece_index) .def_readonly("piece_index", &request_dropped_alert::piece_index)
; ;
class_<block_timeout_alert, bases<peer_alert>, noncopyable>( class_<block_timeout_alert, bases<peer_alert>, noncopyable>(
"block_timeout_alert", no_init "block_timeout_alert", no_init)
)
.def_readonly("block_index", &block_timeout_alert::block_index) .def_readonly("block_index", &block_timeout_alert::block_index)
.def_readonly("piece_index", &block_timeout_alert::piece_index) .def_readonly("piece_index", &block_timeout_alert::piece_index)
; ;
class_<unwanted_block_alert, bases<peer_alert>, noncopyable>( class_<unwanted_block_alert, bases<peer_alert>, noncopyable>(
"unwanted_block_alert", no_init "unwanted_block_alert", no_init)
)
.def_readonly("block_index", &unwanted_block_alert::block_index) .def_readonly("block_index", &unwanted_block_alert::block_index)
.def_readonly("piece_index", &unwanted_block_alert::piece_index) .def_readonly("piece_index", &unwanted_block_alert::piece_index)
; ;
class_<torrent_delete_failed_alert, bases<torrent_alert>, noncopyable>( class_<torrent_delete_failed_alert, bases<torrent_alert>, noncopyable>(
"torrent_delete_failed_alert", no_init "torrent_delete_failed_alert", no_init)
)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &torrent_delete_failed_alert::msg) .def_readonly("msg", &torrent_delete_failed_alert::msg)
#endif #endif
; ;
class_<save_resume_data_failed_alert, bases<torrent_alert>, noncopyable>( class_<save_resume_data_failed_alert, bases<torrent_alert>, noncopyable>(
"save_resume_data_failed_alert", no_init "save_resume_data_failed_alert", no_init)
)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &save_resume_data_failed_alert::msg) .def_readonly("msg", &save_resume_data_failed_alert::msg)
#endif #endif
; ;
class_<performance_alert, bases<torrent_alert>, noncopyable>( class_<performance_alert, bases<torrent_alert>, noncopyable>(
"performance_alert", no_init "performance_alert", no_init)
)
.def_readonly("warning_code", &performance_alert::warning_code) .def_readonly("warning_code", &performance_alert::warning_code)
; ;
enum_<performance_alert::performance_warning_t>("performance_warning_t") enum_<performance_alert::performance_warning_t>("performance_warning_t")
@ -409,11 +360,10 @@ void bind_alert()
class_<stats_alert, bases<torrent_alert>, noncopyable>( class_<stats_alert, bases<torrent_alert>, noncopyable>(
"stats_alert", no_init "stats_alert", no_init)
)
.def_readonly("transferred", &stats_alert::transferred) .def_readonly("transferred", &stats_alert::transferred)
.def_readonly("interval", &stats_alert::interval) .def_readonly("interval", &stats_alert::interval)
; ;
enum_<stats_alert::stats_channel>("stats_channel") enum_<stats_alert::stats_channel>("stats_channel")
.value("upload_payload", stats_alert::upload_payload) .value("upload_payload", stats_alert::upload_payload)
@ -428,4 +378,13 @@ void bind_alert()
.value("download_tracker_protocol", stats_alert::download_tracker_protocol) .value("download_tracker_protocol", stats_alert::download_tracker_protocol)
; ;
class_<anonymous_mode_alert, bases<torrent_alert>, noncopyable>(
"anonymous_mode_alert", no_init)
.def_readonly("kind", &anonymous_mode_alert::kind)
.def_readonly("str", &anonymous_mode_alert::str)
;
enum_<anonymous_mode_alert::kind_t>("kind")
.value("tracker_no_anonymous", anonymous_mode_alert::tracker_not_anonymous)
;
} }

View File

@ -57,10 +57,11 @@
<li><a class="reference internal" href="#set-comment" id="id13">set_comment()</a></li> <li><a class="reference internal" href="#set-comment" id="id13">set_comment()</a></li>
<li><a class="reference internal" href="#set-creator" id="id14">set_creator()</a></li> <li><a class="reference internal" href="#set-creator" id="id14">set_creator()</a></li>
<li><a class="reference internal" href="#set-hash" id="id15">set_hash()</a></li> <li><a class="reference internal" href="#set-hash" id="id15">set_hash()</a></li>
<li><a class="reference internal" href="#add-url-seed" id="id16">add_url_seed()</a></li> <li><a class="reference internal" href="#set-file-hash" id="id16">set_file_hash()</a></li>
<li><a class="reference internal" href="#add-node" id="id17">add_node()</a></li> <li><a class="reference internal" href="#add-url-seed" id="id17">add_url_seed()</a></li>
<li><a class="reference internal" href="#add-tracker" id="id18">add_tracker()</a></li> <li><a class="reference internal" href="#add-node" id="id18">add_node()</a></li>
<li><a class="reference internal" href="#set-priv-priv" id="id19">set_priv() priv()</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>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -110,12 +111,16 @@ bencode(std::ostream_iterator&lt;char&gt;(out), t.generate());
<blockquote> <blockquote>
<pre class="literal-block"> <pre class="literal-block">
template &lt;class Pred&gt; template &lt;class Pred&gt;
void add_files(file_storage&amp; fs, boost::filesystem::path const&amp; path, Pred p); void add_files(file_storage&amp; fs, boost::filesystem::path const&amp; path, Pred p
, boost::uint32_t flags = 0);
template &lt;class Pred&gt; template &lt;class Pred&gt;
void add_files(file_storage&amp; fs, boost::filesystem::wpath const&amp; path, Pred p); void add_files(file_storage&amp; fs, boost::filesystem::wpath const&amp; path, Pred p
, boost::uint32_t flags = 0);
void add_files(file_storage&amp; fs, boost::filesystem::path const&amp; path); void add_files(file_storage&amp; fs, boost::filesystem::path const&amp; path
void add_files(file_storage&amp; fs, boost::filesystem::wpath const&amp; path); , boost::uint32_t flags = 0);
void add_files(file_storage&amp; fs, boost::filesystem::wpath const&amp; path
, boost::uint32_t flags = 0);
</pre> </pre>
</blockquote> </blockquote>
<p>Adds the file specified by <tt class="docutils literal"><span class="pre">path</span></tt> to the <tt class="docutils literal"><span class="pre">file_storage</span></tt> object. In case <tt class="docutils literal"><span class="pre">path</span></tt> <p>Adds the file specified by <tt class="docutils literal"><span class="pre">path</span></tt> to the <tt class="docutils literal"><span class="pre">file_storage</span></tt> object. In case <tt class="docutils literal"><span class="pre">path</span></tt>
@ -134,6 +139,8 @@ bool Pred(boost::filesystem::wpath const&amp; p);
directory. If no predicate is specified, all files are added, and all directories directory. If no predicate is specified, all files are added, and all directories
are traveresed.</p> are traveresed.</p>
<p>The &quot;..&quot; directory is never traversed.</p> <p>The &quot;..&quot; directory is never traversed.</p>
<p>The <tt class="docutils literal"><span class="pre">flags</span></tt> argument should be the same as the flags passed to the <a class="reference internal" href="#create-torrent">create_torrent</a>
constructor.</p>
</div> </div>
<div class="section" id="set-piece-hashes"> <div class="section" id="set-piece-hashes">
<h1>set_piece_hashes()</h1> <h1>set_piece_hashes()</h1>
@ -269,8 +276,10 @@ struct create_torrent
, merkle = 2 , merkle = 2
, modification_time = 4 , modification_time = 4
, symlink = 8 , symlink = 8
, calculate_file_hashes = 16
}; };
create_torrent(file_storage&amp; fs, int piece_size = 0, int pad_size_limit = -1, int flags = optimize); create_torrent(file_storage&amp; fs, int piece_size = 0, int pad_size_limit = -1
, int flags = optimize);
create_torrent(torrent_info const&amp; ti); create_torrent(torrent_info const&amp; ti);
entry generate() const; entry generate() const;
@ -280,6 +289,7 @@ struct create_torrent
void set_comment(char const* str); void set_comment(char const* str);
void set_creator(char const* str); void set_creator(char const* str);
void set_hash(int index, sha1_hash const&amp; h); void set_hash(int index, sha1_hash const&amp; h);
void set_file_hash(int index, sha1_hash const&amp; h);
void add_url_seed(std::string const&amp; url); void add_url_seed(std::string const&amp; url);
void add_node(std::pair&lt;std::string, int&gt; const&amp; node); void add_node(std::pair&lt;std::string, int&gt; const&amp; node);
void add_tracker(std::string const&amp; url, int tier = 0); void add_tracker(std::string const&amp; url, int tier = 0);
@ -300,8 +310,10 @@ enum {
, merkle = 2 , merkle = 2
, modification_time = 4 , modification_time = 4
, symlink = 8 , symlink = 8
, calculate_file_hashes = 16
}; };
create_torrent(file_storage&amp; fs, int piece_size = 0, int pad_size_limit = -1, int flags = optimize); create_torrent(file_storage&amp; fs, int piece_size = 0, int pad_size_limit = -1
, int flags = optimize);
create_torrent(torrent_info const&amp; ti); create_torrent(torrent_info const&amp; ti);
</pre> </pre>
</blockquote> </blockquote>
@ -338,11 +350,15 @@ yield the same info-hash. If the files have different modification times,
with this option enabled, you would get different info-hashes for the with this option enabled, you would get different info-hashes for the
files.</dd> files.</dd>
<dt>symlink</dt> <dt>symlink</dt>
<dd>If this flag is defined, files that are symlinks get a symlink attribute <dd>If this flag is set, files that are symlinks get a symlink attribute
set on them. The file data will still be the same, the symlink will always set on them and their data will not be included in the torrent. This
be followed when opening the file, but the file list will include the path is useful if you need to reconstruct a file hierarchy which contains
of the symlink so that the original directory structure can be reproduced symlinks.</dd>
on the downloading side.</dd> <dt>calculate_file_hashes</dt>
<dd>If this is set, the <a class="reference internal" href="#set-piece-hashes">set_piece_hashes()</a> function will, as it calculates
the piece hashes, also calculate the file hashes and add those associated
with each file. Note that unless you use the <a class="reference internal" href="#set-piece-hashes">set_piece_hashes()</a> function,
this flag will have no effect.</dd>
</dl> </dl>
</div> </div>
<div class="section" id="generate"> <div class="section" id="generate">
@ -406,6 +422,17 @@ to set the hash for every piece in the torrent before generating it. If you have
the files on disk, you can use the high level convenience function to do this. the files on disk, you can use the high level convenience function to do this.
See <a class="reference internal" href="#set-piece-hashes">set_piece_hashes()</a>.</p> See <a class="reference internal" href="#set-piece-hashes">set_piece_hashes()</a>.</p>
</div> </div>
<div class="section" id="set-file-hash">
<h2>set_file_hash()</h2>
<blockquote>
<pre class="literal-block">
void set_file_hash(int index, sha1_hash const&amp; h);
</pre>
</blockquote>
<p>This sets the sha1 hash for this file. This hash will end up under the key <tt class="docutils literal"><span class="pre">sha1</span></tt>
associated with this file (for multi-file torrents) or in the root info dictionary
for single-file torrents.</p>
</div>
<div class="section" id="add-url-seed"> <div class="section" id="add-url-seed">
<h2>add_url_seed()</h2> <h2>add_url_seed()</h2>
<blockquote> <blockquote>

View File

@ -246,57 +246,58 @@
<li><a class="reference internal" href="#cache-flushed-alert" id="id201">cache_flushed_alert</a></li> <li><a class="reference internal" href="#cache-flushed-alert" id="id201">cache_flushed_alert</a></li>
<li><a class="reference internal" href="#dht-announce-alert" id="id202">dht_announce_alert</a></li> <li><a class="reference internal" href="#dht-announce-alert" id="id202">dht_announce_alert</a></li>
<li><a class="reference internal" href="#dht-get-peers-alert" id="id203">dht_get_peers_alert</a></li> <li><a class="reference internal" href="#dht-get-peers-alert" id="id203">dht_get_peers_alert</a></li>
<li><a class="reference internal" href="#dispatcher" id="id204">dispatcher</a></li> <li><a class="reference internal" href="#anonymous-mode-alert" id="id204">anonymous_mode_alert</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#exceptions" id="id205">exceptions</a><ul> <li><a class="reference internal" href="#alert-dispatcher" id="id205">alert dispatcher</a></li>
<li><a class="reference internal" href="#libtorrent-exception" id="id206">libtorrent_exception</a></li> <li><a class="reference internal" href="#exceptions" id="id206">exceptions</a><ul>
<li><a class="reference internal" href="#libtorrent-exception" id="id207">libtorrent_exception</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#error-code" id="id207">error_code</a><ul> <li><a class="reference internal" href="#error-code" id="id208">error_code</a><ul>
<li><a class="reference internal" href="#translating-error-codes" id="id208">translating error codes</a></li> <li><a class="reference internal" href="#translating-error-codes" id="id209">translating error codes</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#storage-interface" id="id209">storage_interface</a><ul> <li><a class="reference internal" href="#storage-interface" id="id210">storage_interface</a><ul>
<li><a class="reference internal" href="#initialize" id="id210">initialize()</a></li> <li><a class="reference internal" href="#initialize" id="id211">initialize()</a></li>
<li><a class="reference internal" href="#has-any-file" id="id211">has_any_file()</a></li> <li><a class="reference internal" href="#has-any-file" id="id212">has_any_file()</a></li>
<li><a class="reference internal" href="#readv-writev" id="id212">readv() writev()</a></li> <li><a class="reference internal" href="#readv-writev" id="id213">readv() writev()</a></li>
<li><a class="reference internal" href="#sparse-end" id="id213">sparse_end()</a></li> <li><a class="reference internal" href="#sparse-end" id="id214">sparse_end()</a></li>
<li><a class="reference internal" href="#id14" id="id214">move_storage()</a></li> <li><a class="reference internal" href="#id14" id="id215">move_storage()</a></li>
<li><a class="reference internal" href="#verify-resume-data" id="id215">verify_resume_data()</a></li> <li><a class="reference internal" href="#verify-resume-data" id="id216">verify_resume_data()</a></li>
<li><a class="reference internal" href="#write-resume-data" id="id216">write_resume_data()</a></li> <li><a class="reference internal" href="#write-resume-data" id="id217">write_resume_data()</a></li>
<li><a class="reference internal" href="#move-slot" id="id217">move_slot()</a></li> <li><a class="reference internal" href="#move-slot" id="id218">move_slot()</a></li>
<li><a class="reference internal" href="#swap-slots" id="id218">swap_slots()</a></li> <li><a class="reference internal" href="#swap-slots" id="id219">swap_slots()</a></li>
<li><a class="reference internal" href="#swap-slots3" id="id219">swap_slots3()</a></li> <li><a class="reference internal" href="#swap-slots3" id="id220">swap_slots3()</a></li>
<li><a class="reference internal" href="#id15" id="id220">rename_file()</a></li> <li><a class="reference internal" href="#id15" id="id221">rename_file()</a></li>
<li><a class="reference internal" href="#release-files" id="id221">release_files()</a></li> <li><a class="reference internal" href="#release-files" id="id222">release_files()</a></li>
<li><a class="reference internal" href="#delete-files" id="id222">delete_files()</a></li> <li><a class="reference internal" href="#delete-files" id="id223">delete_files()</a></li>
<li><a class="reference internal" href="#finalize-file" id="id223">finalize_file()</a></li> <li><a class="reference internal" href="#finalize-file" id="id224">finalize_file()</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#magnet-links" id="id224">magnet links</a></li> <li><a class="reference internal" href="#magnet-links" id="id225">magnet links</a></li>
<li><a class="reference internal" href="#queuing" id="id225">queuing</a><ul> <li><a class="reference internal" href="#queuing" id="id226">queuing</a><ul>
<li><a class="reference internal" href="#downloading" id="id226">downloading</a></li> <li><a class="reference internal" href="#downloading" id="id227">downloading</a></li>
<li><a class="reference internal" href="#seeding" id="id227">seeding</a></li> <li><a class="reference internal" href="#seeding" id="id228">seeding</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#fast-resume" id="id228">fast resume</a><ul> <li><a class="reference internal" href="#fast-resume" id="id229">fast resume</a><ul>
<li><a class="reference internal" href="#file-format" id="id229">file format</a></li> <li><a class="reference internal" href="#file-format" id="id230">file format</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#threads" id="id230">threads</a></li> <li><a class="reference internal" href="#threads" id="id231">threads</a></li>
<li><a class="reference internal" href="#storage-allocation" id="id231">storage allocation</a><ul> <li><a class="reference internal" href="#storage-allocation" id="id232">storage allocation</a><ul>
<li><a class="reference internal" href="#sparse-allocation" id="id232">sparse allocation</a></li> <li><a class="reference internal" href="#sparse-allocation" id="id233">sparse allocation</a></li>
<li><a class="reference internal" href="#full-allocation" id="id233">full allocation</a></li> <li><a class="reference internal" href="#full-allocation" id="id234">full allocation</a></li>
<li><a class="reference internal" href="#compact-allocation" id="id234">compact allocation</a></li> <li><a class="reference internal" href="#compact-allocation" id="id235">compact allocation</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#extensions" id="id235">extensions</a><ul> <li><a class="reference internal" href="#extensions" id="id236">extensions</a><ul>
<li><a class="reference internal" href="#metadata-from-peers" id="id236">metadata from peers</a></li> <li><a class="reference internal" href="#metadata-from-peers" id="id237">metadata from peers</a></li>
<li><a class="reference internal" href="#http-seeding" id="id237">HTTP seeding</a></li> <li><a class="reference internal" href="#http-seeding" id="id238">HTTP seeding</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#filename-checks" id="id238">filename checks</a></li> <li><a class="reference internal" href="#filename-checks" id="id239">filename checks</a></li>
</ul> </ul>
</div> </div>
<div class="section" id="overview"> <div class="section" id="overview">
@ -1163,6 +1164,7 @@ socket listening on different ports. If the DHT is active when <tt class="docuti
called, the udp port will be rebound to the new port, if it was configured to use called, the udp port will be rebound to the new port, if it was configured to use
the same port as the tcp socket, and if the listen_on call failed to bind to the the same port as the tcp socket, and if the listen_on call failed to bind to the
same port that the udp uses.</p> same port that the udp uses.</p>
<p>If you want the OS to pick a port for you, pass in 0 as both first and second.</p>
<p>The reason why it's a good idea to run the DHT and the bittorrent socket on the same <p>The reason why it's a good idea to run the DHT and the bittorrent socket on the same
port is because that is an assumption that may be used to increase performance. One port is because that is an assumption that may be used to increase performance. One
way to accelerate the connecting of peers on windows may be to first ping all peers way to accelerate the connecting of peers on windows may be to first ping all peers
@ -1791,9 +1793,12 @@ struct file_entry
size_type offset; size_type offset;
size_type size; size_type size;
size_type file_base; size_type file_base;
std::string symlink_path;
boost::shared_ptr&lt;sha1_hash&gt; filehash;
bool pad_file:1; bool pad_file:1;
bool hidden_attribute:1; bool hidden_attribute:1;
bool executable_attribute:1; bool executable_attribute:1;
bool symlink_attribute:1;
}; };
</pre> </pre>
<p>The <tt class="docutils literal"><span class="pre">path</span></tt> is the full (relative) path of each file. i.e. if it is a multi-file <p>The <tt class="docutils literal"><span class="pre">path</span></tt> is the full (relative) path of each file. i.e. if it is a multi-file
@ -1812,6 +1817,13 @@ file.</p>
They are just there to make sure the next file is aligned to a particular byte offset They are just there to make sure the next file is aligned to a particular byte offset
or piece boundry. These files should typically be hidden from an end user. They are or piece boundry. These files should typically be hidden from an end user. They are
not written to disk.</p> not written to disk.</p>
<p><tt class="docutils literal"><span class="pre">hidden_attribute</span></tt> is true if the file was marked as hidden (on windows).</p>
<p><tt class="docutils literal"><span class="pre">executable_attribute</span></tt> is true if the file was marked as executable (posix)</p>
<p><tt class="docutils literal"><span class="pre">symlink_attribute</span></tt> is true if the file was a symlink. If this is the case
the <tt class="docutils literal"><span class="pre">symlink_path</span></tt> specifies the original location where the data for this file
was found.</p>
<p><tt class="docutils literal"><span class="pre">filehash</span></tt> is a pointer that is set in case the torrent file included a sha1 hash
for this file. This may be use to look up more sources for this file on other networks.</p>
</div> </div>
<div class="section" id="num-files-file-at"> <div class="section" id="num-files-file-at">
<h2>num_files() file_at()</h2> <h2>num_files() file_at()</h2>
@ -3777,6 +3789,8 @@ struct session_settings
int active_downloads; int active_downloads;
int active_seeds; int active_seeds;
int active_dht_limit;
int active_tracker_limit;
int active_limit; int active_limit;
bool auto_manage_prefer_seeds; bool auto_manage_prefer_seeds;
bool dont_count_slow_torrents; bool dont_count_slow_torrents;
@ -3854,6 +3868,9 @@ struct session_settings
int default_peer_upload_rate; int default_peer_upload_rate;
int default_peer_download_rate; int default_peer_download_rate;
bool broadcast_lsd;
bool ignore_resume_timestamps;
bool anonymous_mode;
}; };
</pre> </pre>
<p><tt class="docutils literal"><span class="pre">user_agent</span></tt> this is the client identification to the tracker. <p><tt class="docutils literal"><span class="pre">user_agent</span></tt> this is the client identification to the tracker.
@ -4142,6 +4159,17 @@ to make it more likely to utilize all available bandwidth, and avoid having torr
that don't transfer anything block the active slots.</p> that don't transfer anything block the active slots.</p>
<p><tt class="docutils literal"><span class="pre">active_limit</span></tt> is a hard limit on the number of active torrents. This applies even to <p><tt class="docutils literal"><span class="pre">active_limit</span></tt> is a hard limit on the number of active torrents. This applies even to
slow torrents.</p> slow torrents.</p>
<p><tt class="docutils literal"><span class="pre">active_dht_limit</span></tt> is the max number of torrents to announce to the DHT. By default
this is set to 88, which is no more than one DHT announce every 10 seconds.</p>
<p><tt class="docutils literal"><span class="pre">active_tracker_limit</span></tt> is the max number of torrents to announce to their trackers.
By default this is 360, which is no more than one announce every 5 seconds.</p>
<p><tt class="docutils literal"><span class="pre">active_lsd_limit</span></tt> is the max number of torrents to announce to the local network
over the local service discovery protocol. By default this is 80, which is no more
than one announce every 5 seconds (assuming the default announce interval of 5 minutes).</p>
<p>You can have more torrents <em>active</em>, even though they are not announced to the DHT,
lsd or their tracker. If some peer knows about you for any reason and tries to connect,
it will still be accepted, unless the torrent is paused, which means it won't accept
any connections.</p>
<p><tt class="docutils literal"><span class="pre">auto_manage_interval</span></tt> is the number of seconds between the torrent queue <p><tt class="docutils literal"><span class="pre">auto_manage_interval</span></tt> is the number of seconds between the torrent queue
is updated, and rotated.</p> is updated, and rotated.</p>
<p><tt class="docutils literal"><span class="pre">share_ratio_limit</span></tt> is the upload / download ratio limit for considering a <p><tt class="docutils literal"><span class="pre">share_ratio_limit</span></tt> is the upload / download ratio limit for considering a
@ -4368,6 +4396,28 @@ 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 set on new peer connections (not existing ones). The peer rate limits can
be changed individually later using be changed individually later using
<a class="reference internal" href="#set-peer-upload-limit-set-peer-download-limit">set_peer_upload_limit() set_peer_download_limit()</a>.</p> <a class="reference internal" href="#set-peer-upload-limit-set-peer-download-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
(or Local Service Discovery) will not only use IP multicast, but also
broadcast its messages. This can be useful when running on networks
that don't support multicast. It's off by default since it's inefficient.</p>
<p><tt class="docutils literal"><span class="pre">ignore_resume_timestamps</span></tt> determines if the storage, when loading
resume data files, should verify that the file modification time
with the timestamps in the resume data. This defaults to false, which
means timestamps are taken into account, and resume data is less likely
to accepted (torrents are more likely to be fully checked when loaded).
It might be useful to set this to true if your network is faster than your
disk, and it would be faster to redownload potentially missed pieces than
to go through the whole storage to look for them.</p>
<p><tt class="docutils literal"><span class="pre">anonymous_mode</span></tt> defaults to false. When set to true, the client tries
to hide its identity to a certain degree. The peer-ID will no longer
include the client's fingerprint. The user-agent will be reset to an
empty string. Trackers will only be used if they are using a proxy
server. The listen sockets are closed, and incoming connections will
only be accepted through a SOCKS5 or I2P proxy (if a peer proxy is set up and
is run on the same machine as the tracker proxy). Since no incoming connections
are accepted, NAT-PMP, UPnP, DHT and local peer discovery are all turned off
when this setting is enabled.</p>
<p>If you're using I2P, it might make sense to enable anonymous mode as well.</p>
</div> </div>
</div> </div>
<div class="section" id="pe-settings"> <div class="section" id="pe-settings">
@ -4985,7 +5035,7 @@ has the followinf signature:</p>
template &lt;T&gt; T* alert_cast(alert* a); template &lt;T&gt; T* alert_cast(alert* a);
template &lt;T&gt; T const* alert_cast(alert const* a); template &lt;T&gt; T const* alert_cast(alert const* a);
</pre> </pre>
<p>You can also use a <a class="reference internal" href="#dispatcher">dispatcher</a> mechanism that's available in libtorrent.</p> <p>You can also use a <a class="reference internal" href="#alert-dispatcher">alert dispatcher</a> mechanism that's available in libtorrent.</p>
<p>All alert types are defined in the <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert_types.hpp&gt;</span></tt> header file.</p> <p>All alert types are defined in the <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert_types.hpp&gt;</span></tt> header file.</p>
<p>The <tt class="docutils literal"><span class="pre">alert</span></tt> class is the base class that specific messages are derived from. This <p>The <tt class="docutils literal"><span class="pre">alert</span></tt> class is the base class that specific messages are derived from. This
is its synopsis:</p> is its synopsis:</p>
@ -5808,8 +5858,32 @@ struct dht_get_peers_alert: alert
}; };
</pre> </pre>
</div> </div>
<div class="section" id="dispatcher"> <div class="section" id="anonymous-mode-alert">
<h2>dispatcher</h2> <h2>anonymous_mode_alert</h2>
<p>This alert is posted when a bittorrent feature is blocked because of the
anonymous mode. For instance, if the tracker proxy is not set up, no
trackers will be used, because trackers can only be used through proxies
when in anonymous mode.</p>
<pre class="literal-block">
struct anonymous_mode_alert: tracker_alert
{
// ...
enum kind_t
{
tracker_not_anonymous = 1
};
int kind;
std::string str;
};
</pre>
<p><tt class="docutils literal"><span class="pre">kind</span></tt> specifies what error this is, it's one of:</p>
<p><tt class="docutils literal"><span class="pre">tracker_not_anonymous</span></tt> means that there's no proxy set up for tracker
communication and the tracker will not be contacted. The tracker which
this failed for is specified in the <tt class="docutils literal"><span class="pre">str</span></tt> member.</p>
</div>
</div>
<div class="section" id="alert-dispatcher">
<h1>alert dispatcher</h1>
<p>The <tt class="docutils literal"><span class="pre">handle_alert</span></tt> class is defined in <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert.hpp&gt;</span></tt>.</p> <p>The <tt class="docutils literal"><span class="pre">handle_alert</span></tt> class is defined in <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert.hpp&gt;</span></tt>.</p>
<p>Examples usage:</p> <p>Examples usage:</p>
<pre class="literal-block"> <pre class="literal-block">
@ -5853,7 +5927,6 @@ parameters to select between more types. If the number of types are more than
15, you can define <tt class="docutils literal"><span class="pre">TORRENT_MAX_ALERT_TYPES</span></tt> to a greater number before 15, you can define <tt class="docutils literal"><span class="pre">TORRENT_MAX_ALERT_TYPES</span></tt> to a greater number before
including <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert.hpp&gt;</span></tt>.</p> including <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert.hpp&gt;</span></tt>.</p>
</div> </div>
</div>
<div class="section" id="exceptions"> <div class="section" id="exceptions">
<h1>exceptions</h1> <h1>exceptions</h1>
<p>Many functions in libtorrent have two versions, one that throws exceptions on <p>Many functions in libtorrent have two versions, one that throws exceptions on

View File

@ -3885,6 +3885,7 @@ session_settings
int default_peer_download_rate; int default_peer_download_rate;
bool broadcast_lsd; bool broadcast_lsd;
bool ignore_resume_timestamps; bool ignore_resume_timestamps;
bool anonymous_mode;
}; };
``user_agent`` this is the client identification to the tracker. ``user_agent`` this is the client identification to the tracker.
@ -4525,6 +4526,18 @@ It might be useful to set this to true if your network is faster than your
disk, and it would be faster to redownload potentially missed pieces than disk, and it would be faster to redownload potentially missed pieces than
to go through the whole storage to look for them. to go through the whole storage to look for them.
``anonymous_mode`` defaults to false. When set to true, the client tries
to hide its identity to a certain degree. The peer-ID will no longer
include the client's fingerprint. The user-agent will be reset to an
empty string. Trackers will only be used if they are using a proxy
server. The listen sockets are closed, and incoming connections will
only be accepted through a SOCKS5 or I2P proxy (if a peer proxy is set up and
is run on the same machine as the tracker proxy). Since no incoming connections
are accepted, NAT-PMP, UPnP, DHT and local peer discovery are all turned off
when this setting is enabled.
If you're using I2P, it might make sense to enable anonymous mode as well.
pe_settings pe_settings
=========== ===========
@ -5176,7 +5189,7 @@ has the followinf signature::
template <T> T* alert_cast(alert* a); template <T> T* alert_cast(alert* a);
template <T> T const* alert_cast(alert const* a); template <T> T const* alert_cast(alert const* a);
You can also use a dispatcher_ mechanism that's available in libtorrent. You can also use a `alert dispatcher`_ mechanism that's available in libtorrent.
All alert types are defined in the ``<libtorrent/alert_types.hpp>`` header file. All alert types are defined in the ``<libtorrent/alert_types.hpp>`` header file.
@ -6170,8 +6183,35 @@ It belongs to the ``dht_notification`` category.
sha1_hash info_hash; sha1_hash info_hash;
}; };
dispatcher anonymous_mode_alert
---------- --------------------
This alert is posted when a bittorrent feature is blocked because of the
anonymous mode. For instance, if the tracker proxy is not set up, no
trackers will be used, because trackers can only be used through proxies
when in anonymous mode.
::
struct anonymous_mode_alert: tracker_alert
{
// ...
enum kind_t
{
tracker_not_anonymous = 1
};
int kind;
std::string str;
};
``kind`` specifies what error this is, it's one of:
``tracker_not_anonymous`` means that there's no proxy set up for tracker
communication and the tracker will not be contacted. The tracker which
this failed for is specified in the ``str`` member.
alert dispatcher
================
The ``handle_alert`` class is defined in ``<libtorrent/alert.hpp>``. The ``handle_alert`` class is defined in ``<libtorrent/alert.hpp>``.

View File

@ -1130,6 +1130,30 @@ namespace libtorrent
const static int static_category = alert::storage_notification; const static int static_category = alert::storage_notification;
}; };
struct TORRENT_EXPORT anonymous_mode_alert: torrent_alert
{
anonymous_mode_alert(torrent_handle const& h
, int kind_, std::string const& str_)
: torrent_alert(h)
, kind(kind_)
, str(str_)
{}
TORRENT_DEFINE_ALERT(anonymous_mode_alert);
const static int static_category = alert::error_notification;
virtual std::string message() const;
enum kind_t
{
tracker_not_anonymous = 0
};
int kind;
std::string str;
};
} }

View File

@ -570,6 +570,7 @@ namespace libtorrent
// 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;
boost::uint16_t m_socks_listen_port;
void open_new_incoming_socks_connection(); void open_new_incoming_socks_connection();

View File

@ -53,6 +53,8 @@ namespace libtorrent
TORRENT_EXPORT bool string_begins_no_case(char const* s1, char const* s2); TORRENT_EXPORT bool string_begins_no_case(char const* s1, char const* s2);
TORRENT_EXPORT bool string_equal_no_case(char const* s1, char const* s2); TORRENT_EXPORT bool string_equal_no_case(char const* s1, char const* s2);
TORRENT_EXPORT void url_random(char* begin, char* end);
TORRENT_EXPORT std::string unescape_string(std::string const& s, error_code& ec); TORRENT_EXPORT std::string unescape_string(std::string const& s, error_code& ec);
// replaces all disallowed URL characters by their %-encoding // replaces all disallowed URL characters by their %-encoding
TORRENT_EXPORT std::string escape_string(const char* str, int len); TORRENT_EXPORT std::string escape_string(const char* str, int len);

View File

@ -212,6 +212,7 @@ namespace libtorrent
, default_peer_download_rate(0) , default_peer_download_rate(0)
, broadcast_lsd(false) , broadcast_lsd(false)
, ignore_resume_timestamps(false) , ignore_resume_timestamps(false)
, anonymous_mode(false)
{} {}
// this is the user agent that will be sent to the tracker // this is the user agent that will be sent to the tracker
@ -817,6 +818,12 @@ namespace libtorrent
// file and is typically compared to make sure the files haven't changed // file and is typically compared to make sure the files haven't changed
// since the last session // since the last session
bool ignore_resume_timestamps; bool ignore_resume_timestamps;
// when this is true, libtorrent will take actions to make sure any
// privacy sensitive information is leaked out from the client. This
// mode is assumed to be combined with using a proxy for all your
// traffic. With this option, your true IP address will not be exposed
bool anonymous_mode;
}; };
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT

View File

@ -465,5 +465,17 @@ namespace libtorrent {
cache_flushed_alert::cache_flushed_alert(torrent_handle const& h): torrent_alert(h) {} cache_flushed_alert::cache_flushed_alert(torrent_handle const& h): torrent_alert(h) {}
std::string anonymous_mode_alert::message() const
{
char msg[200];
char const* msgs[] = {
"tracker is not anonymous, set a proxy"
};
snprintf(msg, sizeof(msg), "%s: %s: %s"
, torrent_alert::message().c_str()
, msgs[kind], str.c_str());
return msg;
}
} // namespace libtorrent } // namespace libtorrent

View File

@ -1869,8 +1869,12 @@ namespace libtorrent
// only send the port in case we bade the connection // only send the port in case we bade the connection
// on incoming connections the other end already knows // on incoming connections the other end already knows
// our listen port // our listen port
if (is_local()) handshake["p"] = m_ses.listen_port(); if (!m_ses.m_settings.anonymous_mode)
handshake["v"] = m_ses.settings().user_agent; {
if (is_local()) handshake["p"] = m_ses.listen_port();
handshake["v"] = m_ses.settings().user_agent;
}
std::string remote_address; std::string remote_address;
std::back_insert_iterator<std::string> out(remote_address); std::back_insert_iterator<std::string> out(remote_address);
detail::write_address(remote().address(), out); detail::write_address(remote().address(), out);
@ -1893,13 +1897,16 @@ namespace libtorrent
)) ))
handshake["upload_only"] = 1; handshake["upload_only"] = 1;
tcp::endpoint ep = m_ses.get_ipv6_interface(); if (!m_ses.m_settings.anonymous_mode)
if (!is_any(ep.address()))
{ {
std::string ipv6_address; tcp::endpoint ep = m_ses.get_ipv6_interface();
std::back_insert_iterator<std::string> out(ipv6_address); if (!is_any(ep.address()))
detail::write_address(ep.address(), out); {
handshake["ipv6"] = ipv6_address; std::string ipv6_address;
std::back_insert_iterator<std::string> out(ipv6_address);
detail::write_address(ep.address(), out);
handshake["ipv6"] = ipv6_address;
}
} }
// loop backwards, to make the first extension be the last // loop backwards, to make the first extension be the last

View File

@ -103,6 +103,19 @@ namespace libtorrent
return bool(std::strchr(ws, c)); return bool(std::strchr(ws, c));
} }
// generate a url-safe random string
void url_random(char* begin, char* end)
{
// http-accepted characters:
// excluding ', since some buggy trackers don't support that
static char const printable[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz-_.!~*()";
// the random number
while (begin != end)
*begin++ = printable[rand() % (sizeof(printable)-1)];
}
char to_lower(char c) char to_lower(char c)
{ {
return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c;

View File

@ -221,7 +221,7 @@ namespace libtorrent
request += " HTTP/1.1\r\n"; request += " HTTP/1.1\r\n";
request += "Host: "; request += "Host: ";
request += m_host; request += m_host;
if (m_first_request) if (m_first_request && !m_ses.settings().user_agent.empty())
{ {
request += "\r\nUser-Agent: "; request += "\r\nUser-Agent: ";
request += m_ses.settings().user_agent; request += m_ses.settings().user_agent;

View File

@ -205,7 +205,8 @@ namespace libtorrent
:settings.tracker_completion_timeout; :settings.tracker_completion_timeout;
m_tracker_connection->get(url, seconds(timeout) m_tracker_connection->get(url, seconds(timeout)
, 1, &m_ps, 5, settings.user_agent, bind_interface() , 1, &m_ps, 5, settings.anonymous_mode ? "" : settings.user_agent
, bind_interface()
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, m_i2p_conn , m_i2p_conn
#endif #endif

View File

@ -306,7 +306,9 @@ namespace aux {
TORRENT_SETTING(boolean, strict_end_game_mode) TORRENT_SETTING(boolean, strict_end_game_mode)
TORRENT_SETTING(integer, default_peer_upload_rate) TORRENT_SETTING(integer, default_peer_upload_rate)
TORRENT_SETTING(integer, default_peer_download_rate) TORRENT_SETTING(integer, default_peer_download_rate)
TORRENT_SETTING(boolean, broadcast_lsd)
TORRENT_SETTING(boolean, ignore_resume_timestamps) TORRENT_SETTING(boolean, ignore_resume_timestamps)
TORRENT_SETTING(boolean, anonymous_mode)
}; };
#undef TORRENT_SETTING #undef TORRENT_SETTING
@ -709,17 +711,7 @@ namespace aux {
, print.begin() + print.length() , print.begin() + print.length()
, m_peer_id.begin()); , m_peer_id.begin());
// http-accepted characters: url_random((char*)&m_peer_id[print.length()], (char*)&m_peer_id[0] + 20);
// excluding ', since some buggy trackers don't support that
static char const printable[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz-_.!~*()";
// the random number
for (unsigned char* i = m_peer_id.begin() + print.length();
i != m_peer_id.end(); ++i)
{
*i = printable[rand() % (sizeof(printable)-1)];
}
m_timer.expires_from_now(milliseconds(100), ec); m_timer.expires_from_now(milliseconds(100), ec);
m_timer.async_wait(bind(&session_impl::on_tick, this, _1)); m_timer.async_wait(bind(&session_impl::on_tick, this, _1));
@ -1229,7 +1221,31 @@ namespace aux {
|| m_settings.active_limit != s.active_limit) || m_settings.active_limit != s.active_limit)
&& m_auto_manage_time_scaler > 2) && m_auto_manage_time_scaler > 2)
m_auto_manage_time_scaler = 2; m_auto_manage_time_scaler = 2;
// if anonymous mode was enabled, clear out the peer ID
bool anonymous = (m_settings.anonymous_mode != s.anonymous_mode && s.anonymous_mode);
m_settings = s; m_settings = s;
// enable anonymous mode. We don't want to accept any incoming
// connections, except through a proxy.
if (anonymous)
{
m_settings.user_agent.clear();
url_random((char*)&m_peer_id[0], (char*)&m_peer_id[0] + 20);
stop_lsd();
stop_upnp();
stop_natpmp();
#ifndef TORRENT_DISABLE_DHT
stop_dht();
#endif
// close the listen sockets
error_code ec;
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
, end(m_listen_sockets.end()); i != end; ++i)
i->sock->close(ec);
m_listen_sockets.clear();
}
if (m_settings.connection_speed < 0) m_settings.connection_speed = 200; if (m_settings.connection_speed < 0) m_settings.connection_speed = 200;
if (m_settings.broadcast_lsd && m_lsd) if (m_settings.broadcast_lsd && m_lsd)
m_lsd->use_broadcast(true); m_lsd->use_broadcast(true);
@ -1465,7 +1481,9 @@ namespace aux {
socks5_stream& s = *m_socks_listen_socket->get<socks5_stream>(); socks5_stream& s = *m_socks_listen_socket->get<socks5_stream>();
s.set_command(2); // 2 means BIND (as opposed to CONNECT) s.set_command(2); // 2 means BIND (as opposed to CONNECT)
s.async_connect(tcp::endpoint(address_v4::any(), m_listen_interface.port()) m_socks_listen_port = m_listen_interface.port();
if (m_socks_listen_port == 0) m_socks_listen_port = 2000 + rand() % 60000;
s.async_connect(tcp::endpoint(address_v4::any(), m_socks_listen_port)
, boost::bind(&session_impl::on_socks_accept, this, m_socks_listen_socket, _1)); , boost::bind(&session_impl::on_socks_accept, this, m_socks_listen_socket, _1));
} }
@ -3173,6 +3191,17 @@ namespace aux {
unsigned short session_impl::listen_port() const unsigned short session_impl::listen_port() const
{ {
// 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->is_open()
&& m_peer_proxy.hostname == m_tracker_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; if (m_listen_sockets.empty()) return 0;
return m_listen_sockets.front().external_port; return m_listen_sockets.front().external_port;
} }

View File

@ -1392,11 +1392,14 @@ namespace libtorrent
req.event = e; req.event = e;
error_code ec; error_code ec;
tcp::endpoint ep; if (!m_ses.m_settings.anonymous_mode)
ep = m_ses.get_ipv6_interface(); {
if (ep != tcp::endpoint()) req.ipv6 = ep.address().to_string(ec); tcp::endpoint ep;
ep = m_ses.get_ipv4_interface(); ep = m_ses.get_ipv6_interface();
if (ep != tcp::endpoint()) req.ipv4 = ep.address().to_string(ec); if (ep != tcp::endpoint()) req.ipv6 = ep.address().to_string(ec);
ep = m_ses.get_ipv4_interface();
if (ep != tcp::endpoint()) req.ipv4 = ep.address().to_string(ec);
}
// if we are aborting. we don't want any new peers // if we are aborting. we don't want any new peers
req.num_want = (req.event == tracker_request::stopped) req.num_want = (req.event == tracker_request::stopped)
@ -1451,6 +1454,40 @@ namespace libtorrent
if (!is_any(bind_interface)) req.bind_ip = bind_interface; if (!is_any(bind_interface)) req.bind_ip = bind_interface;
else req.bind_ip = m_ses.m_listen_interface.address(); else req.bind_ip = m_ses.m_listen_interface.address();
if (settings().anonymous_mode)
{
// in anonymous_mode we don't talk directly to trackers
// only if there is a proxy
std::string protocol = req.url.substr(0, req.url.find(':'));
int proxy_type = m_ses.m_tracker_proxy.type;
if ((protocol == "http" || protocol == "https")
&& proxy_type == proxy_settings::none)
{
if (m_ses.m_alerts.should_post<anonymous_mode_alert>())
{
m_ses.m_alerts.post_alert(
anonymous_mode_alert(get_handle()
, anonymous_mode_alert::tracker_not_anonymous, req.url));
}
continue;
}
if (protocol == "udp"
|| (proxy_type != proxy_settings::socks5
&& proxy_type != proxy_settings::socks5_pw
&& proxy_type != proxy_settings::i2p_proxy))
{
if (m_ses.m_alerts.should_post<anonymous_mode_alert>())
{
m_ses.m_alerts.post_alert(
anonymous_mode_alert(get_handle()
, anonymous_mode_alert::tracker_not_anonymous, req.url));
}
continue;
}
}
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
(*m_ses.m_logger) << time_now_string() << " ==> TACKER REQUEST " << req.url (*m_ses.m_logger) << time_now_string() << " ==> TACKER REQUEST " << req.url
<< " event=" << (req.event==tracker_request::stopped?"stopped" << " event=" << (req.event==tracker_request::stopped?"stopped"

View File

@ -224,7 +224,7 @@ namespace libtorrent
request += " HTTP/1.1\r\n"; request += " HTTP/1.1\r\n";
request += "Host: "; request += "Host: ";
request += m_host; request += m_host;
if (m_first_request) if (m_first_request && !m_ses.settings().user_agent.empty())
{ {
request += "\r\nUser-Agent: "; request += "\r\nUser-Agent: ";
request += m_ses.settings().user_agent; request += m_ses.settings().user_agent;
@ -285,7 +285,7 @@ namespace libtorrent
request += " HTTP/1.1\r\n"; request += " HTTP/1.1\r\n";
request += "Host: "; request += "Host: ";
request += m_host; request += m_host;
if (m_first_request) if (m_first_request && !m_ses.settings().user_agent.empty())
{ {
request += "\r\nUser-Agent: "; request += "\r\nUser-Agent: ";
request += m_ses.settings().user_agent; request += m_ses.settings().user_agent;