fixes in DHT to make it work when the number of transaction slots are full (very rare case). Added a feature to (optionally) resolve the countries of peers and updated the docs (see peer_info::country).
This commit is contained in:
parent
c2a032be7a
commit
f14c84b01e
|
@ -1,3 +1,5 @@
|
|||
* Added the possibility to have libtorrent resolve the countries of
|
||||
the peers in torrents.
|
||||
* Improved the bandwidth limiter (it now implements a leaky bucket).
|
||||
* Improved the HTTP seed downloader to report accurate progress.
|
||||
* Added more client peer-id signatures to be recognized.
|
||||
|
|
276
docs/manual.html
276
docs/manual.html
|
@ -24,143 +24,144 @@
|
|||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title first"><a name="table-of-contents">Table of contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#overview" id="id15" name="id15">overview</a></li>
|
||||
<li><a class="reference" href="#primitive-network-types" id="id16" name="id16">primitive network types</a></li>
|
||||
<li><a class="reference" href="#session" id="id17" name="id17">session</a><ul>
|
||||
<li><a class="reference" href="#id1" id="id18" name="id18">session()</a></li>
|
||||
<li><a class="reference" href="#id2" id="id19" name="id19">~session()</a></li>
|
||||
<li><a class="reference" href="#abort" id="id20" name="id20">abort()</a></li>
|
||||
<li><a class="reference" href="#add-torrent" id="id21" name="id21">add_torrent()</a></li>
|
||||
<li><a class="reference" href="#remove-torrent-find-torrent-get-torrents" id="id22" name="id22">remove_torrent() find_torrent() get_torrents()</a></li>
|
||||
<li><a class="reference" href="#set-upload-rate-limit-set-download-rate-limit-upload-rate-limit-download-rate-limit" id="id23" name="id23">set_upload_rate_limit() set_download_rate_limit() upload_rate_limit() download_rate_limit()</a></li>
|
||||
<li><a class="reference" href="#set-max-uploads-set-max-connections" id="id24" name="id24">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#num-uploads-num-connections" id="id25" name="id25">num_uploads() num_connections()</a></li>
|
||||
<li><a class="reference" href="#set-max-half-open-connections" id="id26" name="id26">set_max_half_open_connections()</a></li>
|
||||
<li><a class="reference" href="#set-ip-filter" id="id27" name="id27">set_ip_filter()</a></li>
|
||||
<li><a class="reference" href="#status" id="id28" name="id28">status()</a></li>
|
||||
<li><a class="reference" href="#is-listening-listen-port-listen-on" id="id29" name="id29">is_listening() listen_port() listen_on()</a></li>
|
||||
<li><a class="reference" href="#pop-alert-set-severity-level" id="id30" name="id30">pop_alert() set_severity_level()</a></li>
|
||||
<li><a class="reference" href="#add-extension" id="id31" name="id31">add_extension()</a></li>
|
||||
<li><a class="reference" href="#start-dht-stop-dht-set-dht-settings-dht-state" id="id32" name="id32">start_dht() stop_dht() set_dht_settings() dht_state()</a></li>
|
||||
<li><a class="reference" href="#add-dht-node-add-dht-router" id="id33" name="id33">add_dht_node() add_dht_router()</a></li>
|
||||
<li><a class="reference" href="#overview" id="id16" name="id16">overview</a></li>
|
||||
<li><a class="reference" href="#primitive-network-types" id="id17" name="id17">primitive network types</a></li>
|
||||
<li><a class="reference" href="#session" id="id18" name="id18">session</a><ul>
|
||||
<li><a class="reference" href="#id1" id="id19" name="id19">session()</a></li>
|
||||
<li><a class="reference" href="#id2" id="id20" name="id20">~session()</a></li>
|
||||
<li><a class="reference" href="#abort" id="id21" name="id21">abort()</a></li>
|
||||
<li><a class="reference" href="#add-torrent" id="id22" name="id22">add_torrent()</a></li>
|
||||
<li><a class="reference" href="#remove-torrent-find-torrent-get-torrents" id="id23" name="id23">remove_torrent() find_torrent() get_torrents()</a></li>
|
||||
<li><a class="reference" href="#set-upload-rate-limit-set-download-rate-limit-upload-rate-limit-download-rate-limit" id="id24" name="id24">set_upload_rate_limit() set_download_rate_limit() upload_rate_limit() download_rate_limit()</a></li>
|
||||
<li><a class="reference" href="#set-max-uploads-set-max-connections" id="id25" name="id25">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#num-uploads-num-connections" id="id26" name="id26">num_uploads() num_connections()</a></li>
|
||||
<li><a class="reference" href="#set-max-half-open-connections" id="id27" name="id27">set_max_half_open_connections()</a></li>
|
||||
<li><a class="reference" href="#set-ip-filter" id="id28" name="id28">set_ip_filter()</a></li>
|
||||
<li><a class="reference" href="#status" id="id29" name="id29">status()</a></li>
|
||||
<li><a class="reference" href="#is-listening-listen-port-listen-on" id="id30" name="id30">is_listening() listen_port() listen_on()</a></li>
|
||||
<li><a class="reference" href="#pop-alert-set-severity-level" id="id31" name="id31">pop_alert() set_severity_level()</a></li>
|
||||
<li><a class="reference" href="#add-extension" id="id32" name="id32">add_extension()</a></li>
|
||||
<li><a class="reference" href="#start-dht-stop-dht-set-dht-settings-dht-state" id="id33" name="id33">start_dht() stop_dht() set_dht_settings() dht_state()</a></li>
|
||||
<li><a class="reference" href="#add-dht-node-add-dht-router" id="id34" name="id34">add_dht_node() add_dht_router()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#entry" id="id34" name="id34">entry</a><ul>
|
||||
<li><a class="reference" href="#integer-string-list-dict-type" id="id35" name="id35">integer() string() list() dict() type()</a></li>
|
||||
<li><a class="reference" href="#operator" id="id36" name="id36">operator[]</a></li>
|
||||
<li><a class="reference" href="#find-key" id="id37" name="id37">find_key()</a></li>
|
||||
<li><a class="reference" href="#entry" id="id35" name="id35">entry</a><ul>
|
||||
<li><a class="reference" href="#integer-string-list-dict-type" id="id36" name="id36">integer() string() list() dict() type()</a></li>
|
||||
<li><a class="reference" href="#operator" id="id37" name="id37">operator[]</a></li>
|
||||
<li><a class="reference" href="#find-key" id="id38" name="id38">find_key()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#torrent-info" id="id38" name="id38">torrent_info</a><ul>
|
||||
<li><a class="reference" href="#id3" id="id39" name="id39">torrent_info()</a></li>
|
||||
<li><a class="reference" href="#set-comment-set-piece-size-set-creator-set-hash-add-tracker-add-file" id="id40" name="id40">set_comment() set_piece_size() set_creator() set_hash() add_tracker() add_file()</a></li>
|
||||
<li><a class="reference" href="#create-torrent" id="id41" name="id41">create_torrent()</a></li>
|
||||
<li><a class="reference" href="#begin-files-end-files-rbegin-files-rend-files" id="id42" name="id42">begin_files() end_files() rbegin_files() rend_files()</a></li>
|
||||
<li><a class="reference" href="#num-files-file-at" id="id43" name="id43">num_files() file_at()</a></li>
|
||||
<li><a class="reference" href="#map-block" id="id44" name="id44">map_block()</a></li>
|
||||
<li><a class="reference" href="#map-file" id="id45" name="id45">map_file()</a></li>
|
||||
<li><a class="reference" href="#url-seeds" id="id46" name="id46">url_seeds()</a></li>
|
||||
<li><a class="reference" href="#print" id="id47" name="id47">print()</a></li>
|
||||
<li><a class="reference" href="#trackers" id="id48" name="id48">trackers()</a></li>
|
||||
<li><a class="reference" href="#total-size-piece-length-piece-size-num-pieces" id="id49" name="id49">total_size() piece_length() piece_size() num_pieces()</a></li>
|
||||
<li><a class="reference" href="#hash-for-piece-info-hash" id="id50" name="id50">hash_for_piece() info_hash()</a></li>
|
||||
<li><a class="reference" href="#name-comment-creation-date-creator" id="id51" name="id51">name() comment() creation_date() creator()</a></li>
|
||||
<li><a class="reference" href="#priv-set-priv" id="id52" name="id52">priv() set_priv()</a></li>
|
||||
<li><a class="reference" href="#nodes" id="id53" name="id53">nodes()</a></li>
|
||||
<li><a class="reference" href="#add-node" id="id54" name="id54">add_node()</a></li>
|
||||
<li><a class="reference" href="#torrent-info" id="id39" name="id39">torrent_info</a><ul>
|
||||
<li><a class="reference" href="#id3" id="id40" name="id40">torrent_info()</a></li>
|
||||
<li><a class="reference" href="#set-comment-set-piece-size-set-creator-set-hash-add-tracker-add-file" id="id41" name="id41">set_comment() set_piece_size() set_creator() set_hash() add_tracker() add_file()</a></li>
|
||||
<li><a class="reference" href="#create-torrent" id="id42" name="id42">create_torrent()</a></li>
|
||||
<li><a class="reference" href="#begin-files-end-files-rbegin-files-rend-files" id="id43" name="id43">begin_files() end_files() rbegin_files() rend_files()</a></li>
|
||||
<li><a class="reference" href="#num-files-file-at" id="id44" name="id44">num_files() file_at()</a></li>
|
||||
<li><a class="reference" href="#map-block" id="id45" name="id45">map_block()</a></li>
|
||||
<li><a class="reference" href="#map-file" id="id46" name="id46">map_file()</a></li>
|
||||
<li><a class="reference" href="#url-seeds" id="id47" name="id47">url_seeds()</a></li>
|
||||
<li><a class="reference" href="#print" id="id48" name="id48">print()</a></li>
|
||||
<li><a class="reference" href="#trackers" id="id49" name="id49">trackers()</a></li>
|
||||
<li><a class="reference" href="#total-size-piece-length-piece-size-num-pieces" id="id50" name="id50">total_size() piece_length() piece_size() num_pieces()</a></li>
|
||||
<li><a class="reference" href="#hash-for-piece-info-hash" id="id51" name="id51">hash_for_piece() info_hash()</a></li>
|
||||
<li><a class="reference" href="#name-comment-creation-date-creator" id="id52" name="id52">name() comment() creation_date() creator()</a></li>
|
||||
<li><a class="reference" href="#priv-set-priv" id="id53" name="id53">priv() set_priv()</a></li>
|
||||
<li><a class="reference" href="#nodes" id="id54" name="id54">nodes()</a></li>
|
||||
<li><a class="reference" href="#add-node" id="id55" name="id55">add_node()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#torrent-handle" id="id55" name="id55">torrent_handle</a><ul>
|
||||
<li><a class="reference" href="#file-progress" id="id56" name="id56">file_progress()</a></li>
|
||||
<li><a class="reference" href="#save-path" id="id57" name="id57">save_path()</a></li>
|
||||
<li><a class="reference" href="#move-storage" id="id58" name="id58">move_storage()</a></li>
|
||||
<li><a class="reference" href="#force-reannounce" id="id59" name="id59">force_reannounce()</a></li>
|
||||
<li><a class="reference" href="#connect-peer" id="id60" name="id60">connect_peer()</a></li>
|
||||
<li><a class="reference" href="#name" id="id61" name="id61">name()</a></li>
|
||||
<li><a class="reference" href="#set-ratio" id="id62" name="id62">set_ratio()</a></li>
|
||||
<li><a class="reference" href="#set-upload-limit-set-download-limit" id="id63" name="id63">set_upload_limit() set_download_limit()</a></li>
|
||||
<li><a class="reference" href="#set-sequenced-download-threshold" id="id64" name="id64">set_sequenced_download_threshold()</a></li>
|
||||
<li><a class="reference" href="#set-peer-upload-limit-set-peer-download-limit" id="id65" name="id65">set_peer_upload_limit() set_peer_download_limit()</a></li>
|
||||
<li><a class="reference" href="#pause-resume-is-paused" id="id66" name="id66">pause() resume() is_paused()</a></li>
|
||||
<li><a class="reference" href="#is-seed" id="id67" name="id67">is_seed()</a></li>
|
||||
<li><a class="reference" href="#has-metadata" id="id68" name="id68">has_metadata()</a></li>
|
||||
<li><a class="reference" href="#set-tracker-login" id="id69" name="id69">set_tracker_login()</a></li>
|
||||
<li><a class="reference" href="#trackers-replace-trackers" id="id70" name="id70">trackers() replace_trackers()</a></li>
|
||||
<li><a class="reference" href="#add-url-seed" id="id71" name="id71">add_url_seed()</a></li>
|
||||
<li><a class="reference" href="#use-interface" id="id72" name="id72">use_interface()</a></li>
|
||||
<li><a class="reference" href="#info-hash" id="id73" name="id73">info_hash()</a></li>
|
||||
<li><a class="reference" href="#id5" id="id74" name="id74">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#write-resume-data" id="id75" name="id75">write_resume_data()</a></li>
|
||||
<li><a class="reference" href="#id6" id="id76" name="id76">status()</a></li>
|
||||
<li><a class="reference" href="#get-download-queue" id="id77" name="id77">get_download_queue()</a></li>
|
||||
<li><a class="reference" href="#get-peer-info" id="id78" name="id78">get_peer_info()</a></li>
|
||||
<li><a class="reference" href="#get-torrent-info" id="id79" name="id79">get_torrent_info()</a></li>
|
||||
<li><a class="reference" href="#is-valid" id="id80" name="id80">is_valid()</a></li>
|
||||
<li><a class="reference" href="#torrent-handle" id="id56" name="id56">torrent_handle</a><ul>
|
||||
<li><a class="reference" href="#file-progress" id="id57" name="id57">file_progress()</a></li>
|
||||
<li><a class="reference" href="#save-path" id="id58" name="id58">save_path()</a></li>
|
||||
<li><a class="reference" href="#move-storage" id="id59" name="id59">move_storage()</a></li>
|
||||
<li><a class="reference" href="#force-reannounce" id="id60" name="id60">force_reannounce()</a></li>
|
||||
<li><a class="reference" href="#connect-peer" id="id61" name="id61">connect_peer()</a></li>
|
||||
<li><a class="reference" href="#name" id="id62" name="id62">name()</a></li>
|
||||
<li><a class="reference" href="#set-ratio" id="id63" name="id63">set_ratio()</a></li>
|
||||
<li><a class="reference" href="#set-upload-limit-set-download-limit" id="id64" name="id64">set_upload_limit() set_download_limit()</a></li>
|
||||
<li><a class="reference" href="#set-sequenced-download-threshold" id="id65" name="id65">set_sequenced_download_threshold()</a></li>
|
||||
<li><a class="reference" href="#set-peer-upload-limit-set-peer-download-limit" id="id66" name="id66">set_peer_upload_limit() set_peer_download_limit()</a></li>
|
||||
<li><a class="reference" href="#pause-resume-is-paused" id="id67" name="id67">pause() resume() is_paused()</a></li>
|
||||
<li><a class="reference" href="#resolve-countries" id="id68" name="id68">resolve_countries()</a></li>
|
||||
<li><a class="reference" href="#is-seed" id="id69" name="id69">is_seed()</a></li>
|
||||
<li><a class="reference" href="#has-metadata" id="id70" name="id70">has_metadata()</a></li>
|
||||
<li><a class="reference" href="#set-tracker-login" id="id71" name="id71">set_tracker_login()</a></li>
|
||||
<li><a class="reference" href="#trackers-replace-trackers" id="id72" name="id72">trackers() replace_trackers()</a></li>
|
||||
<li><a class="reference" href="#add-url-seed" id="id73" name="id73">add_url_seed()</a></li>
|
||||
<li><a class="reference" href="#use-interface" id="id74" name="id74">use_interface()</a></li>
|
||||
<li><a class="reference" href="#info-hash" id="id75" name="id75">info_hash()</a></li>
|
||||
<li><a class="reference" href="#id5" id="id76" name="id76">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#write-resume-data" id="id77" name="id77">write_resume_data()</a></li>
|
||||
<li><a class="reference" href="#id6" id="id78" name="id78">status()</a></li>
|
||||
<li><a class="reference" href="#get-download-queue" id="id79" name="id79">get_download_queue()</a></li>
|
||||
<li><a class="reference" href="#get-peer-info" id="id80" name="id80">get_peer_info()</a></li>
|
||||
<li><a class="reference" href="#get-torrent-info" id="id81" name="id81">get_torrent_info()</a></li>
|
||||
<li><a class="reference" href="#is-valid" id="id82" name="id82">is_valid()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#torrent-status" id="id81" name="id81">torrent_status</a></li>
|
||||
<li><a class="reference" href="#peer-info" id="id82" name="id82">peer_info</a></li>
|
||||
<li><a class="reference" href="#session-settings" id="id83" name="id83">session_settings</a></li>
|
||||
<li><a class="reference" href="#ip-filter" id="id84" name="id84">ip_filter</a><ul>
|
||||
<li><a class="reference" href="#id8" id="id85" name="id85">ip_filter()</a></li>
|
||||
<li><a class="reference" href="#add-rule" id="id86" name="id86">add_rule()</a></li>
|
||||
<li><a class="reference" href="#access" id="id87" name="id87">access()</a></li>
|
||||
<li><a class="reference" href="#export-filter" id="id88" name="id88">export_filter()</a></li>
|
||||
<li><a class="reference" href="#torrent-status" id="id83" name="id83">torrent_status</a></li>
|
||||
<li><a class="reference" href="#peer-info" id="id84" name="id84">peer_info</a></li>
|
||||
<li><a class="reference" href="#session-settings" id="id85" name="id85">session_settings</a></li>
|
||||
<li><a class="reference" href="#ip-filter" id="id86" name="id86">ip_filter</a><ul>
|
||||
<li><a class="reference" href="#id9" id="id87" name="id87">ip_filter()</a></li>
|
||||
<li><a class="reference" href="#add-rule" id="id88" name="id88">add_rule()</a></li>
|
||||
<li><a class="reference" href="#access" id="id89" name="id89">access()</a></li>
|
||||
<li><a class="reference" href="#export-filter" id="id90" name="id90">export_filter()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#big-number" id="id89" name="id89">big_number</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id90" name="id90">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id91" name="id91">fingerprint</a></li>
|
||||
<li><a class="reference" href="#free-functions" id="id92" name="id92">free functions</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id93" name="id93">identify_client()</a></li>
|
||||
<li><a class="reference" href="#client-fingerprint" id="id94" name="id94">client_fingerprint()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id95" name="id95">bdecode() bencode()</a></li>
|
||||
<li><a class="reference" href="#big-number" id="id91" name="id91">big_number</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id92" name="id92">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id93" name="id93">fingerprint</a></li>
|
||||
<li><a class="reference" href="#free-functions" id="id94" name="id94">free functions</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id95" name="id95">identify_client()</a></li>
|
||||
<li><a class="reference" href="#client-fingerprint" id="id96" name="id96">client_fingerprint()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id97" name="id97">bdecode() bencode()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#alerts" id="id96" name="id96">alerts</a><ul>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id97" name="id97">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id98" name="id98">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id99" name="id99">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id100" name="id100">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id101" name="id101">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id102" name="id102">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id103" name="id103">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id104" name="id104">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id105" name="id105">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id106" name="id106">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id107" name="id107">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id108" name="id108">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id109" name="id109">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id110" name="id110">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id111" name="id111">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id112" name="id112">dispatcher</a></li>
|
||||
<li><a class="reference" href="#alerts" id="id98" name="id98">alerts</a><ul>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id99" name="id99">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id100" name="id100">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id101" name="id101">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id102" name="id102">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id103" name="id103">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id104" name="id104">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id105" name="id105">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id106" name="id106">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id107" name="id107">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id108" name="id108">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id109" name="id109">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id110" name="id110">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id111" name="id111">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id112" name="id112">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id113" name="id113">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id114" name="id114">dispatcher</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#exceptions" id="id113" name="id113">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id114" name="id114">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id115" name="id115">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id116" name="id116">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id117" name="id117">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id118" name="id118">invalid_torrent_file</a></li>
|
||||
<li><a class="reference" href="#exceptions" id="id115" name="id115">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id116" name="id116">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id117" name="id117">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id118" name="id118">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id119" name="id119">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id120" name="id120">invalid_torrent_file</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#fast-resume" id="id119" name="id119">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id120" name="id120">file format</a></li>
|
||||
<li><a class="reference" href="#fast-resume" id="id121" name="id121">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id122" name="id122">file format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#threads" id="id121" name="id121">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id122" name="id122">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#full-allocation" id="id123" name="id123">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id124" name="id124">compact allocation</a></li>
|
||||
<li><a class="reference" href="#threads" id="id123" name="id123">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id124" name="id124">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#full-allocation" id="id125" name="id125">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id126" name="id126">compact allocation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#extensions" id="id125" name="id125">extensions</a><ul>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id126" name="id126">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id127" name="id127">HTTP seeding</a></li>
|
||||
<li><a class="reference" href="#extensions" id="id127" name="id127">extensions</a><ul>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id128" name="id128">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id129" name="id129">HTTP seeding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#filename-checks" id="id128" name="id128">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgments" id="id129" name="id129">acknowledgments</a></li>
|
||||
<li><a class="reference" href="#filename-checks" id="id130" name="id130">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgments" id="id131" name="id131">acknowledgments</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
|
@ -1247,6 +1248,9 @@ struct torrent_handle
|
|||
bool is_paused() const;
|
||||
bool is_seed() const;
|
||||
|
||||
void resolve_countries(bool r);
|
||||
bool resolve_countries() const;
|
||||
|
||||
void filter_piece(int index, bool filter) const;
|
||||
void filter_pieces(std::vector<bool> const& bitmask) const;
|
||||
bool is_piece_filtered(int index) const;
|
||||
|
@ -1423,6 +1427,19 @@ is currently paused. Torrents may be paused automatically if there is a file err
|
|||
or something similar. See <a class="reference" href="#file-error-alert">file_error_alert</a>.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="resolve-countries" name="resolve-countries">resolve_countries()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
void resolve_countries(bool r);
|
||||
bool resolve_countries() const;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Sets or gets the flag that derermines if countries should be resolved for the peers of this
|
||||
torrent. It defaults to false. If it is set to true, the <a class="reference" href="#peer-info">peer_info</a> structure for the peers
|
||||
in this torrent will have their <tt class="docutils literal"><span class="pre">country</span></tt> member set. See <a class="reference" href="#peer-info">peer_info</a> for more information
|
||||
on how to interpret this field.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="is-seed" name="is-seed">is_seed()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
|
@ -1837,6 +1854,8 @@ struct peer_info
|
|||
int upload_limit;
|
||||
int download_limit;
|
||||
|
||||
char country[2];
|
||||
|
||||
size_type load_balancing;
|
||||
|
||||
int download_queue_length;
|
||||
|
@ -1925,6 +1944,12 @@ peer every second. It may be -1 if there's no local limit on the peer. The globa
|
|||
limit and the torrent limit is always enforced anyway.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">download_limit</span></tt> is the number of bytes per second this peer is allowed to
|
||||
receive. -1 means it's unlimited.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">country</span></tt> is the two letter <a class="reference" href="http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166 country code</a> for the country the peer
|
||||
is connected from. If the country hasn't been resolved yet, both chars are set
|
||||
to 0. If the resolution failed for some reason, the field is set to "--". If the
|
||||
resolution service returns an invalid country code, it is set to "!!".
|
||||
The <tt class="docutils literal"><span class="pre">countries.nerd.dk</span></tt> service is used to look up countries. This field will
|
||||
remain set to 0 unless the torrent is set to resolve countries, see <a class="reference" href="#resolve-countries">resolve_countries()</a>.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">load_balancing</span></tt> is a measurement of the balancing of free download (that we get)
|
||||
and free upload that we give. Every peer gets a certain amount of free upload, but
|
||||
this member says how much <em>extra</em> free upload this peer has got. If it is a negative
|
||||
|
@ -2088,7 +2113,7 @@ public:
|
|||
</pre>
|
||||
</blockquote>
|
||||
<div class="section">
|
||||
<h2><a id="id8" name="id8">ip_filter()</a></h2>
|
||||
<h2><a id="id9" name="id9">ip_filter()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
ip_filter()
|
||||
|
@ -2975,25 +3000,6 @@ length-prefix, message-id nor extension-id).</p>
|
|||
handshake, it may be incompatible with future versions of the mainline
|
||||
bittorrent client.</p>
|
||||
<p>These are the extensions that are currently implemented.</p>
|
||||
<!-- chat messages
|
||||
- - - - - - - - - - - - -
|
||||
|
||||
Extension name: "chat"
|
||||
|
||||
The payload in the packet is a bencoded dictionary with any
|
||||
combination of the following entries:
|
||||
|
||||
+- - - - - - - - - -+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
|
||||
| "msg" | This is a string that contains a message that |
|
||||
| | should be displayed to the user. |
|
||||
+- - - - - - - - - -+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
|
||||
| "ctrl" | This is a control string that can tell a client that |
|
||||
| | it is ignored (to make the user aware of that) and |
|
||||
| | it can also tell a client that it is no longer ignored.|
|
||||
| | These notifications are encoded as the strings: |
|
||||
| | "ignored" and "not ignored". |
|
||||
| | Any unrecognized strings should be ignored. |
|
||||
+- - - - - - - - - -+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ -->
|
||||
<div class="section">
|
||||
<h2><a id="metadata-from-peers" name="metadata-from-peers">metadata from peers</a></h2>
|
||||
<p>Extension name: "LT_metadata"</p>
|
||||
|
|
|
@ -1194,6 +1194,9 @@ Its declaration looks like this::
|
|||
bool is_paused() const;
|
||||
bool is_seed() const;
|
||||
|
||||
void resolve_countries(bool r);
|
||||
bool resolve_countries() const;
|
||||
|
||||
void filter_piece(int index, bool filter) const;
|
||||
void filter_pieces(std::vector<bool> const& bitmask) const;
|
||||
bool is_piece_filtered(int index) const;
|
||||
|
@ -1379,6 +1382,19 @@ all potential (not connected) peers. You can use ``is_paused()`` to determine if
|
|||
is currently paused. Torrents may be paused automatically if there is a file error (e.g. disk full)
|
||||
or something similar. See file_error_alert_.
|
||||
|
||||
resolve_countries()
|
||||
-------------------
|
||||
|
||||
::
|
||||
|
||||
void resolve_countries(bool r);
|
||||
bool resolve_countries() const;
|
||||
|
||||
Sets or gets the flag that derermines if countries should be resolved for the peers of this
|
||||
torrent. It defaults to false. If it is set to true, the peer_info_ structure for the peers
|
||||
in this torrent will have their ``country`` member set. See peer_info_ for more information
|
||||
on how to interpret this field.
|
||||
|
||||
is_seed()
|
||||
---------
|
||||
|
||||
|
@ -1820,6 +1836,8 @@ It contains the following fields::
|
|||
int upload_limit;
|
||||
int download_limit;
|
||||
|
||||
char country[2];
|
||||
|
||||
size_type load_balancing;
|
||||
|
||||
int download_queue_length;
|
||||
|
@ -1906,6 +1924,15 @@ limit and the torrent limit is always enforced anyway.
|
|||
``download_limit`` is the number of bytes per second this peer is allowed to
|
||||
receive. -1 means it's unlimited.
|
||||
|
||||
``country`` is the two letter `ISO 3166 country code`__ for the country the peer
|
||||
is connected from. If the country hasn't been resolved yet, both chars are set
|
||||
to 0. If the resolution failed for some reason, the field is set to "--". If the
|
||||
resolution service returns an invalid country code, it is set to "!!".
|
||||
The ``countries.nerd.dk`` service is used to look up countries. This field will
|
||||
remain set to 0 unless the torrent is set to resolve countries, see `resolve_countries()`_.
|
||||
|
||||
__ http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html
|
||||
|
||||
``load_balancing`` is a measurement of the balancing of free download (that we get)
|
||||
and free upload that we give. Every peer gets a certain amount of free upload, but
|
||||
this member says how much *extra* free upload this peer has got. If it is a negative
|
||||
|
@ -3066,26 +3093,6 @@ bittorrent client.
|
|||
|
||||
These are the extensions that are currently implemented.
|
||||
|
||||
.. chat messages
|
||||
-------------
|
||||
|
||||
Extension name: "chat"
|
||||
|
||||
The payload in the packet is a bencoded dictionary with any
|
||||
combination of the following entries:
|
||||
|
||||
+----------+--------------------------------------------------------+
|
||||
| "msg" | This is a string that contains a message that |
|
||||
| | should be displayed to the user. |
|
||||
+----------+--------------------------------------------------------+
|
||||
| "ctrl" | This is a control string that can tell a client that |
|
||||
| | it is ignored (to make the user aware of that) and |
|
||||
| | it can also tell a client that it is no longer ignored.|
|
||||
| | These notifications are encoded as the strings: |
|
||||
| | "ignored" and "not ignored". |
|
||||
| | Any unrecognized strings should be ignored. |
|
||||
+----------+--------------------------------------------------------+
|
||||
|
||||
metadata from peers
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -243,8 +243,9 @@ int peer_index(libtorrent::tcp::endpoint addr, std::vector<libtorrent::peer_info
|
|||
void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const& peers)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
out << " down (total) up (total) q r flags block progress client \n";
|
||||
#ifndef ANSI_TERMINAL_COLORS
|
||||
out << " down (total) up (total) q r flags block progress country client \n";
|
||||
#endif
|
||||
|
||||
for (std::vector<peer_info>::const_iterator i = peers.begin();
|
||||
i != peers.end(); ++i)
|
||||
|
@ -274,6 +275,15 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
|
|||
out << progress_bar(0.f, 15);
|
||||
}
|
||||
|
||||
if (i->country[0] == 0)
|
||||
{
|
||||
out << " ..";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << " " << i->country[0] << i->country[1];
|
||||
}
|
||||
|
||||
if (i->flags & peer_info::handshake)
|
||||
{
|
||||
out << esc("31") << " waiting for handshake" << esc("0") << "\n";
|
||||
|
@ -350,6 +360,7 @@ void add_torrent(libtorrent::session& ses
|
|||
h.set_max_uploads(-1);
|
||||
h.set_ratio(preferred_ratio);
|
||||
h.set_sequenced_download_threshold(15);
|
||||
h.resolve_countries(true);
|
||||
}
|
||||
catch (std::exception&) {};
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <deque>
|
||||
|
||||
namespace pt = boost::posix_time;
|
||||
|
@ -157,12 +158,14 @@ struct bandwidth_manager
|
|||
|
||||
void throttle(int limit)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
assert(limit >= 0);
|
||||
m_limit = limit;
|
||||
}
|
||||
|
||||
int throttle() const
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
return m_limit;
|
||||
}
|
||||
|
||||
|
@ -181,6 +184,9 @@ private:
|
|||
void on_history_expire(asio::error_code const& e);
|
||||
void hand_out_bandwidth();
|
||||
|
||||
typedef boost::mutex mutex_t;
|
||||
mutable mutex_t m_mutex;
|
||||
|
||||
// the io_service used for the timer
|
||||
io_service& m_ios;
|
||||
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace libtorrent
|
|||
, std::size_t bytes_transferred);
|
||||
|
||||
virtual void get_peer_info(peer_info& p) const;
|
||||
virtual bool in_handshake() const;
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
bool support_extensions() const { return m_supports_extensions; }
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
);
|
||||
|
||||
void ping_reply(node_id id);
|
||||
void ping_timeout(node_id id);
|
||||
void ping_timeout(node_id id, bool prevent_request = false);
|
||||
|
||||
private:
|
||||
template<class InIt>
|
||||
|
@ -88,7 +88,7 @@ private:
|
|||
void done();
|
||||
void invoke(node_id const& id, udp::endpoint addr);
|
||||
|
||||
void invoke_pings_or_finish();
|
||||
void invoke_pings_or_finish(bool prevent_request = false);
|
||||
|
||||
int m_max_active_pings;
|
||||
int m_active_pings;
|
||||
|
|
|
@ -128,6 +128,12 @@ struct observer : boost::noncopyable
|
|||
// this is called when no reply has been received within
|
||||
// some timeout
|
||||
virtual void timeout() = 0;
|
||||
|
||||
// if this is called the destructor should
|
||||
// not invoke any new messages, and should
|
||||
// only clean up. It means the rpc-manager
|
||||
// is being destructed
|
||||
virtual void abort() = 0;
|
||||
|
||||
udp::endpoint target_addr;
|
||||
boost::posix_time::ptime sent;
|
||||
|
@ -162,7 +168,8 @@ public:
|
|||
private:
|
||||
|
||||
enum { max_transactions = 2048 };
|
||||
unsigned int new_transaction_id();
|
||||
|
||||
unsigned int new_transaction_id(boost::shared_ptr<observer> o);
|
||||
void update_oldest_transaction_id();
|
||||
|
||||
boost::uint32_t calc_connection_id(udp::endpoint addr);
|
||||
|
@ -170,6 +177,7 @@ private:
|
|||
typedef boost::array<boost::shared_ptr<observer>, max_transactions>
|
||||
transactions_t;
|
||||
transactions_t m_transactions;
|
||||
std::vector<boost::shared_ptr<observer> > m_aborted_transactions;
|
||||
|
||||
// this is the next transaction id to be used
|
||||
int m_next_transaction_id;
|
||||
|
@ -185,6 +193,7 @@ private:
|
|||
routing_table& m_table;
|
||||
boost::posix_time::ptime m_timer;
|
||||
node_id m_random_number;
|
||||
bool m_destructing;
|
||||
};
|
||||
|
||||
} } // namespace libtorrent::dht
|
||||
|
|
|
@ -58,7 +58,7 @@ class traversal_algorithm : boost::noncopyable
|
|||
public:
|
||||
void traverse(node_id const& id, udp::endpoint addr);
|
||||
void finished(node_id const& id);
|
||||
void failed(node_id const& id);
|
||||
void failed(node_id const& id, bool prevent_request = false);
|
||||
virtual ~traversal_algorithm() {}
|
||||
|
||||
protected:
|
||||
|
@ -73,7 +73,6 @@ protected:
|
|||
, InIt end
|
||||
);
|
||||
|
||||
void add_request(node_id const& id, udp::endpoint addr);
|
||||
void add_requests();
|
||||
void add_entry(node_id const& id, udp::endpoint addr, unsigned char flags);
|
||||
|
||||
|
|
|
@ -308,6 +308,10 @@ namespace libtorrent
|
|||
|
||||
virtual void get_peer_info(peer_info& p) const = 0;
|
||||
|
||||
// is true until we can be sure that the other end
|
||||
// speaks our protocol (be it bittorrent or http).
|
||||
virtual bool in_handshake() const = 0;
|
||||
|
||||
// returns the block currently being
|
||||
// downloaded. And the progress of that
|
||||
// block. If the peer isn't downloading
|
||||
|
@ -326,6 +330,14 @@ namespace libtorrent
|
|||
buffer::interval allocate_send_buffer(int size);
|
||||
void setup_send();
|
||||
|
||||
void set_country(char const* c)
|
||||
{
|
||||
assert(strlen(c) == 2);
|
||||
m_country[0] = c[0];
|
||||
m_country[1] = c[1];
|
||||
}
|
||||
bool has_country() const { return m_country[0] != 0; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void write_choke() = 0;
|
||||
|
@ -414,6 +426,12 @@ namespace libtorrent
|
|||
extension_list_t m_extensions;
|
||||
#endif
|
||||
|
||||
// in case the session settings is set
|
||||
// to resolve countries, this is set to
|
||||
// the two character country code this
|
||||
// peer resides in.
|
||||
char m_country[2];
|
||||
|
||||
private:
|
||||
|
||||
void fill_send_buffer();
|
||||
|
|
|
@ -69,6 +69,12 @@ namespace libtorrent
|
|||
bool seed; // true if this is a seed
|
||||
int upload_limit;
|
||||
int download_limit;
|
||||
|
||||
// in case the session settings is set
|
||||
// to resolve countries, this is set to
|
||||
// the two character country code this
|
||||
// peer resides in.
|
||||
char country[2];
|
||||
|
||||
size_type load_balancing;
|
||||
|
||||
|
|
|
@ -190,6 +190,11 @@ namespace libtorrent
|
|||
float ratio() const
|
||||
{ return m_ratio; }
|
||||
|
||||
void resolve_countries(bool r)
|
||||
{ m_resolve_countries = r; }
|
||||
|
||||
bool resolving_countries() const { return m_resolve_countries; }
|
||||
|
||||
// --------------------------------------------
|
||||
// BANDWIDTH MANAGEMENT
|
||||
|
||||
|
@ -242,6 +247,7 @@ namespace libtorrent
|
|||
peer_iterator begin() { return m_connections.begin(); }
|
||||
peer_iterator end() { return m_connections.end(); }
|
||||
|
||||
void resolve_peer_country(boost::intrusive_ptr<peer_connection> const& p) const;
|
||||
|
||||
// --------------------------------------------
|
||||
// TRACKER MANAGEMENT
|
||||
|
@ -457,6 +463,8 @@ namespace libtorrent
|
|||
|
||||
void try_next_tracker();
|
||||
int prioritize_tracker(int tracker_index);
|
||||
void on_country_lookup(asio::error_code const& error, tcp::resolver::iterator i
|
||||
, boost::intrusive_ptr<peer_connection> p) const;
|
||||
|
||||
torrent_info m_torrent_file;
|
||||
|
||||
|
@ -516,8 +524,18 @@ namespace libtorrent
|
|||
std::set<std::string> m_resolving_web_seeds;
|
||||
|
||||
// used to resolve the names of web seeds
|
||||
tcp::resolver m_host_resolver;
|
||||
mutable tcp::resolver m_host_resolver;
|
||||
|
||||
// this is true while there is a country
|
||||
// resolution in progress. To avoid flodding
|
||||
// the DNS request queue, only one ip is reolved
|
||||
// at a time.
|
||||
mutable bool m_resolving_country;
|
||||
|
||||
// this is true if the user has enabled
|
||||
// country resolution in this torrent
|
||||
bool m_resolve_countries;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
||||
, std::vector<tcp::endpoint> const& peers);
|
||||
|
|
|
@ -243,6 +243,9 @@ namespace libtorrent
|
|||
bool is_paused() const;
|
||||
void pause() const;
|
||||
void resume() const;
|
||||
|
||||
void resolve_countries(bool r);
|
||||
bool resolve_countries() const;
|
||||
|
||||
// marks the piece with the given index as filtered
|
||||
// it will not be downloaded
|
||||
|
|
|
@ -112,7 +112,8 @@ namespace libtorrent
|
|||
std::string const& url() const { return m_url; }
|
||||
|
||||
virtual void get_peer_info(peer_info& p) const;
|
||||
|
||||
virtual bool in_handshake() const;
|
||||
|
||||
// the following functions appends messages
|
||||
// to the send buffer
|
||||
void write_choke() {}
|
||||
|
|
|
@ -60,6 +60,9 @@ namespace libtorrent
|
|||
void bandwidth_manager::request_bandwidth(intrusive_ptr<peer_connection> peer)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
// make sure this peer isn't already in line
|
||||
// waiting for bandwidth
|
||||
#ifndef NDEBUG
|
||||
|
@ -115,6 +118,8 @@ namespace libtorrent
|
|||
|
||||
if (e) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
#if defined TORRENT_LOGGING || defined TORRENT_VERBOSE_LOGGING
|
||||
// (*m_ses->m_logger) << "bw expire [" << m_channel << "]\n";
|
||||
#endif
|
||||
|
@ -187,6 +192,11 @@ namespace libtorrent
|
|||
// send. If the peer was added to the queue while the data was
|
||||
// still being sent, max_assignable may have been > 0 at that time.
|
||||
int max_assignable = peer->max_assignable_bandwidth(m_channel);
|
||||
if (max_assignable == 0)
|
||||
{
|
||||
t->expire_bandwidth(m_channel, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// so, hand out max_assignable, but no more than
|
||||
// the available bandwidth (amount) and no more
|
||||
|
@ -194,8 +204,9 @@ namespace libtorrent
|
|||
int single_amount = std::min(amount
|
||||
, std::min(bandwidth_block_size_limit
|
||||
, max_assignable));
|
||||
assert(single_amount > 0);
|
||||
amount -= single_amount;
|
||||
if (single_amount > 0) peer->assign_bandwidth(m_channel, single_amount);
|
||||
peer->assign_bandwidth(m_channel, single_amount);
|
||||
t->assign_bandwidth(m_channel, single_amount);
|
||||
add_history_entry(history_entry(peer, t, single_amount, now + window_size));
|
||||
}
|
||||
|
|
|
@ -182,6 +182,9 @@ namespace libtorrent
|
|||
p.payload_up_speed = statistics().upload_payload_rate();
|
||||
p.pid = pid();
|
||||
p.ip = remote();
|
||||
|
||||
p.country[0] = m_country[0];
|
||||
p.country[1] = m_country[1];
|
||||
|
||||
p.total_download = statistics().total_payload_download();
|
||||
p.total_upload = statistics().total_payload_upload();
|
||||
|
@ -234,6 +237,11 @@ namespace libtorrent
|
|||
p.client = m_client_version;
|
||||
p.connection_type = peer_info::standard_bittorrent;
|
||||
}
|
||||
|
||||
bool bt_peer_connection::in_handshake() const
|
||||
{
|
||||
return m_state < read_packet_size;
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_handshake()
|
||||
{
|
||||
|
@ -1146,8 +1154,9 @@ namespace libtorrent
|
|||
, recv_buffer.end) << "'\n";
|
||||
#endif
|
||||
const char protocol_string[] = "BitTorrent protocol";
|
||||
if (!std::equal(recv_buffer.begin, recv_buffer.end
|
||||
, protocol_string))
|
||||
if (recv_buffer.end - recv_buffer.begin != 19
|
||||
|| !std::equal(recv_buffer.begin, recv_buffer.end
|
||||
, protocol_string))
|
||||
{
|
||||
const char cmd[] = "version";
|
||||
if (recv_buffer.end - recv_buffer.begin == 7 && std::equal(
|
||||
|
|
|
@ -47,12 +47,12 @@ public:
|
|||
closest_nodes_observer(
|
||||
boost::intrusive_ptr<traversal_algorithm> const& algorithm
|
||||
, node_id self
|
||||
, node_id target
|
||||
)
|
||||
, node_id target)
|
||||
: m_algorithm(algorithm)
|
||||
, m_target(target)
|
||||
, m_self(self)
|
||||
{}
|
||||
~closest_nodes_observer();
|
||||
|
||||
void send(msg& p)
|
||||
{
|
||||
|
@ -61,6 +61,7 @@ public:
|
|||
|
||||
void timeout();
|
||||
void reply(msg const&);
|
||||
void abort() { m_algorithm = 0; }
|
||||
|
||||
private:
|
||||
boost::intrusive_ptr<traversal_algorithm> m_algorithm;
|
||||
|
@ -68,8 +69,19 @@ private:
|
|||
node_id const m_self;
|
||||
};
|
||||
|
||||
closest_nodes_observer::~closest_nodes_observer()
|
||||
{
|
||||
if (m_algorithm) m_algorithm->failed(m_self, true);
|
||||
}
|
||||
|
||||
void closest_nodes_observer::reply(msg const& in)
|
||||
{
|
||||
if (!m_algorithm)
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in.nodes.empty())
|
||||
{
|
||||
for (msg::nodes_t::const_iterator i = in.nodes.begin()
|
||||
|
@ -79,11 +91,14 @@ void closest_nodes_observer::reply(msg const& in)
|
|||
}
|
||||
}
|
||||
m_algorithm->finished(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
void closest_nodes_observer::timeout()
|
||||
{
|
||||
if (!m_algorithm) return;
|
||||
m_algorithm->failed(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
, m_target(target)
|
||||
, m_self(self)
|
||||
{}
|
||||
~find_data_observer();
|
||||
|
||||
void send(msg& m)
|
||||
{
|
||||
|
@ -61,6 +62,7 @@ public:
|
|||
|
||||
void timeout();
|
||||
void reply(msg const&);
|
||||
void abort() { m_algorithm = 0; }
|
||||
|
||||
private:
|
||||
boost::intrusive_ptr<find_data> m_algorithm;
|
||||
|
@ -68,8 +70,19 @@ private:
|
|||
node_id const m_self;
|
||||
};
|
||||
|
||||
find_data_observer::~find_data_observer()
|
||||
{
|
||||
if (m_algorithm) m_algorithm->failed(m_self);
|
||||
}
|
||||
|
||||
void find_data_observer::reply(msg const& m)
|
||||
{
|
||||
if (!m_algorithm)
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m.peers.empty())
|
||||
{
|
||||
m_algorithm->got_data(&m);
|
||||
|
@ -83,11 +96,14 @@ void find_data_observer::reply(msg const& m)
|
|||
}
|
||||
}
|
||||
m_algorithm->finished(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
void find_data_observer::timeout()
|
||||
{
|
||||
if (!m_algorithm) return;
|
||||
m_algorithm->failed(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ namespace
|
|||
|
||||
void timeout() {}
|
||||
void reply(msg const&) {}
|
||||
void abort() {}
|
||||
|
||||
private:
|
||||
sha1_hash m_info_hash;
|
||||
|
@ -311,6 +312,7 @@ namespace
|
|||
new announce_observer(m_info_hash, m_listen_port, r.write_token)));
|
||||
m_fun(r.peers, m_info_hash);
|
||||
}
|
||||
void abort() {}
|
||||
|
||||
private:
|
||||
sha1_hash m_info_hash;
|
||||
|
@ -344,6 +346,7 @@ namespace
|
|||
virtual void reply(msg const&) {}
|
||||
virtual void timeout() {}
|
||||
virtual void send(msg&) {}
|
||||
virtual void abort() {}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
, m_self(self)
|
||||
, m_algorithm(algorithm)
|
||||
{}
|
||||
~refresh_observer();
|
||||
|
||||
void send(msg& m)
|
||||
{
|
||||
|
@ -72,6 +73,8 @@ public:
|
|||
|
||||
void timeout();
|
||||
void reply(msg const& m);
|
||||
void abort() { m_algorithm = 0; }
|
||||
|
||||
|
||||
private:
|
||||
node_id const m_target;
|
||||
|
@ -79,8 +82,15 @@ private:
|
|||
boost::intrusive_ptr<refresh> m_algorithm;
|
||||
};
|
||||
|
||||
refresh_observer::~refresh_observer()
|
||||
{
|
||||
if (m_algorithm) m_algorithm->failed(m_self, true);
|
||||
}
|
||||
|
||||
void refresh_observer::reply(msg const& in)
|
||||
{
|
||||
if (!m_algorithm) return;
|
||||
|
||||
if (!in.nodes.empty())
|
||||
{
|
||||
for (msg::nodes_t::const_iterator i = in.nodes.begin()
|
||||
|
@ -90,11 +100,14 @@ void refresh_observer::reply(msg const& in)
|
|||
}
|
||||
}
|
||||
m_algorithm->finished(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
void refresh_observer::timeout()
|
||||
{
|
||||
if (!m_algorithm) return;
|
||||
m_algorithm->failed(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
class ping_observer : public observer
|
||||
|
@ -107,24 +120,37 @@ public:
|
|||
: m_self(self)
|
||||
, m_algorithm(algorithm)
|
||||
{}
|
||||
~ping_observer();
|
||||
|
||||
void send(msg& p) {}
|
||||
void timeout();
|
||||
void reply(msg const& m);
|
||||
void abort() { m_algorithm = 0; }
|
||||
|
||||
|
||||
private:
|
||||
node_id const m_self;
|
||||
boost::intrusive_ptr<refresh> m_algorithm;
|
||||
};
|
||||
|
||||
ping_observer::~ping_observer()
|
||||
{
|
||||
if (m_algorithm) m_algorithm->ping_timeout(m_self, true);
|
||||
}
|
||||
|
||||
void ping_observer::reply(msg const& m)
|
||||
{
|
||||
if (!m_algorithm) return;
|
||||
|
||||
m_algorithm->ping_reply(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
void ping_observer::timeout()
|
||||
{
|
||||
if (!m_algorithm) return;
|
||||
m_algorithm->ping_timeout(m_self);
|
||||
m_algorithm = 0;
|
||||
}
|
||||
|
||||
void refresh::invoke(node_id const& nid, udp::endpoint addr)
|
||||
|
@ -152,32 +178,44 @@ void refresh::ping_reply(node_id nid)
|
|||
invoke_pings_or_finish();
|
||||
}
|
||||
|
||||
void refresh::ping_timeout(node_id nid)
|
||||
void refresh::ping_timeout(node_id nid, bool prevent_request)
|
||||
{
|
||||
m_active_pings--;
|
||||
invoke_pings_or_finish();
|
||||
invoke_pings_or_finish(prevent_request);
|
||||
}
|
||||
|
||||
void refresh::invoke_pings_or_finish()
|
||||
void refresh::invoke_pings_or_finish(bool prevent_request)
|
||||
{
|
||||
while (m_active_pings < m_max_active_pings)
|
||||
if (prevent_request)
|
||||
{
|
||||
if (m_leftover_nodes_iterator == m_results.end()) break;
|
||||
|
||||
result const& node = *m_leftover_nodes_iterator;
|
||||
|
||||
// Skip initial nodes
|
||||
if (node.flags & result::initial)
|
||||
--m_max_active_pings;
|
||||
if (m_max_active_pings <= 0)
|
||||
m_max_active_pings = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (m_active_pings < m_max_active_pings)
|
||||
{
|
||||
++m_leftover_nodes_iterator;
|
||||
continue;
|
||||
if (m_leftover_nodes_iterator == m_results.end()) break;
|
||||
|
||||
result const& node = *m_leftover_nodes_iterator;
|
||||
|
||||
// Skip initial nodes
|
||||
if (node.flags & result::initial)
|
||||
{
|
||||
++m_leftover_nodes_iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
observer_ptr p(new ping_observer(this, node.id));
|
||||
m_rpc.invoke(messages::ping, node.addr, p);
|
||||
++m_active_pings;
|
||||
++m_leftover_nodes_iterator;
|
||||
}
|
||||
catch (std::exception& e) {}
|
||||
}
|
||||
|
||||
observer_ptr p(new ping_observer(this, node.id));
|
||||
|
||||
m_rpc.invoke(messages::ping, node.addr, p);
|
||||
++m_active_pings;
|
||||
++m_leftover_nodes_iterator;
|
||||
}
|
||||
|
||||
if (m_active_pings == 0)
|
||||
|
|
|
@ -72,15 +72,25 @@ rpc_manager::rpc_manager(fun const& f, node_id const& our_id
|
|||
, m_table(table)
|
||||
, m_timer(boost::posix_time::microsec_clock::universal_time())
|
||||
, m_random_number(generate_id())
|
||||
, m_destructing(false)
|
||||
{
|
||||
std::srand(time(0));
|
||||
}
|
||||
|
||||
rpc_manager::~rpc_manager()
|
||||
{
|
||||
m_destructing = true;
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(rpc) << "Destructing";
|
||||
#endif
|
||||
std::for_each(m_aborted_transactions.begin(), m_aborted_transactions.end()
|
||||
, bind(&observer::abort, _1));
|
||||
|
||||
for (transactions_t::iterator i = m_transactions.begin()
|
||||
, end(m_transactions.end()); i != end; ++i)
|
||||
{
|
||||
if (*i) (*i)->abort();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -104,6 +114,8 @@ bool rpc_manager::incoming(msg const& m)
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_destructing) return false;
|
||||
|
||||
if (m.reply)
|
||||
{
|
||||
// if we don't have the transaction id in our
|
||||
|
@ -195,6 +207,8 @@ time_duration rpc_manager::tick()
|
|||
|
||||
if (m_next_transaction_id == m_oldest_transaction_id) return milliseconds(timeout_ms);
|
||||
|
||||
std::vector<shared_ptr<observer> > timeouts;
|
||||
|
||||
for (;m_next_transaction_id != m_oldest_transaction_id;
|
||||
m_oldest_transaction_id = (m_oldest_transaction_id + 1) % max_transactions)
|
||||
{
|
||||
|
@ -215,24 +229,39 @@ time_duration rpc_manager::tick()
|
|||
try
|
||||
{
|
||||
m_transactions[m_oldest_transaction_id].reset();
|
||||
o->timeout();
|
||||
timeouts.push_back(o);
|
||||
} catch (std::exception) {}
|
||||
}
|
||||
|
||||
check_invariant();
|
||||
|
||||
std::for_each(timeouts.begin(), timeouts.end(), bind(&observer::timeout, _1));
|
||||
timeouts.clear();
|
||||
|
||||
// clear the aborted transactions, will likely
|
||||
// generate new requests. We need to swap, since the
|
||||
// destrutors may add more observers to the m_aborted_transactions
|
||||
std::vector<shared_ptr<observer> >().swap(m_aborted_transactions);
|
||||
return milliseconds(timeout_ms);
|
||||
}
|
||||
|
||||
unsigned int rpc_manager::new_transaction_id()
|
||||
unsigned int rpc_manager::new_transaction_id(shared_ptr<observer> o)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
unsigned int tid = m_next_transaction_id;
|
||||
m_next_transaction_id = (m_next_transaction_id + 1) % max_transactions;
|
||||
// boost::shared_ptr<observer> o = m_transactions[m_next_transaction_id];
|
||||
if (m_transactions[m_next_transaction_id])
|
||||
{
|
||||
// moving the observer into the set of aborted transactions
|
||||
// it will prevent it from spawning new requests right now,
|
||||
// since that would break the invariant
|
||||
m_aborted_transactions.push_back(m_transactions[m_next_transaction_id]);
|
||||
m_transactions[m_next_transaction_id].reset();
|
||||
assert(m_oldest_transaction_id == m_next_transaction_id);
|
||||
}
|
||||
assert(!m_transactions[tid]);
|
||||
m_transactions[tid] = o;
|
||||
if (m_oldest_transaction_id == m_next_transaction_id)
|
||||
{
|
||||
m_oldest_transaction_id = (m_oldest_transaction_id + 1) % max_transactions;
|
||||
|
@ -243,21 +272,6 @@ unsigned int rpc_manager::new_transaction_id()
|
|||
update_oldest_transaction_id();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(!m_transactions[m_next_transaction_id]);
|
||||
for (int i = (m_next_transaction_id + 1) % max_transactions;
|
||||
i != m_oldest_transaction_id; i = (i + 1) % max_transactions)
|
||||
{
|
||||
assert(!m_transactions[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// hopefully this wouldn't happen, but unfortunately, the
|
||||
// traversal algorithm will simply fail in case its connections
|
||||
// are overwritten. If timeout() is called, it will likely spawn
|
||||
// another connection, which in turn will close the next one
|
||||
// and so on.
|
||||
// if (o) o->timeout();
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
@ -280,33 +294,48 @@ void rpc_manager::invoke(int message_id, udp::endpoint target_addr
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_destructing)
|
||||
{
|
||||
o->abort();
|
||||
return;
|
||||
}
|
||||
|
||||
msg m;
|
||||
m.message_id = message_id;
|
||||
m.reply = false;
|
||||
m.id = m_our_id;
|
||||
m.addr = target_addr;
|
||||
int tid = new_transaction_id();
|
||||
m.transaction_id.clear();
|
||||
std::back_insert_iterator<std::string> out(m.transaction_id);
|
||||
io::write_uint16(tid, out);
|
||||
|
||||
o->send(m);
|
||||
assert(!m_transactions[m_next_transaction_id]);
|
||||
try
|
||||
{
|
||||
m.transaction_id.clear();
|
||||
std::back_insert_iterator<std::string> out(m.transaction_id);
|
||||
io::write_uint16(m_next_transaction_id, out);
|
||||
|
||||
o->send(m);
|
||||
|
||||
m_transactions[tid] = o;
|
||||
o->sent = boost::posix_time::microsec_clock::universal_time();
|
||||
o->target_addr = target_addr;
|
||||
o->sent = boost::posix_time::microsec_clock::universal_time();
|
||||
o->target_addr = target_addr;
|
||||
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(rpc) << "Invoking " << messages::ids[message_id]
|
||||
<< " -> " << target_addr;
|
||||
#endif
|
||||
m_send(m);
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(rpc) << "Invoking " << messages::ids[message_id]
|
||||
<< " -> " << target_addr;
|
||||
#endif
|
||||
m_send(m);
|
||||
new_transaction_id(o);
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void rpc_manager::reply(msg& m, msg const& reply_to)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_destructing) return;
|
||||
|
||||
if (m.message_id != messages::error)
|
||||
m.message_id = reply_to.message_id;
|
||||
m.addr = reply_to.addr;
|
||||
|
@ -325,6 +354,7 @@ namespace
|
|||
virtual void reply(msg const&) {}
|
||||
virtual void timeout() {}
|
||||
virtual void send(msg&) {}
|
||||
void abort() {}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -332,6 +362,8 @@ void rpc_manager::reply_with_ping(msg& m, msg const& reply_to)
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_destructing) return;
|
||||
|
||||
if (m.message_id != messages::error)
|
||||
m.message_id = reply_to.message_id;
|
||||
m.addr = reply_to.addr;
|
||||
|
@ -340,17 +372,24 @@ void rpc_manager::reply_with_ping(msg& m, msg const& reply_to)
|
|||
m.id = m_our_id;
|
||||
m.transaction_id = reply_to.transaction_id;
|
||||
|
||||
int ptid = new_transaction_id();
|
||||
m.ping_transaction_id.clear();
|
||||
std::back_insert_iterator<std::string> out(m.ping_transaction_id);
|
||||
io::write_uint16(ptid, out);
|
||||
try
|
||||
{
|
||||
m.ping_transaction_id.clear();
|
||||
std::back_insert_iterator<std::string> out(m.ping_transaction_id);
|
||||
io::write_uint16(m_next_transaction_id, out);
|
||||
|
||||
boost::shared_ptr<observer> o(new dummy_observer);
|
||||
m_transactions[ptid] = o;
|
||||
o->sent = boost::posix_time::microsec_clock::universal_time();
|
||||
o->target_addr = m.addr;
|
||||
|
||||
m_send(m);
|
||||
boost::shared_ptr<observer> o(new dummy_observer);
|
||||
assert(!m_transactions[m_next_transaction_id]);
|
||||
o->sent = boost::posix_time::microsec_clock::universal_time();
|
||||
o->target_addr = m.addr;
|
||||
|
||||
m_send(m);
|
||||
new_transaction_id(o);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,6 +65,9 @@ void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsig
|
|||
|
||||
if (i == m_results.end() || i->id != id)
|
||||
{
|
||||
assert(std::find_if(m_results.begin(), m_results.end()
|
||||
, bind(std::equal_to<node_id>()
|
||||
, bind(&result::id, _1), id)) == m_results.end());
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(traversal) << "adding result: " << id << " " << addr;
|
||||
#endif
|
||||
|
@ -84,7 +87,10 @@ void traversal_algorithm::finished(node_id const& id)
|
|||
if (m_invoke_count == 0) done();
|
||||
}
|
||||
|
||||
void traversal_algorithm::failed(node_id const& id)
|
||||
// prevent request means that the total number of requests has
|
||||
// overflown. This query failed because it was the oldest one.
|
||||
// So, if this is true, don't make another request
|
||||
void traversal_algorithm::failed(node_id const& id, bool prevent_request)
|
||||
{
|
||||
m_invoke_count--;
|
||||
|
||||
|
@ -100,23 +106,28 @@ void traversal_algorithm::failed(node_id const& id)
|
|||
|
||||
assert(i != m_results.end());
|
||||
|
||||
assert(i->flags & result::queried);
|
||||
m_failed.insert(i->addr);
|
||||
if (i != m_results.end())
|
||||
{
|
||||
assert(i->flags & result::queried);
|
||||
m_failed.insert(i->addr);
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(traversal) << "failed: " << i->id << " " << i->addr;
|
||||
TORRENT_LOG(traversal) << "failed: " << i->id << " " << i->addr;
|
||||
#endif
|
||||
m_results.erase(i);
|
||||
m_table.node_failed(id);
|
||||
m_results.erase(i);
|
||||
}
|
||||
if (prevent_request)
|
||||
{
|
||||
--m_branch_factor;
|
||||
if (m_branch_factor <= 0) m_branch_factor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_table.node_failed(id);
|
||||
}
|
||||
add_requests();
|
||||
if (m_invoke_count == 0) done();
|
||||
}
|
||||
|
||||
void traversal_algorithm::add_request(node_id const& id, udp::endpoint addr)
|
||||
{
|
||||
invoke(id, addr);
|
||||
++m_invoke_count;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool bitwise_nand(unsigned char lhs, unsigned char rhs)
|
||||
|
@ -128,7 +139,7 @@ namespace
|
|||
void traversal_algorithm::add_requests()
|
||||
{
|
||||
while (m_invoke_count < m_branch_factor)
|
||||
{
|
||||
{
|
||||
// Find the first node that hasn't already been queried.
|
||||
// TODO: Better heuristic
|
||||
std::vector<result>::iterator i = std::find_if(
|
||||
|
@ -146,8 +157,13 @@ void traversal_algorithm::add_requests()
|
|||
|
||||
if (i == last_iterator()) break;
|
||||
|
||||
add_request(i->id, i->addr);
|
||||
i->flags |= result::queried;
|
||||
try
|
||||
{
|
||||
invoke(i->id, i->addr);
|
||||
++m_invoke_count;
|
||||
i->flags |= result::queried;
|
||||
}
|
||||
catch (std::exception& e) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ namespace libtorrent
|
|||
, m_in_constructor(true)
|
||||
#endif
|
||||
{
|
||||
std::fill(m_country, m_country + 2, 0);
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
m_logger = m_ses.create_log(m_remote.address().to_string() + "_"
|
||||
+ boost::lexical_cast<std::string>(m_remote.port()), m_ses.listen_port());
|
||||
|
@ -185,6 +186,7 @@ namespace libtorrent
|
|||
, m_in_constructor(true)
|
||||
#endif
|
||||
{
|
||||
std::fill(m_country, m_country + 2, 0);
|
||||
m_remote = m_socket->remote_endpoint();
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
|
|
318
src/torrent.cpp
318
src/torrent.cpp
|
@ -239,6 +239,8 @@ namespace libtorrent
|
|||
, m_complete(-1)
|
||||
, m_incomplete(-1)
|
||||
, m_host_resolver(ses.m_io_service)
|
||||
, m_resolving_country(false)
|
||||
, m_resolve_countries(false)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
, m_dht_announce_timer(ses.m_io_service)
|
||||
#endif
|
||||
|
@ -326,6 +328,8 @@ namespace libtorrent
|
|||
, m_complete(-1)
|
||||
, m_incomplete(-1)
|
||||
, m_host_resolver(ses.m_io_service)
|
||||
, m_resolving_country(false)
|
||||
, m_resolve_countries(false)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
, m_dht_announce_timer(ses.m_io_service)
|
||||
#endif
|
||||
|
@ -1187,6 +1191,320 @@ namespace libtorrent
|
|||
|
||||
}
|
||||
|
||||
void torrent::resolve_peer_country(boost::intrusive_ptr<peer_connection> const& p) const
|
||||
{
|
||||
if (m_resolving_country
|
||||
|| p->has_country()
|
||||
|| p->is_connecting()
|
||||
|| p->is_queued()
|
||||
|| p->in_handshake()) return;
|
||||
|
||||
m_resolving_country = true;
|
||||
tcp::resolver::query q(boost::lexical_cast<std::string>(p->remote().address())
|
||||
+ ".zz.countries.nerd.dk", "0");
|
||||
m_host_resolver.async_resolve(q, m_ses.m_strand.wrap(
|
||||
bind(&torrent::on_country_lookup, shared_from_this(), _1, _2, p)));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef std::pair<int, char const*> country_entry;
|
||||
|
||||
bool compare_first(country_entry const& lhs, country_entry const& rhs)
|
||||
{
|
||||
return lhs.first < rhs.first;
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::on_country_lookup(asio::error_code const& error, tcp::resolver::iterator i
|
||||
, intrusive_ptr<peer_connection> p) const
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
m_resolving_country = false;
|
||||
|
||||
// must be ordered in increasing order
|
||||
country_entry country_map[] =
|
||||
{
|
||||
country_entry( 4, "AF")
|
||||
, country_entry( 8, "AL")
|
||||
, country_entry( 10, "AQ")
|
||||
, country_entry( 12, "DZ")
|
||||
, country_entry( 16, "AS")
|
||||
, country_entry( 20, "AD")
|
||||
, country_entry( 24, "AO")
|
||||
, country_entry( 28, "AG")
|
||||
, country_entry( 31, "AZ")
|
||||
, country_entry( 32, "AR")
|
||||
, country_entry( 36, "AU")
|
||||
, country_entry( 40, "AT")
|
||||
, country_entry( 44, "BS")
|
||||
, country_entry( 48, "BH")
|
||||
, country_entry( 50, "BD")
|
||||
, country_entry( 51, "AM")
|
||||
, country_entry( 52, "BB")
|
||||
, country_entry( 56, "BE")
|
||||
, country_entry( 60, "BM")
|
||||
, country_entry( 64, "BT")
|
||||
, country_entry( 68, "BO")
|
||||
, country_entry( 70, "BA")
|
||||
, country_entry( 72, "BW")
|
||||
, country_entry( 74, "BV")
|
||||
, country_entry( 76, "BR")
|
||||
, country_entry( 84, "BZ")
|
||||
, country_entry( 86, "IO")
|
||||
, country_entry( 90, "SB")
|
||||
, country_entry( 92, "VG")
|
||||
, country_entry( 96, "BN")
|
||||
, country_entry(100, "BG")
|
||||
, country_entry(104, "MM")
|
||||
, country_entry(108, "BI")
|
||||
, country_entry(112, "BY")
|
||||
, country_entry(116, "KH")
|
||||
, country_entry(120, "CM")
|
||||
, country_entry(124, "CA")
|
||||
, country_entry(132, "CV")
|
||||
, country_entry(136, "KY")
|
||||
, country_entry(140, "CF")
|
||||
, country_entry(144, "LK")
|
||||
, country_entry(148, "TD")
|
||||
, country_entry(152, "CL")
|
||||
, country_entry(156, "CN")
|
||||
, country_entry(158, "TW")
|
||||
, country_entry(162, "CX")
|
||||
, country_entry(166, "CC")
|
||||
, country_entry(170, "CO")
|
||||
, country_entry(174, "KM")
|
||||
, country_entry(175, "YT")
|
||||
, country_entry(178, "CG")
|
||||
, country_entry(180, "CD")
|
||||
, country_entry(184, "CK")
|
||||
, country_entry(188, "CR")
|
||||
, country_entry(191, "HR")
|
||||
, country_entry(192, "CU")
|
||||
, country_entry(203, "CZ")
|
||||
, country_entry(204, "BJ")
|
||||
, country_entry(208, "DK")
|
||||
, country_entry(212, "DM")
|
||||
, country_entry(214, "DO")
|
||||
, country_entry(218, "EC")
|
||||
, country_entry(222, "SV")
|
||||
, country_entry(226, "GQ")
|
||||
, country_entry(231, "ET")
|
||||
, country_entry(232, "ER")
|
||||
, country_entry(233, "EE")
|
||||
, country_entry(234, "FO")
|
||||
, country_entry(238, "FK")
|
||||
, country_entry(239, "GS")
|
||||
, country_entry(242, "FJ")
|
||||
, country_entry(246, "FI")
|
||||
, country_entry(248, "AX")
|
||||
, country_entry(250, "FR")
|
||||
, country_entry(254, "GF")
|
||||
, country_entry(258, "PF")
|
||||
, country_entry(260, "TF")
|
||||
, country_entry(262, "DJ")
|
||||
, country_entry(266, "GA")
|
||||
, country_entry(268, "GE")
|
||||
, country_entry(270, "GM")
|
||||
, country_entry(275, "PS")
|
||||
, country_entry(276, "DE")
|
||||
, country_entry(288, "GH")
|
||||
, country_entry(292, "GI")
|
||||
, country_entry(296, "KI")
|
||||
, country_entry(300, "GR")
|
||||
, country_entry(304, "GL")
|
||||
, country_entry(308, "GD")
|
||||
, country_entry(312, "GP")
|
||||
, country_entry(316, "GU")
|
||||
, country_entry(320, "GT")
|
||||
, country_entry(324, "GN")
|
||||
, country_entry(328, "GY")
|
||||
, country_entry(332, "HT")
|
||||
, country_entry(334, "HM")
|
||||
, country_entry(336, "VA")
|
||||
, country_entry(340, "HN")
|
||||
, country_entry(344, "HK")
|
||||
, country_entry(348, "HU")
|
||||
, country_entry(352, "IS")
|
||||
, country_entry(356, "IN")
|
||||
, country_entry(360, "ID")
|
||||
, country_entry(364, "IR")
|
||||
, country_entry(368, "IQ")
|
||||
, country_entry(372, "IE")
|
||||
, country_entry(376, "IL")
|
||||
, country_entry(380, "IT")
|
||||
, country_entry(384, "CI")
|
||||
, country_entry(388, "JM")
|
||||
, country_entry(392, "JP")
|
||||
, country_entry(398, "KZ")
|
||||
, country_entry(400, "JO")
|
||||
, country_entry(404, "KE")
|
||||
, country_entry(408, "KP")
|
||||
, country_entry(410, "KR")
|
||||
, country_entry(414, "KW")
|
||||
, country_entry(417, "KG")
|
||||
, country_entry(418, "LA")
|
||||
, country_entry(422, "LB")
|
||||
, country_entry(426, "LS")
|
||||
, country_entry(428, "LV")
|
||||
, country_entry(430, "LR")
|
||||
, country_entry(434, "LY")
|
||||
, country_entry(438, "LI")
|
||||
, country_entry(440, "LT")
|
||||
, country_entry(442, "LU")
|
||||
, country_entry(446, "MO")
|
||||
, country_entry(450, "MG")
|
||||
, country_entry(454, "MW")
|
||||
, country_entry(458, "MY")
|
||||
, country_entry(462, "MV")
|
||||
, country_entry(466, "ML")
|
||||
, country_entry(470, "MT")
|
||||
, country_entry(474, "MQ")
|
||||
, country_entry(478, "MR")
|
||||
, country_entry(480, "MU")
|
||||
, country_entry(484, "MX")
|
||||
, country_entry(492, "MC")
|
||||
, country_entry(496, "MN")
|
||||
, country_entry(498, "MD")
|
||||
, country_entry(500, "MS")
|
||||
, country_entry(504, "MA")
|
||||
, country_entry(508, "MZ")
|
||||
, country_entry(512, "OM")
|
||||
, country_entry(516, "NA")
|
||||
, country_entry(520, "NR")
|
||||
, country_entry(524, "NP")
|
||||
, country_entry(528, "NL")
|
||||
, country_entry(530, "AN")
|
||||
, country_entry(533, "AW")
|
||||
, country_entry(540, "NC")
|
||||
, country_entry(548, "VU")
|
||||
, country_entry(554, "NZ")
|
||||
, country_entry(558, "NI")
|
||||
, country_entry(562, "NE")
|
||||
, country_entry(566, "NG")
|
||||
, country_entry(570, "NU")
|
||||
, country_entry(574, "NF")
|
||||
, country_entry(578, "NO")
|
||||
, country_entry(580, "MP")
|
||||
, country_entry(581, "UM")
|
||||
, country_entry(583, "FM")
|
||||
, country_entry(584, "MH")
|
||||
, country_entry(585, "PW")
|
||||
, country_entry(586, "PK")
|
||||
, country_entry(591, "PA")
|
||||
, country_entry(598, "PG")
|
||||
, country_entry(600, "PY")
|
||||
, country_entry(604, "PE")
|
||||
, country_entry(608, "PH")
|
||||
, country_entry(612, "PN")
|
||||
, country_entry(616, "PL")
|
||||
, country_entry(620, "PT")
|
||||
, country_entry(624, "GW")
|
||||
, country_entry(626, "TL")
|
||||
, country_entry(630, "PR")
|
||||
, country_entry(634, "QA")
|
||||
, country_entry(634, "QA")
|
||||
, country_entry(638, "RE")
|
||||
, country_entry(642, "RO")
|
||||
, country_entry(643, "RU")
|
||||
, country_entry(646, "RW")
|
||||
, country_entry(654, "SH")
|
||||
, country_entry(659, "KN")
|
||||
, country_entry(660, "AI")
|
||||
, country_entry(662, "LC")
|
||||
, country_entry(666, "PM")
|
||||
, country_entry(670, "VC")
|
||||
, country_entry(674, "SM")
|
||||
, country_entry(678, "ST")
|
||||
, country_entry(682, "SA")
|
||||
, country_entry(686, "SN")
|
||||
, country_entry(690, "SC")
|
||||
, country_entry(694, "SL")
|
||||
, country_entry(702, "SG")
|
||||
, country_entry(703, "SK")
|
||||
, country_entry(704, "VN")
|
||||
, country_entry(705, "SI")
|
||||
, country_entry(706, "SO")
|
||||
, country_entry(710, "ZA")
|
||||
, country_entry(716, "ZW")
|
||||
, country_entry(724, "ES")
|
||||
, country_entry(732, "EH")
|
||||
, country_entry(736, "SD")
|
||||
, country_entry(740, "SR")
|
||||
, country_entry(744, "SJ")
|
||||
, country_entry(748, "SZ")
|
||||
, country_entry(752, "SE")
|
||||
, country_entry(756, "CH")
|
||||
, country_entry(760, "SY")
|
||||
, country_entry(762, "TJ")
|
||||
, country_entry(764, "TH")
|
||||
, country_entry(768, "TG")
|
||||
, country_entry(772, "TK")
|
||||
, country_entry(776, "TO")
|
||||
, country_entry(780, "TT")
|
||||
, country_entry(784, "AE")
|
||||
, country_entry(788, "TN")
|
||||
, country_entry(792, "TR")
|
||||
, country_entry(795, "TM")
|
||||
, country_entry(796, "TC")
|
||||
, country_entry(798, "TV")
|
||||
, country_entry(800, "UG")
|
||||
, country_entry(804, "UA")
|
||||
, country_entry(807, "MK")
|
||||
, country_entry(818, "EG")
|
||||
, country_entry(826, "GB")
|
||||
, country_entry(834, "TZ")
|
||||
, country_entry(840, "US")
|
||||
, country_entry(850, "VI")
|
||||
, country_entry(854, "BF")
|
||||
, country_entry(858, "UY")
|
||||
, country_entry(860, "UZ")
|
||||
, country_entry(862, "VE")
|
||||
, country_entry(876, "WF")
|
||||
, country_entry(882, "WS")
|
||||
, country_entry(887, "YE")
|
||||
, country_entry(891, "CS")
|
||||
, country_entry(894, "ZM")
|
||||
};
|
||||
|
||||
if (error || i == tcp::resolver::iterator())
|
||||
{
|
||||
// this is used to indicate that we shouldn't
|
||||
// try to resolve it again
|
||||
p->set_country("--");
|
||||
return;
|
||||
}
|
||||
|
||||
while (i != tcp::resolver::iterator()
|
||||
&& !i->endpoint().address().is_v4()) ++i;
|
||||
if (i != tcp::resolver::iterator())
|
||||
{
|
||||
// country is an ISO 3166 country code
|
||||
int country = i->endpoint().address().to_v4().to_ulong() & 0xffff;
|
||||
|
||||
// look up the country code in the map
|
||||
const int size = sizeof(country_map)/sizeof(country_map[0]);
|
||||
country_entry* i =
|
||||
std::lower_bound(country_map, country_map + size
|
||||
, country_entry(country, ""), &compare_first);
|
||||
if (i == country_map + size
|
||||
|| i->first != country)
|
||||
{
|
||||
// unknown country!
|
||||
p->set_country("!!");
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_ses.m_logger) << "IP " << p->remote().address() << " was mapped to unknown country: " << country << "\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
p->set_country(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::on_name_lookup(asio::error_code const& e, tcp::resolver::iterator host
|
||||
, std::string url) try
|
||||
{
|
||||
|
|
|
@ -632,6 +632,20 @@ namespace libtorrent
|
|||
, bind(&torrent::set_ratio, _1, ratio));
|
||||
}
|
||||
|
||||
void torrent_handle::resolve_countries(bool r)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
call_member<void>(m_ses, m_chk, m_info_hash
|
||||
, bind(&torrent::resolve_countries, _1, r));
|
||||
}
|
||||
|
||||
bool torrent_handle::resolve_countries() const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
return call_member<bool>(m_ses, m_chk, m_info_hash
|
||||
, bind(&torrent::resolving_countries, _1));
|
||||
}
|
||||
|
||||
void torrent_handle::get_peer_info(std::vector<peer_info>& v) const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
@ -657,6 +671,8 @@ namespace libtorrent
|
|||
peer_info& p = v.back();
|
||||
|
||||
peer->get_peer_info(p);
|
||||
if (t->resolving_countries())
|
||||
t->resolve_peer_country(intrusive_ptr<peer_connection>(peer));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -455,6 +455,9 @@ namespace libtorrent
|
|||
p.payload_up_speed = statistics().upload_payload_rate();
|
||||
p.pid = pid();
|
||||
p.ip = remote();
|
||||
|
||||
p.country[0] = m_country[0];
|
||||
p.country[1] = m_country[1];
|
||||
|
||||
p.total_download = statistics().total_payload_download();
|
||||
p.total_upload = statistics().total_payload_upload();
|
||||
|
@ -507,6 +510,11 @@ namespace libtorrent
|
|||
p.connection_type = peer_info::web_seed;
|
||||
}
|
||||
|
||||
bool web_peer_connection::in_handshake() const
|
||||
{
|
||||
return m_server_string.empty();
|
||||
}
|
||||
|
||||
// throws exception when the client should be disconnected
|
||||
void web_peer_connection::on_sent(asio::error_code const& error
|
||||
, std::size_t bytes_transferred)
|
||||
|
|
Loading…
Reference in New Issue