| alert_types.hpp | | alert_types.hpp | |
| | | | |
| skipping to change at line 39 | | skipping to change at line 39 | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_ALERT_TYPES_HPP_INCLUDED | | #ifndef TORRENT_ALERT_TYPES_HPP_INCLUDED | |
| #define TORRENT_ALERT_TYPES_HPP_INCLUDED | | #define TORRENT_ALERT_TYPES_HPP_INCLUDED | |
| | | | |
| #include "libtorrent/alert.hpp" | | #include "libtorrent/alert.hpp" | |
| #include "libtorrent/torrent_handle.hpp" | | #include "libtorrent/torrent_handle.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
|
| #include "libtorrent/peer_connection.hpp" | | | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/identify_client.hpp" | | #include "libtorrent/identify_client.hpp" | |
|
| | | #include "libtorrent/address.hpp" | |
| #include "libtorrent/stat.hpp" | | #include "libtorrent/stat.hpp" | |
|
| | | #include "libtorrent/rss.hpp" // for feed_handle | |
| | | | |
| | | // lines reserved for future includes | |
| | | // the type-ids of the alert types | |
| | | // are derived from the line on which | |
| | | // they are declared | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| | | | |
| | | // user defined alerts should use IDs greater than this | |
| | | const static int user_alert_id = 10000; | |
| | | | |
| struct TORRENT_EXPORT torrent_alert: alert | | struct TORRENT_EXPORT torrent_alert: alert | |
| { | | { | |
| torrent_alert(torrent_handle const& h) | | torrent_alert(torrent_handle const& h) | |
| : handle(h) | | : handle(h) | |
| {} | | {} | |
| | | | |
|
| virtual std::string message() const | | const static int alert_type = 1; | |
| { return handle.is_valid()?handle.name():" - "; } | | virtual std::string message() const; | |
| | | | |
| torrent_handle handle; | | torrent_handle handle; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_alert: torrent_alert | | struct TORRENT_EXPORT peer_alert: torrent_alert | |
| { | | { | |
| peer_alert(torrent_handle const& h, tcp::endpoint const& ip_ | | peer_alert(torrent_handle const& h, tcp::endpoint const& ip_ | |
| , peer_id const& pid_) | | , peer_id const& pid_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , ip(ip_) | | , ip(ip_) | |
| , pid(pid_) | | , pid(pid_) | |
| {} | | {} | |
| | | | |
|
| | | const static int alert_type = 2; | |
| const static int static_category = alert::peer_notification; | | const static int static_category = alert::peer_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
|
| virtual std::string message() const | | virtual std::string message() const; | |
| { | | | |
| error_code ec; | | | |
| return torrent_alert::message() + " peer (" + ip.add | | | |
| ress().to_string(ec) | | | |
| + ", " + identify_client(pid) + ")"; | | | |
| } | | | |
| | | | |
| tcp::endpoint ip; | | tcp::endpoint ip; | |
| peer_id pid; | | peer_id pid; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_alert: torrent_alert | | struct TORRENT_EXPORT tracker_alert: torrent_alert | |
| { | | { | |
| tracker_alert(torrent_handle const& h | | tracker_alert(torrent_handle const& h | |
| , std::string const& url_) | | , std::string const& url_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , url(url_) | | , url(url_) | |
| {} | | {} | |
| | | | |
|
| | | const static int alert_type = 3; | |
| const static int static_category = alert::tracker_notificati
on; | | const static int static_category = alert::tracker_notificati
on; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
|
| virtual std::string message() const | | virtual std::string message() const; | |
| { | | | |
| return torrent_alert::message() + " (" + url + ")"; | | | |
| } | | | |
| | | | |
| std::string url; | | std::string url; | |
| }; | | }; | |
| | | | |
|
| | | #define TORRENT_DEFINE_ALERT(name) \ | |
| | | const static int alert_type = __LINE__; \ | |
| | | virtual int type() const { return alert_type; } \ | |
| | | virtual std::auto_ptr<alert> clone() const \ | |
| | | { return std::auto_ptr<alert>(new name(*this)); } \ | |
| | | virtual int category() const { return static_category; } \ | |
| | | virtual char const* what() const { return #name; } | |
| | | | |
| | | struct TORRENT_EXPORT torrent_added_alert: torrent_alert | |
| | | { | |
| | | torrent_added_alert(torrent_handle const& h) | |
| | | : torrent_alert(h) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(torrent_added_alert); | |
| | | const static int static_category = alert::status_notificatio | |
| | | n; | |
| | | virtual std::string message() const; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT torrent_removed_alert: torrent_alert | |
| | | { | |
| | | torrent_removed_alert(torrent_handle const& h, sha1_hash con | |
| | | st& ih) | |
| | | : torrent_alert(h) | |
| | | , info_hash(ih) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(torrent_removed_alert); | |
| | | const static int static_category = alert::status_notificatio | |
| | | n; | |
| | | virtual std::string message() const; | |
| | | sha1_hash info_hash; | |
| | | }; | |
| | | | |
| struct TORRENT_EXPORT read_piece_alert: torrent_alert | | struct TORRENT_EXPORT read_piece_alert: torrent_alert | |
| { | | { | |
| read_piece_alert(torrent_handle const& h | | read_piece_alert(torrent_handle const& h | |
| , int p, boost::shared_array<char> d, int s) | | , int p, boost::shared_array<char> d, int s) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , buffer(d) | | , buffer(d) | |
| , piece(p) | | , piece(p) | |
| , size(s) | | , size(s) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(read_piece_alert); | |
| { return std::auto_ptr<alert>(new read_piece_alert(*this)); | | | |
| } | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual char const* what() const { return "read piece"; } | | virtual bool discardable() const { return false; } | |
| virtual std::string message() const | | | |
| { | | | |
| char msg[200]; | | | |
| snprintf(msg, sizeof(msg), "%s: piece %s %u", torren | | | |
| t_alert::message().c_str() | | | |
| , buffer ? "successful" : "failed", piece); | | | |
| return msg; | | | |
| } | | | |
| | | | |
| boost::shared_array<char> buffer; | | boost::shared_array<char> buffer; | |
| int piece; | | int piece; | |
| int size; | | int size; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT file_completed_alert: torrent_alert | | struct TORRENT_EXPORT file_completed_alert: torrent_alert | |
| { | | { | |
| file_completed_alert(torrent_handle const& h | | file_completed_alert(torrent_handle const& h | |
| , int index_) | | , int index_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , index(index_) | | , index(index_) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(file_completed_alert); | |
| { return std::auto_ptr<alert>(new file_completed_alert(*this | | | |
| )); } | | | |
| const static int static_category = alert::progress_notificat
ion; | | const static int static_category = alert::progress_notificat
ion; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual char const* what() const { return "file completed"; | | | |
| } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char msg[200]; | | | |
| snprintf(msg, sizeof(msg), "%s: file %d finished dow | | | |
| nloading" | | | |
| , torrent_alert::message().c_str(), index); | | | |
| return msg; | | | |
| } | | | |
| | | | |
| int index; | | int index; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT file_renamed_alert: torrent_alert | | struct TORRENT_EXPORT file_renamed_alert: torrent_alert | |
| { | | { | |
| file_renamed_alert(torrent_handle const& h | | file_renamed_alert(torrent_handle const& h | |
| , std::string const& name_ | | , std::string const& name_ | |
| , int index_) | | , int index_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , name(name_) | | , name(name_) | |
| , index(index_) | | , index(index_) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(file_renamed_alert); | |
| { return std::auto_ptr<alert>(new file_renamed_alert(*this)) | | | |
| ; } | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual char const* what() const { return "file renamed"; } | | virtual bool discardable() const { return false; } | |
| virtual std::string message() const | | | |
| { | | | |
| char msg[200 + NAME_MAX]; | | | |
| snprintf(msg, sizeof(msg), "%s: file %d renamed to % | | | |
| s", torrent_alert::message().c_str() | | | |
| , index, name.c_str()); | | | |
| return msg; | | | |
| } | | | |
| | | | |
| std::string name; | | std::string name; | |
| int index; | | int index; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT file_rename_failed_alert: torrent_alert | | struct TORRENT_EXPORT file_rename_failed_alert: torrent_alert | |
| { | | { | |
| file_rename_failed_alert(torrent_handle const& h | | file_rename_failed_alert(torrent_handle const& h | |
| , int index_ | | , int index_ | |
| , error_code ec_) | | , error_code ec_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , index(index_) | | , index(index_) | |
| , error(ec_) | | , error(ec_) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(file_rename_failed_alert); | |
| { return std::auto_ptr<alert>(new file_rename_failed_alert(* | | | |
| this)); } | | | |
| | | | |
| virtual char const* what() const { return "file rename faile | | | |
| d"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[200 + NAME_MAX]; | | | |
| snprintf(ret, sizeof(ret), "%s: failed to rename fil | | | |
| e %d: %s" | | | |
| , torrent_alert::message().c_str(), index, e | | | |
| rror.message().c_str()); | | | |
| return ret; | | | |
| } | | | |
| | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | | |
| | | virtual std::string message() const; | |
| | | virtual bool discardable() const { return false; } | |
| | | | |
| int index; | | int index; | |
| error_code error; | | error_code error; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT performance_alert: torrent_alert | | struct TORRENT_EXPORT performance_alert: torrent_alert | |
| { | | { | |
| enum performance_warning_t | | enum performance_warning_t | |
| { | | { | |
| outstanding_disk_buffer_limit_reached, | | outstanding_disk_buffer_limit_reached, | |
| outstanding_request_limit_reached, | | outstanding_request_limit_reached, | |
| upload_limit_too_low, | | upload_limit_too_low, | |
| download_limit_too_low, | | download_limit_too_low, | |
| send_buffer_watermark_too_low, | | send_buffer_watermark_too_low, | |
|
| | | too_many_optimistic_unchoke_slots, | |
| | | bittyrant_with_no_uplimit, | |
| | | too_high_disk_queue_limit, | |
| | | too_few_outgoing_ports, | |
| | | too_few_file_descriptors, | |
| | | | |
| num_warnings | | num_warnings | |
| }; | | }; | |
| | | | |
| performance_alert(torrent_handle const& h | | performance_alert(torrent_handle const& h | |
| , performance_warning_t w) | | , performance_warning_t w) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , warning_code(w) | | , warning_code(w) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(performance_alert); | |
| { return std::auto_ptr<alert>(new performance_alert(*this)); | | | |
| } | | | |
| | | | |
| virtual char const* what() const { return "performance warni | | | |
| ng"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| static char const* warning_str[] = | | | |
| { | | | |
| "max outstanding disk writes reached", | | | |
| "max outstanding piece requests reached", | | | |
| "upload limit too low (download rate will su | | | |
| ffer)", | | | |
| "download limit too low (upload rate will su | | | |
| ffer)", | | | |
| "send buffer watermark too low (upload rate | | | |
| will suffer)" | | | |
| }; | | | |
| | | | |
| return torrent_alert::message() + ": performance war | | | |
| ning: " | | | |
| + warning_str[warning_code]; | | | |
| } | | | |
| | | | |
| const static int static_category = alert::performance_warnin
g; | | const static int static_category = alert::performance_warnin
g; | |
|
| virtual int category() const { return static_category; } | | | |
| | | virtual std::string message() const; | |
| | | | |
| performance_warning_t warning_code; | | performance_warning_t warning_code; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT state_changed_alert: torrent_alert | | struct TORRENT_EXPORT state_changed_alert: torrent_alert | |
| { | | { | |
| state_changed_alert(torrent_handle const& h | | state_changed_alert(torrent_handle const& h | |
| , torrent_status::state_t state_ | | , torrent_status::state_t state_ | |
| , torrent_status::state_t prev_state_) | | , torrent_status::state_t prev_state_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , state(state_) | | , state(state_) | |
| , prev_state(prev_state_) | | , prev_state(prev_state_) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(state_changed_alert); | |
| { return std::auto_ptr<alert>(new state_changed_alert(*this) | | | |
| ); } | | | |
| | | | |
| virtual char const* what() const { return "torrent state cha | | | |
| nged"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| static char const* state_str[] = | | | |
| {"checking (q)", "checking", "dl metadata" | | | |
| , "downloading", "finished", "seeding", "all | | | |
| ocating" | | | |
| , "checking (r)"}; | | | |
| | | | |
| return torrent_alert::message() + ": state changed t | | | |
| o: " | | | |
| + state_str[state]; | | | |
| } | | | |
| | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | | |
| | | virtual std::string message() const; | |
| | | | |
| torrent_status::state_t state; | | torrent_status::state_t state; | |
| torrent_status::state_t prev_state; | | torrent_status::state_t prev_state; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_error_alert: tracker_alert | | struct TORRENT_EXPORT tracker_error_alert: tracker_alert | |
| { | | { | |
| tracker_error_alert(torrent_handle const& h | | tracker_error_alert(torrent_handle const& h | |
| , int times | | , int times | |
| , int status | | , int status | |
| , std::string const& url_ | | , std::string const& url_ | |
|
| , error_code const& e) | | , error_code const& e | |
| | | , std::string const& m) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , times_in_row(times) | | , times_in_row(times) | |
| , status_code(status) | | , status_code(status) | |
|
| , msg(e.message()) | | , error(e) | |
| | | , msg(m) | |
| { | | { | |
| TORRENT_ASSERT(!url.empty()); | | TORRENT_ASSERT(!url.empty()); | |
| } | | } | |
| | | | |
|
| tracker_error_alert(torrent_handle const& h | | TORRENT_DEFINE_ALERT(tracker_error_alert); | |
| , int times | | | |
| , int status | | | |
| , std::string const& url_ | | | |
| , std::string const& msg_) | | | |
| : tracker_alert(h, url_) | | | |
| , times_in_row(times) | | | |
| , status_code(status) | | | |
| , msg(msg_) | | | |
| { | | | |
| TORRENT_ASSERT(!url.empty()); | | | |
| } | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new tracker_error_alert(*this) | | | |
| ); } | | | |
| const static int static_category = alert::tracker_notificati
on | alert::error_notification; | | const static int static_category = alert::tracker_notificati
on | alert::error_notification; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual char const* what() const { return "tracker error"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[400]; | | | |
| snprintf(ret, sizeof(ret), "%s (%d) %s (%d)" | | | |
| , tracker_alert::message().c_str(), status_c | | | |
| ode | | | |
| , msg.c_str(), times_in_row); | | | |
| return ret; | | | |
| } | | | |
| | | | |
| int times_in_row; | | int times_in_row; | |
| int status_code; | | int status_code; | |
|
| | | error_code error; | |
| std::string msg; | | std::string msg; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_warning_alert: tracker_alert | | struct TORRENT_EXPORT tracker_warning_alert: tracker_alert | |
| { | | { | |
| tracker_warning_alert(torrent_handle const& h | | tracker_warning_alert(torrent_handle const& h | |
| , std::string const& url_ | | , std::string const& url_ | |
| , std::string const& msg_) | | , std::string const& msg_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , msg(msg_) | | , msg(msg_) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
|
| std::string msg; | | TORRENT_DEFINE_ALERT(tracker_warning_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new tracker_warning_alert(*thi | | | |
| s)); } | | | |
| const static int static_category = alert::tracker_notificati
on | alert::error_notification; | | const static int static_category = alert::tracker_notificati
on | alert::error_notification; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual char const* what() const { return "tracker warning"; | | | |
| } | | std::string msg; | |
| virtual std::string message() const | | | |
| { | | | |
| return tracker_alert::message() + " warning: " + msg | | | |
| ; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT scrape_reply_alert: tracker_alert | | struct TORRENT_EXPORT scrape_reply_alert: tracker_alert | |
| { | | { | |
| scrape_reply_alert(torrent_handle const& h | | scrape_reply_alert(torrent_handle const& h | |
| , int incomplete_ | | , int incomplete_ | |
| , int complete_ | | , int complete_ | |
| , std::string const& url_) | | , std::string const& url_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , incomplete(incomplete_) | | , incomplete(incomplete_) | |
| , complete(complete_) | | , complete(complete_) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
|
| | | TORRENT_DEFINE_ALERT(scrape_reply_alert); | |
| | | | |
| | | virtual std::string message() const; | |
| | | | |
| int incomplete; | | int incomplete; | |
| int complete; | | int complete; | |
|
| | | | |
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new scrape_reply_alert(*this)) | | | |
| ; } | | | |
| virtual char const* what() const { return "tracker scrape re | | | |
| ply"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[400]; | | | |
| snprintf(ret, sizeof(ret), "%s scrape reply: %u %u" | | | |
| , tracker_alert::message().c_str(), incomple | | | |
| te, complete); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT scrape_failed_alert: tracker_alert | | struct TORRENT_EXPORT scrape_failed_alert: tracker_alert | |
| { | | { | |
| scrape_failed_alert(torrent_handle const& h | | scrape_failed_alert(torrent_handle const& h | |
| , std::string const& url_ | | , std::string const& url_ | |
| , error_code const& e) | | , error_code const& e) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , msg(e.message()) | | , msg(e.message()) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
| scrape_failed_alert(torrent_handle const& h | | scrape_failed_alert(torrent_handle const& h | |
| , std::string const& url_ | | , std::string const& url_ | |
| , std::string const& msg_) | | , std::string const& msg_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , msg(msg_) | | , msg(msg_) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
|
| std::string msg; | | TORRENT_DEFINE_ALERT(scrape_failed_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new scrape_failed_alert(*this) | | | |
| ); } | | | |
| const static int static_category = alert::tracker_notificati
on | alert::error_notification; | | const static int static_category = alert::tracker_notificati
on | alert::error_notification; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual char const* what() const { return "tracker scrape fa | | | |
| iled"; } | | std::string msg; | |
| virtual std::string message() const | | | |
| { | | | |
| return tracker_alert::message() + " scrape failed: " | | | |
| + msg; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_reply_alert: tracker_alert | | struct TORRENT_EXPORT tracker_reply_alert: tracker_alert | |
| { | | { | |
| tracker_reply_alert(torrent_handle const& h | | tracker_reply_alert(torrent_handle const& h | |
| , int np | | , int np | |
| , std::string const& url_) | | , std::string const& url_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , num_peers(np) | | , num_peers(np) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
|
| int num_peers; | | TORRENT_DEFINE_ALERT(tracker_reply_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | virtual std::string message() const; | |
| { return std::auto_ptr<alert>(new tracker_reply_alert(*this) | | | |
| ); } | | int num_peers; | |
| virtual char const* what() const { return "tracker reply"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[400]; | | | |
| snprintf(ret, sizeof(ret), "%s received peers: %u" | | | |
| , tracker_alert::message().c_str(), num_peer | | | |
| s); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT dht_reply_alert: tracker_alert | | struct TORRENT_EXPORT dht_reply_alert: tracker_alert | |
| { | | { | |
| dht_reply_alert(torrent_handle const& h | | dht_reply_alert(torrent_handle const& h | |
| , int np) | | , int np) | |
| : tracker_alert(h, "") | | : tracker_alert(h, "") | |
| , num_peers(np) | | , num_peers(np) | |
| {} | | {} | |
| | | | |
|
| int num_peers; | | TORRENT_DEFINE_ALERT(dht_reply_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | virtual std::string message() const; | |
| { return std::auto_ptr<alert>(new dht_reply_alert(*this)); } | | | |
| virtual char const* what() const { return "DHT reply"; } | | int num_peers; | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[400]; | | | |
| snprintf(ret, sizeof(ret), "%s received DHT peers: % | | | |
| u" | | | |
| , tracker_alert::message().c_str(), num_peer | | | |
| s); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_announce_alert: tracker_alert | | struct TORRENT_EXPORT tracker_announce_alert: tracker_alert | |
| { | | { | |
| tracker_announce_alert(torrent_handle const& h | | tracker_announce_alert(torrent_handle const& h | |
| , std::string const& url_, int event_) | | , std::string const& url_, int event_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , event(event_) | | , event(event_) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
|
| int event; | | TORRENT_DEFINE_ALERT(tracker_announce_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | virtual std::string message() const; | |
| { return std::auto_ptr<alert>(new tracker_announce_alert(*th | | | |
| is)); } | | int event; | |
| virtual char const* what() const { return "tracker announce | | | |
| sent"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| const static char* event_str[] = {"none", "completed | | | |
| ", "started", "stopped", "paused"}; | | | |
| TORRENT_ASSERT(event < int(sizeof(event_str)/sizeof( | | | |
| event_str[0]))); | | | |
| return tracker_alert::message() + " sending announce | | | |
| (" + event_str[event] + ")"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT hash_failed_alert: torrent_alert | | struct TORRENT_EXPORT hash_failed_alert: torrent_alert | |
| { | | { | |
| hash_failed_alert( | | hash_failed_alert( | |
| torrent_handle const& h | | torrent_handle const& h | |
| , int index) | | , int index) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , piece_index(index) | | , piece_index(index) | |
| { TORRENT_ASSERT(index >= 0);} | | { TORRENT_ASSERT(index >= 0);} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(hash_failed_alert); | |
| { return std::auto_ptr<alert>(new hash_failed_alert(*this)); | | | |
| } | | | |
| virtual char const* what() const { return "piece hash failed | | | |
| "; } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[400]; | | | |
| snprintf(ret, sizeof(ret), "%s hash for piece %u fai | | | |
| led" | | | |
| , torrent_alert::message().c_str(), piece_in | | | |
| dex); | | | |
| return ret; | | | |
| } | | | |
| | | | |
| int piece_index; | | int piece_index; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_ban_alert: peer_alert | | struct TORRENT_EXPORT peer_ban_alert: peer_alert | |
| { | | { | |
| peer_ban_alert(torrent_handle h, tcp::endpoint const& ep | | peer_ban_alert(torrent_handle h, tcp::endpoint const& ep | |
| , peer_id const& peer_id) | | , peer_id const& peer_id) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(peer_ban_alert); | |
| { return std::auto_ptr<alert>(new peer_ban_alert(*this)); } | | | |
| virtual char const* what() const { return "peer banned"; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | | |
| error_code ec; | | | |
| return peer_alert::message() + " banned peer"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_unsnubbed_alert: peer_alert | | struct TORRENT_EXPORT peer_unsnubbed_alert: peer_alert | |
| { | | { | |
| peer_unsnubbed_alert(torrent_handle h, tcp::endpoint const&
ep | | peer_unsnubbed_alert(torrent_handle h, tcp::endpoint const&
ep | |
| , peer_id const& peer_id) | | , peer_id const& peer_id) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(peer_unsnubbed_alert); | |
| { return std::auto_ptr<alert>(new peer_unsnubbed_alert(*this | | | |
| )); } | | virtual std::string message() const; | |
| virtual char const* what() const { return "peer unsnubbed"; | | | |
| } | | | |
| virtual std::string message() const | | | |
| { | | | |
| return peer_alert::message() + " peer unsnubbed"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_snubbed_alert: peer_alert | | struct TORRENT_EXPORT peer_snubbed_alert: peer_alert | |
| { | | { | |
| peer_snubbed_alert(torrent_handle h, tcp::endpoint const& ep | | peer_snubbed_alert(torrent_handle h, tcp::endpoint const& ep | |
| , peer_id const& peer_id) | | , peer_id const& peer_id) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(peer_snubbed_alert); | |
| { return std::auto_ptr<alert>(new peer_snubbed_alert(*this)) | | | |
| ; } | | virtual std::string message() const; | |
| virtual char const* what() const { return "peer snubbed"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| return peer_alert::message() + " peer snubbed"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_error_alert: peer_alert | | struct TORRENT_EXPORT peer_error_alert: peer_alert | |
| { | | { | |
| peer_error_alert(torrent_handle const& h, tcp::endpoint cons
t& ep | | peer_error_alert(torrent_handle const& h, tcp::endpoint cons
t& ep | |
| , peer_id const& peer_id, error_code const& e) | | , peer_id const& peer_id, error_code const& e) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , error(e) | | , error(e) | |
| { | | { | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| msg = error.message(); | | msg = error.message(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(peer_error_alert); | |
| { return std::auto_ptr<alert>(new peer_error_alert(*this)); | | | |
| } | | | |
| virtual char const* what() const { return "peer error"; } | | | |
| const static int static_category = alert::peer_notification; | | const static int static_category = alert::peer_notification; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| error_code ec; | | | |
| return peer_alert::message() + " peer error: " + err
or.message(); | | return peer_alert::message() + " peer error: " + err
or.message(); | |
| } | | } | |
| | | | |
| error_code error; | | error_code error; | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_connect_alert: peer_alert | | struct TORRENT_EXPORT peer_connect_alert: peer_alert | |
| { | | { | |
| peer_connect_alert(torrent_handle h, tcp::endpoint const& ep | | peer_connect_alert(torrent_handle h, tcp::endpoint const& ep | |
| , peer_id const& peer_id) | | , peer_id const& peer_id) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(peer_connect_alert); | |
| { return std::auto_ptr<alert>(new peer_connect_alert(*this)) | | | |
| ; } | | | |
| virtual char const* what() const { return "connecting to pee | | | |
| r"; } | | | |
| const static int static_category = alert::debug_notification
; | | const static int static_category = alert::debug_notification
; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return peer_alert::message() + " connecting to peer"; } | |
| return peer_alert::message() + " connecting to peer" | | | |
| ; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_disconnected_alert: peer_alert | | struct TORRENT_EXPORT peer_disconnected_alert: peer_alert | |
| { | | { | |
| peer_disconnected_alert(torrent_handle const& h, tcp::endpoi
nt const& ep | | peer_disconnected_alert(torrent_handle const& h, tcp::endpoi
nt const& ep | |
| , peer_id const& peer_id, error_code const& e) | | , peer_id const& peer_id, error_code const& e) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , error(e) | | , error(e) | |
| { | | { | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| msg = error.message(); | | msg = error.message(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(peer_disconnected_alert); | |
| { return std::auto_ptr<alert>(new peer_disconnected_alert(*t | | | |
| his)); } | | | |
| virtual char const* what() const { return "peer disconnected | | | |
| "; } | | | |
| const static int static_category = alert::debug_notification
; | | const static int static_category = alert::debug_notification
; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return peer_alert::message() + " disconnecting: " + error. | |
| return peer_alert::message() + " disconnecting: " + | | message(); } | |
| error.message(); | | | |
| } | | | |
| | | | |
| error_code error; | | error_code error; | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT invalid_request_alert: peer_alert | | struct TORRENT_EXPORT invalid_request_alert: peer_alert | |
| { | | { | |
| invalid_request_alert(torrent_handle const& h, tcp::endpoint
const& ep | | invalid_request_alert(torrent_handle const& h, tcp::endpoint
const& ep | |
| , peer_id const& peer_id, peer_request const& r) | | , peer_id const& peer_id, peer_request const& r) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , request(r) | | , request(r) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(invalid_request_alert); | |
| { return std::auto_ptr<alert>(new invalid_request_alert(*thi | | | |
| s)); } | | virtual std::string message() const; | |
| virtual char const* what() const { return "invalid piece req | | | |
| uest"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[200]; | | | |
| snprintf(ret, sizeof(ret), "%s peer sent an invalid | | | |
| piece request (piece: %u start: %u len: %u)" | | | |
| , torrent_alert::message().c_str(), request. | | | |
| piece, request.start, request.length); | | | |
| return ret; | | | |
| } | | | |
| | | | |
| peer_request request; | | peer_request request; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_finished_alert: torrent_alert | | struct TORRENT_EXPORT torrent_finished_alert: torrent_alert | |
| { | | { | |
| torrent_finished_alert( | | torrent_finished_alert( | |
| const torrent_handle& h) | | const torrent_handle& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(torrent_finished_alert); | |
| { return std::auto_ptr<alert>(new torrent_finished_alert(*th | | | |
| is)); } | | | |
| virtual char const* what() const { return "torrent finished" | | | |
| ; } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " torrent finished downl | |
| return torrent_alert::message() + " torrent finished | | oading"; } | |
| downloading"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT piece_finished_alert: torrent_alert | | struct TORRENT_EXPORT piece_finished_alert: torrent_alert | |
| { | | { | |
| piece_finished_alert( | | piece_finished_alert( | |
| const torrent_handle& h | | const torrent_handle& h | |
| , int piece_num) | | , int piece_num) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(piece_index >= 0);} | | { TORRENT_ASSERT(piece_index >= 0);} | |
| | | | |
|
| int piece_index; | | TORRENT_DEFINE_ALERT(piece_finished_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new piece_finished_alert(*this | | | |
| )); } | | | |
| virtual char const* what() const { return "piece finished do | | | |
| wnloading"; } | | | |
| const static int static_category = alert::progress_notificat
ion; | | const static int static_category = alert::progress_notificat
ion; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | int piece_index; | |
| char ret[200]; | | | |
| snprintf(ret, sizeof(ret), "%s piece: %u finished do | | | |
| wnloading" | | | |
| , torrent_alert::message().c_str(), piece_in | | | |
| dex); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT request_dropped_alert: peer_alert | | struct TORRENT_EXPORT request_dropped_alert: peer_alert | |
| { | | { | |
| request_dropped_alert(const torrent_handle& h, tcp::endpoint
const& ep | | request_dropped_alert(const torrent_handle& h, tcp::endpoint
const& ep | |
| , peer_id const& peer_id, int block_num, int piece_n
um) | | , peer_id const& peer_id, int block_num, int piece_n
um) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
|
| int block_index; | | TORRENT_DEFINE_ALERT(request_dropped_alert); | |
| int piece_index; | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new request_dropped_alert(*thi | | | |
| s)); } | | | |
| virtual char const* what() const { return "block request dro | | | |
| pped"; } | | | |
| const static int static_category = alert::progress_notificat
ion | | const static int static_category = alert::progress_notificat
ion | |
| | alert::peer_notification; | | | alert::peer_notification; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | int block_index; | |
| char ret[200]; | | int piece_index; | |
| snprintf(ret, sizeof(ret), "%s peer dropped block ( | | | |
| piece: %u block: %u)" | | | |
| , torrent_alert::message().c_str(), piece_in | | | |
| dex, block_index); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT block_timeout_alert: peer_alert | | struct TORRENT_EXPORT block_timeout_alert: peer_alert | |
| { | | { | |
| block_timeout_alert(const torrent_handle& h, tcp::endpoint c
onst& ep | | block_timeout_alert(const torrent_handle& h, tcp::endpoint c
onst& ep | |
| , peer_id const& peer_id, int block_num, int piece_n
um) | | , peer_id const& peer_id, int block_num, int piece_n
um) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
|
| int block_index; | | TORRENT_DEFINE_ALERT(block_timeout_alert); | |
| int piece_index; | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new block_timeout_alert(*this) | | | |
| ); } | | | |
| virtual char const* what() const { return "block timed out"; | | | |
| } | | | |
| const static int static_category = alert::progress_notificat
ion | | const static int static_category = alert::progress_notificat
ion | |
| | alert::peer_notification; | | | alert::peer_notification; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | int block_index; | |
| char ret[200]; | | int piece_index; | |
| snprintf(ret, sizeof(ret), "%s peer timed out reques | | | |
| t ( piece: %u block: %u)" | | | |
| , torrent_alert::message().c_str(), piece_in | | | |
| dex, block_index); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT block_finished_alert: peer_alert | | struct TORRENT_EXPORT block_finished_alert: peer_alert | |
| { | | { | |
| block_finished_alert(const torrent_handle& h, tcp::endpoint
const& ep | | block_finished_alert(const torrent_handle& h, tcp::endpoint
const& ep | |
| , peer_id const& peer_id, int block_num, int piece_n
um) | | , peer_id const& peer_id, int block_num, int piece_n
um) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
|
| int block_index; | | TORRENT_DEFINE_ALERT(block_finished_alert); | |
| int piece_index; | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new block_finished_alert(*this | | | |
| )); } | | | |
| virtual char const* what() const { return "block finished do | | | |
| wnloading"; } | | | |
| const static int static_category = alert::progress_notificat
ion; | | const static int static_category = alert::progress_notificat
ion; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | int block_index; | |
| char ret[200]; | | int piece_index; | |
| snprintf(ret, sizeof(ret), "%s block finished downlo | | | |
| ading (piece: %u block: %u)" | | | |
| , torrent_alert::message().c_str(), piece_in | | | |
| dex, block_index); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT block_downloading_alert: peer_alert | | struct TORRENT_EXPORT block_downloading_alert: peer_alert | |
| { | | { | |
| block_downloading_alert(const torrent_handle& h, tcp::endpoi
nt const& ep | | block_downloading_alert(const torrent_handle& h, tcp::endpoi
nt const& ep | |
| , peer_id const& peer_id, char const* speedmsg, int
block_num, int piece_num) | | , peer_id const& peer_id, char const* speedmsg, int
block_num, int piece_num) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , peer_speedmsg(speedmsg) | | , peer_speedmsg(speedmsg) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
|
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0); } | |
| | | | |
| | | TORRENT_DEFINE_ALERT(block_downloading_alert); | |
| | | | |
| | | const static int static_category = alert::progress_notificat | |
| | | ion; | |
| | | virtual std::string message() const; | |
| | | | |
| char const* peer_speedmsg; | | char const* peer_speedmsg; | |
| int block_index; | | int block_index; | |
| int piece_index; | | int piece_index; | |
|
| | | | |
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new block_downloading_alert(*t | | | |
| his)); } | | | |
| virtual char const* what() const { return "block requested"; | | | |
| } | | | |
| const static int static_category = alert::progress_notificat | | | |
| ion; | | | |
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[200]; | | | |
| snprintf(ret, sizeof(ret), "%s requested block (piec | | | |
| e: %u block: %u) %s" | | | |
| , torrent_alert::message().c_str(), piece_in | | | |
| dex, block_index, peer_speedmsg); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT unwanted_block_alert: peer_alert | | struct TORRENT_EXPORT unwanted_block_alert: peer_alert | |
| { | | { | |
| unwanted_block_alert(const torrent_handle& h, tcp::endpoint
const& ep | | unwanted_block_alert(const torrent_handle& h, tcp::endpoint
const& ep | |
| , peer_id const& peer_id, int block_num, int piece_n
um) | | , peer_id const& peer_id, int block_num, int piece_n
um) | |
| : peer_alert(h, ep, peer_id) | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
|
| | | TORRENT_DEFINE_ALERT(unwanted_block_alert); | |
| | | | |
| | | virtual std::string message() const; | |
| | | | |
| int block_index; | | int block_index; | |
| int piece_index; | | int piece_index; | |
|
| | | | |
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new unwanted_block_alert(*this | | | |
| )); } | | | |
| virtual char const* what() const { return "unwanted block re | | | |
| ceived"; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| char ret[200]; | | | |
| snprintf(ret, sizeof(ret), "%s received block not in | | | |
| download queue (piece: %u block: %u)" | | | |
| , torrent_alert::message().c_str(), piece_in | | | |
| dex, block_index); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT storage_moved_alert: torrent_alert | | struct TORRENT_EXPORT storage_moved_alert: torrent_alert | |
| { | | { | |
| storage_moved_alert(torrent_handle const& h, std::string con
st& path_) | | storage_moved_alert(torrent_handle const& h, std::string con
st& path_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , path(path_) | | , path(path_) | |
| {} | | {} | |
| | | | |
|
| std::string path; | | TORRENT_DEFINE_ALERT(storage_moved_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new storage_moved_alert(*this) | | | |
| ); } | | | |
| virtual char const* what() const { return "storage moved"; } | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " moved storage to
: " | | return torrent_alert::message() + " moved storage to
: " | |
| + path; | | + path; | |
| } | | } | |
|
| | | | |
| | | std::string path; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT storage_moved_failed_alert: torrent_alert | | struct TORRENT_EXPORT storage_moved_failed_alert: torrent_alert | |
| { | | { | |
| storage_moved_failed_alert(torrent_handle const& h, error_co
de const& ec_) | | storage_moved_failed_alert(torrent_handle const& h, error_co
de const& ec_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , error(ec_) | | , error(ec_) | |
| {} | | {} | |
| | | | |
|
| error_code error; | | TORRENT_DEFINE_ALERT(storage_moved_failed_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new storage_moved_failed_alert | | | |
| (*this)); } | | | |
| virtual char const* what() const { return "storage moved fai | | | |
| led"; } | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " storage move fai
led: " | | return torrent_alert::message() + " storage move fai
led: " | |
| + error.message(); | | + error.message(); | |
| } | | } | |
|
| | | | |
| | | error_code error; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert | | struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert | |
| { | | { | |
| torrent_deleted_alert(torrent_handle const& h, sha1_hash con
st& ih) | | torrent_deleted_alert(torrent_handle const& h, sha1_hash con
st& ih) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| { info_hash = ih; } | | { info_hash = ih; } | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(torrent_deleted_alert); | |
| { return std::auto_ptr<alert>(new torrent_deleted_alert(*thi | | | |
| s)); } | | | |
| virtual char const* what() const { return "torrent deleted"; | | | |
| } | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " deleted"; } | |
| return torrent_alert::message() + " deleted"; | | | |
| } | | | |
| | | | |
| sha1_hash info_hash; | | sha1_hash info_hash; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_delete_failed_alert: torrent_alert | | struct TORRENT_EXPORT torrent_delete_failed_alert: torrent_alert | |
| { | | { | |
| torrent_delete_failed_alert(torrent_handle const& h, error_c
ode const& e) | | torrent_delete_failed_alert(torrent_handle const& h, error_c
ode const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , error(e) | | , error(e) | |
| { | | { | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| msg = error.message(); | | msg = error.message(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| error_code error; | | TORRENT_DEFINE_ALERT(torrent_delete_failed_alert); | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | | |
| std::string msg; | | | |
| #endif | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new torrent_delete_failed_aler | | | |
| t(*this)); } | | | |
| virtual char const* what() const { return "torrent delete fa | | | |
| iled"; } | | | |
| const static int static_category = alert::storage_notificati
on | | const static int static_category = alert::storage_notificati
on | |
| | alert::error_notification; | | | alert::error_notification; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " torrent deletion
failed: " | | return torrent_alert::message() + " torrent deletion
failed: " | |
| + error.message(); | | + error.message(); | |
| } | | } | |
|
| | | | |
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | std::string msg; | |
| | | #endif | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT save_resume_data_alert: torrent_alert | | struct TORRENT_EXPORT save_resume_data_alert: torrent_alert | |
| { | | { | |
| save_resume_data_alert(boost::shared_ptr<entry> const& rd | | save_resume_data_alert(boost::shared_ptr<entry> const& rd | |
| , torrent_handle const& h) | | , torrent_handle const& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , resume_data(rd) | | , resume_data(rd) | |
| {} | | {} | |
| | | | |
|
| boost::shared_ptr<entry> resume_data; | | TORRENT_DEFINE_ALERT(save_resume_data_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new save_resume_data_alert(*th | | | |
| is)); } | | | |
| virtual char const* what() const { return "save resume data | | | |
| complete"; } | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " resume data generated" | |
| return torrent_alert::message() + " resume data gene | | ; } | |
| rated"; | | virtual bool discardable() const { return false; } | |
| } | | | |
| | | boost::shared_ptr<entry> resume_data; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT save_resume_data_failed_alert: torrent_alert | | struct TORRENT_EXPORT save_resume_data_failed_alert: torrent_alert | |
| { | | { | |
| save_resume_data_failed_alert(torrent_handle const& h | | save_resume_data_failed_alert(torrent_handle const& h | |
| , error_code const& e) | | , error_code const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , error(e) | | , error(e) | |
| { | | { | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| msg = error.message(); | | msg = error.message(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| error_code error; | | TORRENT_DEFINE_ALERT(save_resume_data_failed_alert); | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | | |
| std::string msg; | | | |
| #endif | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new save_resume_data_failed_al | | | |
| ert(*this)); } | | | |
| virtual char const* what() const { return "save resume data | | | |
| failed"; } | | | |
| const static int static_category = alert::storage_notificati
on | | const static int static_category = alert::storage_notificati
on | |
| | alert::error_notification; | | | alert::error_notification; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " resume data was
not generated: " | | return torrent_alert::message() + " resume data was
not generated: " | |
| + error.message(); | | + error.message(); | |
| } | | } | |
|
| | | virtual bool discardable() const { return false; } | |
| | | | |
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | std::string msg; | |
| | | #endif | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_paused_alert: torrent_alert | | struct TORRENT_EXPORT torrent_paused_alert: torrent_alert | |
| { | | { | |
| torrent_paused_alert(torrent_handle const& h) | | torrent_paused_alert(torrent_handle const& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(torrent_paused_alert); | |
| { return std::auto_ptr<alert>(new torrent_paused_alert(*this | | | |
| )); } | | | |
| virtual char const* what() const { return "torrent paused"; | | | |
| } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " paused"; } | |
| return torrent_alert::message() + " paused"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_resumed_alert: torrent_alert | | struct TORRENT_EXPORT torrent_resumed_alert: torrent_alert | |
| { | | { | |
| torrent_resumed_alert(torrent_handle const& h) | | torrent_resumed_alert(torrent_handle const& h) | |
| : torrent_alert(h) {} | | : torrent_alert(h) {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(torrent_resumed_alert); | |
| { return std::auto_ptr<alert>(new torrent_resumed_alert(*thi | | | |
| s)); } | | | |
| virtual char const* what() const { return "torrent resumed"; | | | |
| } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " resumed"; } | |
| return torrent_alert::message() + " resumed"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_checked_alert: torrent_alert | | struct TORRENT_EXPORT torrent_checked_alert: torrent_alert | |
| { | | { | |
| torrent_checked_alert(torrent_handle const& h) | | torrent_checked_alert(torrent_handle const& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(torrent_checked_alert); | |
| { return std::auto_ptr<alert>(new torrent_checked_alert(*thi | | | |
| s)); } | | | |
| virtual char const* what() const { return "torrent checked"; | | | |
| } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " checked"; } | |
| return torrent_alert::message() + " checked"; | | }; | |
| } | | | |
| }; | | | |
| | | | |
| struct TORRENT_EXPORT url_seed_alert: torrent_alert | | struct TORRENT_EXPORT url_seed_alert: torrent_alert | |
| { | | { | |
| url_seed_alert( | | url_seed_alert( | |
| torrent_handle const& h | | torrent_handle const& h | |
| , std::string const& url_ | | , std::string const& url_ | |
| , error_code const& e) | | , error_code const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , url(url_) | | , url(url_) | |
| , msg(e.message()) | | , msg(e.message()) | |
| | | | |
| skipping to change at line 1034 | | skipping to change at line 845 | |
| | | | |
| url_seed_alert( | | url_seed_alert( | |
| torrent_handle const& h | | torrent_handle const& h | |
| , std::string const& url_ | | , std::string const& url_ | |
| , std::string const& msg_) | | , std::string const& msg_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , url(url_) | | , url(url_) | |
| , msg(msg_) | | , msg(msg_) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(url_seed_alert); | |
| { return std::auto_ptr<alert>(new url_seed_alert(*this)); } | | | |
| virtual char const* what() const { return "web seed error"; | | | |
| } | | | |
| const static int static_category = alert::peer_notification
| alert::error_notification; | | const static int static_category = alert::peer_notification
| alert::error_notification; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " url seed (" | | return torrent_alert::message() + " url seed (" | |
| + url + ") failed: " + msg; | | + url + ") failed: " + msg; | |
| } | | } | |
| | | | |
| std::string url; | | std::string url; | |
| std::string msg; | | std::string msg; | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1064 | | skipping to change at line 873 | |
| , error_code const& e) | | , error_code const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , file(f) | | , file(f) | |
| , error(e) | | , error(e) | |
| { | | { | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| msg = error.message(); | | msg = error.message(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| std::string file; | | TORRENT_DEFINE_ALERT(file_error_alert); | |
| error_code error; | | | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | | |
| std::string msg; | | | |
| #endif | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new file_error_alert(*this)); | | | |
| } | | | |
| virtual char const* what() const { return "file error"; } | | | |
| const static int static_category = alert::status_notificatio
n | | const static int static_category = alert::status_notificatio
n | |
| | alert::error_notification | | | alert::error_notification | |
| | alert::storage_notification; | | | alert::storage_notification; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " file (" + file +
") error: " | | return torrent_alert::message() + " file (" + file +
") error: " | |
| + error.message(); | | + error.message(); | |
| } | | } | |
|
| | | | |
| | | std::string file; | |
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | std::string msg; | |
| | | #endif | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT metadata_failed_alert: torrent_alert | | struct TORRENT_EXPORT metadata_failed_alert: torrent_alert | |
| { | | { | |
| metadata_failed_alert(const torrent_handle& h) | | metadata_failed_alert(const torrent_handle& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(metadata_failed_alert); | |
| { return std::auto_ptr<alert>(new metadata_failed_alert(*thi | | | |
| s)); } | | | |
| virtual char const* what() const { return "metadata failed"; | | | |
| } | | | |
| const static int static_category = alert::error_notification
; | | const static int static_category = alert::error_notification
; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " invalid metadata recei | |
| return torrent_alert::message() + " invalid metadata | | ved"; } | |
| received"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT metadata_received_alert: torrent_alert | | struct TORRENT_EXPORT metadata_received_alert: torrent_alert | |
| { | | { | |
| metadata_received_alert( | | metadata_received_alert( | |
| const torrent_handle& h) | | const torrent_handle& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| {} | | {} | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(metadata_received_alert); | |
| { return std::auto_ptr<alert>(new metadata_received_alert(*t | | | |
| his)); } | | | |
| virtual char const* what() const { return "metadata received | | | |
| "; } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
|
| { | | { return torrent_alert::message() + " metadata successfully | |
| return torrent_alert::message() + " metadata success | | received"; } | |
| fully received"; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT udp_error_alert: alert | | struct TORRENT_EXPORT udp_error_alert: alert | |
| { | | { | |
| udp_error_alert( | | udp_error_alert( | |
| udp::endpoint const& ep | | udp::endpoint const& ep | |
| , error_code const& ec) | | , error_code const& ec) | |
| : endpoint(ep) | | : endpoint(ep) | |
| , error(ec) | | , error(ec) | |
| {} | | {} | |
| | | | |
|
| udp::endpoint endpoint; | | TORRENT_DEFINE_ALERT(udp_error_alert); | |
| error_code error; | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new udp_error_alert(*this)); } | | | |
| virtual char const* what() const { return "udp error"; } | | | |
| const static int static_category = alert::error_notification
; | | const static int static_category = alert::error_notification
; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| return "UDP error: " + error.message() + " from: " +
endpoint.address().to_string(ec); | | return "UDP error: " + error.message() + " from: " +
endpoint.address().to_string(ec); | |
| } | | } | |
|
| | | | |
| | | udp::endpoint endpoint; | |
| | | error_code error; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT external_ip_alert: alert | | struct TORRENT_EXPORT external_ip_alert: alert | |
| { | | { | |
| external_ip_alert(address const& ip) | | external_ip_alert(address const& ip) | |
| : external_address(ip) | | : external_address(ip) | |
| {} | | {} | |
| | | | |
|
| address external_address; | | TORRENT_DEFINE_ALERT(external_ip_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new external_ip_alert(*this)); | | | |
| } | | | |
| virtual char const* what() const { return "external IP recei | | | |
| ved"; } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| return "external IP received: " + external_address.t
o_string(ec); | | return "external IP received: " + external_address.t
o_string(ec); | |
| } | | } | |
|
| | | | |
| | | address external_address; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT listen_failed_alert: alert | | struct TORRENT_EXPORT listen_failed_alert: alert | |
| { | | { | |
| listen_failed_alert( | | listen_failed_alert( | |
| tcp::endpoint const& ep | | tcp::endpoint const& ep | |
| , error_code const& ec) | | , error_code const& ec) | |
| : endpoint(ep) | | : endpoint(ep) | |
| , error(ec) | | , error(ec) | |
| {} | | {} | |
| | | | |
|
| tcp::endpoint endpoint; | | TORRENT_DEFINE_ALERT(listen_failed_alert); | |
| error_code error; | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new listen_failed_alert(*this) | | | |
| ); } | | | |
| virtual char const* what() const { return "listen failed"; } | | | |
| const static int static_category = alert::status_notificatio
n | alert::error_notification; | | const static int static_category = alert::status_notificatio
n | alert::error_notification; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | virtual bool discardable() const { return false; } | |
| { | | | |
| char ret[200]; | | tcp::endpoint endpoint; | |
| snprintf(ret, sizeof(ret), "listening on %s failed: | | error_code error; | |
| %s" | | | |
| , print_endpoint(endpoint).c_str(), error.me | | | |
| ssage().c_str()); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT listen_succeeded_alert: alert | | struct TORRENT_EXPORT listen_succeeded_alert: alert | |
| { | | { | |
| listen_succeeded_alert(tcp::endpoint const& ep) | | listen_succeeded_alert(tcp::endpoint const& ep) | |
| : endpoint(ep) | | : endpoint(ep) | |
| {} | | {} | |
| | | | |
|
| tcp::endpoint endpoint; | | TORRENT_DEFINE_ALERT(listen_succeeded_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new listen_succeeded_alert(*th | | | |
| is)); } | | | |
| virtual char const* what() const { return "listen succeeded" | | | |
| ; } | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | virtual bool discardable() const { return false; } | |
| { | | | |
| char ret[200]; | | tcp::endpoint endpoint; | |
| snprintf(ret, sizeof(ret), "successfully listening o | | | |
| n %s", print_endpoint(endpoint).c_str()); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT portmap_error_alert: alert | | struct TORRENT_EXPORT portmap_error_alert: alert | |
| { | | { | |
| portmap_error_alert(int i, int t, error_code const& e) | | portmap_error_alert(int i, int t, error_code const& e) | |
|
| : mapping(i), type(t), error(e) | | : mapping(i), map_type(t), error(e) | |
| { | | { | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| msg = error.message(); | | msg = error.message(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| | | TORRENT_DEFINE_ALERT(portmap_error_alert); | |
| | | | |
| | | const static int static_category = alert::port_mapping_notif | |
| | | ication | |
| | | | alert::error_notification; | |
| | | virtual std::string message() const; | |
| | | | |
| int mapping; | | int mapping; | |
|
| int type; | | int map_type; | |
| error_code error; | | error_code error; | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
| #endif | | #endif | |
|
| | | | |
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new portmap_error_alert(*this) | | | |
| ); } | | | |
| virtual char const* what() const { return "port map error"; | | | |
| } | | | |
| const static int static_category = alert::port_mapping_notif | | | |
| ication | | | |
| | alert::error_notification; | | | |
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| static char const* type_str[] = {"NAT-PMP", "UPnP"}; | | | |
| return std::string("could not map port using ") + ty | | | |
| pe_str[type] | | | |
| + ": " + error.message(); | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT portmap_alert: alert | | struct TORRENT_EXPORT portmap_alert: alert | |
| { | | { | |
| portmap_alert(int i, int port, int t) | | portmap_alert(int i, int port, int t) | |
|
| : mapping(i), external_port(port), type(t) | | : mapping(i), external_port(port), map_type(t) | |
| {} | | {} | |
| | | | |
|
| int mapping; | | TORRENT_DEFINE_ALERT(portmap_alert); | |
| int external_port; | | | |
| int type; | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new portmap_alert(*this)); } | | | |
| virtual char const* what() const { return "port map succeede | | | |
| d"; } | | | |
| const static int static_category = alert::port_mapping_notif
ication; | | const static int static_category = alert::port_mapping_notif
ication; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | int mapping; | |
| static char const* type_str[] = {"NAT-PMP", "UPnP"}; | | int external_port; | |
| char ret[200]; | | int map_type; | |
| snprintf(ret, sizeof(ret), "successfully mapped port | | | |
| using %s. external port: %u" | | | |
| , type_str[type], external_port); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT portmap_log_alert: alert | | struct TORRENT_EXPORT portmap_log_alert: alert | |
| { | | { | |
| portmap_log_alert(int t, std::string const& m) | | portmap_log_alert(int t, std::string const& m) | |
|
| : type(t), msg(m) | | : map_type(t), msg(m) | |
| {} | | {} | |
| | | | |
|
| int type; | | TORRENT_DEFINE_ALERT(portmap_log_alert); | |
| std::string msg; | | | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new portmap_log_alert(*this)); | | | |
| } | | | |
| virtual char const* what() const { return "port map log"; } | | | |
| const static int static_category = alert::port_mapping_notif
ication; | | const static int static_category = alert::port_mapping_notif
ication; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | int map_type; | |
| static char const* type_str[] = {"NAT-PMP", "UPnP"}; | | std::string msg; | |
| char ret[600]; | | | |
| snprintf(ret, sizeof(ret), "%s: %s", type_str[type], | | | |
| msg.c_str()); | | | |
| return ret; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert | | struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert | |
| { | | { | |
| fastresume_rejected_alert(torrent_handle const& h | | fastresume_rejected_alert(torrent_handle const& h | |
| , error_code const& e) | | , error_code const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , error(e) | | , error(e) | |
| { | | { | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| msg = error.message(); | | msg = error.message(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| | | TORRENT_DEFINE_ALERT(fastresume_rejected_alert); | |
| | | | |
| | | const static int static_category = alert::status_notificatio | |
| | | n | |
| | | | alert::error_notification; | |
| | | virtual std::string message() const | |
| | | { return torrent_alert::message() + " fast resume rejected: | |
| | | " + error.message(); } | |
| | | | |
| error_code error; | | error_code error; | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
| #endif | | #endif | |
|
| | | | |
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new fastresume_rejected_alert( | | | |
| *this)); } | | | |
| virtual char const* what() const { return "resume data rejec | | | |
| ted"; } | | | |
| const static int static_category = alert::status_notificatio | | | |
| n | | | |
| | alert::error_notification; | | | |
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| return torrent_alert::message() + " fast resume reje | | | |
| cted: " + error.message(); | | | |
| } | | | |
| }; | | }; | |
| | | | |
|
| struct TORRENT_EXPORT peer_blocked_alert: alert | | struct TORRENT_EXPORT peer_blocked_alert: torrent_alert | |
| { | | { | |
|
| peer_blocked_alert(address const& ip_) | | peer_blocked_alert(torrent_handle const& h, address const& i | |
| : ip(ip_) | | p_) | |
| | | : torrent_alert(h) | |
| | | , ip(ip_) | |
| {} | | {} | |
| | | | |
|
| address ip; | | TORRENT_DEFINE_ALERT(peer_blocked_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new peer_blocked_alert(*this)) | | | |
| ; } | | | |
| virtual char const* what() const { return "peer blocked"; } | | | |
| const static int static_category = alert::ip_block_notificat
ion; | | const static int static_category = alert::ip_block_notificat
ion; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| error_code ec; | | error_code ec; | |
|
| return "blocked peer: " + ip.to_string(ec); | | return torrent_alert::message() + ": blocked peer: "
+ ip.to_string(ec); | |
| } | | } | |
|
| | | | |
| | | address ip; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT dht_announce_alert: alert | | struct TORRENT_EXPORT dht_announce_alert: alert | |
| { | | { | |
| dht_announce_alert(address const& ip_, int port_ | | dht_announce_alert(address const& ip_, int port_ | |
| , sha1_hash const& info_hash_) | | , sha1_hash const& info_hash_) | |
| : ip(ip_) | | : ip(ip_) | |
| , port(port_) | | , port(port_) | |
| , info_hash(info_hash_) | | , info_hash(info_hash_) | |
| {} | | {} | |
| | | | |
|
| | | TORRENT_DEFINE_ALERT(dht_announce_alert); | |
| | | | |
| | | const static int static_category = alert::dht_notification; | |
| | | virtual std::string message() const; | |
| | | | |
| address ip; | | address ip; | |
| int port; | | int port; | |
| sha1_hash info_hash; | | sha1_hash info_hash; | |
|
| | | | |
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new dht_announce_alert(*this)) | | | |
| ; } | | | |
| virtual char const* what() const { return "incoming dht anno | | | |
| unce"; } | | | |
| const static int static_category = alert::dht_notification; | | | |
| virtual int category() const { return static_category; } | | | |
| virtual std::string message() const | | | |
| { | | | |
| error_code ec; | | | |
| char ih_hex[41]; | | | |
| to_hex((const char*)&info_hash[0], 20, ih_hex); | | | |
| char msg[200]; | | | |
| snprintf(msg, sizeof(msg), "incoming dht announce: % | | | |
| s:%u (%s)" | | | |
| , ip.to_string(ec).c_str(), port, ih_hex); | | | |
| return msg; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT dht_get_peers_alert: alert | | struct TORRENT_EXPORT dht_get_peers_alert: alert | |
| { | | { | |
| dht_get_peers_alert(sha1_hash const& info_hash_) | | dht_get_peers_alert(sha1_hash const& info_hash_) | |
| : info_hash(info_hash_) | | : info_hash(info_hash_) | |
| {} | | {} | |
| | | | |
|
| sha1_hash info_hash; | | TORRENT_DEFINE_ALERT(dht_get_peers_alert); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | | |
| { return std::auto_ptr<alert>(new dht_get_peers_alert(*this) | | | |
| ); } | | | |
| virtual char const* what() const { return "incoming dht get_ | | | |
| peers request"; } | | | |
| const static int static_category = alert::dht_notification; | | const static int static_category = alert::dht_notification; | |
|
| virtual int category() const { return static_category; } | | virtual std::string message() const; | |
| virtual std::string message() const | | | |
| { | | sha1_hash info_hash; | |
| char ih_hex[41]; | | | |
| to_hex((const char*)&info_hash[0], 20, ih_hex); | | | |
| char msg[200]; | | | |
| snprintf(msg, sizeof(msg), "incoming dht get_peers: | | | |
| %s", ih_hex); | | | |
| return msg; | | | |
| } | | | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT stats_alert: torrent_alert | | struct TORRENT_EXPORT stats_alert: torrent_alert | |
| { | | { | |
| stats_alert(torrent_handle const& h, int interval | | stats_alert(torrent_handle const& h, int interval | |
| , stat const& s); | | , stat const& s); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(stats_alert); | |
| { return std::auto_ptr<alert>(new stats_alert(*this)); } | | | |
| const static int static_category = alert::stats_notification | | | |
| ; | | | |
| virtual int category() const { return static_category; } | | | |
| virtual char const* what() const { return "stats_alert"; } | | | |
| | | | |
|
| | | const static int static_category = alert::stats_notification
; | |
| virtual std::string message() const; | | virtual std::string message() const; | |
| | | | |
| enum stats_channel | | enum stats_channel | |
| { | | { | |
| upload_payload, | | upload_payload, | |
| upload_protocol, | | upload_protocol, | |
|
| | | download_payload, | |
| | | download_protocol, | |
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| upload_ip_protocol, | | upload_ip_protocol, | |
| upload_dht_protocol, | | upload_dht_protocol, | |
| upload_tracker_protocol, | | upload_tracker_protocol, | |
|
| download_payload, | | | |
| download_protocol, | | | |
| download_ip_protocol, | | download_ip_protocol, | |
| download_dht_protocol, | | download_dht_protocol, | |
| download_tracker_protocol, | | download_tracker_protocol, | |
|
| | | #endif | |
| num_channels | | num_channels | |
| }; | | }; | |
| | | | |
| int transferred[num_channels]; | | int transferred[num_channels]; | |
| int interval; | | int interval; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT cache_flushed_alert: torrent_alert | | struct TORRENT_EXPORT cache_flushed_alert: torrent_alert | |
| { | | { | |
| cache_flushed_alert(torrent_handle const& h); | | cache_flushed_alert(torrent_handle const& h); | |
| | | | |
|
| virtual std::auto_ptr<alert> clone() const | | TORRENT_DEFINE_ALERT(cache_flushed_alert); | |
| { return std::auto_ptr<alert>(new cache_flushed_alert(*this) | | | |
| ); } | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
|
| virtual int category() const { return static_category; } | | | |
| virtual char const* what() const { return "cache_flushed_ale | | | |
| rt"; } | | | |
| }; | | }; | |
|
| | | | |
| | | 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; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT lsd_peer_alert: peer_alert | |
| | | { | |
| | | lsd_peer_alert(torrent_handle const& h | |
| | | , tcp::endpoint const& ip_) | |
| | | : peer_alert(h, ip_, peer_id(0)) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(lsd_peer_alert); | |
| | | | |
| | | const static int static_category = alert::peer_notification; | |
| | | virtual std::string message() const; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT trackerid_alert: tracker_alert | |
| | | { | |
| | | trackerid_alert(torrent_handle const& h | |
| | | , std::string const& url_ | |
| | | , const std::string& id) | |
| | | : tracker_alert(h, url_) | |
| | | , trackerid(id) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(trackerid_alert); | |
| | | | |
| | | const static int static_category = alert::status_notificatio | |
| | | n; | |
| | | virtual std::string message() const; | |
| | | | |
| | | std::string trackerid; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT dht_bootstrap_alert: alert | |
| | | { | |
| | | dht_bootstrap_alert() {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(dht_bootstrap_alert); | |
| | | | |
| | | const static int static_category = alert::dht_notification; | |
| | | virtual std::string message() const; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT rss_alert: alert | |
| | | { | |
| | | rss_alert(feed_handle h, std::string const& url_, int state_ | |
| | | , error_code const& ec) | |
| | | : handle(h), url(url_), state(state_), error(ec) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(rss_alert); | |
| | | | |
| | | const static int static_category = alert::rss_notification; | |
| | | virtual std::string message() const; | |
| | | | |
| | | enum state_t | |
| | | { | |
| | | state_updating, state_updated, state_error | |
| | | }; | |
| | | | |
| | | feed_handle handle; | |
| | | std::string url; | |
| | | int state; | |
| | | error_code error; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT torrent_error_alert: torrent_alert | |
| | | { | |
| | | torrent_error_alert(torrent_handle const& h | |
| | | , error_code const& e) | |
| | | : torrent_alert(h) | |
| | | , error(e) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(torrent_error_alert); | |
| | | | |
| | | const static int static_category = alert::error_notification | |
| | | | alert::status_notification; | |
| | | virtual std::string message() const; | |
| | | | |
| | | error_code error; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT torrent_need_cert_alert: torrent_alert | |
| | | { | |
| | | torrent_need_cert_alert(torrent_handle const& h) | |
| | | : torrent_alert(h) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(torrent_need_cert_alert); | |
| | | | |
| | | const static int static_category = alert::status_notificatio | |
| | | n; | |
| | | virtual std::string message() const; | |
| | | virtual bool discardable() const { return false; } | |
| | | | |
| | | error_code error; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT incoming_connection_alert: alert | |
| | | { | |
| | | incoming_connection_alert(int type_, tcp::endpoint const& ip | |
| | | _) | |
| | | : socket_type(type_) | |
| | | , ip(ip_) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(incoming_connection_alert); | |
| | | | |
| | | const static int static_category = alert::peer_notification; | |
| | | virtual std::string message() const; | |
| | | | |
| | | int socket_type; | |
| | | tcp::endpoint ip; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT add_torrent_alert : torrent_alert | |
| | | { | |
| | | add_torrent_alert(torrent_handle h, add_torrent_params const | |
| | | & p, error_code ec) | |
| | | : torrent_alert(h) | |
| | | , params(p) | |
| | | , error(ec) | |
| | | {} | |
| | | | |
| | | TORRENT_DEFINE_ALERT(add_torrent_alert); | |
| | | | |
| | | const static int static_category = alert::status_notificatio | |
| | | n; | |
| | | virtual std::string message() const; | |
| | | virtual bool discardable() const { return false; } | |
| | | | |
| | | add_torrent_params params; | |
| | | error_code error; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT state_update_alert : alert | |
| | | { | |
| | | TORRENT_DEFINE_ALERT(state_update_alert); | |
| | | | |
| | | const static int static_category = alert::status_notificatio | |
| | | n; | |
| | | virtual std::string message() const; | |
| | | virtual bool discardable() const { return false; } | |
| | | | |
| | | std::vector<torrent_status> status; | |
| | | }; | |
| | | | |
| | | #undef TORRENT_DEFINE_ALERT | |
| | | | |
| } | | } | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 169 change blocks. |
| 701 lines changed or deleted | | 473 lines changed or added | |
|
| bt_peer_connection.hpp | | bt_peer_connection.hpp | |
| | | | |
| skipping to change at line 62 | | skipping to change at line 62 | |
| #include <boost/cstdint.hpp> | | #include <boost/cstdint.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/buffer.hpp" | | #include "libtorrent/buffer.hpp" | |
| #include "libtorrent/peer_connection.hpp" | | #include "libtorrent/peer_connection.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
|
| #include "libtorrent/storage.hpp" | | | |
| #include "libtorrent/stat.hpp" | | #include "libtorrent/stat.hpp" | |
| #include "libtorrent/alert.hpp" | | #include "libtorrent/alert.hpp" | |
|
| #include "libtorrent/torrent_handle.hpp" | | | |
| #include "libtorrent/torrent.hpp" | | #include "libtorrent/torrent.hpp" | |
| #include "libtorrent/peer_request.hpp" | | #include "libtorrent/peer_request.hpp" | |
| #include "libtorrent/piece_block_progress.hpp" | | #include "libtorrent/piece_block_progress.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/pe_crypto.hpp" | | #include "libtorrent/pe_crypto.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| class torrent; | | class torrent; | |
| | | | |
| namespace detail | | namespace detail | |
| { | | { | |
| struct session_impl; | | struct session_impl; | |
| } | | } | |
| | | | |
|
| class TORRENT_EXPORT bt_peer_connection | | class TORRENT_EXTRA_EXPORT bt_peer_connection | |
| : public peer_connection | | : public peer_connection | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| public: | | public: | |
| | | | |
| // this is the constructor where the we are the active part. | | // this is the constructor where the we are the active part. | |
| // The peer_conenction should handshake and verify that the | | // The peer_conenction should handshake and verify that the | |
| // other end has the correct id | | // other end has the correct id | |
| bt_peer_connection( | | bt_peer_connection( | |
| aux::session_impl& ses | | aux::session_impl& ses | |
| , boost::weak_ptr<torrent> t | | , boost::weak_ptr<torrent> t | |
| , boost::shared_ptr<socket_type> s | | , boost::shared_ptr<socket_type> s | |
| , tcp::endpoint const& remote | | , tcp::endpoint const& remote | |
|
| , policy::peer* peerinfo); | | , policy::peer* peerinfo | |
| | | , bool outgoing = true); | |
| | | | |
| // with this constructor we have been contacted and we still
don't | | // with this constructor we have been contacted and we still
don't | |
| // know which torrent the connection belongs to | | // know which torrent the connection belongs to | |
| bt_peer_connection( | | bt_peer_connection( | |
| aux::session_impl& ses | | aux::session_impl& ses | |
| , boost::shared_ptr<socket_type> s | | , boost::shared_ptr<socket_type> s | |
| , tcp::endpoint const& remote | | , tcp::endpoint const& remote | |
| , policy::peer* peerinfo); | | , policy::peer* peerinfo); | |
| | | | |
| void start(); | | void start(); | |
| | | | |
|
| enum { | | enum | |
| | | { | |
| upload_only_msg = 2, | | upload_only_msg = 2, | |
|
| dont_have_msg = 5 | | holepunch_msg = 3, | |
| | | share_mode_msg = 4, | |
| | | dont_have_msg = 5, | |
| }; | | }; | |
| | | | |
| ~bt_peer_connection(); | | ~bt_peer_connection(); | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| bool supports_encryption() const | | bool supports_encryption() const | |
| { return m_encrypted; } | | { return m_encrypted; } | |
|
| | | bool rc4_encrypted() const | |
| | | { return m_rc4_encrypted; } | |
| #endif | | #endif | |
| | | | |
|
| | | virtual int type() const { return peer_connection::bittorren | |
| | | t_connection; } | |
| | | | |
| enum message_type | | enum message_type | |
| { | | { | |
| // standard messages | | // standard messages | |
| msg_choke = 0, | | msg_choke = 0, | |
| msg_unchoke, | | msg_unchoke, | |
| msg_interested, | | msg_interested, | |
| msg_not_interested, | | msg_not_interested, | |
| msg_have, | | msg_have, | |
| msg_bitfield, | | msg_bitfield, | |
| msg_request, | | msg_request, | |
| | | | |
| skipping to change at line 146 | | skipping to change at line 152 | |
| msg_have_none, | | msg_have_none, | |
| msg_reject_request, | | msg_reject_request, | |
| msg_allowed_fast, | | msg_allowed_fast, | |
| | | | |
| // extension protocol message | | // extension protocol message | |
| msg_extended = 20, | | msg_extended = 20, | |
| | | | |
| num_supported_messages | | num_supported_messages | |
| }; | | }; | |
| | | | |
|
| | | enum hp_message_t | |
| | | { | |
| | | // msg_types | |
| | | hp_rendezvous = 0, | |
| | | hp_connect = 1, | |
| | | hp_failed = 2, | |
| | | | |
| | | // error codes | |
| | | hp_no_such_peer = 1, | |
| | | hp_not_connected = 2, | |
| | | hp_no_support = 3, | |
| | | hp_no_self = 4 | |
| | | }; | |
| | | | |
| // called from the main loop when this connection has any | | // called from the main loop when this connection has any | |
| // work to do. | | // work to do. | |
| | | | |
| void on_sent(error_code const& error | | void on_sent(error_code const& error | |
| , std::size_t bytes_transferred); | | , std::size_t bytes_transferred); | |
| void on_receive(error_code const& error | | void on_receive(error_code const& error | |
| , std::size_t bytes_transferred); | | , std::size_t bytes_transferred); | |
| | | | |
| virtual void get_specific_peer_info(peer_info& p) const; | | virtual void get_specific_peer_info(peer_info& p) const; | |
| virtual bool in_handshake() const; | | virtual bool in_handshake() const; | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
|
| bool support_extensions() const { return m_supports_extensio | | bool supports_holepunch() const { return m_holepunch_id != 0 | |
| ns; } | | ; } | |
| | | | |
| template <class T> | | | |
| T* supports_extension() const | | | |
| { | | | |
| for (extension_list_t::const_iterator i = m_extensio | | | |
| ns.begin() | | | |
| , end(m_extensions.end()); i != end; ++i) | | | |
| { | | | |
| T* ret = dynamic_cast<T*>(i->get()); | | | |
| if (ret) return ret; | | | |
| } | | | |
| return 0; | | | |
| } | | | |
| #endif | | #endif | |
| | | | |
|
| | | bool support_extensions() const { return m_supports_extensio | |
| | | ns; } | |
| | | | |
| // the message handlers are called | | // the message handlers are called | |
| // each time a recv() returns some new | | // each time a recv() returns some new | |
| // data, the last time it will be called | | // data, the last time it will be called | |
| // is when the entire packet has been | | // is when the entire packet has been | |
| // received, then it will no longer | | // received, then it will no longer | |
| // be called. i.e. most handlers need | | // be called. i.e. most handlers need | |
| // to check how much of the packet they | | // to check how much of the packet they | |
| // have received before any processing | | // have received before any processing | |
| void on_keepalive(); | | void on_keepalive(); | |
| void on_choke(int received); | | void on_choke(int received); | |
| | | | |
| skipping to change at line 201 | | skipping to change at line 211 | |
| | | | |
| // DHT extension | | // DHT extension | |
| void on_dht_port(int received); | | void on_dht_port(int received); | |
| | | | |
| // FAST extension | | // FAST extension | |
| void on_suggest_piece(int received); | | void on_suggest_piece(int received); | |
| void on_have_all(int received); | | void on_have_all(int received); | |
| void on_have_none(int received); | | void on_have_none(int received); | |
| void on_reject_request(int received); | | void on_reject_request(int received); | |
| void on_allowed_fast(int received); | | void on_allowed_fast(int received); | |
|
| | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| | | void on_holepunch(); | |
| | | #endif | |
| | | | |
| void on_extended(int received); | | void on_extended(int received); | |
| | | | |
| void on_extended_handshake(); | | void on_extended_handshake(); | |
| | | | |
| typedef void (bt_peer_connection::*message_handler)(int rece
ived); | | typedef void (bt_peer_connection::*message_handler)(int rece
ived); | |
| | | | |
| // the following functions appends messages | | // the following functions appends messages | |
| // to the send buffer | | // to the send buffer | |
| void write_choke(); | | void write_choke(); | |
| | | | |
| skipping to change at line 223 | | skipping to change at line 236 | |
| void write_not_interested(); | | void write_not_interested(); | |
| void write_request(peer_request const& r); | | void write_request(peer_request const& r); | |
| void write_cancel(peer_request const& r); | | void write_cancel(peer_request const& r); | |
| void write_bitfield(); | | void write_bitfield(); | |
| void write_have(int index); | | void write_have(int index); | |
| void write_piece(peer_request const& r, disk_buffer_holder&
buffer); | | void write_piece(peer_request const& r, disk_buffer_holder&
buffer); | |
| void write_handshake(); | | void write_handshake(); | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void write_extensions(); | | void write_extensions(); | |
| void write_upload_only(); | | void write_upload_only(); | |
|
| | | void write_share_mode(); | |
| | | void write_holepunch_msg(int type, tcp::endpoint const& ep, | |
| | | int error); | |
| #endif | | #endif | |
| void write_metadata(std::pair<int, int> req); | | void write_metadata(std::pair<int, int> req); | |
| void write_metadata_request(std::pair<int, int> req); | | void write_metadata_request(std::pair<int, int> req); | |
| void write_keepalive(); | | void write_keepalive(); | |
| | | | |
| // DHT extension | | // DHT extension | |
| void write_dht_port(int listen_port); | | void write_dht_port(int listen_port); | |
| | | | |
| // FAST extension | | // FAST extension | |
| void write_have_all(); | | void write_have_all(); | |
| void write_have_none(); | | void write_have_none(); | |
| void write_reject_request(peer_request const&); | | void write_reject_request(peer_request const&); | |
| void write_allow_fast(int piece); | | void write_allow_fast(int piece); | |
|
| | | void write_suggest(int piece); | |
| | | | |
| void on_connected(); | | void on_connected(); | |
| void on_metadata(); | | void on_metadata(); | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| ptime m_last_choke; | | ptime m_last_choke; | |
| #endif | | #endif | |
| | | | |
| private: | | private: | |
| | | | |
| skipping to change at line 269 | | skipping to change at line 285 | |
| // 1. a -> b dhkey, pad | | // 1. a -> b dhkey, pad | |
| // 2. b -> a dhkey, pad | | // 2. b -> a dhkey, pad | |
| // 3. a -> b sync, payload | | // 3. a -> b sync, payload | |
| // 4. b -> a sync, payload | | // 4. b -> a sync, payload | |
| // 5. a -> b payload | | // 5. a -> b payload | |
| | | | |
| void write_pe1_2_dhkey(); | | void write_pe1_2_dhkey(); | |
| void write_pe3_sync(); | | void write_pe3_sync(); | |
| void write_pe4_sync(int crypto_select); | | void write_pe4_sync(int crypto_select); | |
| | | | |
|
| void write_pe_vc_cryptofield(buffer::interval& write_buf | | void write_pe_vc_cryptofield(char* write_buf, int len | |
| , int crypto_field, int pad_size); | | , int crypto_field, int pad_size); | |
| | | | |
| // stream key (info hash of attached torrent) | | // stream key (info hash of attached torrent) | |
| // secret is the DH shared secret | | // secret is the DH shared secret | |
|
| // initializes m_RC4_handler | | // initializes m_enc_handler | |
| void init_pe_RC4_handler(char const* secret, sha1_hash const | | void init_pe_rc4_handler(char const* secret, sha1_hash const | |
| & stream_key); | | & stream_key); | |
| | | | |
| public: | | public: | |
| | | | |
| // these functions encrypt the send buffer if m_rc4_encrypte
d | | // these functions encrypt the send buffer if m_rc4_encrypte
d | |
| // is true, otherwise it passes the call to the | | // is true, otherwise it passes the call to the | |
| // peer_connection functions of the same names | | // peer_connection functions of the same names | |
| virtual void append_const_send_buffer(char const* buffer, in
t size); | | virtual void append_const_send_buffer(char const* buffer, in
t size); | |
|
| void send_buffer(char const* buf, int size, int flags = 0); | | virtual void send_buffer(char const* begin, int size, int fl | |
| buffer::interval allocate_send_buffer(int size); | | ags = 0 | |
| | | , void (*fun)(char*, int, void*) = 0, void* userdata | |
| | | = 0); | |
| template <class Destructor> | | template <class Destructor> | |
| void append_send_buffer(char* buffer, int size, Destructor c
onst& destructor) | | void append_send_buffer(char* buffer, int size, Destructor c
onst& destructor) | |
| { | | { | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| if (m_rc4_encrypted) | | if (m_rc4_encrypted) | |
|
| { | | m_enc_handler->encrypt(buffer, size); | |
| TORRENT_ASSERT(send_buffer_size() == m_encry | | | |
| pted_bytes); | | | |
| m_RC4_handler->encrypt(buffer, size); | | | |
| #ifdef TORRENT_DEBUG | | | |
| m_encrypted_bytes += size; | | | |
| TORRENT_ASSERT(m_encrypted_bytes == send_buf | | | |
| fer_size() + size); | | | |
| #endif | | | |
| } | | | |
| #endif | | #endif | |
|
| peer_connection::append_send_buffer(buffer, size, de
structor); | | peer_connection::append_send_buffer(buffer, size, de
structor, true); | |
| } | | } | |
|
| void setup_send(); | | | |
| | | | |
| private: | | private: | |
| | | | |
|
| void encrypt_pending_buffer(); | | | |
| | | | |
| // Returns offset at which bytestream (src, src + src_size) | | // Returns offset at which bytestream (src, src + src_size) | |
| // matches bytestream(target, target + target_size). | | // matches bytestream(target, target + target_size). | |
| // If no sync found, return -1 | | // If no sync found, return -1 | |
| int get_syncoffset(char const* src, int src_size | | int get_syncoffset(char const* src, int src_size | |
| , char const* target, int target_size) const; | | , char const* target, int target_size) const; | |
| #endif | | #endif | |
| | | | |
| enum state | | enum state | |
| { | | { | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| | | | |
| skipping to change at line 373 | | skipping to change at line 379 | |
| TORRENT_ASSERT(s >= 0); | | TORRENT_ASSERT(s >= 0); | |
| TORRENT_ASSERT(l > 0); | | TORRENT_ASSERT(l > 0); | |
| } | | } | |
| int start; | | int start; | |
| int length; | | int length; | |
| }; | | }; | |
| static bool range_below_zero(const range& r) | | static bool range_below_zero(const range& r) | |
| { return r.start < 0; } | | { return r.start < 0; } | |
| std::vector<range> m_payloads; | | std::vector<range> m_payloads; | |
| | | | |
|
| | | // we have suggested these pieces to the peer | |
| | | // don't suggest it again | |
| | | bitfield m_sent_suggested_pieces; | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| // the message ID for upload only message | | // the message ID for upload only message | |
| // 0 if not supported | | // 0 if not supported | |
|
| int m_upload_only_id; | | boost::uint8_t m_upload_only_id; | |
| | | | |
| | | // the message ID for holepunch messages | |
| | | boost::uint8_t m_holepunch_id; | |
| | | | |
| // the message ID for don't-have message | | // the message ID for don't-have message | |
| boost::uint8_t m_dont_have_id; | | boost::uint8_t m_dont_have_id; | |
| | | | |
|
| | | // the message ID for share mode message | |
| | | // 0 if not supported | |
| | | boost::uint8_t m_share_mode_id; | |
| | | | |
| char m_reserved_bits[8]; | | char m_reserved_bits[8]; | |
|
| | | #endif | |
| // this is set to true if the handshake from | | // this is set to true if the handshake from | |
| // the peer indicated that it supports the | | // the peer indicated that it supports the | |
| // extension protocol | | // extension protocol | |
| bool m_supports_extensions:1; | | bool m_supports_extensions:1; | |
|
| #endif | | | |
| bool m_supports_dht_port:1; | | bool m_supports_dht_port:1; | |
| bool m_supports_fast:1; | | bool m_supports_fast:1; | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| // this is set to true after the encryption method has been | | // this is set to true after the encryption method has been | |
| // succesfully negotiated (either plaintext or rc4), to sign
al | | // succesfully negotiated (either plaintext or rc4), to sign
al | |
| // automatic encryption/decryption. | | // automatic encryption/decryption. | |
| bool m_encrypted; | | bool m_encrypted; | |
| | | | |
| // true if rc4, false if plaintext | | // true if rc4, false if plaintext | |
| bool m_rc4_encrypted; | | bool m_rc4_encrypted; | |
| | | | |
| // used to disconnect peer if sync points are not found with
in | | // used to disconnect peer if sync points are not found with
in | |
| // the maximum number of bytes | | // the maximum number of bytes | |
| int m_sync_bytes_read; | | int m_sync_bytes_read; | |
| | | | |
|
| // hold information about latest allocated send buffer | | | |
| // need to check for non zero (begin, end) for operations wi | | | |
| th this | | | |
| buffer::interval m_enc_send_buffer; | | | |
| | | | |
| // initialized during write_pe1_2_dhkey, and destroyed on | | // initialized during write_pe1_2_dhkey, and destroyed on | |
|
| // creation of m_RC4_handler. Cannot reinitialize once | | // creation of m_enc_handler. Cannot reinitialize once | |
| // initialized. | | // initialized. | |
| boost::scoped_ptr<dh_key_exchange> m_dh_key_exchange; | | boost::scoped_ptr<dh_key_exchange> m_dh_key_exchange; | |
| | | | |
|
| // if RC4 is negotiated, this is used for | | // if encryption is negotiated, this is used for | |
| // encryption/decryption during the entire session. Destroye
d | | // encryption/decryption during the entire session. Destroye
d | |
| // if plaintext is selected | | // if plaintext is selected | |
|
| boost::scoped_ptr<RC4_handler> m_RC4_handler; | | boost::scoped_ptr<encryption_handler> m_enc_handler; | |
| | | | |
| // (outgoing only) synchronize verification constant with | | // (outgoing only) synchronize verification constant with | |
|
| // remote peer, this will hold RC4_decrypt(vc). Destroyed | | // remote peer, this will hold rc4_decrypt(vc). Destroyed | |
| // after the sync step. | | // after the sync step. | |
| boost::scoped_array<char> m_sync_vc; | | boost::scoped_array<char> m_sync_vc; | |
| | | | |
| // (incoming only) synchronize hash with remote peer, holds | | // (incoming only) synchronize hash with remote peer, holds | |
| // the sync hash (hash("req1",secret)). Destroyed after the | | // the sync hash (hash("req1",secret)). Destroyed after the | |
| // sync step. | | // sync step. | |
| boost::scoped_ptr<sha1_hash> m_sync_hash; | | boost::scoped_ptr<sha1_hash> m_sync_hash; | |
| #endif // #ifndef TORRENT_DISABLE_ENCRYPTION | | #endif // #ifndef TORRENT_DISABLE_ENCRYPTION | |
| | | | |
|
| #ifdef TORRENT_DEBUG | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| // this is set to true when the client's | | // this is set to true when the client's | |
| // bitfield is sent to this peer | | // bitfield is sent to this peer | |
| bool m_sent_bitfield; | | bool m_sent_bitfield; | |
| | | | |
| bool m_in_constructor; | | bool m_in_constructor; | |
| | | | |
| bool m_sent_handshake; | | bool m_sent_handshake; | |
|
| | | | |
| // the number of bytes in the send buffer | | | |
| // that have been encrypted (only used for | | | |
| // encrypted connections) | | | |
| public: | | | |
| int m_encrypted_bytes; | | | |
| #endif | | #endif | |
| | | | |
| }; | | }; | |
| } | | } | |
| | | | |
| #endif // TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED | | #endif // TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED | |
| | | | |
End of changes. 33 change blocks. |
| 59 lines changed or deleted | | 67 lines changed or added | |
|
| config.hpp | | config.hpp | |
| | | | |
| skipping to change at line 41 | | skipping to change at line 41 | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_CONFIG_HPP_INCLUDED | | #ifndef TORRENT_CONFIG_HPP_INCLUDED | |
| #define TORRENT_CONFIG_HPP_INCLUDED | | #define TORRENT_CONFIG_HPP_INCLUDED | |
| | | | |
| #include <boost/config.hpp> | | #include <boost/config.hpp> | |
| #include <boost/version.hpp> | | #include <boost/version.hpp> | |
| #include <stdio.h> // for snprintf | | #include <stdio.h> // for snprintf | |
| #include <limits.h> // for IOV_MAX | | #include <limits.h> // for IOV_MAX | |
| | | | |
|
| #ifndef WIN32 | | #if defined TORRENT_DEBUG_BUFFERS && !defined TORRENT_DISABLE_POOL_ALLOCATO | |
| | | R | |
| | | #error TORRENT_DEBUG_BUFFERS only works if you also disable pool allocators | |
| | | with TORRENT_DISABLE_POOL_ALLOCATOR | |
| | | #endif | |
| | | | |
| | | #if !defined BOOST_ASIO_SEPARATE_COMPILATION && !defined BOOST_ASIO_DYN_LIN | |
| | | K | |
| | | #error you must define either BOOST_ASIO_SEPARATE_COMPILATION or BOOST_ASIO | |
| | | _DYN_LINK in your project in \ | |
| | | order for asio's declarations to be correct. If you're linking dynam | |
| | | ically against libtorrent, define \ | |
| | | BOOST_ASIO_DYN_LINK otherwise BOOST_ASIO_SEPARATE_COMPILATION. You c | |
| | | an also use pkg-config or boost \ | |
| | | build, to automatically apply these defines | |
| | | #endif | |
| | | | |
| | | #ifndef _MSC_VER | |
| #define __STDC_FORMAT_MACROS | | #define __STDC_FORMAT_MACROS | |
| #include <inttypes.h> | | #include <inttypes.h> | |
| #endif | | #endif | |
| | | | |
| #ifndef PRId64 | | #ifndef PRId64 | |
| // MinGW uses microsofts runtime | | // MinGW uses microsofts runtime | |
| #if defined _MSC_VER || defined __MINGW32__ | | #if defined _MSC_VER || defined __MINGW32__ | |
| #define PRId64 "I64d" | | #define PRId64 "I64d" | |
|
| | | #define PRIu64 "I64u" | |
| | | #define PRIu32 "u" | |
| #else | | #else | |
| #define PRId64 "lld" | | #define PRId64 "lld" | |
|
| | | #define PRIu64 "llu" | |
| | | #define PRIu32 "u" | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
|
| | | // backwards compatibility with older versions of boost | |
| | | #if !defined BOOST_SYMBOL_EXPORT && !defined BOOST_SYMBOL_IMPORT | |
| | | # if defined _MSC_VER || defined __MINGW32__ | |
| | | # define BOOST_SYMBOL_EXPORT __declspec(dllexport) | |
| | | # define BOOST_SYMBOL_IMPORT __declspec(dllimport) | |
| | | # elif __GNU__ >= 4 | |
| | | # define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) | |
| | | # define BOOST_SYMBOL_IMPORT __attribute__((visibility("default"))) | |
| | | # else | |
| | | # define BOOST_SYMBOL_EXPORT | |
| | | # define BOOST_SYMBOL_IMPORT | |
| | | # endif | |
| | | #endif | |
| | | | |
| | | #if defined TORRENT_BUILDING_SHARED | |
| | | # define TORRENT_EXPORT BOOST_SYMBOL_EXPORT | |
| | | #elif defined TORRENT_LINKING_SHARED | |
| | | # define TORRENT_EXPORT BOOST_SYMBOL_IMPORT | |
| | | #endif | |
| | | | |
| | | // when this is specified, export a bunch of extra | |
| | | // symbols, mostly for the unit tests to reach | |
| | | #if TORRENT_EXPORT_EXTRA | |
| | | # if defined TORRENT_BUILDING_SHARED | |
| | | # define TORRENT_EXTRA_EXPORT BOOST_SYMBOL_EXPORT | |
| | | # elif defined TORRENT_LINKING_SHARED | |
| | | # define TORRENT_EXTRA_EXPORT BOOST_SYMBOL_IMPORT | |
| | | # endif | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_EXTRA_EXPORT | |
| | | # define TORRENT_EXTRA_EXPORT | |
| | | #endif | |
| | | | |
| // ======= GCC ========= | | // ======= GCC ========= | |
| | | | |
| #if defined __GNUC__ | | #if defined __GNUC__ | |
| | | | |
|
| # define TORRENT_DEPRECATED __attribute__ ((deprecated)) | | # if __GNUC__ >= 3 | |
| | | # define TORRENT_DEPRECATED __attribute__ ((deprecated)) | |
| // GCC pre 4.0 did not have support for the visibility attribute | | | |
| # if __GNUC__ >= 4 | | | |
| # if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED) | | | |
| # define TORRENT_EXPORT __attribute__ ((visibility("default"))) | | | |
| # else | | | |
| # define TORRENT_EXPORT | | | |
| # endif | | | |
| # else | | | |
| # define TORRENT_EXPORT | | | |
| # endif | | # endif | |
| | | | |
| // ======= SUNPRO ========= | | // ======= SUNPRO ========= | |
| | | | |
| #elif defined __SUNPRO_CC | | #elif defined __SUNPRO_CC | |
| | | | |
|
| # if __SUNPRO_CC >= 0x550 | | // SunPRO seems to have an overly-strict | |
| # if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED) | | // definition of POD types and doesn't | |
| # define TORRENT_EXPORT __global | | // seem to allow boost::array in unions | |
| # else | | #define TORRENT_BROKEN_UNIONS 1 | |
| # define TORRENT_EXPORT | | | |
| # endif | | | |
| # else | | | |
| # define TORRENT_EXPORT | | | |
| # endif | | | |
| | | | |
| // ======= MSVC ========= | | // ======= MSVC ========= | |
| | | | |
| #elif defined BOOST_MSVC | | #elif defined BOOST_MSVC | |
| | | | |
| #pragma warning(disable: 4258) | | #pragma warning(disable: 4258) | |
| #pragma warning(disable: 4251) | | #pragma warning(disable: 4251) | |
| | | | |
|
| # if defined(TORRENT_BUILDING_SHARED) | | // class X needs to have dll-interface to be used by clients of class Y | |
| # define TORRENT_EXPORT __declspec(dllexport) | | #pragma warning(disable:4251) | |
| # elif defined(TORRENT_LINKING_SHARED) | | // '_vsnprintf': This function or variable may be unsafe | |
| # define TORRENT_EXPORT __declspec(dllimport) | | #pragma warning(disable:4996) | |
| # else | | // 'strdup': The POSIX name for this item is deprecated. Instead, use the I | |
| # define TORRENT_EXPORT | | SO C++ conformant name: _strdup | |
| # endif | | #pragma warning(disable: 4996) | |
| | | #define strdup _strdup | |
| | | | |
| #define TORRENT_DEPRECATED_PREFIX __declspec(deprecated) | | #define TORRENT_DEPRECATED_PREFIX __declspec(deprecated) | |
| | | | |
|
| // ======= GENERIC COMPILER ========= | | | |
| | | | |
| #else | | | |
| # define TORRENT_EXPORT | | | |
| #endif | | #endif | |
| | | | |
|
| #ifndef TORRENT_DEPRECATED_PREFIX | | // ======= PLATFORMS ========= | |
| #define TORRENT_DEPRECATED_PREFIX | | | |
| #endif | | | |
| | | | |
|
| #ifndef TORRENT_DEPRECATED | | // set up defines for target environments | |
| #define TORRENT_DEPRECATED | | // ==== AMIGA === | |
| | | #if defined __AMIGA__ || defined __amigaos__ || defined __AROS__ | |
| | | #define TORRENT_AMIGA | |
| | | #define TORRENT_USE_MLOCK 0 | |
| | | #define TORRENT_USE_WRITEV 0 | |
| | | #define TORRENT_USE_READV 0 | |
| | | #define TORRENT_USE_IPV6 0 | |
| | | #define TORRENT_USE_BOOST_THREAD 0 | |
| | | #define TORRENT_USE_IOSTREAM 0 | |
| | | // set this to 1 to disable all floating point operations | |
| | | // (disables some float-dependent APIs) | |
| | | #define TORRENT_NO_FPU 1 | |
| | | #define TORRENT_USE_I2P 0 | |
| | | #ifndef TORRENT_USE_ICONV | |
| | | #define TORRENT_USE_ICONV 0 | |
| #endif | | #endif | |
| | | | |
|
| // set up defines for target environments | | // ==== Darwin/BSD === | |
| #if (defined __APPLE__ && __MACH__) || defined __FreeBSD__ || defined __Net | | #elif (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || def | |
| BSD__ \ | | ined __NetBSD__ \ | |
| || defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__
\ | | || defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__
\ | |
| || defined __FreeBSD_kernel__ | | || defined __FreeBSD_kernel__ | |
| #define TORRENT_BSD | | #define TORRENT_BSD | |
|
| | | // we don't need iconv on mac, because | |
| | | // the locale is always utf-8 | |
| | | #if defined __APPLE__ | |
| | | #ifndef TORRENT_USE_ICONV | |
| | | #define TORRENT_USE_ICONV 0 | |
| | | #define TORRENT_USE_LOCALE 0 | |
| | | #define TORRENT_CLOSE_MAY_BLOCK 1 | |
| | | #endif | |
| | | #else | |
| | | // FreeBSD has a reasonable iconv signature | |
| | | #define TORRENT_ICONV_ARG (const char**) | |
| | | #endif | |
| #define TORRENT_HAS_FALLOCATE 0 | | #define TORRENT_HAS_FALLOCATE 0 | |
|
| | | #define TORRENT_USE_IFADDRS 1 | |
| | | #define TORRENT_USE_SYSCTL 1 | |
| | | #define TORRENT_USE_IFCONF 1 | |
| | | | |
| | | // ==== LINUX === | |
| #elif defined __linux__ | | #elif defined __linux__ | |
| #define TORRENT_LINUX | | #define TORRENT_LINUX | |
|
| | | #define TORRENT_USE_IFADDRS 1 | |
| | | #define TORRENT_USE_NETLINK 1 | |
| | | #define TORRENT_USE_IFCONF 1 | |
| | | #define TORRENT_HAS_SALEN 0 | |
| | | | |
| | | // ==== MINGW === | |
| #elif defined __MINGW32__ | | #elif defined __MINGW32__ | |
| #define TORRENT_MINGW | | #define TORRENT_MINGW | |
| #define TORRENT_WINDOWS | | #define TORRENT_WINDOWS | |
|
| #define TORRENT_HAS_FALLOCATE 0 | | #ifndef TORRENT_USE_ICONV | |
| | | #define TORRENT_USE_ICONV 0 | |
| | | #define TORRENT_USE_LOCALE 1 | |
| | | #endif | |
| | | #define TORRENT_USE_RLIMIT 0 | |
| | | #define TORRENT_USE_NETLINK 0 | |
| | | #define TORRENT_USE_GETADAPTERSADDRESSES 1 | |
| | | #define TORRENT_HAS_SALEN 0 | |
| | | #define TORRENT_USE_GETIPFORWARDTABLE 1 | |
| | | #ifndef TORRENT_USE_UNC_PATHS | |
| | | #define TORRENT_USE_UNC_PATHS 1 | |
| | | #endif | |
| | | | |
| | | // ==== WINDOWS === | |
| #elif defined WIN32 | | #elif defined WIN32 | |
| #define TORRENT_WINDOWS | | #define TORRENT_WINDOWS | |
|
| | | #ifndef TORRENT_USE_GETIPFORWARDTABLE | |
| | | #define TORRENT_USE_GETIPFORWARDTABLE 1 | |
| | | #endif | |
| | | #define TORRENT_USE_GETADAPTERSADDRESSES 1 | |
| | | #define TORRENT_HAS_SALEN 0 | |
| | | // windows has its own functions to convert | |
| | | #ifndef TORRENT_USE_ICONV | |
| | | #define TORRENT_USE_ICONV 0 | |
| | | #define TORRENT_USE_LOCALE 1 | |
| | | #endif | |
| | | #define TORRENT_USE_RLIMIT 0 | |
| #define TORRENT_HAS_FALLOCATE 0 | | #define TORRENT_HAS_FALLOCATE 0 | |
|
| | | #ifndef TORRENT_USE_UNC_PATHS | |
| | | #define TORRENT_USE_UNC_PATHS 1 | |
| | | #endif | |
| | | | |
| | | // ==== SOLARIS === | |
| #elif defined sun || defined __sun | | #elif defined sun || defined __sun | |
| #define TORRENT_SOLARIS | | #define TORRENT_SOLARIS | |
| #define TORRENT_COMPLETE_TYPES_REQUIRED 1 | | #define TORRENT_COMPLETE_TYPES_REQUIRED 1 | |
|
| | | #define TORRENT_USE_IFCONF 1 | |
| | | #define TORRENT_HAS_SALEN 0 | |
| | | | |
| | | // ==== BEOS === | |
| | | #elif defined __BEOS__ || defined __HAIKU__ | |
| | | #define TORRENT_BEOS | |
| | | #include <storage/StorageDefs.h> // B_PATH_NAME_LENGTH | |
| | | #define TORRENT_HAS_FALLOCATE 0 | |
| | | #define TORRENT_USE_MLOCK 0 | |
| | | #ifndef TORRENT_USE_ICONV | |
| | | #define TORRENT_USE_ICONV 0 | |
| | | #endif | |
| | | | |
| | | // ==== GNU/Hurd === | |
| | | #elif defined __GNU__ | |
| | | #define TORRENT_HURD | |
| | | #define TORRENT_USE_IFADDRS 1 | |
| | | #define TORRENT_USE_IFCONF 1 | |
| | | | |
| #else | | #else | |
| #warning unknown OS, assuming BSD | | #warning unknown OS, assuming BSD | |
| #define TORRENT_BSD | | #define TORRENT_BSD | |
| #endif | | #endif | |
| | | | |
|
| #define TORRENT_USE_IPV6 1 | | // on windows, NAME_MAX refers to Unicode characters | |
| #define TORRENT_USE_MLOCK 1 | | // on linux it refers to bytes (utf-8 encoded) | |
| #define TORRENT_USE_READV 1 | | // TODO: Make this count Unicode characters instead of bytes on windows | |
| #define TORRENT_USE_WRITEV 1 | | | |
| #define TORRENT_USE_IOSTREAM 1 | | | |
| | | | |
|
| #if defined TORRENT_BSD || defined TORRENT_LINUX || defined TORRENT_SOLARIS | | // windows | |
| #define TORRENT_USE_RLIMIT 1 | | #if defined FILENAME_MAX | |
| #else | | #define TORRENT_MAX_PATH FILENAME_MAX | |
| #define TORRENT_USE_RLIMIT 0 | | | |
| #endif | | | |
| | | | |
|
| #ifndef TORRENT_HAS_FALLOCATE | | // beos | |
| #define TORRENT_HAS_FALLOCATE 1 | | #elif defined B_PATH_NAME_LENGTH | |
| #endif | | #define TORRENT_MAX_PATH B_PATH_NAME_LENGTH | |
| | | | |
|
| // should wpath or path be used? | | // solaris | |
| #if defined UNICODE && !defined BOOST_FILESYSTEM_NARROW_ONLY \ | | #elif defined MAXPATH | |
| && BOOST_VERSION >= 103400 && !defined __APPLE__ \ | | #define TORRENT_MAX_PATH MAXPATH | |
| && !defined TORRENT_MINGW \ | | | |
| && !defined TORRENT_SOLARIS | | | |
| #define TORRENT_USE_WPATH 1 | | | |
| #else | | | |
| #define TORRENT_USE_WPATH 0 | | | |
| #endif | | | |
| | | | |
|
| // set this to 1 to disable all floating point operations | | // posix | |
| // (disables some float-dependent APIs) | | #elif defined NAME_MAX | |
| #define TORRENT_NO_FPU 0 | | #define TORRENT_MAX_PATH NAME_MAX | |
| | | | |
|
| // make sure NAME_MAX is defined | | // none of the above | |
| #ifndef NAME_MAX | | | |
| #ifdef MAXPATH | | | |
| #define NAME_MAX MAXPATH | | | |
| #else | | #else | |
| // this is the maximum number of characters in a | | // this is the maximum number of characters in a | |
| // path element / filename on windows | | // path element / filename on windows | |
|
| #define NAME_MAX 255 | | #define TORRENT_MAX_PATH 255 | |
| #endif // MAXPATH | | #warning unknown platform, assuming the longest path is 255 | |
| #endif // NAME_MAX | | | |
| | | | |
|
| #if defined TORRENT_WINDOWS && !defined TORRENT_MINGW | | #endif | |
| | | | |
|
| #pragma warning(disable:4251) // class X needs to have dll-interface to be
used by clients of class Y | | #if defined TORRENT_WINDOWS && !defined TORRENT_MINGW | |
| | | | |
| #include <stdarg.h> | | #include <stdarg.h> | |
|
| // '_vsnprintf': This function or variable may be unsafe | | | |
| #pragma warning(disable:4996) | | | |
| | | | |
| inline int snprintf(char* buf, int len, char const* fmt, ...) | | inline int snprintf(char* buf, int len, char const* fmt, ...) | |
| { | | { | |
| va_list lp; | | va_list lp; | |
| va_start(lp, fmt); | | va_start(lp, fmt); | |
| int ret = _vsnprintf(buf, len, fmt, lp); | | int ret = _vsnprintf(buf, len, fmt, lp); | |
| va_end(lp); | | va_end(lp); | |
| if (ret < 0) { buf[len-1] = 0; ret = len-1; } | | if (ret < 0) { buf[len-1] = 0; ret = len-1; } | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| #define strtoll _strtoi64 | | #define strtoll _strtoi64 | |
| #else | | #else | |
| #include <limits.h> | | #include <limits.h> | |
| #endif | | #endif | |
| | | | |
|
| #if (defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)) && !defi | | #if (defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)) \ | |
| ned (TORRENT_UPNP_LOGGING) | | && !defined (TORRENT_UPNP_LOGGING) && TORRENT_USE_IOSTREAM | |
| #define TORRENT_UPNP_LOGGING | | #define TORRENT_UPNP_LOGGING | |
| #endif | | #endif | |
| | | | |
|
| #if !TORRENT_USE_WPATH && (defined TORRENT_LINUX || defined TORRENT_MINGW) | | #ifndef TORRENT_ICONV_ARG | |
| | | #define TORRENT_ICONV_ARG (char**) | |
| | | #endif | |
| | | | |
| // libiconv presence, not implemented yet | | // libiconv presence, not implemented yet | |
|
| #define TORRENT_USE_LOCALE_FILENAMES 1 | | #ifndef TORRENT_USE_ICONV | |
| | | #define TORRENT_USE_ICONV 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_HAS_SALEN | |
| | | #define TORRENT_HAS_SALEN 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_GETADAPTERSADDRESSES | |
| | | #define TORRENT_USE_GETADAPTERSADDRESSES 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_NETLINK | |
| | | #define TORRENT_USE_NETLINK 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_SYSCTL | |
| | | #define TORRENT_USE_SYSCTL 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_GETIPFORWARDTABLE | |
| | | #define TORRENT_USE_GETIPFORWARDTABLE 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_LOCALE | |
| | | #define TORRENT_USE_LOCALE 0 | |
| | | #endif | |
| | | | |
| | | // set this to true if close() may block on your system | |
| | | // Mac OS X does this if the file being closed is not fully | |
| | | // allocated on disk yet for instance. When defined, the disk | |
| | | // I/O subsytem will use a separate thread for closing files | |
| | | #ifndef TORRENT_CLOSE_MAY_BLOCK | |
| | | #define TORRENT_CLOSE_MAY_BLOCK 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_BROKEN_UNIONS | |
| | | #define TORRENT_BROKEN_UNIONS 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_WSTRING | |
| | | #if defined UNICODE && !defined BOOST_NO_STD_WSTRING | |
| | | #define TORRENT_USE_WSTRING 1 | |
| #else | | #else | |
|
| #define TORRENT_USE_LOCALE_FILENAMES 0 | | #define TORRENT_USE_WSTRING 0 | |
| | | #endif // UNICODE | |
| | | #endif // TORRENT_USE_WSTRING | |
| | | | |
| | | #ifndef TORRENT_HAS_FALLOCATE | |
| | | #define TORRENT_HAS_FALLOCATE 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_EXPORT | |
| | | # define TORRENT_EXPORT | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_DEPRECATED_PREFIX | |
| | | #define TORRENT_DEPRECATED_PREFIX | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_DEPRECATED | |
| | | #define TORRENT_DEPRECATED | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_COMPLETE_TYPES_REQUIRED | |
| | | #define TORRENT_COMPLETE_TYPES_REQUIRED 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_UNC_PATHS | |
| | | #define TORRENT_USE_UNC_PATHS 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_RLIMIT | |
| | | #define TORRENT_USE_RLIMIT 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_IFADDRS | |
| | | #define TORRENT_USE_IFADDRS 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_IPV6 | |
| | | #define TORRENT_USE_IPV6 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_MLOCK | |
| | | #define TORRENT_USE_MLOCK 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_WRITEV | |
| | | #define TORRENT_USE_WRITEV 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_READV | |
| | | #define TORRENT_USE_READV 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_NO_FPU | |
| | | #define TORRENT_NO_FPU 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_IOSTREAM | |
| | | #ifndef BOOST_NO_IOSTREAM | |
| | | #define TORRENT_USE_IOSTREAM 1 | |
| | | #else | |
| | | #define TORRENT_USE_IOSTREAM 0 | |
| | | #endif | |
| | | #endif | |
| | | | |
| | | // if set to true, piece picker will use less RAM | |
| | | // but only support up to ~260000 pieces in a torrent | |
| | | #ifndef TORRENT_COMPACT_PICKER | |
| | | #define TORRENT_COMPACT_PICKER 0 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_USE_I2P | |
| | | #define TORRENT_USE_I2P 1 | |
| | | #endif | |
| | | | |
| | | #ifndef TORRENT_HAS_STRDUP | |
| | | #define TORRENT_HAS_STRDUP 1 | |
| #endif | | #endif | |
| | | | |
| #if !defined TORRENT_IOV_MAX | | #if !defined TORRENT_IOV_MAX | |
| #ifdef IOV_MAX | | #ifdef IOV_MAX | |
| #define TORRENT_IOV_MAX IOV_MAX | | #define TORRENT_IOV_MAX IOV_MAX | |
| #else | | #else | |
| #define TORRENT_IOV_MAX INT_MAX | | #define TORRENT_IOV_MAX INT_MAX | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #if !defined(TORRENT_READ_HANDLER_MAX_SIZE) | | #if !defined(TORRENT_READ_HANDLER_MAX_SIZE) | |
|
| # define TORRENT_READ_HANDLER_MAX_SIZE 256 | | # define TORRENT_READ_HANDLER_MAX_SIZE 300 | |
| #endif | | #endif | |
| | | | |
| #if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE) | | #if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE) | |
|
| # define TORRENT_WRITE_HANDLER_MAX_SIZE 256 | | # define TORRENT_WRITE_HANDLER_MAX_SIZE 300 | |
| #endif | | | |
| | | | |
| #ifndef TORRENT_ICONV_ARG | | | |
| #define TORRENT_ICONV_ARG (char**) | | | |
| #endif | | #endif | |
| | | | |
| #if defined _MSC_VER && _MSC_VER <= 1200 | | #if defined _MSC_VER && _MSC_VER <= 1200 | |
| #define for if (false) {} else for | | #define for if (false) {} else for | |
| #endif | | #endif | |
| | | | |
|
| | | #if TORRENT_BROKEN_UNIONS | |
| | | #define TORRENT_UNION struct | |
| | | #else | |
| | | #define TORRENT_UNION union | |
| | | #endif | |
| | | | |
| // determine what timer implementation we can use | | // determine what timer implementation we can use | |
|
| | | // if one is already defined, don't pick one | |
| | | // autmatically. This lets the user control this | |
| | | // from the Jamfile | |
| | | #if !defined TORRENT_USE_ABSOLUTE_TIME \ | |
| | | && !defined TORRENT_USE_QUERY_PERFORMANCE_TIMER \ | |
| | | && !defined TORRENT_USE_CLOCK_GETTIME \ | |
| | | && !defined TORRENT_USE_BOOST_DATE_TIME \ | |
| | | && !defined TORRENT_USE_ECLOCK \ | |
| | | && !defined TORRENT_USE_SYSTEM_TIME | |
| | | | |
|
| #if defined(__MACH__) | | #if defined __APPLE__ && defined __MACH__ | |
| #define TORRENT_USE_ABSOLUTE_TIME 1 | | #define TORRENT_USE_ABSOLUTE_TIME 1 | |
|
| #elif defined(_WIN32) | | #elif defined(_WIN32) || defined TORRENT_MINGW | |
| #define TORRENT_USE_QUERY_PERFORMANCE_TIMER 1 | | #define TORRENT_USE_QUERY_PERFORMANCE_TIMER 1 | |
| #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 | | #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 | |
| #define TORRENT_USE_CLOCK_GETTIME 1 | | #define TORRENT_USE_CLOCK_GETTIME 1 | |
|
| | | #elif defined(TORRENT_AMIGA) | |
| | | #define TORRENT_USE_ECLOCK 1 | |
| | | #elif defined(TORRENT_BEOS) | |
| | | #define TORRENT_USE_SYSTEM_TIME 1 | |
| #else | | #else | |
| #define TORRENT_USE_BOOST_DATE_TIME 1 | | #define TORRENT_USE_BOOST_DATE_TIME 1 | |
| #endif | | #endif | |
| | | | |
|
| | | #endif | |
| | | | |
| | | #if !TORRENT_HAS_STRDUP | |
| | | inline char* strdup(char const* str) | |
| | | { | |
| | | if (str == 0) return 0; | |
| | | char* tmp = (char*)malloc(strlen(str) + 1); | |
| | | if (tmp == 0) return 0; | |
| | | strcpy(tmp, str); | |
| | | return tmp; | |
| | | } | |
| | | #endif | |
| | | | |
| | | // for non-exception builds | |
| | | #ifdef BOOST_NO_EXCEPTIONS | |
| | | #define TORRENT_TRY if (true) | |
| | | #define TORRENT_CATCH(x) else if (false) | |
| | | #define TORRENT_DECLARE_DUMMY(x, y) x y | |
| | | #else | |
| | | #define TORRENT_TRY try | |
| | | #define TORRENT_CATCH(x) catch(x) | |
| | | #define TORRENT_DECLARE_DUMMY(x, y) | |
| | | #endif // BOOST_NO_EXCEPTIONS | |
| | | | |
| #endif // TORRENT_CONFIG_HPP_INCLUDED | | #endif // TORRENT_CONFIG_HPP_INCLUDED | |
| | | | |
End of changes. 40 change blocks. |
| 90 lines changed or deleted | | 354 lines changed or added | |
|
| create_torrent.hpp | | create_torrent.hpp | |
| | | | |
| skipping to change at line 39 | | skipping to change at line 39 | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_CREATE_TORRENT_HPP_INCLUDED | | #ifndef TORRENT_CREATE_TORRENT_HPP_INCLUDED | |
| #define TORRENT_CREATE_TORRENT_HPP_INCLUDED | | #define TORRENT_CREATE_TORRENT_HPP_INCLUDED | |
| | | | |
| #include "libtorrent/bencode.hpp" | | #include "libtorrent/bencode.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
| #include "libtorrent/file_storage.hpp" | | #include "libtorrent/file_storage.hpp" | |
|
| #include "libtorrent/file_pool.hpp" | | | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
| #include "libtorrent/hasher.hpp" | | #include "libtorrent/hasher.hpp" | |
| #include "libtorrent/utf8.hpp" | | #include "libtorrent/utf8.hpp" | |
| #include "libtorrent/allocator.hpp" | | #include "libtorrent/allocator.hpp" | |
|
| | | #include "libtorrent/file.hpp" // for combine_path etc. | |
| | | | |
| #include <vector> | | #include <vector> | |
| #include <string> | | #include <string> | |
| #include <utility> | | #include <utility> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
|
| #include <boost/filesystem/path.hpp> | | | |
| #include <boost/filesystem/operations.hpp> | | | |
| #include <boost/optional.hpp> | | | |
| #include <boost/date_time/posix_time/posix_time_types.hpp> | | | |
| #include <boost/scoped_ptr.hpp> | | #include <boost/scoped_ptr.hpp> | |
| #include <boost/config.hpp> | | #include <boost/config.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| namespace fs = boost::filesystem; | | | |
| namespace pt = boost::posix_time; | | | |
| class torrent_info; | | class torrent_info; | |
| | | | |
| struct TORRENT_EXPORT create_torrent | | struct TORRENT_EXPORT create_torrent | |
| { | | { | |
| enum flags_t | | enum flags_t | |
| { | | { | |
| optimize = 1 | | optimize = 1 | |
| , merkle = 2 | | , merkle = 2 | |
| , modification_time = 4 | | , modification_time = 4 | |
| , symlinks = 8 | | , symlinks = 8 | |
|
| | | , calculate_file_hashes = 16 | |
| }; | | }; | |
| | | | |
| create_torrent(file_storage& fs, int piece_size = 0 | | create_torrent(file_storage& fs, int piece_size = 0 | |
| , int pad_file_limit = -1, int flags = optimize); | | , int pad_file_limit = -1, int flags = optimize); | |
| create_torrent(torrent_info const& ti); | | create_torrent(torrent_info const& ti); | |
|
| | | ~create_torrent(); | |
| entry generate() const; | | entry generate() const; | |
| | | | |
| file_storage const& files() const { return m_files; } | | file_storage const& files() const { return m_files; } | |
| | | | |
| 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& h); | | void set_hash(int index, sha1_hash const& h); | |
|
| | | void set_file_hash(int index, sha1_hash const& h); | |
| void add_url_seed(std::string const& url); | | void add_url_seed(std::string const& url); | |
| void add_http_seed(std::string const& url); | | void add_http_seed(std::string const& url); | |
| void add_node(std::pair<std::string, int> const& node); | | void add_node(std::pair<std::string, int> const& node); | |
| void add_tracker(std::string const& url, int tier = 0); | | void add_tracker(std::string const& url, int tier = 0); | |
|
| | | void set_root_cert(std::string const& pem); | |
| void set_priv(bool p) { m_private = p; } | | void set_priv(bool p) { m_private = p; } | |
| | | | |
| int num_pieces() const { return m_files.num_pieces(); } | | int num_pieces() const { return m_files.num_pieces(); } | |
| int piece_length() const { return m_files.piece_length(); } | | int piece_length() const { return m_files.piece_length(); } | |
| int piece_size(int i) const { return m_files.piece_size(i);
} | | int piece_size(int i) const { return m_files.piece_size(i);
} | |
| bool priv() const { return m_private; } | | bool priv() const { return m_private; } | |
| | | | |
|
| | | bool should_add_file_hashes() const { return m_calculate_fil
e_hashes; } | |
| std::vector<sha1_hash> const& merkle_tree() const { return m
_merkle_tree; } | | std::vector<sha1_hash> const& merkle_tree() const { return m
_merkle_tree; } | |
| | | | |
| private: | | private: | |
| | | | |
| file_storage& m_files; | | file_storage& m_files; | |
| // if m_info_dict is initialized, it is | | // if m_info_dict is initialized, it is | |
| // used instead of m_files to generate | | // used instead of m_files to generate | |
| // the info dictionary | | // the info dictionary | |
| entry m_info_dict; | | entry m_info_dict; | |
| | | | |
| // the urls to the trackers | | // the urls to the trackers | |
| typedef std::pair<std::string, int> announce_entry; | | typedef std::pair<std::string, int> announce_entry; | |
| std::vector<announce_entry> m_urls; | | std::vector<announce_entry> m_urls; | |
| | | | |
| std::vector<std::string> m_url_seeds; | | std::vector<std::string> m_url_seeds; | |
|
| | | std::vector<std::string> m_http_seeds; | |
| | | | |
| std::vector<sha1_hash> m_piece_hash; | | std::vector<sha1_hash> m_piece_hash; | |
| | | | |
|
| | | std::vector<sha1_hash> m_filehashes; | |
| | | | |
| // if we're generating a merkle torrent, this is the | | // if we're generating a merkle torrent, this is the | |
| // merkle tree we got. This should be saved in fast-resume | | // merkle tree we got. This should be saved in fast-resume | |
| // in order to start seeding the torrent | | // in order to start seeding the torrent | |
| mutable std::vector<sha1_hash> m_merkle_tree; | | mutable std::vector<sha1_hash> m_merkle_tree; | |
| | | | |
| // dht nodes to add to the routing table/bootstrap from | | // dht nodes to add to the routing table/bootstrap from | |
| typedef std::vector<std::pair<std::string, int> > nodes_t; | | typedef std::vector<std::pair<std::string, int> > nodes_t; | |
| nodes_t m_nodes; | | nodes_t m_nodes; | |
| | | | |
| // the hash that identifies this torrent | | // the hash that identifies this torrent | |
| // is mutable because it's calculated | | // is mutable because it's calculated | |
| // lazily | | // lazily | |
| mutable sha1_hash m_info_hash; | | mutable sha1_hash m_info_hash; | |
| | | | |
| // if a creation date is found in the torrent file | | // if a creation date is found in the torrent file | |
| // this will be set to that, otherwise it'll be | | // this will be set to that, otherwise it'll be | |
| // 1970, Jan 1 | | // 1970, Jan 1 | |
|
| pt::ptime m_creation_date; | | time_t m_creation_date; | |
| | | | |
| // if a comment is found in the torrent file | | // if a comment is found in the torrent file | |
| // this will be set to that comment | | // this will be set to that comment | |
| std::string m_comment; | | std::string m_comment; | |
| | | | |
| // an optional string naming the software used | | // an optional string naming the software used | |
| // to create the torrent file | | // to create the torrent file | |
| std::string m_created_by; | | std::string m_created_by; | |
| | | | |
|
| | | // this is the root cert for SSL torrents | |
| | | std::string m_root_cert; | |
| | | | |
| // this is used when creating a torrent. If there's | | // this is used when creating a torrent. If there's | |
| // only one file there are cases where it's impossible | | // only one file there are cases where it's impossible | |
| // to know if it should be written as a multifile torrent | | // to know if it should be written as a multifile torrent | |
| // or not. e.g. test/test there's one file and one director
y | | // or not. e.g. test/test there's one file and one director
y | |
| // and they have the same name. | | // and they have the same name. | |
| bool m_multifile:1; | | bool m_multifile:1; | |
| | | | |
| // this is true if the torrent is private. i.e., is should n
ot | | // this is true if the torrent is private. i.e., is should n
ot | |
| // be announced on the dht | | // be announced on the dht | |
| bool m_private:1; | | bool m_private:1; | |
| | | | |
| skipping to change at line 170 | | skipping to change at line 175 | |
| | | | |
| // if set, include the 'mtime' modification time in the | | // if set, include the 'mtime' modification time in the | |
| // torrent file | | // torrent file | |
| bool m_include_mtime:1; | | bool m_include_mtime:1; | |
| | | | |
| // if set, symbolic links are declared as such in | | // if set, symbolic links are declared as such in | |
| // the torrent file. The full data of the pointed-to | | // the torrent file. The full data of the pointed-to | |
| // file is still included | | // file is still included | |
| bool m_include_symlinks:1; | | bool m_include_symlinks:1; | |
| | | | |
|
| // this is added at the end in order to maintain binary | | // this is only used by set_piece_hashes(). It will | |
| // compatibility with previous 0.15.x releases. In the | | // calculate sha1 hashes for each file and add it | |
| // next full version release this member has been moved | | // to the file list | |
| // to a more reasonable location | | bool m_calculate_file_hashes:1; | |
| std::vector<std::string> m_http_seeds; | | | |
| }; | | }; | |
| | | | |
| namespace detail | | namespace detail | |
| { | | { | |
|
| inline bool default_pred(boost::filesystem::path const&) { r | | inline bool default_pred(std::string const&) { return true; | |
| eturn true; } | | } | |
| #if TORRENT_USE_WPATH | | | |
| inline bool wdefault_pred(boost::filesystem::wpath const&) { | | | |
| return true; } | | | |
| #endif | | | |
| | | | |
| inline bool ignore_subdir(std::string const& leaf) | | inline bool ignore_subdir(std::string const& leaf) | |
| { return leaf == ".." || leaf == "."; } | | { return leaf == ".." || leaf == "."; } | |
| | | | |
|
| inline bool ignore_subdir(std::wstring const& leaf) | | | |
| { return leaf == L".." || leaf == L"."; } | | | |
| | | | |
| inline void nop(int i) {} | | inline void nop(int i) {} | |
| | | | |
|
| int TORRENT_EXPORT get_file_attributes(boost::filesystem::pa | | int get_file_attributes(std::string const& p); | |
| th const& p); | | std::string get_symlink_path(std::string const& p); | |
| #if TORRENT_USE_WPATH | | | |
| int TORRENT_EXPORT get_file_attributes(boost::filesystem::wp | | | |
| ath const& p); | | | |
| #endif | | | |
| | | | |
| std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem: | | | |
| :path const& p); | | | |
| #if TORRENT_USE_WPATH | | | |
| std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem: | | | |
| :wpath const& p); | | | |
| #endif | | | |
| | | | |
| fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem:: | | | |
| path const& p); | | | |
| #if TORRENT_USE_WPATH | | | |
| fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem:: | | | |
| wpath const& p); | | | |
| #endif | | | |
| | | | |
| template <class Pred, class Str, class PathTraits> | | | |
| void add_files_impl(file_storage& fs, boost::filesystem::bas | | | |
| ic_path<Str, PathTraits> const& p | | | |
| , boost::filesystem::basic_path<Str, PathTraits> con | | | |
| st& l, Pred pred, boost::uint32_t flags) | | | |
| { | | | |
| using boost::filesystem::basic_path; | | | |
| using boost::filesystem::basic_directory_iterator; | | | |
| basic_path<Str, PathTraits> f(p / l); | | | |
| if (!pred(f)) return; | | | |
| | | | |
| bool recurse = is_directory(f); | | | |
| // if the file is not a link or we're following link | | | |
| s, and it's a directory | | | |
| // only then should we recurse | | | |
| if ((is_symlink(f)) && (flags & create_torrent::syml | | | |
| inks)) | | | |
| recurse = false; | | | |
| | | | |
|
| if (recurse) | | TORRENT_EXPORT void add_files_impl(file_storage& fs, std::st | |
| { | | ring const& p | |
| for (basic_directory_iterator<basic_path<Str | | , std::string const& l, boost::function<bool(std::st | |
| , PathTraits> > i(f), end; i != end; ++i) | | ring)> pred | |
| { | | , boost::uint32_t flags); | |
| #if BOOST_VERSION < 103600 | | | |
| Str const& leaf = i->path().leaf(); | | | |
| #else | | | |
| Str const& leaf = i->path().filename | | | |
| (); | | | |
| #endif | | | |
| if (ignore_subdir(leaf)) continue; | | | |
| add_files_impl(fs, p, l / leaf, pred | | | |
| , flags); | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | | |
| int file_flags = get_file_attributes(f); | | | |
| std::time_t mtime = get_file_mtime(f); | | | |
| //Masking all bits to check if the file is a | | | |
| symlink | | | |
| if ((file_flags & file_storage::attribute_sy | | | |
| mlink) | | | |
| && (flags & create_torrent::symlinks | | | |
| )) | | | |
| { | | | |
| fs::path sym_path = get_symlink_path | | | |
| (f); | | | |
| fs.add_file(l, 0 ,file_flags, mtime, | | | |
| sym_path); | | | |
| } | | | |
| else | | | |
| { | | | |
| fs.add_file(l, file_size(f), file_fl | | | |
| ags, mtime); | | | |
| } | | | |
| } | | | |
| } | | | |
| } | | } | |
| | | | |
|
| // path versions | | | |
| | | | |
| template <class Pred> | | template <class Pred> | |
|
| void add_files(file_storage& fs, boost::filesystem::path const& file | | void add_files(file_storage& fs, std::string const& file, Pred p, bo | |
| , Pred p | | ost::uint32_t flags = 0) | |
| , boost::uint32_t flags = 0) | | | |
| { | | { | |
|
| using boost::filesystem::path; | | detail::add_files_impl(fs, parent_path(complete(file)), file | |
| boost::filesystem::path f = file; | | name(file), p, flags); | |
| #if BOOST_VERSION < 103600 | | | |
| if (f.leaf() == ".") f = f.branch_path(); | | | |
| detail::add_files_impl(fs, complete(f).branch_path(), path(f | | | |
| .leaf()), p, flags); | | | |
| #else | | | |
| if (f.filename() == ".") f = f.parent_path(); | | | |
| detail::add_files_impl(fs, complete(f).parent_path(), path(f | | | |
| .filename()), p, flags); | | | |
| #endif | | | |
| } | | } | |
| | | | |
|
| inline void add_files(file_storage& fs, boost::filesystem::path cons | | inline void add_files(file_storage& fs, std::string const& file, boo | |
| t& file | | st::uint32_t flags = 0) | |
| , boost::uint32_t flags = 0) | | | |
| { | | { | |
|
| using boost::filesystem::path; | | detail::add_files_impl(fs, parent_path(complete(file)), file | |
| boost::filesystem::path f = file; | | name(file) | |
| #if BOOST_VERSION < 103600 | | | |
| if (f.leaf() == ".") f = f.branch_path(); | | | |
| detail::add_files_impl(fs, complete(f).branch_path(), path(f | | | |
| .leaf()) | | | |
| , detail::default_pred, flags); | | | |
| #else | | | |
| if (f.filename() == ".") f = f.parent_path(); | | | |
| detail::add_files_impl(fs, complete(f).parent_path(), path(f | | | |
| .filename()) | | | |
| , detail::default_pred, flags); | | , detail::default_pred, flags); | |
|
| #endif | | | |
| } | | } | |
| | | | |
|
| struct piece_holder | | TORRENT_EXPORT void set_piece_hashes(create_torrent& t, std::string | |
| { | | const& p | |
| piece_holder(int bytes): m_piece(page_aligned_allocator::mal | | , boost::function<void(int)> f, error_code& ec); | |
| loc(bytes)) {} | | | |
| ~piece_holder() { page_aligned_allocator::free(m_piece); } | | | |
| char* bytes() { return m_piece; } | | | |
| private: | | | |
| char* m_piece; | | | |
| }; | | | |
| | | | |
| template <class Fun> | | | |
| void set_piece_hashes(create_torrent& t, boost::filesystem::path con | | | |
| st& p, Fun f | | | |
| , error_code& ec) | | | |
| { | | | |
| file_pool fp; | | | |
| boost::scoped_ptr<storage_interface> st( | | | |
| default_storage_constructor(const_cast<file_storage& | | | |
| >(t.files()), 0, p, fp)); | | | |
| | | | |
| // calculate the hash for all pieces | | | |
| int num = t.num_pieces(); | | | |
| piece_holder buf(t.piece_length()); | | | |
| for (int i = 0; i < num; ++i) | | | |
| { | | | |
| // read hits the disk and will block. Progress shoul | | | |
| d | | | |
| // be updated in between reads | | | |
| st->read(buf.bytes(), i, 0, t.piece_size(i)); | | | |
| if (st->error()) | | | |
| { | | | |
| ec = st->error(); | | | |
| return; | | | |
| } | | | |
| hasher h(buf.bytes(), t.piece_size(i)); | | | |
| t.set_hash(i, h.final()); | | | |
| f(i); | | | |
| } | | | |
| } | | | |
| | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class Fun> | | template <class Fun> | |
|
| void set_piece_hashes(create_torrent& t, boost::filesystem::path con
st& p, Fun f) | | void set_piece_hashes(create_torrent& t, std::string const& p, Fun f
) | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| set_piece_hashes(t, p, f, ec); | | set_piece_hashes(t, p, f, ec); | |
| if (ec) throw libtorrent_exception(ec); | | if (ec) throw libtorrent_exception(ec); | |
| } | | } | |
| | | | |
|
| inline void set_piece_hashes(create_torrent& t, boost::filesystem::p
ath const& p) | | inline void set_piece_hashes(create_torrent& t, std::string const& p
) | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| set_piece_hashes(t, p, detail::nop, ec); | | set_piece_hashes(t, p, detail::nop, ec); | |
| if (ec) throw libtorrent_exception(ec); | | if (ec) throw libtorrent_exception(ec); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| inline void set_piece_hashes(create_torrent& t, boost::filesystem::p
ath const& p, error_code& ec) | | inline void set_piece_hashes(create_torrent& t, std::string const& p
, error_code& ec) | |
| { | | { | |
| set_piece_hashes(t, p, detail::nop, ec); | | set_piece_hashes(t, p, detail::nop, ec); | |
| } | | } | |
| | | | |
|
| #if TORRENT_USE_WPATH | | #if TORRENT_USE_WSTRING | |
| // wpath versions | | // wstring versions | |
| | | | |
| template <class Pred> | | template <class Pred> | |
|
| void add_files(file_storage& fs, boost::filesystem::wpath const& fil | | void add_files(file_storage& fs, std::wstring const& wfile, Pred p, | |
| e, Pred p | | boost::uint32_t flags = 0) | |
| , boost::uint32_t flags = 0) | | | |
| { | | | |
| using boost::filesystem::wpath; | | | |
| wpath f = file; | | | |
| #if BOOST_VERSION < 103600 | | | |
| if (f.leaf() == L".") f = f.branch_path(); | | | |
| detail::add_files_impl(fs, complete(f).branch_path(), wpath( | | | |
| f.leaf()), p, flags); | | | |
| #else | | | |
| if (f.filename() == L".") f = f.parent_path(); | | | |
| detail::add_files_impl(fs, complete(f).parent_path(), wpath( | | | |
| f.filename()), p, flags); | | | |
| #endif | | | |
| } | | | |
| | | | |
| inline void add_files(file_storage& fs, boost::filesystem::wpath con | | | |
| st& file | | | |
| , boost::uint32_t flags = 0) | | | |
| { | | { | |
|
| using boost::filesystem::wpath; | | std::string utf8; | |
| wpath f = file; | | wchar_utf8(wfile, utf8); | |
| #if BOOST_VERSION < 103600 | | detail::add_files_impl(fs, parent_path(complete(utf8)) | |
| if (f.leaf() == L".") f = f.branch_path(); | | , filename(utf8), p, flags); | |
| detail::add_files_impl(fs, complete(f).branch_path(), wpath( | | | |
| f.leaf()), detail::wdefault_pred | | | |
| , flags); | | | |
| #else | | | |
| if (f.filename() == L".") f = f.parent_path(); | | | |
| detail::add_files_impl(fs, complete(f).parent_path(), wpath( | | | |
| f.filename()) | | | |
| , detail::wdefault_pred, flags); | | | |
| #endif | | | |
| } | | } | |
| | | | |
|
| template <class Fun> | | inline void add_files(file_storage& fs, std::wstring const& wfile, b | |
| void set_piece_hashes(create_torrent& t, boost::filesystem::wpath co | | oost::uint32_t flags = 0) | |
| nst& p, Fun f | | | |
| , error_code& ec) | | | |
| { | | { | |
|
| file_pool fp; | | | |
| std::string utf8; | | std::string utf8; | |
|
| wchar_utf8(p.string(), utf8); | | wchar_utf8(wfile, utf8); | |
| boost::scoped_ptr<storage_interface> st( | | detail::add_files_impl(fs, parent_path(complete(utf8)) | |
| default_storage_constructor(const_cast<file_storage& | | , filename(utf8), detail::default_pred, flags); | |
| >(t.files()), 0, utf8, fp)); | | | |
| | | | |
| // calculate the hash for all pieces | | | |
| int num = t.num_pieces(); | | | |
| std::vector<char> buf(t.piece_length()); | | | |
| for (int i = 0; i < num; ++i) | | | |
| { | | | |
| // read hits the disk and will block. Progress shoul | | | |
| d | | | |
| // be updated in between reads | | | |
| st->read(&buf[0], i, 0, t.piece_size(i)); | | | |
| if (st->error()) | | | |
| { | | | |
| ec = st->error(); | | | |
| return; | | | |
| } | | | |
| hasher h(&buf[0], t.piece_size(i)); | | | |
| t.set_hash(i, h.final()); | | | |
| f(i); | | | |
| } | | | |
| } | | } | |
| | | | |
|
| | | void TORRENT_EXPORT set_piece_hashes(create_torrent& t, std::wstring | |
| | | const& p | |
| | | , boost::function<void(int)> const& f, error_code& ec); | |
| | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class Fun> | | template <class Fun> | |
|
| void set_piece_hashes(create_torrent& t, boost::filesystem::wpath co
nst& p, Fun f) | | void set_piece_hashes(create_torrent& t, std::wstring const& p, Fun
f) | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| set_piece_hashes(t, p, f, ec); | | set_piece_hashes(t, p, f, ec); | |
| if (ec) throw libtorrent_exception(ec); | | if (ec) throw libtorrent_exception(ec); | |
| } | | } | |
| | | | |
|
| inline void set_piece_hashes(create_torrent& t, boost::filesystem::w
path const& p) | | inline void set_piece_hashes(create_torrent& t, std::wstring const&
p) | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| set_piece_hashes(t, p, detail::nop, ec); | | set_piece_hashes(t, p, detail::nop, ec); | |
| if (ec) throw libtorrent_exception(ec); | | if (ec) throw libtorrent_exception(ec); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| inline void set_piece_hashes(create_torrent& t, boost::filesystem::w
path const& p, error_code& ec) | | inline void set_piece_hashes(create_torrent& t, std::wstring const&
p, error_code& ec) | |
| { | | { | |
| set_piece_hashes(t, p, detail::nop, ec); | | set_piece_hashes(t, p, detail::nop, ec); | |
| } | | } | |
| | | | |
| #endif // TORRENT_USE_WPATH | | #endif // TORRENT_USE_WPATH | |
| | | | |
| } | | } | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 38 change blocks. |
| 239 lines changed or deleted | | 60 lines changed or added | |
|
| disk_io_thread.hpp | | disk_io_thread.hpp | |
| | | | |
| skipping to change at line 36 | | skipping to change at line 36 | |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_DISK_IO_THREAD | | #ifndef TORRENT_DISK_IO_THREAD | |
| #define TORRENT_DISK_IO_THREAD | | #define TORRENT_DISK_IO_THREAD | |
| | | | |
|
| #if defined TORRENT_DISK_STATS || defined TORRENT_STATS | | | |
| #include <fstream> | | | |
| #endif | | | |
| | | | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
| #include "libtorrent/allocator.hpp" | | #include "libtorrent/allocator.hpp" | |
|
| #include <boost/thread/thread.hpp> | | #include "libtorrent/io_service.hpp" | |
| #include <boost/thread/mutex.hpp> | | #include "libtorrent/sliding_average.hpp" | |
| #include <boost/thread/condition.hpp> | | | |
| #include <boost/function.hpp> | | #include <boost/function/function0.hpp> | |
| #include <boost/bind.hpp> | | #include <boost/function/function2.hpp> | |
| #include <boost/noncopyable.hpp> | | #include <boost/noncopyable.hpp> | |
| #include <boost/shared_array.hpp> | | #include <boost/shared_array.hpp> | |
|
| #include <list> | | #include <deque> | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
|
| #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | | #include "libtorrent/thread.hpp" | |
| #include <boost/pool/pool.hpp> | | #include "libtorrent/disk_buffer_pool.hpp" | |
| #endif | | | |
| #include "libtorrent/session_settings.hpp" | | #include <boost/multi_index_container.hpp> | |
| | | #include <boost/multi_index/member.hpp> | |
| | | #include <boost/multi_index/ordered_index.hpp> | |
| | | #include <boost/multi_index/mem_fun.hpp> | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| | | using boost::multi_index::multi_index_container; | |
| | | using boost::multi_index::ordered_non_unique; | |
| | | using boost::multi_index::ordered_unique; | |
| | | using boost::multi_index::indexed_by; | |
| | | using boost::multi_index::member; | |
| | | using boost::multi_index::const_mem_fun; | |
| | | | |
| struct cached_piece_info | | struct cached_piece_info | |
| { | | { | |
| int piece; | | int piece; | |
| std::vector<bool> blocks; | | std::vector<bool> blocks; | |
| ptime last_use; | | ptime last_use; | |
|
| | | int next_to_hash; | |
| enum kind_t { read_cache = 0, write_cache = 1 }; | | enum kind_t { read_cache = 0, write_cache = 1 }; | |
| kind_t kind; | | kind_t kind; | |
| }; | | }; | |
| | | | |
| struct disk_io_job | | struct disk_io_job | |
| { | | { | |
| disk_io_job() | | disk_io_job() | |
| : action(read) | | : action(read) | |
| , buffer(0) | | , buffer(0) | |
| , buffer_size(0) | | , buffer_size(0) | |
| , piece(0) | | , piece(0) | |
| , offset(0) | | , offset(0) | |
|
| , priority(0) | | , max_cache_line(0) | |
| | | , cache_min_time(0) | |
| {} | | {} | |
| | | | |
| enum action_t | | enum action_t | |
| { | | { | |
| read | | read | |
| , write | | , write | |
| , hash | | , hash | |
| , move_storage | | , move_storage | |
| , release_files | | , release_files | |
| , delete_files | | , delete_files | |
| , check_fastresume | | , check_fastresume | |
| , check_files | | , check_files | |
| , save_resume_data | | , save_resume_data | |
| , rename_file | | , rename_file | |
| , abort_thread | | , abort_thread | |
| , clear_read_cache | | , clear_read_cache | |
| , abort_torrent | | , abort_torrent | |
| , update_settings | | , update_settings | |
| , read_and_hash | | , read_and_hash | |
|
| | | , cache_piece | |
| | | , finalize_file | |
| }; | | }; | |
| | | | |
| action_t action; | | action_t action; | |
| | | | |
| char* buffer; | | char* buffer; | |
| int buffer_size; | | int buffer_size; | |
| boost::intrusive_ptr<piece_manager> storage; | | boost::intrusive_ptr<piece_manager> storage; | |
| // arguments used for read and write | | // arguments used for read and write | |
| int piece, offset; | | int piece, offset; | |
| // used for move_storage and rename_file. On errors, this is
set | | // used for move_storage and rename_file. On errors, this is
set | |
| // to the error message | | // to the error message | |
| std::string str; | | std::string str; | |
| | | | |
| // on error, this is set to the path of the | | // on error, this is set to the path of the | |
| // file the disk operation failed on | | // file the disk operation failed on | |
| std::string error_file; | | std::string error_file; | |
| | | | |
|
| // priority decides whether or not this | | // if this is > 0, it specifies the max number of blocks to | |
| // job will skip entries in the queue or | | read | |
| // not. It always skips in front of entries | | // ahead in the read cache for this access. This is only val | |
| // with lower priority | | id | |
| int priority; | | // for 'read' actions | |
| | | int max_cache_line; | |
| | | | |
| | | // if this is > 0, it may increase the minimum time the cach | |
| | | e | |
| | | // line caused by this operation stays in the cache | |
| | | int cache_min_time; | |
| | | | |
| boost::shared_ptr<entry> resume_data; | | boost::shared_ptr<entry> resume_data; | |
| | | | |
| // the error code from the file operation | | // the error code from the file operation | |
| error_code error; | | error_code error; | |
| | | | |
| // this is called when operation completes | | // this is called when operation completes | |
| boost::function<void(int, disk_io_job const&)> callback; | | boost::function<void(int, disk_io_job const&)> callback; | |
|
| | | | |
| | | // the time when this job was issued. This is used to | |
| | | // keep track of disk I/O congestion | |
| | | ptime start_time; | |
| }; | | }; | |
| | | | |
| // returns true if the fundamental operation | | // returns true if the fundamental operation | |
| // of the given disk job is a read operation | | // of the given disk job is a read operation | |
| bool is_read_operation(disk_io_job const& j); | | bool is_read_operation(disk_io_job const& j); | |
| | | | |
| // this is true if the buffer field in the disk_io_job | | // this is true if the buffer field in the disk_io_job | |
| // points to a disk buffer | | // points to a disk buffer | |
| bool operation_has_buffer(disk_io_job const& j); | | bool operation_has_buffer(disk_io_job const& j); | |
| | | | |
| | | | |
| skipping to change at line 147 | | skipping to change at line 164 | |
| cache_status() | | cache_status() | |
| : blocks_written(0) | | : blocks_written(0) | |
| , writes(0) | | , writes(0) | |
| , blocks_read(0) | | , blocks_read(0) | |
| , blocks_read_hit(0) | | , blocks_read_hit(0) | |
| , reads(0) | | , reads(0) | |
| , queued_bytes(0) | | , queued_bytes(0) | |
| , cache_size(0) | | , cache_size(0) | |
| , read_cache_size(0) | | , read_cache_size(0) | |
| , total_used_buffers(0) | | , total_used_buffers(0) | |
|
| | | , average_queue_time(0) | |
| | | , average_read_time(0) | |
| | | , average_write_time(0) | |
| | | , average_hash_time(0) | |
| | | , average_job_time(0) | |
| | | , average_sort_time(0) | |
| | | , job_queue_length(0) | |
| | | , cumulative_job_time(0) | |
| | | , cumulative_read_time(0) | |
| | | , cumulative_write_time(0) | |
| | | , cumulative_hash_time(0) | |
| | | , cumulative_sort_time(0) | |
| | | , total_read_back(0) | |
| | | , read_queue_size(0) | |
| {} | | {} | |
| | | | |
| // the number of 16kB blocks written | | // the number of 16kB blocks written | |
| size_type blocks_written; | | size_type blocks_written; | |
| // the number of write operations used | | // the number of write operations used | |
| size_type writes; | | size_type writes; | |
| // (blocks_written - writes) / blocks_written represents the | | // (blocks_written - writes) / blocks_written represents the | |
| // "cache hit" ratio in the write cache | | // "cache hit" ratio in the write cache | |
| // the number of blocks read | | // the number of blocks read | |
| | | | |
| | | | |
| skipping to change at line 175 | | skipping to change at line 206 | |
| | | | |
| // the number of blocks in the cache (both read and write) | | // the number of blocks in the cache (both read and write) | |
| int cache_size; | | int cache_size; | |
| | | | |
| // the number of blocks in the cache used for read cache | | // the number of blocks in the cache used for read cache | |
| int read_cache_size; | | int read_cache_size; | |
| | | | |
| // the total number of blocks that are currently in use | | // the total number of blocks that are currently in use | |
| // this includes send and receive buffers | | // this includes send and receive buffers | |
| mutable int total_used_buffers; | | mutable int total_used_buffers; | |
|
| }; | | | |
| | | | |
| struct TORRENT_EXPORT disk_buffer_pool : boost::noncopyable | | | |
| { | | | |
| disk_buffer_pool(int block_size); | | | |
| #ifdef TORRENT_DEBUG | | | |
| ~disk_buffer_pool(); | | | |
| #endif | | | |
| | | | |
| #if defined TORRENT_DEBUG || defined TORRENT_DISK_STATS | | | |
| bool is_disk_buffer(char* buffer | | | |
| , boost::mutex::scoped_lock& l) const; | | | |
| bool is_disk_buffer(char* buffer) const; | | | |
| #endif | | | |
| | | | |
| char* allocate_buffer(char const* category); | | | |
| void free_buffer(char* buf); | | | |
| | | | |
| char* allocate_buffers(int blocks, char const* category); | | | |
| void free_buffers(char* buf, int blocks); | | | |
| | | | |
| int block_size() const { return m_block_size; } | | | |
| | | | |
| #ifdef TORRENT_STATS | | | |
| int disk_allocations() const | | | |
| { return m_allocations; } | | | |
| #endif | | | |
| | | | |
| #ifdef TORRENT_DISK_STATS | | | |
| std::ofstream m_disk_access_log; | | | |
| #endif | | | |
| | | | |
| void release_memory(); | | | |
| | | | |
| int in_use() const { return m_in_use; } | | | |
| | | | |
| protected: | | | |
| | | | |
| // number of bytes per block. The BitTorrent | | | |
| // protocol defines the block size to 16 KiB. | | | |
| const int m_block_size; | | | |
| | | | |
| // number of disk buffers currently allocated | | | |
| int m_in_use; | | | |
| | | | |
|
| session_settings m_settings; | | // times in microseconds | |
| | | int average_queue_time; | |
| private: | | int average_read_time; | |
| | | int average_write_time; | |
| // this only protects the pool allocator | | int average_hash_time; | |
| typedef boost::mutex mutex_t; | | int average_job_time; | |
| mutable mutex_t m_pool_mutex; | | int average_sort_time; | |
| #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | | int job_queue_length; | |
| // memory pool for read and write operations | | | |
| // and disk cache | | | |
| boost::pool<page_aligned_allocator> m_pool; | | | |
| #endif | | | |
| | | | |
|
| #if defined TORRENT_DISK_STATS || defined TORRENT_STATS | | boost::uint32_t cumulative_job_time; | |
| int m_allocations; | | boost::uint32_t cumulative_read_time; | |
| #endif | | boost::uint32_t cumulative_write_time; | |
| #ifdef TORRENT_DISK_STATS | | boost::uint32_t cumulative_hash_time; | |
| public: | | boost::uint32_t cumulative_sort_time; | |
| void rename_buffer(char* buf, char const* category); | | int total_read_back; | |
| protected: | | int read_queue_size; | |
| std::map<std::string, int> m_categories; | | | |
| std::map<char*, std::string> m_buf_to_category; | | | |
| std::ofstream m_log; | | | |
| private: | | | |
| #endif | | | |
| #ifdef TORRENT_DEBUG | | | |
| int m_magic; | | | |
| #endif | | | |
| }; | | }; | |
| | | | |
| // this is a singleton consisting of the thread and a queue | | // this is a singleton consisting of the thread and a queue | |
| // of disk io jobs | | // of disk io jobs | |
|
| struct TORRENT_EXPORT disk_io_thread : disk_buffer_pool | | struct TORRENT_EXTRA_EXPORT disk_io_thread : disk_buffer_pool | |
| { | | { | |
| disk_io_thread(io_service& ios | | disk_io_thread(io_service& ios | |
| , boost::function<void()> const& queue_callback | | , boost::function<void()> const& queue_callback | |
| , file_pool& fp | | , file_pool& fp | |
| , int block_size = 16 * 1024); | | , int block_size = 16 * 1024); | |
| ~disk_io_thread(); | | ~disk_io_thread(); | |
| | | | |
|
| | | void abort(); | |
| void join(); | | void join(); | |
| | | | |
| // aborts read operations | | // aborts read operations | |
| void stop(boost::intrusive_ptr<piece_manager> s); | | void stop(boost::intrusive_ptr<piece_manager> s); | |
|
| void add_job(disk_io_job const& j | | | |
| | | // returns the disk write queue size | |
| | | int add_job(disk_io_job const& j | |
| , boost::function<void(int, disk_io_job const&)> con
st& f | | , boost::function<void(int, disk_io_job const&)> con
st& f | |
| = boost::function<void(int, disk_io_job const&)>()); | | = boost::function<void(int, disk_io_job const&)>()); | |
| | | | |
| // keep track of the number of bytes in the job queue | | // keep track of the number of bytes in the job queue | |
| // at any given time. i.e. the sum of all buffer_size. | | // at any given time. i.e. the sum of all buffer_size. | |
| // this is used to slow down the download global download | | // this is used to slow down the download global download | |
| // speed when the queue buffer size is too big. | | // speed when the queue buffer size is too big. | |
| size_type queue_buffer_size() const; | | size_type queue_buffer_size() const; | |
|
| | | bool can_write() const; | |
| | | | |
| void get_cache_info(sha1_hash const& ih | | void get_cache_info(sha1_hash const& ih | |
| , std::vector<cached_piece_info>& ret) const; | | , std::vector<cached_piece_info>& ret) const; | |
| | | | |
| cache_status status() const; | | cache_status status() const; | |
| | | | |
|
| void operator()(); | | void thread_fun(); | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
| struct cached_block_entry | | struct cached_block_entry | |
| { | | { | |
| cached_block_entry(): buf(0) {} | | cached_block_entry(): buf(0) {} | |
| // the buffer pointer (this is a disk_pool buffer) | | // the buffer pointer (this is a disk_pool buffer) | |
| // or 0 | | // or 0 | |
| | | | |
| skipping to change at line 301 | | skipping to change at line 280 | |
| | | | |
| // callback for when this block is flushed to disk | | // callback for when this block is flushed to disk | |
| boost::function<void(int, disk_io_job const&)> callb
ack; | | boost::function<void(int, disk_io_job const&)> callb
ack; | |
| }; | | }; | |
| | | | |
| struct cached_piece_entry | | struct cached_piece_entry | |
| { | | { | |
| int piece; | | int piece; | |
| // storage this piece belongs to | | // storage this piece belongs to | |
| boost::intrusive_ptr<piece_manager> storage; | | boost::intrusive_ptr<piece_manager> storage; | |
|
| | | // the pointers to the block data | |
| | | boost::shared_array<cached_block_entry> blocks; | |
| // the last time a block was writting to this piece | | // the last time a block was writting to this piece | |
|
| ptime last_use; | | // plus the minimum amount of time the block is guar | |
| | | anteed | |
| | | // to stay in the cache | |
| | | ptime expire; | |
| // the number of blocks in the cache for this piece | | // the number of blocks in the cache for this piece | |
| int num_blocks; | | int num_blocks; | |
|
| // the pointers to the block data | | // used to determine if this piece should be flushed | |
| boost::shared_array<cached_block_entry> blocks; | | int num_contiguous_blocks; | |
| | | // this is the first block that has not yet been has | |
| | | hed | |
| | | // by the partial hasher. When minimizing read-back, | |
| | | this | |
| | | // is used to determine if flushing a range would fo | |
| | | rce us | |
| | | // to read it back later when hashing | |
| | | int next_block_to_hash; | |
| | | | |
| | | std::pair<void*, int> storage_piece_pair() const | |
| | | { return std::pair<void*, int>(storage.get(), piece) | |
| | | ; } | |
| }; | | }; | |
| | | | |
|
| typedef boost::recursive_mutex mutex_t; | | typedef multi_index_container< | |
| | | cached_piece_entry, indexed_by< | |
| | | ordered_unique<const_mem_fun<cached_piece_en | |
| | | try, std::pair<void*, int> | |
| | | , &cached_piece_entry::storage_piece_pair> > | |
| | | , ordered_non_unique<member<cached_piece_ent | |
| | | ry, ptime | |
| | | , &cached_piece_entry::expire> > | |
| | | > | |
| | | > cache_t; | |
| | | | |
|
| // TODO: turn this into a multi-index list | | typedef cache_t::nth_index<0>::type cache_piece_index_t; | |
| // sorted by piece and last use time | | typedef cache_t::nth_index<1>::type cache_lru_index_t; | |
| typedef std::list<cached_piece_entry> cache_t; | | | |
| | | | |
| private: | | private: | |
| | | | |
|
| | | int add_job(disk_io_job const& j | |
| | | , mutex::scoped_lock& l | |
| | | , boost::function<void(int, disk_io_job const&)> con | |
| | | st& f | |
| | | = boost::function<void(int, disk_io_job const&)>()); | |
| | | | |
| bool test_error(disk_io_job& j); | | bool test_error(disk_io_job& j); | |
|
| void post_callback(boost::function<void(int, disk_io_job con | | void post_callback(disk_io_job const& j, int ret); | |
| st&)> const& handler | | | |
| , disk_io_job const& j, int ret); | | | |
| | | | |
| // cache operations | | // cache operations | |
|
| cache_t::iterator find_cached_piece( | | cache_piece_index_t::iterator find_cached_piece( | |
| cache_t& cache, disk_io_job const& j | | cache_t& cache, disk_io_job const& j | |
|
| , mutex_t::scoped_lock& l); | | , mutex::scoped_lock& l); | |
| bool is_cache_hit(cache_t::iterator p | | bool is_cache_hit(cached_piece_entry& p | |
| , disk_io_job const& j, mutex_t::scoped_lock& l); | | , disk_io_job const& j, mutex::scoped_lock& l); | |
| int copy_from_piece(cache_t::iterator p, bool& hit | | int copy_from_piece(cached_piece_entry& p, bool& hit | |
| , disk_io_job const& j, mutex_t::scoped_lock& l); | | , disk_io_job const& j, mutex::scoped_lock& l); | |
| | | | |
| | | struct ignore_t | |
| | | { | |
| | | ignore_t(): piece(-1), storage(0) {} | |
| | | ignore_t(int idx, piece_manager* st): piece(idx), st | |
| | | orage(st) {} | |
| | | int piece; | |
| | | piece_manager* storage; | |
| | | }; | |
| | | | |
| // write cache operations | | // write cache operations | |
| enum options_t { dont_flush_write_blocks = 1, ignore_cache_s
ize = 2 }; | | enum options_t { dont_flush_write_blocks = 1, ignore_cache_s
ize = 2 }; | |
|
| int flush_cache_blocks(mutex_t::scoped_lock& l | | int flush_cache_blocks(mutex::scoped_lock& l | |
| , int blocks, cache_t::iterator ignore | | , int blocks, ignore_t ignore = ignore_t(), int opti | |
| , int options = 0); | | ons = 0); | |
| void flush_expired_pieces(); | | void flush_expired_pieces(); | |
|
| int flush_and_remove(cache_t::iterator i, mutex_t::scoped_lo | | int flush_contiguous_blocks(cached_piece_entry& p | |
| ck& l); | | , mutex::scoped_lock& l, int lower_limit = 0, bool a | |
| int flush_contiguous_blocks(disk_io_thread::cache_t::iterato | | void_readback = false); | |
| r e | | int flush_range(cached_piece_entry& p, int start, int end, m | |
| , mutex_t::scoped_lock& l, int lower_limit = 0); | | utex::scoped_lock& l); | |
| int flush_range(cache_t::iterator i, int start, int end, mut | | | |
| ex_t::scoped_lock& l); | | | |
| int cache_block(disk_io_job& j | | int cache_block(disk_io_job& j | |
| , boost::function<void(int,disk_io_job const&)>& han
dler | | , boost::function<void(int,disk_io_job const&)>& han
dler | |
|
| , mutex_t::scoped_lock& l); | | , int cache_expire | |
| | | , mutex::scoped_lock& l); | |
| | | | |
| // read cache operations | | // read cache operations | |
|
| int clear_oldest_read_piece(int num_blocks, cache_t::iterato | | int clear_oldest_read_piece(int num_blocks, ignore_t ignore | |
| r ignore | | , mutex::scoped_lock& l); | |
| , mutex_t::scoped_lock& l); | | | |
| int read_into_piece(cached_piece_entry& p, int start_block | | int read_into_piece(cached_piece_entry& p, int start_block | |
|
| , int options, int num_blocks, mutex_t::scoped_lock& | | , int options, int num_blocks, mutex::scoped_lock& l | |
| l); | | ); | |
| int cache_read_block(disk_io_job const& j, mutex_t::scoped_l | | int cache_read_block(disk_io_job const& j, mutex::scoped_loc | |
| ock& l); | | k& l); | |
| int cache_read_piece(disk_io_job const& j, mutex_t::scoped_l | | int free_piece(cached_piece_entry& p, mutex::scoped_lock& l) | |
| ock& l); | | ; | |
| int free_piece(cached_piece_entry& p, mutex_t::scoped_lock& | | int drain_piece_bufs(cached_piece_entry& p, std::vector<char | |
| l); | | *>& buf | |
| int try_read_from_cache(disk_io_job const& j); | | , mutex::scoped_lock& l); | |
| | | | |
| | | enum cache_flags_t { | |
| | | cache_only = 1 | |
| | | }; | |
| | | int try_read_from_cache(disk_io_job const& j, bool& hit, int | |
| | | flags = 0); | |
| int read_piece_from_cache_and_hash(disk_io_job const& j, sha
1_hash& h); | | int read_piece_from_cache_and_hash(disk_io_job const& j, sha
1_hash& h); | |
|
| | | int cache_piece(disk_io_job const& j, cache_piece_index_t::i | |
| | | terator& p | |
| | | , bool& hit, int options, mutex::scoped_lock& l); | |
| | | | |
|
| // this mutex only protects m_jobs, m_queue_buffer_size | | // this mutex only protects m_jobs, m_queue_buffer_size, | |
| // and m_abort | | // m_exceeded_write_queue and m_abort | |
| mutable mutex_t m_queue_mutex; | | mutable mutex m_queue_mutex; | |
| boost::condition m_signal; | | event m_signal; | |
| bool m_abort; | | bool m_abort; | |
| bool m_waiting_to_shutdown; | | bool m_waiting_to_shutdown; | |
|
| std::list<disk_io_job> m_jobs; | | std::deque<disk_io_job> m_jobs; | |
| size_type m_queue_buffer_size; | | size_type m_queue_buffer_size; | |
| | | | |
| ptime m_last_file_check; | | ptime m_last_file_check; | |
| | | | |
| // this protects the piece cache and related members | | // this protects the piece cache and related members | |
|
| mutable mutex_t m_piece_mutex; | | mutable mutex m_piece_mutex; | |
| // write cache | | // write cache | |
| cache_t m_pieces; | | cache_t m_pieces; | |
| | | | |
| // read cache | | // read cache | |
| cache_t m_read_pieces; | | cache_t m_read_pieces; | |
| | | | |
|
| | | void flip_stats(ptime now); | |
| | | | |
| // total number of blocks in use by both the read | | // total number of blocks in use by both the read | |
| // and the write cache. This is not supposed to | | // and the write cache. This is not supposed to | |
| // exceed m_cache_size | | // exceed m_cache_size | |
| cache_status m_cache_stats; | | cache_status m_cache_stats; | |
| | | | |
|
| | | // keeps average queue time for disk jobs (in microseconds) | |
| | | average_accumulator m_queue_time; | |
| | | | |
| | | // average read time for cache misses (in microseconds) | |
| | | average_accumulator m_read_time; | |
| | | | |
| | | // average write time (in microseconds) | |
| | | average_accumulator m_write_time; | |
| | | | |
| | | // average hash time (in microseconds) | |
| | | average_accumulator m_hash_time; | |
| | | | |
| | | // average time to serve a job (any job) in microseconds | |
| | | average_accumulator m_job_time; | |
| | | | |
| | | // average time to ask for physical offset on disk | |
| | | // and insert into queue | |
| | | average_accumulator m_sort_time; | |
| | | | |
| | | // the last time we reset the average time and store the | |
| | | // latest value in m_cache_stats | |
| | | ptime m_last_stats_flip; | |
| | | | |
| | | typedef std::multimap<size_type, disk_io_job> read_jobs_t; | |
| | | read_jobs_t m_sorted_read_jobs; | |
| | | | |
| #ifdef TORRENT_DISK_STATS | | #ifdef TORRENT_DISK_STATS | |
| std::ofstream m_log; | | std::ofstream m_log; | |
| #endif | | #endif | |
| | | | |
|
| | | // the amount of physical ram in the machine | |
| | | boost::uint64_t m_physical_ram; | |
| | | | |
| | | // if we exceeded the max queue disk write size | |
| | | // this is set to true. It remains true until the | |
| | | // queue is smaller than the low watermark | |
| | | bool m_exceeded_write_queue; | |
| | | | |
| io_service& m_ios; | | io_service& m_ios; | |
| | | | |
| boost::function<void()> m_queue_callback; | | boost::function<void()> m_queue_callback; | |
| | | | |
| // this keeps the io_service::run() call blocked from | | // this keeps the io_service::run() call blocked from | |
| // returning. When shutting down, it's possible that | | // returning. When shutting down, it's possible that | |
| // the event queue is drained before the disk_io_thread | | // the event queue is drained before the disk_io_thread | |
| // has posted its last callback. When this happens, the | | // has posted its last callback. When this happens, the | |
| // io_service will have a pending callback from the | | // io_service will have a pending callback from the | |
| // disk_io_thread, but the event loop is not running. | | // disk_io_thread, but the event loop is not running. | |
| // this means that the event is destructed after the | | // this means that the event is destructed after the | |
| // disk_io_thread. If the event refers to a disk buffer | | // disk_io_thread. If the event refers to a disk buffer | |
| // it will try to free it, but the buffer pool won't | | // it will try to free it, but the buffer pool won't | |
| // exist anymore, and crash. This prevents that. | | // exist anymore, and crash. This prevents that. | |
|
| boost::optional<asio::io_service::work> m_work; | | boost::optional<io_service::work> m_work; | |
| | | | |
| // reference to the file_pool which is a member of | | // reference to the file_pool which is a member of | |
| // the session_impl object | | // the session_impl object | |
| file_pool& m_file_pool; | | file_pool& m_file_pool; | |
| | | | |
|
| | | // when completion notifications are queued, they're stuck | |
| | | // in this list | |
| | | std::list<std::pair<disk_io_job, int> > m_queued_completions | |
| | | ; | |
| | | | |
| // thread for performing blocking disk io operations | | // thread for performing blocking disk io operations | |
|
| boost::thread m_disk_io_thread; | | thread m_disk_io_thread; | |
| }; | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 43 change blocks. |
| 141 lines changed or deleted | | 209 lines changed or added | |
|
| peer_connection.hpp | | peer_connection.hpp | |
| | | | |
| skipping to change at line 41 | | skipping to change at line 41 | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_PEER_CONNECTION_HPP_INCLUDED | | #ifndef TORRENT_PEER_CONNECTION_HPP_INCLUDED | |
| #define TORRENT_PEER_CONNECTION_HPP_INCLUDED | | #define TORRENT_PEER_CONNECTION_HPP_INCLUDED | |
| | | | |
| #include <ctime> | | #include <ctime> | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| #include <string> | | #include <string> | |
| | | | |
|
| | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING | |
| #include "libtorrent/debug.hpp" | | #include "libtorrent/debug.hpp" | |
|
| | | #endif | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/smart_ptr.hpp> | | #include <boost/smart_ptr.hpp> | |
| #include <boost/weak_ptr.hpp> | | #include <boost/weak_ptr.hpp> | |
|
| | | #include <boost/intrusive_ptr.hpp> | |
| #include <boost/noncopyable.hpp> | | #include <boost/noncopyable.hpp> | |
| #include <boost/array.hpp> | | #include <boost/array.hpp> | |
| #include <boost/optional.hpp> | | #include <boost/optional.hpp> | |
| #include <boost/cstdint.hpp> | | #include <boost/cstdint.hpp> | |
| #include <boost/pool/pool.hpp> | | #include <boost/pool/pool.hpp> | |
| #include <boost/aligned_storage.hpp> | | #include <boost/aligned_storage.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/buffer.hpp" | | #include "libtorrent/buffer.hpp" | |
|
| #include "libtorrent/socket.hpp" | | | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
|
| #include "libtorrent/storage.hpp" | | | |
| #include "libtorrent/stat.hpp" | | #include "libtorrent/stat.hpp" | |
| #include "libtorrent/alert.hpp" | | #include "libtorrent/alert.hpp" | |
|
| #include "libtorrent/torrent_handle.hpp" | | | |
| #include "libtorrent/torrent.hpp" | | | |
| #include "libtorrent/peer_request.hpp" | | #include "libtorrent/peer_request.hpp" | |
| #include "libtorrent/piece_block_progress.hpp" | | #include "libtorrent/piece_block_progress.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
|
| #include "libtorrent/session.hpp" | | | |
| #include "libtorrent/bandwidth_limit.hpp" | | #include "libtorrent/bandwidth_limit.hpp" | |
| #include "libtorrent/policy.hpp" | | #include "libtorrent/policy.hpp" | |
|
| #include "libtorrent/socket_type.hpp" | | #include "libtorrent/socket_type_fwd.hpp" | |
| #include "libtorrent/intrusive_ptr_base.hpp" | | #include "libtorrent/intrusive_ptr_base.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/chained_buffer.hpp" | | #include "libtorrent/chained_buffer.hpp" | |
| #include "libtorrent/disk_buffer_holder.hpp" | | #include "libtorrent/disk_buffer_holder.hpp" | |
| #include "libtorrent/bitfield.hpp" | | #include "libtorrent/bitfield.hpp" | |
|
| | | #include "libtorrent/bandwidth_socket.hpp" | |
| | | #include "libtorrent/socket_type_fwd.hpp" | |
| | | #include "libtorrent/error_code.hpp" | |
| | | #include "libtorrent/sliding_average.hpp" | |
| | | | |
| #ifdef TORRENT_STATS | | #ifdef TORRENT_STATS | |
| #include "libtorrent/aux_/session_impl.hpp" | | #include "libtorrent/aux_/session_impl.hpp" | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| class torrent; | | class torrent; | |
|
| | | struct peer_info; | |
| | | struct disk_io_job; | |
| | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| struct peer_plugin; | | struct peer_plugin; | |
|
| | | #endif | |
| | | | |
| namespace detail | | namespace detail | |
| { | | { | |
| struct session_impl; | | struct session_impl; | |
| } | | } | |
| | | | |
| struct pending_block | | struct pending_block | |
| { | | { | |
| pending_block(piece_block const& b) | | pending_block(piece_block const& b) | |
|
| : skipped(0), not_wanted(false), timed_out(false) | | : block(b), skipped(0), not_wanted(false) | |
| , busy(false), block(b) {} | | , timed_out(false), busy(false) {} | |
| | | | |
| | | piece_block block; | |
| | | | |
| // the number of times the request | | // the number of times the request | |
| // has been skipped by out of order blocks | | // has been skipped by out of order blocks | |
|
| boost::uint16_t skipped; | | boost::uint16_t skipped:13; | |
| | | | |
| // if any of these are set to true, this block | | // if any of these are set to true, this block | |
| // is not allocated | | // is not allocated | |
| // in the piece picker anymore, and open for | | // in the piece picker anymore, and open for | |
| // other peers to pick. This may be caused by | | // other peers to pick. This may be caused by | |
| // it either timing out or being received | | // it either timing out or being received | |
| // unexpectedly from the peer | | // unexpectedly from the peer | |
| bool not_wanted:1; | | bool not_wanted:1; | |
| bool timed_out:1; | | bool timed_out:1; | |
| | | | |
| // the busy flag is set if the block was | | // the busy flag is set if the block was | |
| // requested from another peer when this | | // requested from another peer when this | |
| // request was queued. We only allow a single | | // request was queued. We only allow a single | |
| // busy request at a time in each peer's queue | | // busy request at a time in each peer's queue | |
| bool busy:1; | | bool busy:1; | |
| | | | |
|
| piece_block block; | | | |
| | | | |
| bool operator==(pending_block const& b) | | bool operator==(pending_block const& b) | |
| { | | { | |
| return b.skipped == skipped && b.block == block | | return b.skipped == skipped && b.block == block | |
| && b.not_wanted == not_wanted && b.timed_out
== timed_out; | | && b.not_wanted == not_wanted && b.timed_out
== timed_out; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct has_block | | struct has_block | |
| { | | { | |
| has_block(piece_block const& b): block(b) {} | | has_block(piece_block const& b): block(b) {} | |
| piece_block const& block; | | piece_block const& block; | |
| bool operator()(pending_block const& pb) const | | bool operator()(pending_block const& pb) const | |
| { return pb.block == block; } | | { return pb.block == block; } | |
| }; | | }; | |
| | | | |
|
| class TORRENT_EXPORT peer_connection | | class TORRENT_EXTRA_EXPORT peer_connection | |
| : public intrusive_ptr_base<peer_connection> | | : public bandwidth_socket | |
| , public boost::noncopyable | | , public boost::noncopyable | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| public: | | public: | |
| | | | |
|
| | | enum connection_type | |
| | | { | |
| | | bittorrent_connection = 0, | |
| | | url_seed_connection = 1, | |
| | | http_seed_connection = 2 | |
| | | }; | |
| | | | |
| | | virtual int type() const = 0; | |
| | | | |
| enum channels | | enum channels | |
| { | | { | |
| upload_channel, | | upload_channel, | |
| download_channel, | | download_channel, | |
| num_channels | | num_channels | |
| }; | | }; | |
| | | | |
| // this is the constructor where the we are the active part. | | // this is the constructor where the we are the active part. | |
| // The peer_conenction should handshake and verify that the | | // The peer_conenction should handshake and verify that the | |
| // other end has the correct id | | // other end has the correct id | |
| peer_connection( | | peer_connection( | |
| aux::session_impl& ses | | aux::session_impl& ses | |
| , boost::weak_ptr<torrent> t | | , boost::weak_ptr<torrent> t | |
| , boost::shared_ptr<socket_type> s | | , boost::shared_ptr<socket_type> s | |
| , tcp::endpoint const& remote | | , tcp::endpoint const& remote | |
|
| , policy::peer* peerinfo); | | , policy::peer* peerinfo | |
| | | , bool outgoing = true); | |
| | | | |
| // with this constructor we have been contacted and we still
don't | | // with this constructor we have been contacted and we still
don't | |
| // know which torrent the connection belongs to | | // know which torrent the connection belongs to | |
| peer_connection( | | peer_connection( | |
| aux::session_impl& ses | | aux::session_impl& ses | |
| , boost::shared_ptr<socket_type> s | | , boost::shared_ptr<socket_type> s | |
| , tcp::endpoint const& remote | | , tcp::endpoint const& remote | |
| , policy::peer* peerinfo); | | , policy::peer* peerinfo); | |
| | | | |
| // this function is called after it has been constructed and
properly | | // this function is called after it has been constructed and
properly | |
| | | | |
| skipping to change at line 193 | | skipping to change at line 209 | |
| policy::peer* peer_info_struct() const | | policy::peer* peer_info_struct() const | |
| { return m_peer_info; } | | { return m_peer_info; } | |
| | | | |
| enum peer_speed_t { slow = 1, medium, fast }; | | enum peer_speed_t { slow = 1, medium, fast }; | |
| peer_speed_t peer_speed(); | | peer_speed_t peer_speed(); | |
| | | | |
| void send_allowed_set(); | | void send_allowed_set(); | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void add_extension(boost::shared_ptr<peer_plugin>); | | void add_extension(boost::shared_ptr<peer_plugin>); | |
|
| | | peer_plugin const* find_plugin(char const* type); | |
| #endif | | #endif | |
| | | | |
| // this function is called once the torrent associated | | // this function is called once the torrent associated | |
| // with this peer connection has retrieved the meta- | | // with this peer connection has retrieved the meta- | |
| // data. If the torrent was spawned with metadata | | // data. If the torrent was spawned with metadata | |
| // this is called from the constructor. | | // this is called from the constructor. | |
| void init(); | | void init(); | |
| | | | |
| // this is called when the metadata is retrieved | | // this is called when the metadata is retrieved | |
| // and the files has been checked | | // and the files has been checked | |
| virtual void on_metadata() {}; | | virtual void on_metadata() {}; | |
| | | | |
| void on_metadata_impl(); | | void on_metadata_impl(); | |
| | | | |
|
| | | int get_upload_limit() const; | |
| | | int get_download_limit() const; | |
| void set_upload_limit(int limit); | | void set_upload_limit(int limit); | |
| void set_download_limit(int limit); | | void set_download_limit(int limit); | |
| | | | |
| int upload_limit() const { return m_upload_limit; } | | int upload_limit() const { return m_upload_limit; } | |
| int download_limit() const { return m_download_limit; } | | int download_limit() const { return m_download_limit; } | |
| | | | |
| int prefer_whole_pieces() const | | int prefer_whole_pieces() const | |
| { | | { | |
| if (on_parole()) return 1; | | if (on_parole()) return 1; | |
| return m_prefer_whole_pieces; | | return m_prefer_whole_pieces; | |
| | | | |
| skipping to change at line 239 | | skipping to change at line 258 | |
| | | | |
| void request_large_blocks(bool b) | | void request_large_blocks(bool b) | |
| { m_request_large_blocks = b; } | | { m_request_large_blocks = b; } | |
| | | | |
| void set_endgame(bool b) { m_endgame_mode = b; } | | void set_endgame(bool b) { m_endgame_mode = b; } | |
| bool endgame() const { return m_endgame_mode; } | | bool endgame() const { return m_endgame_mode; } | |
| | | | |
| bool no_download() const { return m_no_download; } | | bool no_download() const { return m_no_download; } | |
| void no_download(bool b) { m_no_download = b; } | | void no_download(bool b) { m_no_download = b; } | |
| | | | |
|
| | | bool ignore_stats() const { return m_ignore_stats; } | |
| | | void ignore_stats(bool b) { m_ignore_stats = b; } | |
| | | | |
| void set_priority(int p) | | void set_priority(int p) | |
| { | | { | |
| TORRENT_ASSERT(p > 0); | | TORRENT_ASSERT(p > 0); | |
| TORRENT_ASSERT(m_priority <= 255); | | TORRENT_ASSERT(m_priority <= 255); | |
| if (p > 255) p = 255; | | if (p > 255) p = 255; | |
| m_priority = p; | | m_priority = p; | |
| } | | } | |
| | | | |
| void fast_reconnect(bool r); | | void fast_reconnect(bool r); | |
| bool fast_reconnect() const { return m_fast_reconnect; } | | bool fast_reconnect() const { return m_fast_reconnect; } | |
| | | | |
| skipping to change at line 265 | | skipping to change at line 287 | |
| // and only allow it to request that piece | | // and only allow it to request that piece | |
| void superseed_piece(int index); | | void superseed_piece(int index); | |
| int superseed_piece() const { return m_superseed_piece; } | | int superseed_piece() const { return m_superseed_piece; } | |
| | | | |
| // tells if this connection has data it want to send | | // tells if this connection has data it want to send | |
| // and has enough upload bandwidth quota left to send it. | | // and has enough upload bandwidth quota left to send it. | |
| bool can_write() const; | | bool can_write() const; | |
| bool can_read(char* state = 0) const; | | bool can_read(char* state = 0) const; | |
| | | | |
| bool is_seed() const; | | bool is_seed() const; | |
|
| | | int num_have_pieces() const { return m_num_pieces; } | |
| | | | |
| | | void set_share_mode(bool m); | |
| | | bool share_mode() const { return m_share_mode; } | |
| | | | |
| void set_upload_only(bool u); | | void set_upload_only(bool u); | |
| bool upload_only() const { return m_upload_only; } | | bool upload_only() const { return m_upload_only; } | |
| | | | |
|
| | | void set_holepunch_mode() | |
| | | { | |
| | | m_holepunch_mode = true; | |
| | | #ifdef TORRENT_VERBOSE_LOGGING | |
| | | peer_log("*** HOLEPUNCH MODE ***"); | |
| | | #endif | |
| | | } | |
| | | | |
| // will send a keep-alive message to the peer | | // will send a keep-alive message to the peer | |
| void keep_alive(); | | void keep_alive(); | |
| | | | |
| peer_id const& pid() const { return m_peer_id; } | | peer_id const& pid() const { return m_peer_id; } | |
| void set_pid(const peer_id& peer_id) { m_peer_id = peer_id;
} | | void set_pid(const peer_id& peer_id) { m_peer_id = peer_id;
} | |
| bool has_piece(int i) const; | | bool has_piece(int i) const; | |
| | | | |
| std::vector<pending_block> const& download_queue() const; | | std::vector<pending_block> const& download_queue() const; | |
| std::vector<pending_block> const& request_queue() const; | | std::vector<pending_block> const& request_queue() const; | |
| std::vector<peer_request> const& upload_queue() const; | | std::vector<peer_request> const& upload_queue() const; | |
| | | | |
|
| | | void clear_request_queue(); | |
| | | | |
| // estimate of how long it will take until we have | | // estimate of how long it will take until we have | |
| // received all piece requests that we have sent | | // received all piece requests that we have sent | |
| // if extra_bytes is specified, it will include those | | // if extra_bytes is specified, it will include those | |
| // bytes as if they've been requested | | // bytes as if they've been requested | |
| time_duration download_queue_time(int extra_bytes = 0) const
; | | time_duration download_queue_time(int extra_bytes = 0) const
; | |
| | | | |
| bool is_interesting() const { return m_interesting; } | | bool is_interesting() const { return m_interesting; } | |
| bool is_choked() const { return m_choked; } | | bool is_choked() const { return m_choked; } | |
| | | | |
| bool is_peer_interested() const { return m_peer_interested;
} | | bool is_peer_interested() const { return m_peer_interested;
} | |
| | | | |
| skipping to change at line 323 | | skipping to change at line 359 | |
| | | | |
| bitfield const& get_bitfield() const; | | bitfield const& get_bitfield() const; | |
| std::vector<int> const& allowed_fast(); | | std::vector<int> const& allowed_fast(); | |
| std::vector<int> const& suggested_pieces() const { return m_
suggested_pieces; } | | std::vector<int> const& suggested_pieces() const { return m_
suggested_pieces; } | |
| | | | |
| ptime connected_time() const { return m_connect; } | | ptime connected_time() const { return m_connect; } | |
| ptime last_received() const { return m_last_receive; } | | ptime last_received() const { return m_last_receive; } | |
| | | | |
| void on_timeout(); | | void on_timeout(); | |
| // this will cause this peer_connection to be disconnected. | | // this will cause this peer_connection to be disconnected. | |
|
| void disconnect(error_code const& ec, int error = 0); | | virtual void disconnect(error_code const& ec, int error = 0) | |
| | | ; | |
| | | // called when a connect attempt fails (not when an | |
| | | // established connection fails) | |
| | | void connect_failed(error_code const& e); | |
| bool is_disconnecting() const { return m_disconnecting; } | | bool is_disconnecting() const { return m_disconnecting; } | |
| | | | |
| // this is called when the connection attempt has succeeded | | // this is called when the connection attempt has succeeded | |
| // and the peer_connection is supposed to set m_connecting | | // and the peer_connection is supposed to set m_connecting | |
| // to false, and stop monitor writability | | // to false, and stop monitor writability | |
| void on_connection_complete(error_code const& e); | | void on_connection_complete(error_code const& e); | |
| | | | |
| // returns true if this connection is still waiting to | | // returns true if this connection is still waiting to | |
| // finish the connection attempt | | // finish the connection attempt | |
| bool is_connecting() const { return m_connecting; } | | bool is_connecting() const { return m_connecting; } | |
| | | | |
| skipping to change at line 363 | | skipping to change at line 402 | |
| void add_free_upload(size_type free_upload); | | void add_free_upload(size_type free_upload); | |
| | | | |
| // trust management. | | // trust management. | |
| void received_valid_data(int index); | | void received_valid_data(int index); | |
| void received_invalid_data(int index); | | void received_invalid_data(int index); | |
| | | | |
| size_type share_diff() const; | | size_type share_diff() const; | |
| | | | |
| // a connection is local if it was initiated by us. | | // a connection is local if it was initiated by us. | |
| // if it was an incoming connection, it is remote | | // if it was an incoming connection, it is remote | |
|
| bool is_local() const { return m_active; } | | bool is_outgoing() const { return m_outgoing; } | |
| | | | |
| | | bool received_listen_port() const { return m_received_listen | |
| | | _port; } | |
| | | void received_listen_port() | |
| | | { m_received_listen_port = true; } | |
| | | | |
| bool on_local_network() const; | | bool on_local_network() const; | |
| bool ignore_bandwidth_limits() const | | bool ignore_bandwidth_limits() const | |
| { return m_ignore_bandwidth_limits; } | | { return m_ignore_bandwidth_limits; } | |
| void ignore_bandwidth_limits(bool i) | | void ignore_bandwidth_limits(bool i) | |
| { m_ignore_bandwidth_limits = i; } | | { m_ignore_bandwidth_limits = i; } | |
| | | | |
| bool ignore_unchoke_slots() const; | | bool ignore_unchoke_slots() const; | |
| void ignore_unchoke_slots(bool i) | | void ignore_unchoke_slots(bool i) | |
| { m_ignore_unchoke_slots = i; } | | { m_ignore_unchoke_slots = i; } | |
| | | | |
| bool failed() const { return m_failed; } | | bool failed() const { return m_failed; } | |
| | | | |
| int desired_queue_size() const | | int desired_queue_size() const | |
| { | | { | |
| // this peer is in end-game mode we only want | | // this peer is in end-game mode we only want | |
| // one outstanding request | | // one outstanding request | |
| return m_endgame_mode ? 1: m_desired_queue_size; | | return m_endgame_mode ? 1: m_desired_queue_size; | |
| } | | } | |
| | | | |
|
| | | bool bittyrant_unchoke_compare( | |
| | | boost::intrusive_ptr<peer_connection const> const& p | |
| | | ) const; | |
| // compares this connection against the given connection | | // compares this connection against the given connection | |
| // for which one is more eligible for an unchoke. | | // for which one is more eligible for an unchoke. | |
| // returns true if this is more eligible | | // returns true if this is more eligible | |
| bool unchoke_compare(boost::intrusive_ptr<peer_connection co
nst> const& p) const; | | bool unchoke_compare(boost::intrusive_ptr<peer_connection co
nst> const& p) const; | |
| bool upload_rate_compare(peer_connection const* p) const; | | bool upload_rate_compare(peer_connection const* p) const; | |
| | | | |
| // resets the byte counters that are used to measure | | // resets the byte counters that are used to measure | |
| // the number of bytes transferred within unchoke cycles | | // the number of bytes transferred within unchoke cycles | |
| void reset_choke_counters(); | | void reset_choke_counters(); | |
| | | | |
| // if this peer connection is useless (neither party is | | // if this peer connection is useless (neither party is | |
| // interested in the other), disconnect it | | // interested in the other), disconnect it | |
| void disconnect_if_redundant(); | | void disconnect_if_redundant(); | |
| | | | |
|
| | | void increase_est_reciprocation_rate(); | |
| | | void decrease_est_reciprocation_rate(); | |
| | | int est_reciprocation_rate() const { return m_est_reciprocat | |
| | | ion_rate; } | |
| | | | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING | |
|
| | | void peer_log(char const* fmt, ...) const; | |
| boost::shared_ptr<logger> m_logger; | | boost::shared_ptr<logger> m_logger; | |
| #endif | | #endif | |
| | | | |
| // the message handlers are called | | // the message handlers are called | |
| // each time a recv() returns some new | | // each time a recv() returns some new | |
| // data, the last time it will be called | | // data, the last time it will be called | |
| // is when the entire packet has been | | // is when the entire packet has been | |
| // received, then it will no longer | | // received, then it will no longer | |
| // be called. i.e. most handlers need | | // be called. i.e. most handlers need | |
| // to check how much of the packet they | | // to check how much of the packet they | |
| | | | |
| skipping to change at line 433 | | skipping to change at line 483 | |
| void incoming_cancel(peer_request const& r); | | void incoming_cancel(peer_request const& r); | |
| | | | |
| void incoming_dht_port(int listen_port); | | void incoming_dht_port(int listen_port); | |
| | | | |
| void incoming_reject_request(peer_request const& r); | | void incoming_reject_request(peer_request const& r); | |
| void incoming_have_all(); | | void incoming_have_all(); | |
| void incoming_have_none(); | | void incoming_have_none(); | |
| void incoming_allowed_fast(int index); | | void incoming_allowed_fast(int index); | |
| void incoming_suggest(int index); | | void incoming_suggest(int index); | |
| | | | |
|
| | | void set_has_metadata(bool m) { m_has_metadata = m; } | |
| | | bool has_metadata() const { return m_has_metadata; } | |
| | | | |
| // the following functions appends messages | | // the following functions appends messages | |
| // to the send buffer | | // to the send buffer | |
| bool send_choke(); | | bool send_choke(); | |
| bool send_unchoke(); | | bool send_unchoke(); | |
| void send_interested(); | | void send_interested(); | |
| void send_not_interested(); | | void send_not_interested(); | |
|
| | | void send_suggest(int piece); | |
| | | | |
| void snub_peer(); | | void snub_peer(); | |
| | | | |
| bool can_request_time_critical() const; | | bool can_request_time_critical() const; | |
| | | | |
| void make_time_critical(piece_block const& block); | | void make_time_critical(piece_block const& block); | |
| | | | |
| // adds a block to the request queue | | // adds a block to the request queue | |
| // returns true if successful, false otherwise | | // returns true if successful, false otherwise | |
| enum flags_t { req_time_critical = 1, req_busy = 2 }; | | enum flags_t { req_time_critical = 1, req_busy = 2 }; | |
| bool add_request(piece_block const& b, int flags = 0); | | bool add_request(piece_block const& b, int flags = 0); | |
| | | | |
| // clears the request queue and sends cancels for all messag
es | | // clears the request queue and sends cancels for all messag
es | |
| // in the download queue | | // in the download queue | |
| void cancel_all_requests(); | | void cancel_all_requests(); | |
| | | | |
| // removes a block from the request queue or download queue | | // removes a block from the request queue or download queue | |
| // sends a cancel message if appropriate | | // sends a cancel message if appropriate | |
| // refills the request queue, and possibly ignoring pieces r
equested | | // refills the request queue, and possibly ignoring pieces r
equested | |
| // by peers in the ignore list (to avoid recursion) | | // by peers in the ignore list (to avoid recursion) | |
|
| void cancel_request(piece_block const& b); | | // if force is true, the blocks is also freed from the piece | |
| | | // picker, allowing another peer to request it immediately | |
| | | void cancel_request(piece_block const& b, bool force = false | |
| | | ); | |
| void send_block_requests(); | | void send_block_requests(); | |
| | | | |
| int bandwidth_throttle(int channel) const | | int bandwidth_throttle(int channel) const | |
| { return m_bandwidth_channel[channel].throttle(); } | | { return m_bandwidth_channel[channel].throttle(); } | |
| | | | |
| void assign_bandwidth(int channel, int amount); | | void assign_bandwidth(int channel, int amount); | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| ptime m_last_choke; | | ptime m_last_choke; | |
| | | | |
| skipping to change at line 485 | | skipping to change at line 541 | |
| | | | |
| // returns the block currently being | | // returns the block currently being | |
| // downloaded. And the progress of that | | // downloaded. And the progress of that | |
| // block. If the peer isn't downloading | | // block. If the peer isn't downloading | |
| // a piece for the moment, the boost::optional | | // a piece for the moment, the boost::optional | |
| // will be invalid. | | // will be invalid. | |
| virtual boost::optional<piece_block_progress> | | virtual boost::optional<piece_block_progress> | |
| downloading_piece_progress() const | | downloading_piece_progress() const | |
| { | | { | |
| #ifdef TORRENT_VERBOSE_LOGGING | | #ifdef TORRENT_VERBOSE_LOGGING | |
|
| (*m_logger) << "downloading_piece_progress() dispatc
hed to the base class!\n"; | | peer_log("*** downloading_piece_progress() dispatche
d to the base class!"); | |
| #endif | | #endif | |
| return boost::optional<piece_block_progress>(); | | return boost::optional<piece_block_progress>(); | |
| } | | } | |
| | | | |
| // these functions are virtual to let bt_peer_connection hoo
k into them | | // these functions are virtual to let bt_peer_connection hoo
k into them | |
| // and encrypt the content | | // and encrypt the content | |
| enum message_type_flags { message_type_request = 1 }; | | enum message_type_flags { message_type_request = 1 }; | |
|
| virtual void send_buffer(char const* begin, int size, int fl | | virtual void send_buffer(char const* begin, int size, int fl | |
| ags = 0); | | ags = 0 | |
| virtual buffer::interval allocate_send_buffer(int size); | | , void (*fun)(char*, int, void*) = 0, void* userdata | |
| | | = 0); | |
| virtual void setup_send(); | | virtual void setup_send(); | |
| | | | |
|
| | | void cork_socket() { TORRENT_ASSERT(!m_corked); m_corked = t | |
| | | rue; } | |
| | | void uncork_socket(); | |
| | | | |
| | | #ifdef TORRENT_DISK_STATS | |
| | | void log_buffer_usage(char* buffer, int size, char const* la | |
| | | bel); | |
| | | #endif | |
| | | | |
| template <class Destructor> | | template <class Destructor> | |
|
| void append_send_buffer(char* buffer, int size, Destructor c | | void append_send_buffer(char* buffer, int size, Destructor c | |
| onst& destructor) | | onst& destructor | |
| | | , bool encrypted = false) | |
| { | | { | |
|
| #if TORRENT_DISK_STATS | | #if defined TORRENT_DISK_STATS | |
| if (m_ses.m_disk_thread.is_disk_buffer(buffer)) | | log_buffer_usage(buffer, size, "queued send buffer") | |
| m_ses.m_disk_thread.rename_buffer(buffer, "q | | ; | |
| ueued send buffer"); | | | |
| #endif | | #endif | |
|
| | | // bittorrent connections should never use this func | |
| | | tion, since | |
| | | // they might be encrypted and this would circumvent | |
| | | the actual | |
| | | // encryption. bt_peer_connection overrides this fun | |
| | | ction with | |
| | | // its own version. | |
| | | TORRENT_ASSERT(encrypted || type() != bittorrent_con | |
| | | nection); | |
| m_send_buffer.append_buffer(buffer, size, size, dest
ructor); | | m_send_buffer.append_buffer(buffer, size, size, dest
ructor); | |
|
| #if defined TORRENT_STATS && defined TORRENT_DISK_STATS | | | |
| m_ses.m_buffer_usage_logger << log_time() << " appen | | | |
| d_send_buffer: " << size << std::endl; | | | |
| m_ses.log_buffer_usage(); | | | |
| #endif | | | |
| } | | } | |
| | | | |
| virtual void append_const_send_buffer(char const* buffer, in
t size); | | virtual void append_const_send_buffer(char const* buffer, in
t size); | |
| | | | |
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| void set_country(char const* c) | | void set_country(char const* c) | |
| { | | { | |
| TORRENT_ASSERT(strlen(c) == 2); | | TORRENT_ASSERT(strlen(c) == 2); | |
| m_country[0] = c[0]; | | m_country[0] = c[0]; | |
| m_country[1] = c[1]; | | m_country[1] = c[1]; | |
| } | | } | |
| bool has_country() const { return m_country[0] != 0; } | | bool has_country() const { return m_country[0] != 0; } | |
| #endif | | #endif | |
| | | | |
|
| | | int outstanding_bytes() const { return m_outstanding_bytes; | |
| | | } | |
| | | | |
| int send_buffer_size() const | | int send_buffer_size() const | |
| { return m_send_buffer.size(); } | | { return m_send_buffer.size(); } | |
| | | | |
| int send_buffer_capacity() const | | int send_buffer_capacity() const | |
| { return m_send_buffer.capacity(); } | | { return m_send_buffer.capacity(); } | |
| | | | |
| int packet_size() const { return m_packet_size; } | | int packet_size() const { return m_packet_size; } | |
| | | | |
| bool packet_finished() const | | bool packet_finished() const | |
| { return m_packet_size <= m_recv_pos; } | | { return m_packet_size <= m_recv_pos; } | |
| | | | |
|
| | | int receive_pos() const { return m_recv_pos; } | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| bool piece_failed; | | bool piece_failed; | |
| #endif | | #endif | |
| | | | |
|
| | | time_t last_seen_complete() const { return m_last_seen_compl | |
| | | ete; } | |
| | | void set_last_seen_complete(int ago) { m_last_seen_complete | |
| | | = time(0) - ago; } | |
| | | | |
| // upload and download channel state | | // upload and download channel state | |
| // enum from peer_info::bw_state | | // enum from peer_info::bw_state | |
| char m_channel_state[2]; | | char m_channel_state[2]; | |
| | | | |
| size_type uploaded_since_unchoke() const | | size_type uploaded_since_unchoke() const | |
| { return m_statistics.total_payload_upload() - m_uploaded_at
_last_unchoke; } | | { return m_statistics.total_payload_upload() - m_uploaded_at
_last_unchoke; } | |
| | | | |
| size_type downloaded_since_unchoke() const | | size_type downloaded_since_unchoke() const | |
| { return m_statistics.total_payload_download() - m_downloade
d_at_last_unchoke; } | | { return m_statistics.total_payload_download() - m_downloade
d_at_last_unchoke; } | |
| | | | |
|
| | | // called when the disk write buffer is drained again, and w | |
| | | e can | |
| | | // start downloading payload again | |
| | | void on_disk(); | |
| | | | |
| | | int num_reading_bytes() const { return m_reading_bytes; } | |
| | | | |
| enum sync_t { read_async, read_sync }; | | enum sync_t { read_async, read_sync }; | |
| void setup_receive(sync_t sync = read_sync); | | void setup_receive(sync_t sync = read_sync); | |
| | | | |
| protected: | | protected: | |
| | | | |
| size_t try_read(sync_t s, error_code& ec); | | size_t try_read(sync_t s, error_code& ec); | |
| | | | |
| virtual void get_specific_peer_info(peer_info& p) const = 0; | | virtual void get_specific_peer_info(peer_info& p) const = 0; | |
| | | | |
| virtual void write_choke() = 0; | | virtual void write_choke() = 0; | |
| virtual void write_unchoke() = 0; | | virtual void write_unchoke() = 0; | |
| virtual void write_interested() = 0; | | virtual void write_interested() = 0; | |
| virtual void write_not_interested() = 0; | | virtual void write_not_interested() = 0; | |
| virtual void write_request(peer_request const& r) = 0; | | virtual void write_request(peer_request const& r) = 0; | |
| virtual void write_cancel(peer_request const& r) = 0; | | virtual void write_cancel(peer_request const& r) = 0; | |
| virtual void write_have(int index) = 0; | | virtual void write_have(int index) = 0; | |
| virtual void write_keepalive() = 0; | | virtual void write_keepalive() = 0; | |
| virtual void write_piece(peer_request const& r, disk_buffer_
holder& buffer) = 0; | | virtual void write_piece(peer_request const& r, disk_buffer_
holder& buffer) = 0; | |
|
| | | virtual void write_suggest(int piece) = 0; | |
| | | | |
| virtual void write_reject_request(peer_request const& r) = 0
; | | virtual void write_reject_request(peer_request const& r) = 0
; | |
| virtual void write_allow_fast(int piece) = 0; | | virtual void write_allow_fast(int piece) = 0; | |
| | | | |
| virtual void on_connected() = 0; | | virtual void on_connected() = 0; | |
| virtual void on_tick() {} | | virtual void on_tick() {} | |
| | | | |
| virtual void on_receive(error_code const& error | | virtual void on_receive(error_code const& error | |
| , std::size_t bytes_transferred) = 0; | | , std::size_t bytes_transferred) = 0; | |
| virtual void on_sent(error_code const& error | | virtual void on_sent(error_code const& error | |
| , std::size_t bytes_transferred) = 0; | | , std::size_t bytes_transferred) = 0; | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| buffer::interval wr_recv_buffer() | | buffer::interval wr_recv_buffer() | |
| { | | { | |
|
| | | if (m_recv_buffer.empty()) | |
| | | { | |
| | | TORRENT_ASSERT(m_recv_pos == 0); | |
| | | return buffer::interval(0,0); | |
| | | } | |
| TORRENT_ASSERT(!m_disk_recv_buffer); | | TORRENT_ASSERT(!m_disk_recv_buffer); | |
| TORRENT_ASSERT(m_disk_recv_buffer_size == 0); | | TORRENT_ASSERT(m_disk_recv_buffer_size == 0); | |
|
| if (m_recv_buffer.empty()) return buffer::interval(0
,0); | | int rcv_pos = (std::min)(m_recv_pos, int(m_recv_buff
er.size())); | |
| return buffer::interval(&m_recv_buffer[0] | | return buffer::interval(&m_recv_buffer[0] | |
|
| , &m_recv_buffer[0] + m_recv_pos); | | , &m_recv_buffer[0] + rcv_pos); | |
| } | | } | |
| | | | |
| std::pair<buffer::interval, buffer::interval> wr_recv_buffer
s(int bytes); | | std::pair<buffer::interval, buffer::interval> wr_recv_buffer
s(int bytes); | |
| #endif | | #endif | |
| | | | |
| buffer::const_interval receive_buffer() const | | buffer::const_interval receive_buffer() const | |
| { | | { | |
|
| if (m_recv_buffer.empty()) return buffer::const_inte | | if (m_recv_buffer.empty()) | |
| rval(0,0); | | { | |
| | | TORRENT_ASSERT(m_recv_pos == 0); | |
| | | return buffer::interval(0,0); | |
| | | } | |
| | | int rcv_pos = (std::min)(m_recv_pos, int(m_recv_buff | |
| | | er.size())); | |
| return buffer::const_interval(&m_recv_buffer[0] | | return buffer::const_interval(&m_recv_buffer[0] | |
|
| , &m_recv_buffer[0] + m_recv_pos); | | , &m_recv_buffer[0] + rcv_pos); | |
| } | | } | |
| | | | |
| bool allocate_disk_receive_buffer(int disk_buffer_size); | | bool allocate_disk_receive_buffer(int disk_buffer_size); | |
| char* release_disk_receive_buffer(); | | char* release_disk_receive_buffer(); | |
| bool has_disk_receive_buffer() const { return m_disk_recv_bu
ffer; } | | bool has_disk_receive_buffer() const { return m_disk_recv_bu
ffer; } | |
|
| void cut_receive_buffer(int size, int packet_size); | | void cut_receive_buffer(int size, int packet_size, int offse
t = 0); | |
| void reset_recv_buffer(int packet_size); | | void reset_recv_buffer(int packet_size); | |
| void set_soft_packet_size(int size) { m_soft_packet_size = s
ize; } | | void set_soft_packet_size(int size) { m_soft_packet_size = s
ize; } | |
| | | | |
|
| void attach_to_torrent(sha1_hash const& ih); | | // if allow_encrypted is false, and the torrent 'ih' turns o | |
| | | ut | |
| | | // to be an encrypted torrent (AES-256 encrypted) the peer w | |
| | | ill | |
| | | // be disconnected. This is to prevent non-encrypted peers t | |
| | | o | |
| | | // attach to an encrypted torrent | |
| | | void attach_to_torrent(sha1_hash const& ih, bool allow_encry | |
| | | pted); | |
| | | | |
| bool verify_piece(peer_request const& p) const; | | bool verify_piece(peer_request const& p) const; | |
| | | | |
|
| | | void update_desired_queue_size(); | |
| | | | |
| // the bandwidth channels, upload and download | | // the bandwidth channels, upload and download | |
| // keeps track of the current quotas | | // keeps track of the current quotas | |
| bandwidth_channel m_bandwidth_channel[num_channels]; | | bandwidth_channel m_bandwidth_channel[num_channels]; | |
| | | | |
| // number of bytes this peer can send and receive | | // number of bytes this peer can send and receive | |
| int m_quota[2]; | | int m_quota[2]; | |
| | | | |
| // statistics about upload and download speeds | | // statistics about upload and download speeds | |
| // and total amount of uploads and downloads for | | // and total amount of uploads and downloads for | |
| // this peer | | // this peer | |
| | | | |
| skipping to change at line 631 | | skipping to change at line 725 | |
| // a back reference to the session | | // a back reference to the session | |
| // the peer belongs to. | | // the peer belongs to. | |
| aux::session_impl& m_ses; | | aux::session_impl& m_ses; | |
| | | | |
| // called from the main loop when this connection has any | | // called from the main loop when this connection has any | |
| // work to do. | | // work to do. | |
| void on_send_data(error_code const& error | | void on_send_data(error_code const& error | |
| , std::size_t bytes_transferred); | | , std::size_t bytes_transferred); | |
| void on_receive_data(error_code const& error | | void on_receive_data(error_code const& error | |
| , std::size_t bytes_transferred); | | , std::size_t bytes_transferred); | |
|
| void on_receive_data_nolock(error_code const& error | | | |
| , std::size_t bytes_transferred); | | | |
| | | | |
| // this is the limit on the number of outstanding requests | | // this is the limit on the number of outstanding requests | |
| // we have to this peer. This is initialized to the settings | | // we have to this peer. This is initialized to the settings | |
| // in the session_settings structure. But it may be lowered | | // in the session_settings structure. But it may be lowered | |
| // if the peer is known to require a smaller limit (like Bit
Comet). | | // if the peer is known to require a smaller limit (like Bit
Comet). | |
| // or if the extended handshake sets a limit. | | // or if the extended handshake sets a limit. | |
| // web seeds also has a limit on the queue size. | | // web seeds also has a limit on the queue size. | |
| int m_max_out_request_queue; | | int m_max_out_request_queue; | |
| | | | |
|
| | | // the average rate of receiving complete piece messages | |
| | | sliding_average<20> m_piece_rate; | |
| | | sliding_average<20> m_send_rate; | |
| | | | |
| void set_timeout(int s) { m_timeout = s; } | | void set_timeout(int s) { m_timeout = s; } | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| typedef std::list<boost::shared_ptr<peer_plugin> > extension
_list_t; | | typedef std::list<boost::shared_ptr<peer_plugin> > extension
_list_t; | |
| extension_list_t m_extensions; | | extension_list_t m_extensions; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| // in case the session settings is set | | // in case the session settings is set | |
| // to resolve countries, this is set to | | // to resolve countries, this is set to | |
| // the two character country code this | | // the two character country code this | |
| // peer resides in. | | // peer resides in. | |
| char m_country[2]; | | char m_country[2]; | |
| #endif | | #endif | |
| | | | |
|
| #ifdef TORRENT_DEBUG | | | |
| boost::intrusive_ptr<peer_connection> self() | | boost::intrusive_ptr<peer_connection> self() | |
| { | | { | |
| TORRENT_ASSERT(!m_in_constructor); | | TORRENT_ASSERT(!m_in_constructor); | |
|
| return intrusive_ptr_base<peer_connection>::self(); | | return boost::intrusive_ptr<peer_connection>(this); | |
| } | | } | |
|
| #endif | | | |
| | | | |
| private: | | private: | |
| | | | |
|
| | | std::pair<int, int> preferred_caching() const; | |
| void fill_send_buffer(); | | void fill_send_buffer(); | |
| void on_disk_read_complete(int ret, disk_io_job const& j, pe
er_request r); | | void on_disk_read_complete(int ret, disk_io_job const& j, pe
er_request r); | |
| void on_disk_write_complete(int ret, disk_io_job const& j | | void on_disk_write_complete(int ret, disk_io_job const& j | |
| , peer_request r, boost::shared_ptr<torrent> t); | | , peer_request r, boost::shared_ptr<torrent> t); | |
|
| void request_upload_bandwidth( | | int request_upload_bandwidth( | |
| bandwidth_channel* bwc1 | | bandwidth_channel* bwc1 | |
| , bandwidth_channel* bwc2 = 0 | | , bandwidth_channel* bwc2 = 0 | |
| , bandwidth_channel* bwc3 = 0 | | , bandwidth_channel* bwc3 = 0 | |
| , bandwidth_channel* bwc4 = 0); | | , bandwidth_channel* bwc4 = 0); | |
|
| void request_download_bandwidth( | | int request_download_bandwidth( | |
| bandwidth_channel* bwc1 | | bandwidth_channel* bwc1 | |
| , bandwidth_channel* bwc2 = 0 | | , bandwidth_channel* bwc2 = 0 | |
| , bandwidth_channel* bwc3 = 0 | | , bandwidth_channel* bwc3 = 0 | |
| , bandwidth_channel* bwc4 = 0); | | , bandwidth_channel* bwc4 = 0); | |
| | | | |
| // keep the io_service running as long as we | | // keep the io_service running as long as we | |
| // have peer connections | | // have peer connections | |
| io_service::work m_work; | | io_service::work m_work; | |
| | | | |
| // the time when we last got a part of a | | // the time when we last got a part of a | |
| | | | |
| skipping to change at line 689 | | skipping to change at line 784 | |
| , bandwidth_channel* bwc3 = 0 | | , bandwidth_channel* bwc3 = 0 | |
| , bandwidth_channel* bwc4 = 0); | | , bandwidth_channel* bwc4 = 0); | |
| | | | |
| // keep the io_service running as long as we | | // keep the io_service running as long as we | |
| // have peer connections | | // have peer connections | |
| io_service::work m_work; | | io_service::work m_work; | |
| | | | |
| // the time when we last got a part of a | | // the time when we last got a part of a | |
| // piece packet from this peer | | // piece packet from this peer | |
| ptime m_last_piece; | | ptime m_last_piece; | |
|
| | | | |
| // the time we sent a request to | | // the time we sent a request to | |
| // this peer the last time | | // this peer the last time | |
| ptime m_last_request; | | ptime m_last_request; | |
| // the time we received the last | | // the time we received the last | |
| // piece request from the peer | | // piece request from the peer | |
| ptime m_last_incoming_request; | | ptime m_last_incoming_request; | |
| // the time when we unchoked this peer | | // the time when we unchoked this peer | |
| ptime m_last_unchoke; | | ptime m_last_unchoke; | |
| | | | |
|
| | | // if we're unchoked by this peer, this | |
| | | // was the time | |
| | | ptime m_last_unchoked; | |
| | | | |
| // timeouts | | // timeouts | |
| ptime m_last_receive; | | ptime m_last_receive; | |
| ptime m_last_sent; | | ptime m_last_sent; | |
| | | | |
| // the time when the first entry in the | | // the time when the first entry in the | |
| // request queue was requested, increased | | // request queue was requested, increased | |
| // for each entry that is popped from the | | // for each entry that is popped from the | |
| // download queue. Used for request timeout | | // download queue. Used for request timeout | |
| ptime m_requested; | | ptime m_requested; | |
| | | | |
|
| // if the timeout is extended for the outstanding | | | |
| // requests, this is the number of seconds it was | | | |
| // extended. | | | |
| int m_timeout_extend; | | | |
| | | | |
| // a timestamp when the remote download rate | | // a timestamp when the remote download rate | |
| // was last updated | | // was last updated | |
| ptime m_remote_dl_update; | | ptime m_remote_dl_update; | |
| | | | |
| // the time when async_connect was called | | // the time when async_connect was called | |
| // or when the incoming connection was established | | // or when the incoming connection was established | |
| ptime m_connect; | | ptime m_connect; | |
| | | | |
| // the time when this peer sent us a not_interested message | | // the time when this peer sent us a not_interested message | |
| // the last time. | | // the last time. | |
| | | | |
| skipping to change at line 779 | | skipping to change at line 874 | |
| // set to the torrent it belongs to. | | // set to the torrent it belongs to. | |
| boost::weak_ptr<torrent> m_torrent; | | boost::weak_ptr<torrent> m_torrent; | |
| | | | |
| // remote peer's id | | // remote peer's id | |
| peer_id m_peer_id; | | peer_id m_peer_id; | |
| | | | |
| // the pieces the other end have | | // the pieces the other end have | |
| bitfield m_have_piece; | | bitfield m_have_piece; | |
| | | | |
| // the queue of requests we have got | | // the queue of requests we have got | |
|
| // from this peer | | // from this peer that haven't been issued | |
| | | // to the disk thread yet | |
| std::vector<peer_request> m_requests; | | std::vector<peer_request> m_requests; | |
| | | | |
| // the blocks we have reserved in the piece | | // the blocks we have reserved in the piece | |
| // picker and will request from this peer. | | // picker and will request from this peer. | |
| std::vector<pending_block> m_request_queue; | | std::vector<pending_block> m_request_queue; | |
| | | | |
| // the queue of blocks we have requested | | // the queue of blocks we have requested | |
| // from this peer | | // from this peer | |
| std::vector<pending_block> m_download_queue; | | std::vector<pending_block> m_download_queue; | |
| | | | |
| | | | |
| skipping to change at line 810 | | skipping to change at line 906 | |
| std::vector<int> m_suggested_pieces; | | std::vector<int> m_suggested_pieces; | |
| | | | |
| // a list of byte offsets inside the send buffer | | // a list of byte offsets inside the send buffer | |
| // the piece requests | | // the piece requests | |
| std::vector<int> m_requests_in_buffer; | | std::vector<int> m_requests_in_buffer; | |
| | | | |
| // the block we're currently receiving. Or | | // the block we're currently receiving. Or | |
| // (-1, -1) if we're not receiving one | | // (-1, -1) if we're not receiving one | |
| piece_block m_receiving_block; | | piece_block m_receiving_block; | |
| | | | |
|
| | | // the time when this peer last saw a complete copy | |
| | | // of this torrent | |
| | | time_t m_last_seen_complete; | |
| | | | |
| | | // if the timeout is extended for the outstanding | |
| | | // requests, this is the number of seconds it was | |
| | | // extended. | |
| | | int m_timeout_extend; | |
| | | | |
| // the number of bytes that the other | | // the number of bytes that the other | |
| // end has to send us in order to respond | | // end has to send us in order to respond | |
| // to all outstanding piece requests we | | // to all outstanding piece requests we | |
| // have sent to it | | // have sent to it | |
| int m_outstanding_bytes; | | int m_outstanding_bytes; | |
| | | | |
| // the number of outstanding bytes expected | | // the number of outstanding bytes expected | |
| // to be received by extensions | | // to be received by extensions | |
| int m_extension_outstanding_bytes; | | int m_extension_outstanding_bytes; | |
| | | | |
| | | | |
| skipping to change at line 915 | | skipping to change at line 1020 | |
| int m_remote_dl_rate; | | int m_remote_dl_rate; | |
| | | | |
| // the number of bytes send to the disk-io | | // the number of bytes send to the disk-io | |
| // thread that hasn't yet been completely written. | | // thread that hasn't yet been completely written. | |
| int m_outstanding_writing_bytes; | | int m_outstanding_writing_bytes; | |
| | | | |
| // max transfer rates seen on this peer | | // max transfer rates seen on this peer | |
| int m_download_rate_peak; | | int m_download_rate_peak; | |
| int m_upload_rate_peak; | | int m_upload_rate_peak; | |
| | | | |
|
| | | // when using the BitTyrant choker, this is our | |
| | | // estimated reciprocation rate. i.e. the rate | |
| | | // we need to send to this peer for it to unchoke | |
| | | // us | |
| | | int m_est_reciprocation_rate; | |
| | | | |
| // estimated round trip time to this peer | | // estimated round trip time to this peer | |
| // based on the time from when async_connect | | // based on the time from when async_connect | |
| // was called to when on_connection_complete | | // was called to when on_connection_complete | |
| // was called. The rtt is specified in milliseconds | | // was called. The rtt is specified in milliseconds | |
| boost::uint16_t m_rtt; | | boost::uint16_t m_rtt; | |
| | | | |
| // if set to non-zero, this peer will always prefer | | // if set to non-zero, this peer will always prefer | |
| // to request entire n pieces, rather than blocks. | | // to request entire n pieces, rather than blocks. | |
| // where n is the value of this variable. | | // where n is the value of this variable. | |
| // if it is 0, the download rate limit setting | | // if it is 0, the download rate limit setting | |
| | | | |
| skipping to change at line 941 | | skipping to change at line 1052 | |
| boost::uint8_t m_desired_queue_size; | | boost::uint8_t m_desired_queue_size; | |
| | | | |
| // the number of piece requests we have rejected | | // the number of piece requests we have rejected | |
| // in a row because the peer is choked. This is | | // in a row because the peer is choked. This is | |
| // used to re-send the choked message in case the | | // used to re-send the choked message in case the | |
| // other end keeps requesting pieces while being | | // other end keeps requesting pieces while being | |
| // choked, and eventuelly disconnect if it keeps | | // choked, and eventuelly disconnect if it keeps | |
| // requesting too many pieces while being choked | | // requesting too many pieces while being choked | |
| boost::uint8_t m_choke_rejects; | | boost::uint8_t m_choke_rejects; | |
| | | | |
|
| // counts the number of recursive calls to on_receive_data | | | |
| // used to limit recursion | | | |
| boost::uint8_t m_read_recurse:5; | | | |
| | | | |
| // if this is true, the disconnection | | // if this is true, the disconnection | |
| // timestamp is not updated when the connection | | // timestamp is not updated when the connection | |
| // is closed. This means the time until we can | | // is closed. This means the time until we can | |
| // reconnect to this peer is shorter, and likely | | // reconnect to this peer is shorter, and likely | |
| // immediate. | | // immediate. | |
| bool m_fast_reconnect:1; | | bool m_fast_reconnect:1; | |
| | | | |
| // is true if it was we that connected to the peer | | // is true if it was we that connected to the peer | |
| // and false if we got an incoming connection | | // and false if we got an incoming connection | |
| // could be considered: true = local, false = remote | | // could be considered: true = local, false = remote | |
|
| bool m_active:1; | | bool m_outgoing:1; | |
| | | | |
| | | // is true if we learn the incoming connections listening | |
| | | // during the extended handshake | |
| | | bool m_received_listen_port:1; | |
| | | | |
| // other side says that it's interested in downloading | | // other side says that it's interested in downloading | |
| // from us. | | // from us. | |
| bool m_peer_interested:1; | | bool m_peer_interested:1; | |
| | | | |
| // the other side has told us that it won't send anymore | | // the other side has told us that it won't send anymore | |
| // data to us for a while | | // data to us for a while | |
| bool m_peer_choked:1; | | bool m_peer_choked:1; | |
| | | | |
| // the peer has pieces we are interested in | | // the peer has pieces we are interested in | |
| | | | |
| skipping to change at line 1019 | | skipping to change at line 1130 | |
| bool m_queued:1; | | bool m_queued:1; | |
| | | | |
| // if this is true, the blocks picked by the piece | | // if this is true, the blocks picked by the piece | |
| // picker will be merged before passed to the | | // picker will be merged before passed to the | |
| // request function. i.e. subsequent blocks are | | // request function. i.e. subsequent blocks are | |
| // merged into larger blocks. This is used by | | // merged into larger blocks. This is used by | |
| // the http-downloader, to request whole pieces | | // the http-downloader, to request whole pieces | |
| // at a time. | | // at a time. | |
| bool m_request_large_blocks:1; | | bool m_request_large_blocks:1; | |
| | | | |
|
| | | // set to true if this peer is in share mode | |
| | | bool m_share_mode:1; | |
| | | | |
| // set to true when this peer is only uploading | | // set to true when this peer is only uploading | |
| bool m_upload_only:1; | | bool m_upload_only:1; | |
| | | | |
| // set to true when a piece request times out. The | | // set to true when a piece request times out. The | |
| // result is that the desired pending queue size | | // result is that the desired pending queue size | |
| // is set to 1 | | // is set to 1 | |
| bool m_snubbed:1; | | bool m_snubbed:1; | |
| | | | |
| // this is set to true once the bitfield is received | | // this is set to true once the bitfield is received | |
| bool m_bitfield_received:1; | | bool m_bitfield_received:1; | |
| | | | |
| skipping to change at line 1041 | | skipping to change at line 1155 | |
| // pick any pieces from this peer | | // pick any pieces from this peer | |
| bool m_no_download:1; | | bool m_no_download:1; | |
| | | | |
| // this is set to true if the last time we tried to | | // this is set to true if the last time we tried to | |
| // pick a piece to download, we could only find | | // pick a piece to download, we could only find | |
| // blocks that were already requested from other | | // blocks that were already requested from other | |
| // peers. In this case, we should not try to pick | | // peers. In this case, we should not try to pick | |
| // another piece until the last one we requested is done | | // another piece until the last one we requested is done | |
| bool m_endgame_mode:1; | | bool m_endgame_mode:1; | |
| | | | |
|
| | | // set to true when we've sent the first round of suggests | |
| | | bool m_sent_suggests:1; | |
| | | | |
| | | // set to true while we're trying to holepunch | |
| | | bool m_holepunch_mode:1; | |
| | | | |
| | | // when this is set, the transfer stats for this connection | |
| | | // is not included in the torrent or session stats | |
| | | bool m_ignore_stats:1; | |
| | | | |
| | | // when this is set, the peer_connection socket is | |
| | | // corked, similar to the linux TCP feature TCP_CORK. | |
| | | // we won't send anything to the actual socket, just | |
| | | // buffer messages up in the application layer send | |
| | | // buffer, and send it once we're uncorked. | |
| | | bool m_corked:1; | |
| | | | |
| | | // set to true if this peer has metadata, and false | |
| | | // otherwise. | |
| | | bool m_has_metadata:1; | |
| | | | |
| template <std::size_t Size> | | template <std::size_t Size> | |
| struct handler_storage | | struct handler_storage | |
| { | | { | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| handler_storage() | | handler_storage() | |
| : used(false) | | : used(false) | |
| {} | | {} | |
| | | | |
| bool used; | | bool used; | |
| #endif | | #endif | |
| | | | |
| skipping to change at line 1126 | | skipping to change at line 1261 | |
| | | | |
| template <class Handler> | | template <class Handler> | |
| allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE> | | allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE> | |
| make_write_handler(Handler const& handler) | | make_write_handler(Handler const& handler) | |
| { | | { | |
| return allocating_handler<Handler, TORRENT_WRITE_HAN
DLER_MAX_SIZE>( | | return allocating_handler<Handler, TORRENT_WRITE_HAN
DLER_MAX_SIZE>( | |
| handler, m_write_handler_storage | | handler, m_write_handler_storage | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| #ifdef TORRENT_DEBUG | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| public: | | public: | |
| bool m_in_constructor:1; | | bool m_in_constructor:1; | |
| bool m_disconnect_started:1; | | bool m_disconnect_started:1; | |
| bool m_initialized:1; | | bool m_initialized:1; | |
|
| | | int m_in_use; | |
| int m_received_in_piece; | | int m_received_in_piece; | |
| #endif | | #endif | |
| }; | | }; | |
|
| | | | |
| | | struct cork | |
| | | { | |
| | | cork(peer_connection& p): m_pc(p) { m_pc.cork_socket(); } | |
| | | ~cork() { m_pc.uncork_socket(); } | |
| | | peer_connection& m_pc; | |
| | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_PEER_CONNECTION_HPP_INCLUDED | | #endif // TORRENT_PEER_CONNECTION_HPP_INCLUDED | |
| | | | |
End of changes. 72 change blocks. |
| 58 lines changed or deleted | | 221 lines changed or added | |
|
| piece_picker.hpp | | piece_picker.hpp | |
| | | | |
| skipping to change at line 45 | | skipping to change at line 45 | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| #include <bitset> | | #include <bitset> | |
| #include <utility> | | #include <utility> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/static_assert.hpp> | | #include <boost/static_assert.hpp> | |
|
| | | #include <boost/cstdint.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
|
| #include "libtorrent/socket.hpp" | | | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/time.hpp" | | #include "libtorrent/time.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| | | | |
| class torrent; | | class torrent; | |
| class peer_connection; | | class peer_connection; | |
| struct bitfield; | | struct bitfield; | |
| | | | |
|
| struct TORRENT_EXPORT piece_block | | struct TORRENT_EXTRA_EXPORT piece_block | |
| { | | { | |
| const static piece_block invalid; | | const static piece_block invalid; | |
| | | | |
| piece_block() {} | | piece_block() {} | |
|
| piece_block(int p_index, int b_index) | | piece_block(boost::uint32_t p_index, boost::uint16_t b_index
) | |
| : piece_index(p_index) | | : piece_index(p_index) | |
| , block_index(b_index) | | , block_index(b_index) | |
|
| {} | | { | |
| int piece_index; | | TORRENT_ASSERT(p_index < (1 << 19)); | |
| int block_index; | | TORRENT_ASSERT(b_index < (1 << 13)); | |
| | | } | |
| | | boost::uint32_t piece_index:19; | |
| | | boost::uint32_t block_index:13; | |
| | | | |
| bool operator<(piece_block const& b) const | | bool operator<(piece_block const& b) const | |
| { | | { | |
| if (piece_index < b.piece_index) return true; | | if (piece_index < b.piece_index) return true; | |
| if (piece_index == b.piece_index) return block_index
< b.block_index; | | if (piece_index == b.piece_index) return block_index
< b.block_index; | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| bool operator==(piece_block const& b) const | | bool operator==(piece_block const& b) const | |
| { return piece_index == b.piece_index && block_index == b.bl
ock_index; } | | { return piece_index == b.piece_index && block_index == b.bl
ock_index; } | |
| | | | |
| bool operator!=(piece_block const& b) const | | bool operator!=(piece_block const& b) const | |
| { return piece_index != b.piece_index || block_index != b.bl
ock_index; } | | { return piece_index != b.piece_index || block_index != b.bl
ock_index; } | |
| | | | |
| }; | | }; | |
| | | | |
|
| class TORRENT_EXPORT piece_picker | | class TORRENT_EXTRA_EXPORT piece_picker | |
| { | | { | |
| public: | | public: | |
| | | | |
|
| | | struct piece_pos; | |
| | | | |
| enum | | enum | |
| { | | { | |
| // the number of priority levels | | // the number of priority levels | |
| priority_levels = 8, | | priority_levels = 8, | |
| // priority factor | | // priority factor | |
| prio_factor = priority_levels - 4 | | prio_factor = priority_levels - 4 | |
| }; | | }; | |
| | | | |
| struct block_info | | struct block_info | |
| { | | { | |
| | | | |
| skipping to change at line 115 | | skipping to change at line 120 | |
| // the peer this block was requested or | | // the peer this block was requested or | |
| // downloaded from. This is a pointer to | | // downloaded from. This is a pointer to | |
| // a policy::peer object | | // a policy::peer object | |
| void* peer; | | void* peer; | |
| // the number of peers that has this block in their | | // the number of peers that has this block in their | |
| // download or request queues | | // download or request queues | |
| unsigned num_peers:14; | | unsigned num_peers:14; | |
| // the state of this block | | // the state of this block | |
| enum { state_none, state_requested, state_writing, s
tate_finished }; | | enum { state_none, state_requested, state_writing, s
tate_finished }; | |
| unsigned state:2; | | unsigned state:2; | |
|
| | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| | | // to allow verifying the invariant of blocks belong | |
| | | ing to the right piece | |
| | | int piece_index; | |
| | | #endif | |
| }; | | }; | |
| | | | |
| // the peers that are downloading this piece | | // the peers that are downloading this piece | |
| // are considered fast peers or slow peers. | | // are considered fast peers or slow peers. | |
| // none is set if the blocks were downloaded | | // none is set if the blocks were downloaded | |
| // in a previous session | | // in a previous session | |
| enum piece_state_t | | enum piece_state_t | |
| { none, slow, medium, fast }; | | { none, slow, medium, fast }; | |
| | | | |
| enum options_t | | enum options_t | |
| | | | |
| skipping to change at line 147 | | skipping to change at line 156 | |
| speed_affinity = 32, | | speed_affinity = 32, | |
| // ignore the prefer_whole_pieces parameter | | // ignore the prefer_whole_pieces parameter | |
| ignore_whole_pieces = 64 | | ignore_whole_pieces = 64 | |
| }; | | }; | |
| | | | |
| struct downloading_piece | | struct downloading_piece | |
| { | | { | |
| downloading_piece(): state(none), index(-1), info(0) | | downloading_piece(): state(none), index(-1), info(0) | |
| , finished(0), writing(0), requested(0) {} | | , finished(0), writing(0), requested(0) {} | |
| | | | |
|
| | | bool operator<(downloading_piece const& rhs) const { | |
| | | return index < rhs.index; } | |
| | | | |
| piece_state_t state; | | piece_state_t state; | |
| | | | |
| // the index of the piece | | // the index of the piece | |
| int index; | | int index; | |
| // info about each block | | // info about each block | |
| // this is a pointer into the m_block_info | | // this is a pointer into the m_block_info | |
| // vector owned by the piece_picker | | // vector owned by the piece_picker | |
| block_info* info; | | block_info* info; | |
| // the number of blocks in the finished state | | // the number of blocks in the finished state | |
| boost::int16_t finished; | | boost::int16_t finished; | |
| | | | |
| skipping to change at line 239 | | skipping to change at line 250 | |
| // The user of this function must lookup if any piece is | | // The user of this function must lookup if any piece is | |
| // marked as being downloaded. If the user of this function | | // marked as being downloaded. If the user of this function | |
| // decides to download a piece, it must mark it as being dow
nloaded | | // decides to download a piece, it must mark it as being dow
nloaded | |
| // itself, by using the mark_as_downloading() member functio
n. | | // itself, by using the mark_as_downloading() member functio
n. | |
| // THIS IS DONE BY THE peer_connection::send_request() MEMBE
R FUNCTION! | | // THIS IS DONE BY THE peer_connection::send_request() MEMBE
R FUNCTION! | |
| // The last argument is the policy::peer pointer for the pee
r that | | // The last argument is the policy::peer pointer for the pee
r that | |
| // we'll download from. | | // we'll download from. | |
| void pick_pieces(bitfield const& pieces | | void pick_pieces(bitfield const& pieces | |
| , std::vector<piece_block>& interesting_blocks, int
num_blocks | | , std::vector<piece_block>& interesting_blocks, int
num_blocks | |
| , int prefer_whole_pieces, void* peer, piece_state_t
speed | | , int prefer_whole_pieces, void* peer, piece_state_t
speed | |
|
| , int options, std::vector<int> const& suggested_pie | | , int options, std::vector<int> const& suggested_pie | |
| ces) const; | | ces | |
| | | , int num_peers) const; | |
| | | | |
| // picks blocks from each of the pieces in the piece_list | | // picks blocks from each of the pieces in the piece_list | |
| // vector that is also in the piece bitmask. The blocks | | // vector that is also in the piece bitmask. The blocks | |
| // are added to interesting_blocks, and busy blocks are | | // are added to interesting_blocks, and busy blocks are | |
| // added to backup_blocks. num blocks is the number of | | // added to backup_blocks. num blocks is the number of | |
| // blocks to be picked. Blocks are not picked from pieces | | // blocks to be picked. Blocks are not picked from pieces | |
| // that are being downloaded | | // that are being downloaded | |
| int add_blocks(int piece, bitfield const& pieces | | int add_blocks(int piece, bitfield const& pieces | |
| , std::vector<piece_block>& interesting_blocks | | , std::vector<piece_block>& interesting_blocks | |
| , std::vector<piece_block>& backup_blocks | | , std::vector<piece_block>& backup_blocks | |
| | | | |
| skipping to change at line 292 | | skipping to change at line 304 | |
| // and false if the block is already finished or writing | | // and false if the block is already finished or writing | |
| bool mark_as_writing(piece_block block, void* peer); | | bool mark_as_writing(piece_block block, void* peer); | |
| | | | |
| void mark_as_finished(piece_block block, void* peer); | | void mark_as_finished(piece_block block, void* peer); | |
| void write_failed(piece_block block); | | void write_failed(piece_block block); | |
| int num_peers(piece_block block) const; | | int num_peers(piece_block block) const; | |
| | | | |
| // returns information about the given piece | | // returns information about the given piece | |
| void piece_info(int index, piece_picker::downloading_piece&
st) const; | | void piece_info(int index, piece_picker::downloading_piece&
st) const; | |
| | | | |
|
| | | piece_pos const& piece_stats(int index) const | |
| | | { | |
| | | TORRENT_ASSERT(index >= 0 && index < int(m_piece_map | |
| | | .size())); | |
| | | return m_piece_map[index]; | |
| | | } | |
| | | | |
| // if a piece had a hash-failure, it must be restored and | | // if a piece had a hash-failure, it must be restored and | |
| // made available for redownloading | | // made available for redownloading | |
| void restore_piece(int index); | | void restore_piece(int index); | |
| | | | |
| // clears the given piece's download flag | | // clears the given piece's download flag | |
| // this means that this piece-block can be picked again | | // this means that this piece-block can be picked again | |
|
| void abort_download(piece_block block); | | void abort_download(piece_block block, void* peer = 0); | |
| | | | |
| bool is_piece_finished(int index) const; | | bool is_piece_finished(int index) const; | |
| | | | |
| // returns the number of blocks there is in the given piece | | // returns the number of blocks there is in the given piece | |
| int blocks_in_piece(int index) const; | | int blocks_in_piece(int index) const; | |
| | | | |
| // the number of downloaded blocks that hasn't passed | | // the number of downloaded blocks that hasn't passed | |
| // the hash-check yet | | // the hash-check yet | |
| int unverified_blocks() const; | | int unverified_blocks() const; | |
| | | | |
| | | | |
| skipping to change at line 358 | | skipping to change at line 376 | |
| | | | |
| private: | | private: | |
| | | | |
| friend struct piece_pos; | | friend struct piece_pos; | |
| | | | |
| bool can_pick(int piece, bitfield const& bitmask) const; | | bool can_pick(int piece, bitfield const& bitmask) const; | |
| bool is_piece_free(int piece, bitfield const& bitmask) const
; | | bool is_piece_free(int piece, bitfield const& bitmask) const
; | |
| std::pair<int, int> expand_piece(int piece, int whole_pieces | | std::pair<int, int> expand_piece(int piece, int whole_pieces | |
| , bitfield const& have) const; | | , bitfield const& have) const; | |
| | | | |
|
| | | public: | |
| | | | |
| struct piece_pos | | struct piece_pos | |
| { | | { | |
| piece_pos() {} | | piece_pos() {} | |
| piece_pos(int peer_count_, int index_) | | piece_pos(int peer_count_, int index_) | |
| : peer_count(peer_count_) | | : peer_count(peer_count_) | |
| , downloading(0) | | , downloading(0) | |
|
| | | , full(0) | |
| , piece_priority(1) | | , piece_priority(1) | |
| , index(index_) | | , index(index_) | |
| { | | { | |
| TORRENT_ASSERT(peer_count_ >= 0); | | TORRENT_ASSERT(peer_count_ >= 0); | |
| TORRENT_ASSERT(index_ >= 0); | | TORRENT_ASSERT(index_ >= 0); | |
| } | | } | |
| | | | |
| // the number of peers that has this piece | | // the number of peers that has this piece | |
| // (availability) | | // (availability) | |
|
| unsigned peer_count : 10; | | #if TORRENT_COMPACT_PICKER | |
| | | boost::uint32_t peer_count : 9; | |
| | | #else | |
| | | boost::uint32_t peer_count : 16; | |
| | | #endif | |
| // is 1 if the piece is marked as being downloaded | | // is 1 if the piece is marked as being downloaded | |
|
| unsigned downloading : 1; | | boost::uint32_t downloading : 1; | |
| | | // set when downloading, but no free blocks to reque | |
| | | st left | |
| | | boost::uint32_t full : 1; | |
| // is 0 if the piece is filtered (not to be download
ed) | | // is 0 if the piece is filtered (not to be download
ed) | |
| // 1 is normal priority (default) | | // 1 is normal priority (default) | |
| // 2 is higher priority than pieces at the same avai
lability level | | // 2 is higher priority than pieces at the same avai
lability level | |
| // 3 is same priority as partial pieces | | // 3 is same priority as partial pieces | |
| // 4 is higher priority than partial pieces | | // 4 is higher priority than partial pieces | |
| // 5 and 6 same priority as availability 1 (ignores
availability) | | // 5 and 6 same priority as availability 1 (ignores
availability) | |
| // 7 is maximum priority (ignores availability) | | // 7 is maximum priority (ignores availability) | |
|
| unsigned piece_priority : 3; | | boost::uint32_t piece_priority : 3; | |
| // index in to the piece_info vector | | // index in to the piece_info vector | |
|
| unsigned index : 18; | | #if TORRENT_COMPACT_PICKER | |
| | | boost::uint32_t index : 18; | |
| | | #else | |
| | | boost::uint32_t index; | |
| | | #endif | |
| | | | |
| enum | | enum | |
| { | | { | |
| // index is set to this to indicate that we
have the | | // index is set to this to indicate that we
have the | |
| // piece. There is no entry for the piece in
the | | // piece. There is no entry for the piece in
the | |
| // buckets if this is the case. | | // buckets if this is the case. | |
|
| | | #if TORRENT_COMPACT_PICKER | |
| we_have_index = 0x3ffff, | | we_have_index = 0x3ffff, | |
|
| | | #else | |
| | | we_have_index = 0xffffffff, | |
| | | #endif | |
| // the priority value that means the piece i
s filtered | | // the priority value that means the piece i
s filtered | |
| filter_priority = 0, | | filter_priority = 0, | |
| // the max number the peer count can hold | | // the max number the peer count can hold | |
|
| max_peer_count = 0x3ff | | #if TORRENT_COMPACT_PICKER | |
| | | max_peer_count = 0x1ff | |
| | | #else | |
| | | max_peer_count = 0xffff | |
| | | #endif | |
| }; | | }; | |
| | | | |
| bool have() const { return index == we_have_index; } | | bool have() const { return index == we_have_index; } | |
| void set_have() { index = we_have_index; TORRENT_ASS
ERT(have()); } | | void set_have() { index = we_have_index; TORRENT_ASS
ERT(have()); } | |
| void set_not_have() { index = 0; TORRENT_ASSERT(!hav
e()); } | | void set_not_have() { index = 0; TORRENT_ASSERT(!hav
e()); } | |
| | | | |
| bool filtered() const { return piece_priority == fil
ter_priority; } | | bool filtered() const { return piece_priority == fil
ter_priority; } | |
| void filtered(bool f) { piece_priority = f ? filter_
priority : 0; } | | void filtered(bool f) { piece_priority = f ? filter_
priority : 0; } | |
| | | | |
| // prio 7 is always top priority | | // prio 7 is always top priority | |
| | | | |
| skipping to change at line 451 | | skipping to change at line 490 | |
| } | | } | |
| | | | |
| bool operator!=(piece_pos p) const | | bool operator!=(piece_pos p) const | |
| { return index != p.index || peer_count != p.peer_co
unt; } | | { return index != p.index || peer_count != p.peer_co
unt; } | |
| | | | |
| bool operator==(piece_pos p) const | | bool operator==(piece_pos p) const | |
| { return index == p.index && peer_count == p.peer_co
unt; } | | { return index == p.index && peer_count == p.peer_co
unt; } | |
| | | | |
| }; | | }; | |
| | | | |
|
| | | private: | |
| | | | |
| | | #if TORRENT_COMPACT_PICKER | |
| BOOST_STATIC_ASSERT(sizeof(piece_pos) == sizeof(char) * 4); | | BOOST_STATIC_ASSERT(sizeof(piece_pos) == sizeof(char) * 4); | |
|
| | | #else | |
| | | BOOST_STATIC_ASSERT(sizeof(piece_pos) == sizeof(char) * 8); | |
| | | #endif | |
| | | | |
| void update_pieces() const; | | void update_pieces() const; | |
| | | | |
| // fills in the range [start, end) of pieces in | | // fills in the range [start, end) of pieces in | |
| // m_pieces that have priority 'prio' | | // m_pieces that have priority 'prio' | |
| void priority_range(int prio, int* start, int* end); | | void priority_range(int prio, int* start, int* end); | |
| | | | |
| // adds the piece 'index' to m_pieces | | // adds the piece 'index' to m_pieces | |
| void add(int index); | | void add(int index); | |
| // removes the piece with the given priority and the | | // removes the piece with the given priority and the | |
| // elem_index in the m_pieces vector | | // elem_index in the m_pieces vector | |
| void remove(int priority, int elem_index); | | void remove(int priority, int elem_index); | |
| // updates the position of the piece with the given | | // updates the position of the piece with the given | |
| // priority and the elem_index in the m_pieces vector | | // priority and the elem_index in the m_pieces vector | |
| void update(int priority, int elem_index); | | void update(int priority, int elem_index); | |
| // shuffles the given piece inside it's priority range | | // shuffles the given piece inside it's priority range | |
| void shuffle(int priority, int elem_index); | | void shuffle(int priority, int elem_index); | |
| | | | |
|
| void sort_piece(std::vector<downloading_piece>::iterator dp)
; | | // void sort_piece(std::vector<downloading_piece>::iterator dp)
; | |
| | | | |
|
| downloading_piece& add_download_piece(); | | downloading_piece& add_download_piece(int index); | |
| void erase_download_piece(std::vector<downloading_piece>::it
erator i); | | void erase_download_piece(std::vector<downloading_piece>::it
erator i); | |
| | | | |
|
| | | std::vector<downloading_piece>::const_iterator find_dl_piece | |
| | | (int index) const; | |
| | | std::vector<downloading_piece>::iterator find_dl_piece(int i | |
| | | ndex); | |
| | | | |
| | | void update_full(downloading_piece& dp); | |
| | | | |
| | | // some compilers (e.g. gcc 2.95, does not inherit access | |
| | | // privileges to nested classes) | |
| | | public: | |
| // the number of seeds. These are not added to | | // the number of seeds. These are not added to | |
| // the availability counters of the pieces | | // the availability counters of the pieces | |
| int m_seeds; | | int m_seeds; | |
|
| | | private: | |
| | | | |
| // the following vectors are mutable because they sometimes
may | | // the following vectors are mutable because they sometimes
may | |
| // be updated lazily, triggered by const functions | | // be updated lazily, triggered by const functions | |
| | | | |
| // this vector contains all piece indices that are pickable | | // this vector contains all piece indices that are pickable | |
| // sorted by priority. Pieces are in random random order | | // sorted by priority. Pieces are in random random order | |
| // among pieces with the same priority | | // among pieces with the same priority | |
| mutable std::vector<int> m_pieces; | | mutable std::vector<int> m_pieces; | |
| | | | |
| // these are indices to the priority boundries inside | | // these are indices to the priority boundries inside | |
| | | | |
| skipping to change at line 503 | | skipping to change at line 557 | |
| // index into the m_piece_info vectors. | | // index into the m_piece_info vectors. | |
| // piece_pos::we_have_index means that we have the piece, so
it | | // piece_pos::we_have_index means that we have the piece, so
it | |
| // doesn't exist in the piece_info buckets | | // doesn't exist in the piece_info buckets | |
| // pieces with the filtered flag set doesn't have entries in | | // pieces with the filtered flag set doesn't have entries in | |
| // the m_piece_info buckets either | | // the m_piece_info buckets either | |
| mutable std::vector<piece_pos> m_piece_map; | | mutable std::vector<piece_pos> m_piece_map; | |
| | | | |
| // each piece that's currently being downloaded | | // each piece that's currently being downloaded | |
| // has an entry in this list with block allocations. | | // has an entry in this list with block allocations. | |
| // i.e. it says wich parts of the piece that | | // i.e. it says wich parts of the piece that | |
|
| // is being downloaded | | // is being downloaded. This list is ordered | |
| | | // by piece index to make lookups efficient | |
| std::vector<downloading_piece> m_downloads; | | std::vector<downloading_piece> m_downloads; | |
| | | | |
| // this holds the information of the | | // this holds the information of the | |
| // blocks in partially downloaded pieces. | | // blocks in partially downloaded pieces. | |
| // the first m_blocks_per_piece entries | | // the first m_blocks_per_piece entries | |
| // in the vector belongs to the first | | // in the vector belongs to the first | |
| // entry in m_downloads, the second | | // entry in m_downloads, the second | |
| // m_blocks_per_piece entries to the | | // m_blocks_per_piece entries to the | |
| // second entry in m_downloads and so on. | | // second entry in m_downloads and so on. | |
| std::vector<block_info> m_block_info; | | std::vector<block_info> m_block_info; | |
| | | | |
| skipping to change at line 547 | | skipping to change at line 602 | |
| int m_reverse_cursor; | | int m_reverse_cursor; | |
| | | | |
| // the number of regions of pieces we don't have. | | // the number of regions of pieces we don't have. | |
| int m_sparse_regions; | | int m_sparse_regions; | |
| | | | |
| // if this is set to true, it means update_pieces() | | // if this is set to true, it means update_pieces() | |
| // has to be called before accessing m_pieces. | | // has to be called before accessing m_pieces. | |
| mutable bool m_dirty; | | mutable bool m_dirty; | |
| public: | | public: | |
| | | | |
|
| | | #if TORRENT_COMPACT_PICKER | |
| enum { max_pieces = piece_pos::we_have_index - 1 }; | | enum { max_pieces = piece_pos::we_have_index - 1 }; | |
|
| | | #else | |
| | | // still limited by piece_block | |
| | | enum { max_pieces = (1 << 19) - 2 }; | |
| | | #endif | |
| | | | |
| }; | | }; | |
| } | | } | |
| | | | |
| #endif // TORRENT_PIECE_PICKER_HPP_INCLUDED | | #endif // TORRENT_PIECE_PICKER_HPP_INCLUDED | |
| | | | |
End of changes. 30 change blocks. |
| 18 lines changed or deleted | | 84 lines changed or added | |
|
| policy.hpp | | policy.hpp | |
| | | | |
| skipping to change at line 42 | | skipping to change at line 42 | |
| | | | |
| #ifndef TORRENT_POLICY_HPP_INCLUDED | | #ifndef TORRENT_POLICY_HPP_INCLUDED | |
| #define TORRENT_POLICY_HPP_INCLUDED | | #define TORRENT_POLICY_HPP_INCLUDED | |
| | | | |
| #include <algorithm> | | #include <algorithm> | |
| #include <deque> | | #include <deque> | |
| | | | |
| #include "libtorrent/peer.hpp" | | #include "libtorrent/peer.hpp" | |
| #include "libtorrent/piece_picker.hpp" | | #include "libtorrent/piece_picker.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
|
| | | #include "libtorrent/address.hpp" | |
| #include "libtorrent/size_type.hpp" | | #include "libtorrent/size_type.hpp" | |
| #include "libtorrent/invariant_check.hpp" | | #include "libtorrent/invariant_check.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
|
| #include "libtorrent/time.hpp" | | | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| | | | |
| class torrent; | | class torrent; | |
| class peer_connection; | | class peer_connection; | |
| | | | |
| // this is compressed as an unsigned floating point value | | // this is compressed as an unsigned floating point value | |
| // the top 13 bits are the mantissa and the low | | // the top 13 bits are the mantissa and the low | |
| // 3 bits is the unsigned exponent. The exponent | | // 3 bits is the unsigned exponent. The exponent | |
| // has an implicit + 4 as well. | | // has an implicit + 4 as well. | |
| // This means that the resolution is no less than 16 | | // This means that the resolution is no less than 16 | |
| // The actual rate is: (upload_rate >> 4) << ((upload_rate & 0xf) +
4) | | // The actual rate is: (upload_rate >> 4) << ((upload_rate & 0xf) +
4) | |
| // the resolution gets worse the higher the value is | | // the resolution gets worse the higher the value is | |
| // min value is 0, max value is 16775168 | | // min value is 0, max value is 16775168 | |
| struct ufloat16 | | struct ufloat16 | |
| { | | { | |
|
| ufloat16() {} | | ufloat16():m_val(0) {} | |
| ufloat16(int v) | | ufloat16(int v) | |
| { *this = v; } | | { *this = v; } | |
| operator int() | | operator int() | |
| { | | { | |
| return (m_val >> 3) << ((m_val & 7) + 4); | | return (m_val >> 3) << ((m_val & 7) + 4); | |
| } | | } | |
| | | | |
| ufloat16& operator=(int v) | | ufloat16& operator=(int v) | |
| { | | { | |
| if (v > 0x1fff << (7 + 4)) m_val = 0xffff; | | if (v > 0x1fff << (7 + 4)) m_val = 0xffff; | |
| | | | |
| skipping to change at line 90 | | skipping to change at line 90 | |
| { | | { | |
| v >>= 1; | | v >>= 1; | |
| ++exp; | | ++exp; | |
| } | | } | |
| TORRENT_ASSERT(exp <= 7); | | TORRENT_ASSERT(exp <= 7); | |
| m_val = (v << 3) || (exp & 7); | | m_val = (v << 3) || (exp & 7); | |
| } | | } | |
| return *this; | | return *this; | |
| } | | } | |
| private: | | private: | |
|
| unsigned int m_val; | | boost::uint16_t m_val; | |
| }; | | }; | |
| | | | |
| enum | | enum | |
| { | | { | |
| // the limits of the download queue size | | // the limits of the download queue size | |
| min_request_queue = 2, | | min_request_queue = 2, | |
| | | | |
| // the amount of free upload allowed before | | // the amount of free upload allowed before | |
| // the peer is choked | | // the peer is choked | |
| free_upload_amount = 4 * 16 * 1024 | | free_upload_amount = 4 * 16 * 1024 | |
| }; | | }; | |
| | | | |
| void request_a_block(torrent& t, peer_connection& c); | | void request_a_block(torrent& t, peer_connection& c); | |
| | | | |
|
| class TORRENT_EXPORT policy | | class TORRENT_EXTRA_EXPORT policy | |
| { | | { | |
| public: | | public: | |
| | | | |
| policy(torrent* t); | | policy(torrent* t); | |
| | | | |
|
| // this is called every 10 seconds to allow | | | |
| // for peer choking management | | | |
| void pulse(); | | | |
| | | | |
| struct peer; | | struct peer; | |
|
| | | | |
| | | #if TORRENT_USE_I2P | |
| | | policy::peer* add_i2p_peer(char const* destination, int sour | |
| | | ce, char flags); | |
| | | #endif | |
| | | | |
| // this is called once for every peer we get from | | // this is called once for every peer we get from | |
| // the tracker, pex, lsd or dht. | | // the tracker, pex, lsd or dht. | |
| policy::peer* add_peer(const tcp::endpoint& remote, const pe
er_id& pid | | policy::peer* add_peer(const tcp::endpoint& remote, const pe
er_id& pid | |
| , int source, char flags); | | , int source, char flags); | |
| | | | |
| // false means duplicate connection | | // false means duplicate connection | |
| bool update_peer_port(int port, policy::peer* p, int src); | | bool update_peer_port(int port, policy::peer* p, int src); | |
| | | | |
| // called when an incoming connection is accepted | | // called when an incoming connection is accepted | |
| // false means the connection was refused or failed | | // false means the connection was refused or failed | |
| | | | |
| skipping to change at line 142 | | skipping to change at line 143 | |
| void set_connection(policy::peer* p, peer_connection* c); | | void set_connection(policy::peer* p, peer_connection* c); | |
| void set_failcount(policy::peer* p, int f); | | void set_failcount(policy::peer* p, int f); | |
| | | | |
| // the peer has got at least one interesting piece | | // the peer has got at least one interesting piece | |
| void peer_is_interesting(peer_connection& c); | | void peer_is_interesting(peer_connection& c); | |
| | | | |
| void ip_filter_updated(); | | void ip_filter_updated(); | |
| | | | |
| void set_seed(policy::peer* p, bool s); | | void set_seed(policy::peer* p, bool s); | |
| | | | |
|
| #ifdef TORRENT_DEBUG | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| bool has_connection(const peer_connection* p); | | bool has_connection(const peer_connection* p); | |
|
| | | #endif | |
| | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
| // intended struct layout (on 32 bit architectures) | | // intended struct layout (on 32 bit architectures) | |
| // offset size alignment field | | // offset size alignment field | |
|
| // 0 12 1 prev_amount_upload, prev_amount_download | | // 0 8 4 prev_amount_upload, prev_amount_download | |
| // 12 4 4 connection | | // 8 4 4 connection | |
| // 16 2 2 last_optimistically_unchoked | | // 12 2 2 last_optimistically_unchoked | |
| // 18 2 2 last_connected | | // 14 2 2 last_connected | |
| // 20 16 1 addr | | // 16 16 1 addr | |
| // 36 2 2 port | | // 32 2 2 port | |
| // 38 2 2 upload_rate_limit | | // 34 2 2 upload_rate_limit | |
| // 40 2 2 download_rate_limit | | // 36 2 2 download_rate_limit | |
| // 42 1 1 hashfails | | // 38 1 1 hashfails | |
| // 43 1 1 failcount, connectable, optimistically_unchoked, | | // 39 1 1 failcount, connectable, optimistically_unchoked, | |
| seed | | seed | |
| // 44 1 1 fast_reconnects, trust_points | | // 40 1 1 fast_reconnects, trust_points | |
| // 45 1 1 source, pe_support, is_v6_addr | | // 41 1 1 source, pe_support, is_v6_addr | |
| // 46 1 1 on_parole, banned, added_to_dht | | // 42 1 1 on_parole, banned, added_to_dht, supports_utp, | |
| // 47 1 1 <padding> | | // supports_holepunch, web_seed | |
| // 48 | | // 43 1 1 <padding> | |
| struct TORRENT_EXPORT peer | | // 44 | |
| | | struct TORRENT_EXTRA_EXPORT peer | |
| { | | { | |
|
| peer(); | | | |
| peer(boost::uint16_t port, bool connectable, int src
); | | peer(boost::uint16_t port, bool connectable, int src
); | |
| | | | |
| size_type total_download() const; | | size_type total_download() const; | |
| size_type total_upload() const; | | size_type total_upload() const; | |
| | | | |
| libtorrent::address address() const; | | libtorrent::address address() const; | |
|
| | | char const* dest() const; | |
| | | | |
| tcp::endpoint ip() const { return tcp::endpoint(addr
ess(), port); } | | tcp::endpoint ip() const { return tcp::endpoint(addr
ess(), port); } | |
| | | | |
| // this is the accumulated amount of | | // this is the accumulated amount of | |
| // uploaded and downloaded data to this | | // uploaded and downloaded data to this | |
| // peer. It only accounts for what was | | // peer. It only accounts for what was | |
| // shared during the last connection to | | // shared during the last connection to | |
| // this peer. i.e. These are only updated | | // this peer. i.e. These are only updated | |
| // when the connection is closed. For the | | // when the connection is closed. For the | |
| // total amount of upload and download | | // total amount of upload and download | |
| // we'll have to add thes figures with the | | // we'll have to add thes figures with the | |
| // statistics from the peer_connection. | | // statistics from the peer_connection. | |
|
| // 48 bits can fit 256 Terabytes | | // since these values don't need to be stored | |
| #ifdef __SUNPRO_CC | | // with byte-precision, they specify the number | |
| unsigned prev_amount_upload:48; | | // of kiB. i.e. shift left 10 bits to compare to | |
| unsigned prev_amount_download:48; | | // byte counters. | |
| #else | | boost::uint32_t prev_amount_upload; | |
| boost::uint64_t prev_amount_upload:48; | | boost::uint32_t prev_amount_download; | |
| boost::uint64_t prev_amount_download:48; | | | |
| #endif | | | |
| | | | |
| // if the peer is connected now, this | | // if the peer is connected now, this | |
| // will refer to a valid peer_connection | | // will refer to a valid peer_connection | |
| peer_connection* connection; | | peer_connection* connection; | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| // only used in debug mode to assert that | | // only used in debug mode to assert that | |
| // the first entry in the AS pair keeps the same | | // the first entry in the AS pair keeps the same | |
| boost::uint16_t inet_as_num; | | boost::uint16_t inet_as_num; | |
| | | | |
| skipping to change at line 286 | | skipping to change at line 287 | |
| // This will be toggled everytime either an | | // This will be toggled everytime either an | |
| // encrypted or non-encrypted handshake fails. | | // encrypted or non-encrypted handshake fails. | |
| bool pe_support:1; | | bool pe_support:1; | |
| #endif | | #endif | |
| | | | |
| #if TORRENT_USE_IPV6 | | #if TORRENT_USE_IPV6 | |
| // this is true if the v6 union member in addr is | | // this is true if the v6 union member in addr is | |
| // the one to use, false if it's the v4 one | | // the one to use, false if it's the v4 one | |
| bool is_v6_addr:1; | | bool is_v6_addr:1; | |
| #endif | | #endif | |
|
| | | #if TORRENT_USE_I2P | |
| | | // set if the i2p_destination is in use in the addr | |
| | | union | |
| | | bool is_i2p_addr:1; | |
| | | #endif | |
| | | | |
| // if this is true, the peer has previously | | // if this is true, the peer has previously | |
| // participated in a piece that failed the piece | | // participated in a piece that failed the piece | |
| // hash check. This will put the peer on parole | | // hash check. This will put the peer on parole | |
| // and only request entire pieces. If a piece pass | | // and only request entire pieces. If a piece pass | |
| // that was partially requested from this peer it | | // that was partially requested from this peer it | |
| // will leave parole mode and continue download | | // will leave parole mode and continue download | |
| // pieces as normal peers. | | // pieces as normal peers. | |
| bool on_parole:1; | | bool on_parole:1; | |
| | | | |
| // is set to true if this peer has been banned | | // is set to true if this peer has been banned | |
| bool banned:1; | | bool banned:1; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| // this is set to true when this peer as been | | // this is set to true when this peer as been | |
| // pinged by the DHT | | // pinged by the DHT | |
| bool added_to_dht:1; | | bool added_to_dht:1; | |
| #endif | | #endif | |
|
| #ifdef TORRENT_DEBUG | | // we think this peer supports uTP | |
| | | bool supports_utp:1; | |
| | | // we have been connected via uTP at least once | |
| | | bool confirmed_supports_utp:1; | |
| | | bool supports_holepunch:1; | |
| | | // this is set to one for web seeds. Web seeds | |
| | | // are not stored in the policy m_peers list, | |
| | | // and are excempt from connect candidate bookkeepin | |
| | | g | |
| | | // so, any peer with the web_seed bit set, is | |
| | | // never considered a connect candidate | |
| | | bool web_seed:1; | |
| | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| bool in_use:1; | | bool in_use:1; | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
|
| struct TORRENT_EXPORT ipv4_peer : peer | | struct TORRENT_EXTRA_EXPORT ipv4_peer : peer | |
| { | | { | |
| ipv4_peer(tcp::endpoint const& ip, bool connectable,
int src); | | ipv4_peer(tcp::endpoint const& ip, bool connectable,
int src); | |
|
| ipv4_peer(libtorrent::address const& a); | | | |
| | | | |
|
| address_v4 addr; | | const address_v4 addr; | |
| }; | | }; | |
| | | | |
|
| | | #if TORRENT_USE_I2P | |
| | | struct TORRENT_EXTRA_EXPORT i2p_peer : peer | |
| | | { | |
| | | i2p_peer(char const* destination, bool connectable, | |
| | | int src); | |
| | | ~i2p_peer(); | |
| | | | |
| | | char* destination; | |
| | | }; | |
| | | #endif | |
| | | | |
| #if TORRENT_USE_IPV6 | | #if TORRENT_USE_IPV6 | |
|
| struct TORRENT_EXPORT ipv6_peer : peer | | struct TORRENT_EXTRA_EXPORT ipv6_peer : peer | |
| { | | { | |
| ipv6_peer(tcp::endpoint const& ip, bool connectable,
int src); | | ipv6_peer(tcp::endpoint const& ip, bool connectable,
int src); | |
|
| ipv6_peer(libtorrent::address const& a); | | | |
| | | | |
|
| address_v6::bytes_type addr; | | const address_v6::bytes_type addr; | |
| }; | | }; | |
| #endif | | #endif | |
| | | | |
| int num_peers() const { return m_peers.size(); } | | int num_peers() const { return m_peers.size(); } | |
| | | | |
| struct peer_address_compare | | struct peer_address_compare | |
| { | | { | |
| bool operator()( | | bool operator()( | |
| peer const* lhs, libtorrent::address const&
rhs) const | | peer const* lhs, libtorrent::address const&
rhs) const | |
| { | | { | |
| return lhs->address() < rhs; | | return lhs->address() < rhs; | |
| } | | } | |
| | | | |
| bool operator()( | | bool operator()( | |
| libtorrent::address const& lhs, peer const*
rhs) const | | libtorrent::address const& lhs, peer const*
rhs) const | |
| { | | { | |
| return lhs < rhs->address(); | | return lhs < rhs->address(); | |
| } | | } | |
| | | | |
|
| | | #if TORRENT_USE_I2P | |
| | | bool operator()( | |
| | | peer const* lhs, char const* rhs) const | |
| | | { | |
| | | return strcmp(lhs->dest(), rhs) < 0; | |
| | | } | |
| | | | |
| | | bool operator()( | |
| | | char const* lhs, peer const* rhs) const | |
| | | { | |
| | | return strcmp(lhs, rhs->dest()) < 0; | |
| | | } | |
| | | #endif | |
| | | | |
| bool operator()( | | bool operator()( | |
| peer const* lhs, peer const* rhs) const | | peer const* lhs, peer const* rhs) const | |
| { | | { | |
|
| | | #if TORRENT_USE_I2P | |
| | | if (rhs->is_i2p_addr == lhs->is_i2p_addr) | |
| | | return strcmp(lhs->dest(), rhs->dest | |
| | | ()) < 0; | |
| | | #endif | |
| return lhs->address() < rhs->address(); | | return lhs->address() < rhs->address(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| typedef std::deque<peer*> peers_t; | | typedef std::deque<peer*> peers_t; | |
| | | | |
| typedef peers_t::iterator iterator; | | typedef peers_t::iterator iterator; | |
| typedef peers_t::const_iterator const_iterator; | | typedef peers_t::const_iterator const_iterator; | |
| iterator begin_peer() { return m_peers.begin(); } | | iterator begin_peer() { return m_peers.begin(); } | |
| iterator end_peer() { return m_peers.end(); } | | iterator end_peer() { return m_peers.end(); } | |
| | | | |
| skipping to change at line 384 | | skipping to change at line 426 | |
| | | | |
| int num_seeds() const { return m_num_seeds; } | | int num_seeds() const { return m_num_seeds; } | |
| int num_connect_candidates() const { return m_num_connect_ca
ndidates; } | | int num_connect_candidates() const { return m_num_connect_ca
ndidates; } | |
| void recalculate_connect_candidates(); | | void recalculate_connect_candidates(); | |
| | | | |
| void erase_peer(policy::peer* p); | | void erase_peer(policy::peer* p); | |
| void erase_peer(iterator i); | | void erase_peer(iterator i); | |
| | | | |
| private: | | private: | |
| | | | |
|
| | | void update_peer(policy::peer* p, int src, int flags | |
| | | , tcp::endpoint const& remote, char const* destination); | |
| | | bool insert_peer(policy::peer* p, iterator iter, int flags); | |
| | | | |
| bool compare_peer_erase(policy::peer const& lhs, policy::pee
r const& rhs) const; | | bool compare_peer_erase(policy::peer const& lhs, policy::pee
r const& rhs) const; | |
| bool compare_peer(policy::peer const& lhs, policy::peer cons
t& rhs | | bool compare_peer(policy::peer const& lhs, policy::peer cons
t& rhs | |
| , address const& external_ip) const; | | , address const& external_ip) const; | |
| | | | |
| iterator find_connect_candidate(int session_time); | | iterator find_connect_candidate(int session_time); | |
| | | | |
| bool is_connect_candidate(peer const& p, bool finished) cons
t; | | bool is_connect_candidate(peer const& p, bool finished) cons
t; | |
| bool is_erase_candidate(peer const& p, bool finished) const; | | bool is_erase_candidate(peer const& p, bool finished) const; | |
|
| | | bool is_force_erase_candidate(peer const& pe) const; | |
| bool should_erase_immediately(peer const& p) const; | | bool should_erase_immediately(peer const& p) const; | |
| | | | |
|
| void erase_peers(); | | enum flags_t { force_erase = 1 }; | |
| | | void erase_peers(int flags = 0); | |
| | | | |
| peers_t m_peers; | | peers_t m_peers; | |
| | | | |
|
| | | torrent* m_torrent; | |
| | | | |
| // since the peer list can grow too large | | // since the peer list can grow too large | |
| // to scan all of it, start at this iterator | | // to scan all of it, start at this iterator | |
| int m_round_robin; | | int m_round_robin; | |
| | | | |
|
| torrent* m_torrent; | | | |
| | | | |
| // The number of peers in our peer list | | // The number of peers in our peer list | |
| // that are connect candidates. i.e. they're | | // that are connect candidates. i.e. they're | |
| // not already connected and they have not | | // not already connected and they have not | |
| // yet reached their max try count and they | | // yet reached their max try count and they | |
| // have the connectable state (we have a listen | | // have the connectable state (we have a listen | |
| // port for them). | | // port for them). | |
| int m_num_connect_candidates; | | int m_num_connect_candidates; | |
| | | | |
| // the number of seeds in the peer list | | // the number of seeds in the peer list | |
| int m_num_seeds; | | int m_num_seeds; | |
| | | | |
| // this was the state of the torrent the | | // this was the state of the torrent the | |
| // last time we recalculated the number of | | // last time we recalculated the number of | |
| // connect candidates. Since seeds (or upload | | // connect candidates. Since seeds (or upload | |
| // only) peers are not connect candidates | | // only) peers are not connect candidates | |
| // when we're finished, the set depends on | | // when we're finished, the set depends on | |
| // this state. Every time m_torrent->is_finished() | | // this state. Every time m_torrent->is_finished() | |
| // is different from this state, we need to | | // is different from this state, we need to | |
| // recalculate the connect candidates. | | // recalculate the connect candidates. | |
|
| bool m_finished; | | bool m_finished:1; | |
| }; | | }; | |
| | | | |
| inline policy::ipv4_peer::ipv4_peer( | | inline policy::ipv4_peer::ipv4_peer( | |
| tcp::endpoint const& ep, bool c, int src | | tcp::endpoint const& ep, bool c, int src | |
| ) | | ) | |
|
| : peer(ep.port(), c, src) | | : peer(ep.port(), c, src) | |
| , addr(ep.address().to_v4()) | | , addr(ep.address().to_v4()) | |
| { | | { | |
|
| | | #if TORRENT_USE_IPV6 | |
| is_v6_addr = false; | | is_v6_addr = false; | |
|
| | | #endif | |
| | | #if TORRENT_USE_I2P | |
| | | is_i2p_addr = false; | |
| | | #endif | |
| } | | } | |
| | | | |
|
| inline policy::ipv4_peer::ipv4_peer(libtorrent::address const& a) | | #if TORRENT_USE_I2P | |
| : addr(a.to_v4()) | | inline policy::i2p_peer::i2p_peer(char const* dest, bool connectable | |
| | | , int src) | |
| | | : peer(0, connectable, src), destination(strdup(dest)) | |
| { | | { | |
|
| | | #if TORRENT_USE_IPV6 | |
| is_v6_addr = false; | | is_v6_addr = false; | |
|
| | | #endif | |
| | | is_i2p_addr = true; | |
| } | | } | |
| | | | |
|
| | | inline policy::i2p_peer::~i2p_peer() | |
| | | { free(destination); } | |
| | | #endif // TORRENT_USE_I2P | |
| | | | |
| | | #if TORRENT_USE_IPV6 | |
| inline policy::ipv6_peer::ipv6_peer( | | inline policy::ipv6_peer::ipv6_peer( | |
| tcp::endpoint const& ep, bool c, int src | | tcp::endpoint const& ep, bool c, int src | |
| ) | | ) | |
|
| : peer(ep.port(), c, src) | | : peer(ep.port(), c, src) | |
| , addr(ep.address().to_v6().to_bytes()) | | , addr(ep.address().to_v6().to_bytes()) | |
| { | | { | |
| is_v6_addr = true; | | is_v6_addr = true; | |
|
| | | #if TORRENT_USE_I2P | |
| | | is_i2p_addr = false; | |
| | | #endif | |
| } | | } | |
| | | | |
|
| inline policy::ipv6_peer::ipv6_peer(libtorrent::address const& a) | | #endif // TORRENT_USE_IPV6 | |
| : addr(a.to_v6().to_bytes()) | | | |
| | | #if TORRENT_USE_I2P | |
| | | inline char const* policy::peer::dest() const | |
| { | | { | |
|
| is_v6_addr = true; | | if (is_i2p_addr) | |
| | | return static_cast<policy::i2p_peer const*>(this)->d | |
| | | estination; | |
| | | return ""; | |
| } | | } | |
|
| | | #endif | |
| | | | |
| inline libtorrent::address policy::peer::address() const | | inline libtorrent::address policy::peer::address() const | |
| { | | { | |
| #if TORRENT_USE_IPV6 | | #if TORRENT_USE_IPV6 | |
| if (is_v6_addr) | | if (is_v6_addr) | |
| return libtorrent::address_v6( | | return libtorrent::address_v6( | |
| static_cast<policy::ipv6_peer const*>(this)-
>addr); | | static_cast<policy::ipv6_peer const*>(this)-
>addr); | |
|
| | | else | |
| | | #endif | |
| | | #if TORRENT_USE_I2P | |
| | | if (is_i2p_addr) return libtorrent::address(); | |
| | | else | |
| #endif | | #endif | |
| return static_cast<policy::ipv4_peer const*>(this)->addr; | | return static_cast<policy::ipv4_peer const*>(this)->addr; | |
| } | | } | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_POLICY_HPP_INCLUDED | | #endif // TORRENT_POLICY_HPP_INCLUDED | |
| | | | |
End of changes. 43 change blocks. |
| 56 lines changed or deleted | | 138 lines changed or added | |
|
| session.hpp | | session.hpp | |
| | | | |
| skipping to change at line 44 | | skipping to change at line 44 | |
| #define TORRENT_SESSION_HPP_INCLUDED | | #define TORRENT_SESSION_HPP_INCLUDED | |
| | | | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/limits.hpp> | | #include <boost/limits.hpp> | |
|
| #include <boost/filesystem/path.hpp> | | | |
| #include <boost/thread.hpp> | | | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/torrent_handle.hpp" | | #include "libtorrent/torrent_handle.hpp" | |
| #include "libtorrent/entry.hpp" | | #include "libtorrent/entry.hpp" | |
| #include "libtorrent/session_status.hpp" | | #include "libtorrent/session_status.hpp" | |
| #include "libtorrent/version.hpp" | | #include "libtorrent/version.hpp" | |
| #include "libtorrent/fingerprint.hpp" | | #include "libtorrent/fingerprint.hpp" | |
| #include "libtorrent/disk_io_thread.hpp" | | #include "libtorrent/disk_io_thread.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
|
| #include "libtorrent/alert.hpp" | | #include "libtorrent/alert.hpp" // alert::error_notification | |
| | | #include "libtorrent/add_torrent_params.hpp" | |
| | | #include "libtorrent/rss.hpp" | |
| | | #include "libtorrent/build_config.hpp" | |
| | | | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
|
| #include <boost/preprocessor/cat.hpp> | | | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| # include <eh.h> | | # include <eh.h> | |
| #endif | | #endif | |
| | | | |
|
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | // this is a nasty openssl macro | |
| | | #ifdef set_key | |
| | | #undef set_key | |
| | | #endif | |
| | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| | | struct plugin; | |
| struct torrent_plugin; | | struct torrent_plugin; | |
| class torrent; | | class torrent; | |
| struct ip_filter; | | struct ip_filter; | |
| class port_filter; | | class port_filter; | |
| class connection_queue; | | class connection_queue; | |
| class natpmp; | | class natpmp; | |
| class upnp; | | class upnp; | |
| class alert; | | class alert; | |
| | | | |
|
| // this is used to create linker errors when trying to link to | | TORRENT_EXPORT session_settings min_memory_usage(); | |
| // a library with a conflicting build configuration than the applica | | TORRENT_EXPORT session_settings high_performance_seed(); | |
| tion | | | |
| #ifdef TORRENT_DEBUG | | | |
| #define G _release | | | |
| #else | | | |
| #define G _debug | | | |
| #endif | | | |
| | | | |
| #ifdef TORRENT_USE_OPENSSL | | | |
| #define S _ssl | | | |
| #else | | | |
| #define S _nossl | | | |
| #endif | | | |
| | | | |
| #ifdef TORRENT_DISABLE_DHT | | | |
| #define D _nodht | | | |
| #else | | | |
| #define D _dht | | | |
| #endif | | | |
| | | | |
|
| #ifdef TORRENT_DISABLE_POOL_ALLOCATOR | | #ifndef TORRENT_CFG | |
| #define P _nopoolalloc | | #error TORRENT_CFG is not defined! | |
| #else | | | |
| #define P _poolalloc | | | |
| #endif | | #endif | |
| | | | |
|
| #define TORRENT_LINK_TEST_PREFIX libtorrent_build_config | | void TORRENT_EXPORT TORRENT_CFG(); | |
| #define TORRENT_LINK_TEST_NAME BOOST_PP_CAT(TORRENT_LINK_TEST_PREFIX, BOOST | | | |
| _PP_CAT(P, BOOST_PP_CAT(D, BOOST_PP_CAT(S, G)))) | | | |
| #undef P | | | |
| #undef D | | | |
| #undef S | | | |
| #undef G | | | |
| | | | |
| inline void test_link() | | | |
| { | | | |
| extern void TORRENT_LINK_TEST_NAME(); | | | |
| TORRENT_LINK_TEST_NAME(); | | | |
| } | | | |
| | | | |
| namespace fs = boost::filesystem; | | | |
| | | | |
| session_settings min_memory_usage(); | | | |
| session_settings high_performance_seed(); | | | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
| // workaround for microsofts | | // workaround for microsofts | |
| // hardware exceptions that makes | | // hardware exceptions that makes | |
| // it hard to debug stuff | | // it hard to debug stuff | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
|
| struct eh_initializer | | struct TORRENT_EXPORT eh_initializer | |
| { | | { | |
|
| eh_initializer() | | eh_initializer(); | |
| { | | | |
| ::_set_se_translator(straight_to_debugger); | | | |
| } | | | |
| | | | |
| static void straight_to_debugger(unsigned int, _EXCE
PTION_POINTERS*) | | static void straight_to_debugger(unsigned int, _EXCE
PTION_POINTERS*) | |
| { throw; } | | { throw; } | |
| }; | | }; | |
| #else | | #else | |
| struct eh_initializer {}; | | struct eh_initializer {}; | |
| #endif | | #endif | |
| struct session_impl; | | struct session_impl; | |
|
| | | | |
| struct filesystem_init | | | |
| { | | | |
| filesystem_init(); | | | |
| }; | | | |
| | | | |
| } | | } | |
| | | | |
| class TORRENT_EXPORT session_proxy | | class TORRENT_EXPORT session_proxy | |
| { | | { | |
| friend class session; | | friend class session; | |
| public: | | public: | |
| session_proxy() {} | | session_proxy() {} | |
| private: | | private: | |
| session_proxy(boost::shared_ptr<aux::session_impl> impl) | | session_proxy(boost::shared_ptr<aux::session_impl> impl) | |
| : m_impl(impl) {} | | : m_impl(impl) {} | |
| boost::shared_ptr<aux::session_impl> m_impl; | | boost::shared_ptr<aux::session_impl> m_impl; | |
| }; | | }; | |
| | | | |
|
| struct add_torrent_params | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | |
| { | | ORRENT_ERROR_LOGGING | |
| add_torrent_params(storage_constructor_type sc = default_sto | | #define TORRENT_LOGPATH_ARG_DEFAULT , std::string logpath = "." | |
| rage_constructor) | | #define TORRENT_LOGPATH_ARG , std::string logpath | |
| : tracker_url(0) | | #define TORRENT_LOGPATH , logpath | |
| , name(0) | | #else | |
| , resume_data(0) | | #define TORRENT_LOGPATH_ARG_DEFAULT | |
| , storage_mode(storage_mode_sparse) | | #define TORRENT_LOGPATH_ARG | |
| , paused(true) | | #define TORRENT_LOGPATH | |
| , auto_managed(true) | | #endif | |
| , duplicate_is_error(false) | | | |
| , storage(sc) | | | |
| , userdata(0) | | | |
| , seed_mode(false) | | | |
| , override_resume_data(false) | | | |
| , upload_mode(false) | | | |
| {} | | | |
| | | | |
| boost::intrusive_ptr<torrent_info> ti; | | | |
| char const* tracker_url; | | | |
| sha1_hash info_hash; | | | |
| char const* name; | | | |
| fs::path save_path; | | | |
| std::vector<char>* resume_data; | | | |
| storage_mode_t storage_mode; | | | |
| bool paused; | | | |
| bool auto_managed; | | | |
| bool duplicate_is_error; | | | |
| storage_constructor_type storage; | | | |
| void* userdata; | | | |
| bool seed_mode; | | | |
| bool override_resume_data; | | | |
| bool upload_mode; | | | |
| }; | | | |
| | | | |
| class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_ini
tializer | | class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_ini
tializer | |
| { | | { | |
| public: | | public: | |
| | | | |
| session(fingerprint const& print = fingerprint("LT" | | session(fingerprint const& print = fingerprint("LT" | |
| , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR
, 0, 0) | | , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR
, 0, 0) | |
| , int flags = start_default_features | add_default_p
lugins | | , int flags = start_default_features | add_default_p
lugins | |
|
| , int alert_mask = alert::error_notification | | , boost::uint32_t alert_mask = alert::error_notifica | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | | tion | |
| ORRENT_ERROR_LOGGING | | TORRENT_LOGPATH_ARG_DEFAULT) | |
| , fs::path logpath = "." | | { | |
| #endif | | TORRENT_CFG(); | |
| ); | | init(std::make_pair(0, 0), "0.0.0.0", print, flags, | |
| | | alert_mask TORRENT_LOGPATH); | |
| | | } | |
| | | | |
| session( | | session( | |
| fingerprint const& print | | fingerprint const& print | |
| , std::pair<int, int> listen_port_range | | , std::pair<int, int> listen_port_range | |
| , char const* listen_interface = "0.0.0.0" | | , char const* listen_interface = "0.0.0.0" | |
| , int flags = start_default_features | add_default_p
lugins | | , int flags = start_default_features | add_default_p
lugins | |
| , int alert_mask = alert::error_notification | | , int alert_mask = alert::error_notification | |
|
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | | TORRENT_LOGPATH_ARG_DEFAULT) | |
| ORRENT_ERROR_LOGGING | | { | |
| , fs::path logpath = "." | | TORRENT_CFG(); | |
| #endif | | TORRENT_ASSERT(listen_port_range.first > 0); | |
| ); | | TORRENT_ASSERT(listen_port_range.first < listen_port | |
| | | _range.second); | |
| | | init(listen_port_range, listen_interface, print, fla | |
| | | gs, alert_mask TORRENT_LOGPATH); | |
| | | } | |
| | | | |
| ~session(); | | ~session(); | |
| | | | |
| enum save_state_flags_t | | enum save_state_flags_t | |
| { | | { | |
|
| save_settings = 0x001, | | save_settings = 0x001, | |
| save_dht_settings = 0x002, | | save_dht_settings = 0x002, | |
|
| #ifndef TORRENT_NO_DEPRECATE | | save_dht_state = 0x004, | |
| save_dht_proxy = 0x004, | | save_proxy = 0x008, | |
| #endif | | save_i2p_proxy = 0x010, | |
| save_dht_state = 0x008, | | | |
| save_i2p_proxy = 0x010, | | | |
| save_encryption_settings = 0x020, | | save_encryption_settings = 0x020, | |
|
| | | save_as_map = 0x040, | |
| | | save_feeds = 0x080 | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
|
| save_peer_proxy = 0x040, | | , | |
| save_web_proxy = 0x080, | | save_dht_proxy = save_proxy, | |
| save_tracker_proxy = 0x100, | | save_peer_proxy = save_proxy, | |
| | | save_web_proxy = save_proxy, | |
| | | save_tracker_proxy = save_proxy | |
| #endif | | #endif | |
|
| save_as_map = 0x200, | | | |
| save_proxy = 0x1c4 | | | |
| }; | | }; | |
| void save_state(entry& e, boost::uint32_t flags = 0xffffffff
) const; | | void save_state(entry& e, boost::uint32_t flags = 0xffffffff
) const; | |
| void load_state(lazy_entry const& e); | | void load_state(lazy_entry const& e); | |
| | | | |
|
| | | void get_torrent_status(std::vector<torrent_status>* ret | |
| | | , boost::function<bool(torrent_status const&)> const | |
| | | & pred | |
| | | , boost::uint32_t flags = 0) const; | |
| | | void refresh_torrent_status(std::vector<torrent_status>* ret | |
| | | , boost::uint32_t flags = 0) const; | |
| | | void post_torrent_updates(); | |
| | | | |
| // returns a list of all torrents in this session | | // returns a list of all torrents in this session | |
| std::vector<torrent_handle> get_torrents() const; | | std::vector<torrent_handle> get_torrents() const; | |
| | | | |
| io_service& get_io_service(); | | io_service& get_io_service(); | |
| | | | |
| // returns an invalid handle in case the torrent doesn't exi
st | | // returns an invalid handle in case the torrent doesn't exi
st | |
| torrent_handle find_torrent(sha1_hash const& info_hash) cons
t; | | torrent_handle find_torrent(sha1_hash const& info_hash) cons
t; | |
| | | | |
| // all torrent_handles must be destructed before the session
is destructed! | | // all torrent_handles must be destructed before the session
is destructed! | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| torrent_handle add_torrent(add_torrent_params const& params)
; | | torrent_handle add_torrent(add_torrent_params const& params)
; | |
|
| | | #endif | |
| torrent_handle add_torrent(add_torrent_params const& params,
error_code& ec); | | torrent_handle add_torrent(add_torrent_params const& params,
error_code& ec); | |
|
| | | void async_add_torrent(add_torrent_params const& params); | |
| | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // deprecated in 0.14 | | // deprecated in 0.14 | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| torrent_handle add_torrent( | | torrent_handle add_torrent( | |
| torrent_info const& ti | | torrent_info const& ti | |
|
| , fs::path const& save_path | | , std::string const& save_path | |
| , entry const& resume_data = entry() | | , entry const& resume_data = entry() | |
| , storage_mode_t storage_mode = storage_mode_sparse | | , storage_mode_t storage_mode = storage_mode_sparse | |
| , bool paused = false | | , bool paused = false | |
| , storage_constructor_type sc = default_storage_cons
tructor) TORRENT_DEPRECATED; | | , storage_constructor_type sc = default_storage_cons
tructor) TORRENT_DEPRECATED; | |
| | | | |
| // deprecated in 0.14 | | // deprecated in 0.14 | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| torrent_handle add_torrent( | | torrent_handle add_torrent( | |
| boost::intrusive_ptr<torrent_info> ti | | boost::intrusive_ptr<torrent_info> ti | |
|
| , fs::path const& save_path | | , std::string const& save_path | |
| , entry const& resume_data = entry() | | , entry const& resume_data = entry() | |
| , storage_mode_t storage_mode = storage_mode_sparse | | , storage_mode_t storage_mode = storage_mode_sparse | |
| , bool paused = false | | , bool paused = false | |
| , storage_constructor_type sc = default_storage_cons
tructor | | , storage_constructor_type sc = default_storage_cons
tructor | |
| , void* userdata = 0) TORRENT_DEPRECATED; | | , void* userdata = 0) TORRENT_DEPRECATED; | |
| | | | |
| // deprecated in 0.14 | | // deprecated in 0.14 | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| torrent_handle add_torrent( | | torrent_handle add_torrent( | |
| char const* tracker_url | | char const* tracker_url | |
| , sha1_hash const& info_hash | | , sha1_hash const& info_hash | |
| , char const* name | | , char const* name | |
|
| , fs::path const& save_path | | , std::string const& save_path | |
| , entry const& resume_data = entry() | | , entry const& resume_data = entry() | |
| , storage_mode_t storage_mode = storage_mode_sparse | | , storage_mode_t storage_mode = storage_mode_sparse | |
| , bool paused = false | | , bool paused = false | |
| , storage_constructor_type sc = default_storage_cons
tructor | | , storage_constructor_type sc = default_storage_cons
tructor | |
| , void* userdata = 0) TORRENT_DEPRECATED; | | , void* userdata = 0) TORRENT_DEPRECATED; | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| session_proxy abort() { return session_proxy(m_impl); } | | session_proxy abort() { return session_proxy(m_impl); } | |
| | | | |
| void pause(); | | void pause(); | |
| void resume(); | | void resume(); | |
| bool is_paused() const; | | bool is_paused() const; | |
| | | | |
| session_status status() const; | | session_status status() const; | |
| cache_status get_cache_status() const; | | cache_status get_cache_status() const; | |
| | | | |
| void get_cache_info(sha1_hash const& ih | | void get_cache_info(sha1_hash const& ih | |
| , std::vector<cached_piece_info>& ret) const; | | , std::vector<cached_piece_info>& ret) const; | |
| | | | |
|
| | | feed_handle add_feed(feed_settings const& feed); | |
| | | void remove_feed(feed_handle h); | |
| | | void get_feeds(std::vector<feed_handle>& f) const; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| void start_dht(); | | void start_dht(); | |
| void stop_dht(); | | void stop_dht(); | |
| void set_dht_settings(dht_settings const& settings); | | void set_dht_settings(dht_settings const& settings); | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // deprecated in 0.15 | | // deprecated in 0.15 | |
| // use save_state and load_state instead | | // use save_state and load_state instead | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| entry dht_state() const TORRENT_DEPRECATED; | | entry dht_state() const TORRENT_DEPRECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void start_dht(entry const& startup_state) TORRENT_DEPRECATE
D; | | void start_dht(entry const& startup_state) TORRENT_DEPRECATE
D; | |
| #endif | | #endif | |
| void add_dht_node(std::pair<std::string, int> const& node); | | void add_dht_node(std::pair<std::string, int> const& node); | |
| void add_dht_router(std::pair<std::string, int> const& node)
; | | void add_dht_router(std::pair<std::string, int> const& node)
; | |
| bool is_dht_running() const; | | bool is_dht_running() const; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| void set_pe_settings(pe_settings const& settings); | | void set_pe_settings(pe_settings const& settings); | |
|
| pe_settings const& get_pe_settings() const; | | pe_settings get_pe_settings() const; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> ext); | | void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> ext); | |
|
| | | void add_extension(boost::shared_ptr<plugin> ext); | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| int as_for_ip(address const& addr); | | int as_for_ip(address const& addr); | |
|
| bool load_asnum_db(char const* file); | | void load_asnum_db(char const* file); | |
| bool load_country_db(char const* file); | | void load_country_db(char const* file); | |
| #ifndef BOOST_FILESYSTEM_NARROW_ONLY | | #if TORRENT_USE_WSTRING | |
| bool load_country_db(wchar_t const* file); | | void load_country_db(wchar_t const* file); | |
| bool load_asnum_db(wchar_t const* file); | | void load_asnum_db(wchar_t const* file); | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // deprecated in 0.15 | | // deprecated in 0.15 | |
| // use load_state and save_state instead | | // use load_state and save_state instead | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void load_state(entry const& ses_state) TORRENT_DEPRECATED; | | void load_state(entry const& ses_state) TORRENT_DEPRECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| entry state() const TORRENT_DEPRECATED; | | entry state() const TORRENT_DEPRECATED; | |
| #endif | | #endif | |
| | | | |
| void set_ip_filter(ip_filter const& f); | | void set_ip_filter(ip_filter const& f); | |
|
| ip_filter const& get_ip_filter() const; | | ip_filter get_ip_filter() const; | |
| | | | |
| void set_port_filter(port_filter const& f); | | void set_port_filter(port_filter const& f); | |
| void set_peer_id(peer_id const& pid); | | void set_peer_id(peer_id const& pid); | |
| void set_key(int key); | | void set_key(int key); | |
| peer_id id() const; | | peer_id id() const; | |
| | | | |
| bool is_listening() const; | | bool is_listening() const; | |
| | | | |
| // if the listen port failed in some way | | // if the listen port failed in some way | |
| // you can retry to listen on another port- | | // you can retry to listen on another port- | |
| // range with this function. If the listener | | // range with this function. If the listener | |
| // succeeded and is currently listening, | | // succeeded and is currently listening, | |
| // a call to this function will shut down the | | // a call to this function will shut down the | |
| // listen port and reopen it using these new | | // listen port and reopen it using these new | |
| // properties (the given interface and port range). | | // properties (the given interface and port range). | |
| // As usual, if the interface is left as 0 | | // As usual, if the interface is left as 0 | |
| // this function will return false on failure. | | // this function will return false on failure. | |
| // If it fails, it will also generate alerts describing | | // If it fails, it will also generate alerts describing | |
| // the error. It will return true on success. | | // the error. It will return true on success. | |
|
| | | enum listen_on_flags_t | |
| | | { | |
| | | listen_reuse_address = 0x01, | |
| | | listen_no_system_port = 0x02 | |
| | | }; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | // deprecated in 0.16 | |
| | | TORRENT_DEPRECATED_PREFIX | |
| bool listen_on( | | bool listen_on( | |
| std::pair<int, int> const& port_range | | std::pair<int, int> const& port_range | |
|
| , const char* net_interface = 0); | | , const char* net_interface = 0 | |
| | | , int flags = 0) TORRENT_DEPRECATED; | |
| | | #endif | |
| | | | |
| | | void listen_on( | |
| | | std::pair<int, int> const& port_range | |
| | | , error_code& ec | |
| | | , const char* net_interface = 0 | |
| | | , int flags = 0); | |
| | | | |
| // returns the port we ended up listening on | | // returns the port we ended up listening on | |
| unsigned short listen_port() const; | | unsigned short listen_port() const; | |
| | | | |
|
| // Get the number of uploads. | | | |
| int num_uploads() const; | | | |
| | | | |
| // Get the number of connections. This number also contains | | | |
| the | | | |
| // number of half open connections. | | | |
| int num_connections() const; | | | |
| | | | |
| enum options_t | | enum options_t | |
| { | | { | |
| none = 0, | | none = 0, | |
| delete_files = 1 | | delete_files = 1 | |
| }; | | }; | |
| | | | |
| enum session_flags_t | | enum session_flags_t | |
| { | | { | |
| add_default_plugins = 1, | | add_default_plugins = 1, | |
| start_default_features = 2 | | start_default_features = 2 | |
| }; | | }; | |
| | | | |
| void remove_torrent(const torrent_handle& h, int options = n
one); | | void remove_torrent(const torrent_handle& h, int options = n
one); | |
| | | | |
| void set_settings(session_settings const& s); | | void set_settings(session_settings const& s); | |
|
| session_settings const& settings(); | | session_settings settings() const; | |
| | | | |
| void set_proxy(proxy_settings const& s); | | void set_proxy(proxy_settings const& s); | |
|
| proxy_settings const& proxy() const; | | proxy_settings proxy() const; | |
| | | | |
| | | #ifdef TORRENT_STATS | |
| | | void enable_stats_logging(bool s); | |
| | | #endif | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
|
| | | // deprecated in 0.16 | |
| | | // Get the number of uploads. | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int num_uploads() const TORRENT_DEPRECATED; | |
| | | | |
| | | // Get the number of connections. This number also contains | |
| | | the | |
| | | // number of half open connections. | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int num_connections() const TORRENT_DEPRECATED; | |
| | | | |
| // deprecated in 0.15. | | // deprecated in 0.15. | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void set_peer_proxy(proxy_settings const& s) TORRENT_DEPRECA
TED; | | void set_peer_proxy(proxy_settings const& s) TORRENT_DEPRECA
TED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void set_web_seed_proxy(proxy_settings const& s) TORRENT_DEP
RECATED; | | void set_web_seed_proxy(proxy_settings const& s) TORRENT_DEP
RECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void set_tracker_proxy(proxy_settings const& s) TORRENT_DEPR
ECATED; | | void set_tracker_proxy(proxy_settings const& s) TORRENT_DEPR
ECATED; | |
| | | | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
|
| proxy_settings const& peer_proxy() const TORRENT_DEPRECATED; | | proxy_settings peer_proxy() const TORRENT_DEPRECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
|
| proxy_settings const& web_seed_proxy() const TORRENT_DEPRECA
TED; | | proxy_settings web_seed_proxy() const TORRENT_DEPRECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
|
| proxy_settings const& tracker_proxy() const TORRENT_DEPRECAT
ED; | | proxy_settings tracker_proxy() const TORRENT_DEPRECATED; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void set_dht_proxy(proxy_settings const& s) TORRENT_DEPRECAT
ED; | | void set_dht_proxy(proxy_settings const& s) TORRENT_DEPRECAT
ED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
|
| proxy_settings const& dht_proxy() const TORRENT_DEPRECATED; | | proxy_settings dht_proxy() const TORRENT_DEPRECATED; | |
| #endif | | #endif | |
| #endif // TORRENT_NO_DEPRECATE | | #endif // TORRENT_NO_DEPRECATE | |
| | | | |
|
| int upload_rate_limit() const; | | #if TORRENT_USE_I2P | |
| int download_rate_limit() const; | | void set_i2p_proxy(proxy_settings const& s); | |
| int local_upload_rate_limit() const; | | proxy_settings i2p_proxy() const; | |
| int local_download_rate_limit() const; | | #endif | |
| int max_half_open_connections() const; | | | |
| | | | |
|
| void set_local_upload_rate_limit(int bytes_per_second); | | #ifndef TORRENT_NO_DEPRECATE | |
| void set_local_download_rate_limit(int bytes_per_second); | | // deprecated in 0.16 | |
| void set_upload_rate_limit(int bytes_per_second); | | TORRENT_DEPRECATED_PREFIX | |
| void set_download_rate_limit(int bytes_per_second); | | int upload_rate_limit() const TORRENT_DEPRECATED; | |
| void set_max_uploads(int limit); | | TORRENT_DEPRECATED_PREFIX | |
| void set_max_connections(int limit); | | int download_rate_limit() const TORRENT_DEPRECATED; | |
| void set_max_half_open_connections(int limit); | | TORRENT_DEPRECATED_PREFIX | |
| | | int local_upload_rate_limit() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int local_download_rate_limit() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int max_half_open_connections() const TORRENT_DEPRECATED; | |
| | | | |
|
| int max_connections() const; | | TORRENT_DEPRECATED_PREFIX | |
| int max_uploads() const; | | void set_local_upload_rate_limit(int bytes_per_second) TORRE | |
| | | NT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_local_download_rate_limit(int bytes_per_second) TOR | |
| | | RENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_upload_rate_limit(int bytes_per_second) TORRENT_DEP | |
| | | RECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_download_rate_limit(int bytes_per_second) TORRENT_D | |
| | | EPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_max_uploads(int limit) TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_max_connections(int limit) TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_max_half_open_connections(int limit) TORRENT_DEPREC | |
| | | ATED; | |
| | | | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int max_connections() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int max_uploads() const TORRENT_DEPRECATED; | |
| | | #endif | |
| | | | |
| | | // pop one alert from the alert queue, or do nothing | |
| | | // and return a NULL pointer if there are no alerts | |
| | | // in the queue | |
| std::auto_ptr<alert> pop_alert(); | | std::auto_ptr<alert> pop_alert(); | |
|
| | | | |
| | | // pop all alerts in the alert queue and returns them | |
| | | // in the supplied dequeue 'alerts'. The passed in | |
| | | // queue must be empty when passed in. | |
| | | // the responsibility of individual alerts returned | |
| | | // in the dequeue is passed on to the caller of this functio | |
| | | n. | |
| | | // when you're done with reacting to the alerts, you need to | |
| | | // delete them all. | |
| | | void pop_alerts(std::deque<alert*>* alerts); | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void set_severity_level(alert::severity_t s) TORRENT_DEPRECA
TED; | | void set_severity_level(alert::severity_t s) TORRENT_DEPRECA
TED; | |
|
| | | | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
|
| void set_alert_mask(int m) TORRENT_DEPRECATED; | | size_t set_alert_queue_size_limit(size_t queue_size_limit_)
TORRENT_DEPRECATED; | |
| #endif | | #endif | |
| void set_alert_mask(boost::uint32_t m); | | void set_alert_mask(boost::uint32_t m); | |
|
| size_t set_alert_queue_size_limit(size_t queue_size_limit_); | | | |
| | | | |
| alert const* wait_for_alert(time_duration max_wait); | | alert const* wait_for_alert(time_duration max_wait); | |
|
| void set_alert_dispatch(boost::function<void(alert const&)>
const& fun); | | void set_alert_dispatch(boost::function<void(std::auto_ptr<a
lert>)> const& fun); | |
| | | | |
| connection_queue& get_connection_queue(); | | connection_queue& get_connection_queue(); | |
| | | | |
| // starts/stops UPnP, NATPMP or LSD port mappers | | // starts/stops UPnP, NATPMP or LSD port mappers | |
| // they are stopped by default | | // they are stopped by default | |
| void start_lsd(); | | void start_lsd(); | |
| natpmp* start_natpmp(); | | natpmp* start_natpmp(); | |
| upnp* start_upnp(); | | upnp* start_upnp(); | |
| | | | |
| void stop_lsd(); | | void stop_lsd(); | |
| void stop_natpmp(); | | void stop_natpmp(); | |
| void stop_upnp(); | | void stop_upnp(); | |
| | | | |
| private: | | private: | |
| | | | |
|
| // just a way to initialize boost.filesystem | | void init(std::pair<int, int> listen_range, char const* list | |
| // before the session_impl is created | | en_interface | |
| aux::filesystem_init m_dummy; | | , fingerprint const& id, int flags, boost::uint32_t | |
| | | alert_mask TORRENT_LOGPATH_ARG); | |
| | | | |
| // data shared between the main thread | | // data shared between the main thread | |
| // and the working thread | | // and the working thread | |
| boost::shared_ptr<aux::session_impl> m_impl; | | boost::shared_ptr<aux::session_impl> m_impl; | |
| }; | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_SESSION_HPP_INCLUDED | | #endif // TORRENT_SESSION_HPP_INCLUDED | |
| | | | |
End of changes. 51 change blocks. |
| 159 lines changed or deleted | | 186 lines changed or added | |
|
| session_impl.hpp | | session_impl.hpp | |
| | | | |
| skipping to change at line 53 | | skipping to change at line 53 | |
| #include "libtorrent/GeoIP.h" | | #include "libtorrent/GeoIP.h" | |
| #else | | #else | |
| #include <GeoIP.h> | | #include <GeoIP.h> | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
|
| #include <boost/filesystem/path.hpp> | | | |
| #include <boost/thread.hpp> | | | |
| #include <boost/thread/condition.hpp> | | | |
| #include <boost/pool/object_pool.hpp> | | #include <boost/pool/object_pool.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/torrent_handle.hpp" | | #include "libtorrent/torrent_handle.hpp" | |
| #include "libtorrent/entry.hpp" | | #include "libtorrent/entry.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
| #include "libtorrent/tracker_manager.hpp" | | #include "libtorrent/tracker_manager.hpp" | |
| #include "libtorrent/debug.hpp" | | #include "libtorrent/debug.hpp" | |
| #include "libtorrent/piece_block_progress.hpp" | | #include "libtorrent/piece_block_progress.hpp" | |
| #include "libtorrent/ip_filter.hpp" | | #include "libtorrent/ip_filter.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/session_settings.hpp" | | #include "libtorrent/session_settings.hpp" | |
| #include "libtorrent/session_status.hpp" | | #include "libtorrent/session_status.hpp" | |
|
| #include "libtorrent/session.hpp" | | #include "libtorrent/add_torrent_params.hpp" | |
| #include "libtorrent/stat.hpp" | | #include "libtorrent/stat.hpp" | |
| #include "libtorrent/file_pool.hpp" | | #include "libtorrent/file_pool.hpp" | |
| #include "libtorrent/bandwidth_manager.hpp" | | #include "libtorrent/bandwidth_manager.hpp" | |
| #include "libtorrent/socket_type.hpp" | | #include "libtorrent/socket_type.hpp" | |
| #include "libtorrent/connection_queue.hpp" | | #include "libtorrent/connection_queue.hpp" | |
| #include "libtorrent/disk_io_thread.hpp" | | #include "libtorrent/disk_io_thread.hpp" | |
| #include "libtorrent/udp_socket.hpp" | | #include "libtorrent/udp_socket.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
|
| | | #include "libtorrent/thread.hpp" | |
| #include "libtorrent/policy.hpp" // for policy::peer | | #include "libtorrent/policy.hpp" // for policy::peer | |
| #include "libtorrent/alert.hpp" // for alert_manager | | #include "libtorrent/alert.hpp" // for alert_manager | |
|
| | | #include "libtorrent/deadline_timer.hpp" | |
| | | #include "libtorrent/socket_io.hpp" // for print_address | |
| | | #include "libtorrent/address.hpp" | |
| | | #include "libtorrent/utp_socket_manager.hpp" | |
| | | #include "libtorrent/bloom_filter.hpp" | |
| | | #include "libtorrent/rss.hpp" | |
| | | | |
| #if TORRENT_COMPLETE_TYPES_REQUIRED | | #if TORRENT_COMPLETE_TYPES_REQUIRED | |
| #include "libtorrent/peer_connection.hpp" | | #include "libtorrent/peer_connection.hpp" | |
| #endif | | #endif | |
| | | | |
|
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | #include <boost/asio/ssl/context.hpp> | |
| | | #endif | |
| | | | |
| | | #if defined TORRENT_STATS && defined __MACH__ | |
| | | #include <mach/vm_statistics.h> | |
| | | #include <mach/mach_init.h> | |
| | | #include <mach/host_info.h> | |
| | | #include <mach/mach_host.h> | |
| | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| | | | |
|
| namespace fs = boost::filesystem; | | struct plugin; | |
| class peer_connection; | | | |
| class upnp; | | class upnp; | |
| class natpmp; | | class natpmp; | |
| class lsd; | | class lsd; | |
| struct fingerprint; | | struct fingerprint; | |
| class torrent; | | class torrent; | |
| class alert; | | class alert; | |
| | | | |
| namespace dht | | namespace dht | |
| { | | { | |
| struct dht_tracker; | | struct dht_tracker; | |
| } | | } | |
| | | | |
|
| | | struct bencode_map_entry; | |
| | | | |
| | | struct listen_socket_t | |
| | | { | |
| | | listen_socket_t(): external_port(0), ssl(false) {} | |
| | | | |
| | | // this is typically empty but can be set | |
| | | // to the WAN IP address of NAT-PMP or UPnP router | |
| | | address external_address; | |
| | | | |
| | | // this is typically set to the same as the local | |
| | | // listen port. In case a NAT port forward was | |
| | | // successfully opened, this will be set to the | |
| | | // port that is open on the external (NAT) interface | |
| | | // on the NAT box itself. This is the port that has | |
| | | // to be published to peers, since this is the port | |
| | | // the client is reachable through. | |
| | | int external_port; | |
| | | | |
| | | // set to true if this is an SSL listen socket | |
| | | bool ssl; | |
| | | | |
| | | // the actual socket | |
| | | boost::shared_ptr<socket_acceptor> sock; | |
| | | }; | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
| struct session_impl; | | struct session_impl; | |
| | | | |
|
| | | #if defined TORRENT_STATS && !defined __MACH__ | |
| | | struct vm_statistics_data_t | |
| | | { | |
| | | boost::uint64_t active_count; | |
| | | boost::uint64_t inactive_count; | |
| | | boost::uint64_t wire_count; | |
| | | boost::uint64_t free_count; | |
| | | boost::uint64_t pageins; | |
| | | boost::uint64_t pageouts; | |
| | | boost::uint64_t faults; | |
| | | }; | |
| | | #endif | |
| | | | |
| | | struct thread_cpu_usage | |
| | | { | |
| | | ptime user_time; | |
| | | ptime system_time; | |
| | | }; | |
| | | | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| struct tracker_logger; | | struct tracker_logger; | |
| #endif | | #endif | |
| | | | |
| // used to initialize the g_current_time before | | // used to initialize the g_current_time before | |
| // anything else | | // anything else | |
| struct initialize_timer | | struct initialize_timer | |
| { | | { | |
| initialize_timer(); | | initialize_timer(); | |
| }; | | }; | |
| | | | |
|
| | | TORRENT_EXPORT std::pair<bencode_map_entry*, int> settings_m | |
| | | ap(); | |
| | | | |
| // this is the link between the main thread and the | | // this is the link between the main thread and the | |
| // thread started to run the main downloader loop | | // thread started to run the main downloader loop | |
|
| struct session_impl: boost::noncopyable, initialize_timer | | struct TORRENT_EXTRA_EXPORT session_impl: boost::noncopyable | |
| | | , initialize_timer | |
| | | , boost::enable_shared_from_this<session_impl> | |
| { | | { | |
|
| | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | |
| | | ORRENT_ERROR_LOGGING | |
| | | // this needs to be destructed last, since other com | |
| | | ponents may log | |
| | | // things as they are being destructed. That's why i | |
| | | t's declared at | |
| | | // the top of session_impl | |
| | | boost::shared_ptr<logger> m_logger; | |
| | | #endif | |
| | | | |
| // the size of each allocation that is chained in th
e send buffer | | // the size of each allocation that is chained in th
e send buffer | |
| enum { send_buffer_size = 128 }; | | enum { send_buffer_size = 128 }; | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| friend class ::libtorrent::peer_connection; | | friend class ::libtorrent::peer_connection; | |
| #endif | | #endif | |
| friend struct checker_impl; | | friend struct checker_impl; | |
| friend class invariant_access; | | friend class invariant_access; | |
| typedef std::set<boost::intrusive_ptr<peer_connectio
n> > connection_map; | | typedef std::set<boost::intrusive_ptr<peer_connectio
n> > connection_map; | |
| typedef std::map<sha1_hash, boost::shared_ptr<torren
t> > torrent_map; | | typedef std::map<sha1_hash, boost::shared_ptr<torren
t> > torrent_map; | |
| | | | |
| session_impl( | | session_impl( | |
| std::pair<int, int> listen_port_range | | std::pair<int, int> listen_port_range | |
| , fingerprint const& cl_fprint | | , fingerprint const& cl_fprint | |
| , char const* listen_interface | | , char const* listen_interface | |
|
| | | , boost::uint32_t alert_mask | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
|
| , fs::path const& logpath | | , std::string const& logpath | |
| #endif | | #endif | |
| ); | | ); | |
| ~session_impl(); | | ~session_impl(); | |
|
| | | void init(); | |
| | | void start_session(); | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void add_extension(boost::function<boost::shared_ptr
<torrent_plugin>( | | void add_extension(boost::function<boost::shared_ptr
<torrent_plugin>( | |
| torrent*, void*)> ext); | | torrent*, void*)> ext); | |
|
| | | void add_ses_extension(boost::shared_ptr<plugin> ext
); | |
| #endif | | #endif | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| bool has_peer(peer_connection const* p) const | | bool has_peer(peer_connection const* p) const | |
| { | | { | |
|
| | | TORRENT_ASSERT(is_network_thread()); | |
| return std::find_if(m_connections.begin(), m
_connections.end() | | return std::find_if(m_connections.begin(), m
_connections.end() | |
| , boost::bind(&boost::intrusive_ptr<
peer_connection>::get, _1) == p) | | , boost::bind(&boost::intrusive_ptr<
peer_connection>::get, _1) == p) | |
| != m_connections.end(); | | != m_connections.end(); | |
| } | | } | |
| #endif | | #endif | |
|
| void operator()(); | | void main_thread(); | |
| | | | |
|
| void open_listen_port(); | | void open_listen_port(int flags, error_code& ec); | |
| | | | |
| // if we are listening on an IPv6 interface | | // if we are listening on an IPv6 interface | |
| // this will return one of the IPv6 addresses on thi
s | | // this will return one of the IPv6 addresses on thi
s | |
| // machine, otherwise just an empty endpoint | | // machine, otherwise just an empty endpoint | |
| tcp::endpoint get_ipv6_interface() const; | | tcp::endpoint get_ipv6_interface() const; | |
| tcp::endpoint get_ipv4_interface() const; | | tcp::endpoint get_ipv4_interface() const; | |
| | | | |
|
| void async_accept(boost::shared_ptr<socket_acceptor>
const& listener); | | void async_accept(boost::shared_ptr<socket_acceptor>
const& listener, bool ssl); | |
| void on_accept_connection(boost::shared_ptr<socket_t
ype> const& s | | void on_accept_connection(boost::shared_ptr<socket_t
ype> const& s | |
|
| , boost::weak_ptr<socket_acceptor> listener,
error_code const& e); | | , boost::weak_ptr<socket_acceptor> listener,
error_code const& e, bool ssl); | |
| void on_socks_accept(boost::shared_ptr<socket_type>
const& s | | void on_socks_accept(boost::shared_ptr<socket_type>
const& s | |
| , error_code const& e); | | , error_code const& e); | |
| | | | |
| void incoming_connection(boost::shared_ptr<socket_ty
pe> const& s); | | void incoming_connection(boost::shared_ptr<socket_ty
pe> const& s); | |
| | | | |
|
| // must be locked to access the data | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| // in this struct | | bool is_network_thread() const | |
| typedef boost::mutex mutex_t; | | { | |
| mutable mutex_t m_mutex; | | #if defined BOOST_HAS_PTHREADS | |
| | | if (m_network_thread == 0) return true; | |
| | | return m_network_thread == pthread_self(); | |
| | | #endif | |
| | | return true; | |
| | | } | |
| | | #endif | |
| | | | |
| | | feed_handle add_feed(feed_settings const& feed); | |
| | | void remove_feed(feed_handle h); | |
| | | void get_feeds(std::vector<feed_handle>* f) const; | |
| | | | |
| | | boost::weak_ptr<torrent> find_torrent(sha1_hash cons | |
| | | t& info_hash); | |
| | | boost::weak_ptr<torrent> find_torrent(std::string co | |
| | | nst& uuid); | |
| | | | |
|
| boost::weak_ptr<torrent> find_torrent(const sha1_has
h& info_hash); | | | |
| peer_id const& get_peer_id() const { return m_peer_i
d; } | | peer_id const& get_peer_id() const { return m_peer_i
d; } | |
| | | | |
| void close_connection(peer_connection const* p, erro
r_code const& ec); | | void close_connection(peer_connection const* p, erro
r_code const& ec); | |
| | | | |
| void set_settings(session_settings const& s); | | void set_settings(session_settings const& s); | |
| session_settings const& settings() const { return m_
settings; } | | session_settings const& settings() const { return m_
settings; } | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
|
| void add_dht_node(std::pair<std::string, int> const&
node); | | void add_dht_node_name(std::pair<std::string, int> c
onst& node); | |
| void add_dht_node(udp::endpoint n); | | void add_dht_node(udp::endpoint n); | |
| void add_dht_router(std::pair<std::string, int> cons
t& node); | | void add_dht_router(std::pair<std::string, int> cons
t& node); | |
| void set_dht_settings(dht_settings const& s); | | void set_dht_settings(dht_settings const& s); | |
| dht_settings const& get_dht_settings() const { retur
n m_dht_settings; } | | dht_settings const& get_dht_settings() const { retur
n m_dht_settings; } | |
| void start_dht(); | | void start_dht(); | |
| void stop_dht(); | | void stop_dht(); | |
| void start_dht(entry const& startup_state); | | void start_dht(entry const& startup_state); | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
|
| entry dht_state(session_impl::mutex_t::scoped_lock&
l) const; | | entry dht_state() const; | |
| #endif | | #endif | |
|
| void maybe_update_udp_mapping(int nat, int local_por
t, int external_port); | | void on_dht_announce(error_code const& e); | |
| void on_dht_router_name_lookup(error_code const& e | | void on_dht_router_name_lookup(error_code const& e | |
| , tcp::resolver::iterator host); | | , tcp::resolver::iterator host); | |
| #endif | | #endif | |
| | | | |
|
| | | void maybe_update_udp_mapping(int nat, int local_por | |
| | | t, int external_port); | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| void set_pe_settings(pe_settings const& settings); | | void set_pe_settings(pe_settings const& settings); | |
| pe_settings const& get_pe_settings() const { return
m_pe_settings; } | | pe_settings const& get_pe_settings() const { return
m_pe_settings; } | |
| #endif | | #endif | |
| | | | |
| void on_port_map_log(char const* msg, int map_transp
ort); | | void on_port_map_log(char const* msg, int map_transp
ort); | |
| | | | |
| void on_lsd_announce(error_code const& e); | | void on_lsd_announce(error_code const& e); | |
| | | | |
| // called when a port mapping is successful, or a ro
uter returns | | // called when a port mapping is successful, or a ro
uter returns | |
| // a failure to map a port | | // a failure to map a port | |
|
| void on_port_mapping(int mapping, int port, error_co | | void on_port_mapping(int mapping, address const& ip, | |
| de const& ec | | int port | |
| , int nat_transport); | | , error_code const& ec, int nat_transport); | |
| | | | |
| bool is_aborted() const { return m_abort; } | | bool is_aborted() const { return m_abort; } | |
| bool is_paused() const { return m_paused; } | | bool is_paused() const { return m_paused; } | |
| | | | |
| void pause(); | | void pause(); | |
| void resume(); | | void resume(); | |
| | | | |
| void set_ip_filter(ip_filter const& f); | | void set_ip_filter(ip_filter const& f); | |
| ip_filter const& get_ip_filter() const; | | ip_filter const& get_ip_filter() const; | |
| | | | |
| void set_port_filter(port_filter const& f); | | void set_port_filter(port_filter const& f); | |
| | | | |
|
| bool listen_on( | | void listen_on( | |
| std::pair<int, int> const& port_range | | std::pair<int, int> const& port_range | |
|
| , const char* net_interface = 0); | | , error_code& ec | |
| | | , const char* net_interface = 0 | |
| | | , int flags = 0); | |
| bool is_listening() const; | | bool is_listening() const; | |
| | | | |
| torrent_handle add_torrent(add_torrent_params const&
, error_code& ec); | | torrent_handle add_torrent(add_torrent_params const&
, error_code& ec); | |
|
| | | void async_add_torrent(add_torrent_params* params); | |
| | | | |
| void remove_torrent(torrent_handle const& h, int opt
ions); | | void remove_torrent(torrent_handle const& h, int opt
ions); | |
|
| | | void remove_torrent_impl(boost::shared_ptr<torrent>
tptr, int options); | |
| | | | |
|
| std::vector<torrent_handle> get_torrents(); | | void get_torrent_status(std::vector<torrent_status>* | |
| | | ret | |
| | | , boost::function<bool(torrent_status const& | |
| | | )> const& pred | |
| | | , boost::uint32_t flags) const; | |
| | | void refresh_torrent_status(std::vector<torrent_stat | |
| | | us>* ret | |
| | | , boost::uint32_t flags) const; | |
| | | void post_torrent_updates(); | |
| | | | |
| | | std::vector<torrent_handle> get_torrents() const; | |
| | | | |
| void queue_check_torrent(boost::shared_ptr<torrent>
const& t); | | void queue_check_torrent(boost::shared_ptr<torrent>
const& t); | |
| void dequeue_check_torrent(boost::shared_ptr<torrent
> const& t); | | void dequeue_check_torrent(boost::shared_ptr<torrent
> const& t); | |
| | | | |
| void set_alert_mask(boost::uint32_t m); | | void set_alert_mask(boost::uint32_t m); | |
| size_t set_alert_queue_size_limit(size_t queue_size_
limit_); | | size_t set_alert_queue_size_limit(size_t queue_size_
limit_); | |
| std::auto_ptr<alert> pop_alert(); | | std::auto_ptr<alert> pop_alert(); | |
|
| void set_alert_dispatch(boost::function<void(alert c | | void pop_alerts(std::deque<alert*>* alerts); | |
| onst&)> const&); | | void set_alert_dispatch(boost::function<void(std::au | |
| | | to_ptr<alert>)> const&); | |
| | | void post_alert(const alert& alert_); | |
| | | | |
| alert const* wait_for_alert(time_duration max_wait); | | alert const* wait_for_alert(time_duration max_wait); | |
| | | | |
|
| | | #ifndef TORRENT_NO_DEPRECATE | |
| int upload_rate_limit() const; | | int upload_rate_limit() const; | |
| int download_rate_limit() const; | | int download_rate_limit() const; | |
| int local_upload_rate_limit() const; | | int local_upload_rate_limit() const; | |
| int local_download_rate_limit() const; | | int local_download_rate_limit() const; | |
| | | | |
| void set_local_download_rate_limit(int bytes_per_sec
ond); | | void set_local_download_rate_limit(int bytes_per_sec
ond); | |
| void set_local_upload_rate_limit(int bytes_per_secon
d); | | void set_local_upload_rate_limit(int bytes_per_secon
d); | |
|
| | | | |
| void set_download_rate_limit(int bytes_per_second); | | void set_download_rate_limit(int bytes_per_second); | |
| void set_upload_rate_limit(int bytes_per_second); | | void set_upload_rate_limit(int bytes_per_second); | |
| void set_max_half_open_connections(int limit); | | void set_max_half_open_connections(int limit); | |
| void set_max_connections(int limit); | | void set_max_connections(int limit); | |
| void set_max_uploads(int limit); | | void set_max_uploads(int limit); | |
| | | | |
|
| int max_connections() const { return m_max_connectio | | int max_connections() const; | |
| ns; } | | int max_uploads() const; | |
| int max_uploads() const { return m_max_uploads; } | | int max_half_open_connections() const; | |
| int max_half_open_connections() const { return m_hal | | | |
| f_open.limit(); } | | #endif | |
| | | | |
| int num_uploads() const { return m_num_unchoked; } | | int num_uploads() const { return m_num_unchoked; } | |
| int num_connections() const | | int num_connections() const | |
| { return m_connections.size(); } | | { return m_connections.size(); } | |
| | | | |
| void unchoke_peer(peer_connection& c); | | void unchoke_peer(peer_connection& c); | |
| void choke_peer(peer_connection& c); | | void choke_peer(peer_connection& c); | |
| | | | |
| session_status status() const; | | session_status status() const; | |
| void set_peer_id(peer_id const& id); | | void set_peer_id(peer_id const& id); | |
| void set_key(int key); | | void set_key(int key); | |
|
| unsigned short listen_port() const; | | address listen_address() const; | |
| | | boost::uint16_t listen_port() const; | |
| | | boost::uint16_t ssl_listen_port() const; | |
| | | | |
| void abort(); | | void abort(); | |
| | | | |
| torrent_handle find_torrent_handle(sha1_hash const&
info_hash); | | torrent_handle find_torrent_handle(sha1_hash const&
info_hash); | |
| | | | |
|
| void announce_lsd(sha1_hash const& ih); | | void announce_lsd(sha1_hash const& ih, int port, boo
l broadcast = false); | |
| | | | |
|
| void save_state(entry& e, boost::uint32_t flags, ses | | void save_state(entry* e, boost::uint32_t flags) con | |
| sion_impl::mutex_t::scoped_lock& l) const; | | st; | |
| void load_state(lazy_entry const& e); | | void load_state(lazy_entry const* e); | |
| | | | |
| void set_proxy(proxy_settings const& s); | | void set_proxy(proxy_settings const& s); | |
|
| proxy_settings const& proxy() const { return m_peer_
proxy; } | | proxy_settings const& proxy() const { return m_proxy
; } | |
| | | | |
|
| void set_peer_proxy(proxy_settings const& s) | | #ifndef TORRENT_NO_DEPRECATE | |
| { | | void set_peer_proxy(proxy_settings const& s) { set_p | |
| m_peer_proxy = s; | | roxy(s); } | |
| // in case we just set a socks proxy, we mig | | void set_web_seed_proxy(proxy_settings const& s) { s | |
| ht have to | | et_proxy(s); } | |
| // open the socks incoming connection | | void set_tracker_proxy(proxy_settings const& s) { se | |
| if (!m_socks_listen_socket) open_new_incomin | | t_proxy(s); } | |
| g_socks_connection(); | | proxy_settings const& peer_proxy() const { return pr | |
| } | | oxy(); } | |
| void set_web_seed_proxy(proxy_settings const& s) | | proxy_settings const& web_seed_proxy() const { retur | |
| { m_web_seed_proxy = s; } | | n proxy(); } | |
| void set_tracker_proxy(proxy_settings const& s) | | proxy_settings const& tracker_proxy() const { return | |
| { m_tracker_proxy = s; } | | proxy(); } | |
| proxy_settings const& peer_proxy() const | | | |
| { return m_peer_proxy; } | | | |
| proxy_settings const& web_seed_proxy() const | | | |
| { return m_web_seed_proxy; } | | | |
| proxy_settings const& tracker_proxy() const | | | |
| { return m_tracker_proxy; } | | | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
|
| void set_dht_proxy(proxy_settings const& s) | | void set_dht_proxy(proxy_settings const& s) { set_pr | |
| | | oxy(s); } | |
| | | proxy_settings const& dht_proxy() const { return pro | |
| | | xy(); } | |
| | | #endif | |
| | | #endif // TORRENT_NO_DEPRECATE | |
| | | | |
| | | #ifndef TORRENT_DISABLE_DHT | |
| | | bool is_dht_running() const { return m_dht; } | |
| | | #endif | |
| | | | |
| | | #if TORRENT_USE_I2P | |
| | | void set_i2p_proxy(proxy_settings const& s) | |
| { | | { | |
|
| m_dht_proxy = s; | | m_i2p_conn.open(s, boost::bind(&session_impl | |
| m_dht_socket->set_proxy_settings(s); | | ::on_i2p_open, this, _1)); | |
| | | open_new_incoming_i2p_connection(); | |
| } | | } | |
|
| proxy_settings const& dht_proxy() const | | void on_i2p_open(error_code const& ec); | |
| { return m_dht_proxy; } | | proxy_settings const& i2p_proxy() const | |
| | | { return m_i2p_conn.proxy(); } | |
| | | void open_new_incoming_i2p_connection(); | |
| | | void on_i2p_accept(boost::shared_ptr<socket_type> co | |
| | | nst& s | |
| | | , error_code const& e); | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| std::string as_name_for_ip(address const& a); | | std::string as_name_for_ip(address const& a); | |
| int as_for_ip(address const& a); | | int as_for_ip(address const& a); | |
| std::pair<const int, int>* lookup_as(int as); | | std::pair<const int, int>* lookup_as(int as); | |
|
| bool load_asnum_db(char const* file); | | void load_asnum_db(std::string file); | |
| bool has_asnum_db() const { return m_asnum_db; } | | bool has_asnum_db() const { return m_asnum_db; } | |
| | | | |
|
| bool load_country_db(char const* file); | | void load_country_db(std::string file); | |
| bool has_country_db() const { return m_country_db; } | | bool has_country_db() const { return m_country_db; } | |
| char const* country_for_ip(address const& a); | | char const* country_for_ip(address const& a); | |
| | | | |
|
| #ifndef BOOST_FILESYSTEM_NARROW_ONLY | | #if TORRENT_USE_WSTRING | |
| bool load_asnum_db(wchar_t const* file); | | void load_asnum_dbw(std::wstring file); | |
| bool load_country_db(wchar_t const* file); | | void load_country_dbw(std::wstring file); | |
| #endif | | #endif // TORRENT_USE_WSTRING | |
| #endif | | #endif // TORRENT_DISABLE_GEO_IP | |
| | | | |
| void start_lsd(); | | void start_lsd(); | |
|
| void start_natpmp(natpmp* n); | | natpmp* start_natpmp(); | |
| void start_upnp(upnp* u); | | upnp* start_upnp(); | |
| | | | |
| void stop_lsd(); | | void stop_lsd(); | |
| void stop_natpmp(); | | void stop_natpmp(); | |
| void stop_upnp(); | | void stop_upnp(); | |
| | | | |
| int next_port(); | | int next_port(); | |
| | | | |
|
| void add_redundant_bytes(size_type b) | | void add_redundant_bytes(size_type b, int reason) | |
| { | | { | |
| TORRENT_ASSERT(b > 0); | | TORRENT_ASSERT(b > 0); | |
| m_total_redundant_bytes += b; | | m_total_redundant_bytes += b; | |
|
| | | m_redundant_bytes[reason] += b; | |
| } | | } | |
| | | | |
| void add_failed_bytes(size_type b) | | void add_failed_bytes(size_type b) | |
| { | | { | |
| TORRENT_ASSERT(b > 0); | | TORRENT_ASSERT(b > 0); | |
| m_total_failed_bytes += b; | | m_total_failed_bytes += b; | |
| } | | } | |
| | | | |
|
| std::pair<char*, int> allocate_buffer(int size); | | char* allocate_buffer(); | |
| void free_buffer(char* buf, int size); | | void free_buffer(char* buf); | |
| | | | |
| char* allocate_disk_buffer(char const* category); | | char* allocate_disk_buffer(char const* category); | |
| void free_disk_buffer(char* buf); | | void free_disk_buffer(char* buf); | |
| | | | |
|
| void set_external_address(address const& ip); | | enum | |
| | | { | |
| | | source_dht = 1, | |
| | | source_peer = 2, | |
| | | source_tracker = 4, | |
| | | source_router = 8 | |
| | | }; | |
| | | | |
| | | void set_external_address(address const& ip | |
| | | , int source_type, address const& source); | |
| address const& external_address() const { return m_e
xternal_address; } | | address const& external_address() const { return m_e
xternal_address; } | |
| | | | |
|
| | | bool can_write_to_disk() const | |
| | | { return m_disk_thread.can_write(); } | |
| | | | |
| | | // used when posting synchronous function | |
| | | // calls to session_impl and torrent objects | |
| | | mutable libtorrent::mutex mut; | |
| | | mutable libtorrent::condition cond; | |
| | | | |
| | | void inc_disk_queue(int channel) | |
| | | { | |
| | | TORRENT_ASSERT(channel >= 0 && channel < 2); | |
| | | ++m_disk_queues[channel]; | |
| | | } | |
| | | | |
| | | void dec_disk_queue(int channel) | |
| | | { | |
| | | TORRENT_ASSERT(channel >= 0 && channel < 2); | |
| | | TORRENT_ASSERT(m_disk_queues[channel] > 0); | |
| | | --m_disk_queues[channel]; | |
| | | } | |
| | | | |
| | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| | | bool in_state_updates(boost::shared_ptr<torrent> t) | |
| | | { | |
| | | return std::find_if(m_state_updates.begin(), | |
| | | m_state_updates.end() | |
| | | , boost::bind(&boost::weak_ptr<torre | |
| | | nt>::lock, _1) == t) != m_state_updates.end(); | |
| | | } | |
| | | #endif | |
| | | | |
| | | void add_to_update_queue(boost::weak_ptr<torrent> t) | |
| | | { | |
| | | TORRENT_ASSERT(std::find_if(m_state_updates. | |
| | | begin(), m_state_updates.end() | |
| | | , boost::bind(&boost::weak_ptr<torre | |
| | | nt>::lock, _1) == t.lock()) == m_state_updates.end()); | |
| | | m_state_updates.push_back(t); | |
| | | } | |
| | | | |
| // private: | | // private: | |
| | | | |
|
| | | void update_connections_limit(); | |
| | | void update_unchoke_limit(); | |
| | | void update_rate_settings(); | |
| | | | |
| void update_disk_thread_settings(); | | void update_disk_thread_settings(); | |
|
| void on_dht_state_callback(boost::condition& c | | | |
| , entry& e, bool& done) const; | | | |
| void on_lsd_peer(tcp::endpoint peer, sha1_hash const
& ih); | | void on_lsd_peer(tcp::endpoint peer, sha1_hash const
& ih); | |
| void setup_socket_buffers(socket_type& s); | | void setup_socket_buffers(socket_type& s); | |
| | | | |
|
| | | // the settings for the client | |
| | | session_settings m_settings; | |
| | | | |
| // this is a shared pool where policy_peer objects | | // this is a shared pool where policy_peer objects | |
| // are allocated. It's a pool since we're likely | | // are allocated. It's a pool since we're likely | |
| // to have tens of thousands of peers, and a pool | | // to have tens of thousands of peers, and a pool | |
| // saves significant overhead | | // saves significant overhead | |
| #ifdef TORRENT_STATS | | #ifdef TORRENT_STATS | |
| struct logging_allocator | | struct logging_allocator | |
| { | | { | |
| typedef std::size_t size_type; | | typedef std::size_t size_type; | |
| typedef std::ptrdiff_t difference_type; | | typedef std::ptrdiff_t difference_type; | |
| | | | |
| | | | |
| skipping to change at line 408 | | skipping to change at line 567 | |
| { | | { | |
| --allocations; | | --allocations; | |
| return ::free(block); | | return ::free(block); | |
| } | | } | |
| | | | |
| static int allocations; | | static int allocations; | |
| static int allocated_bytes; | | static int allocated_bytes; | |
| }; | | }; | |
| boost::object_pool< | | boost::object_pool< | |
| policy::ipv4_peer, logging_allocator> m_ipv4
_peer_pool; | | policy::ipv4_peer, logging_allocator> m_ipv4
_peer_pool; | |
|
| # if TORRENT_USE_IPV6 | | #if TORRENT_USE_IPV6 | |
| boost::object_pool< | | boost::object_pool< | |
| policy::ipv6_peer, logging_allocator> m_ipv6
_peer_pool; | | policy::ipv6_peer, logging_allocator> m_ipv6
_peer_pool; | |
|
| # endif | | #endif | |
| | | #if TORRENT_USE_I2P | |
| | | boost::object_pool< | |
| | | policy::i2p_peer, logging_allocator> m_i2p_p | |
| | | eer_pool; | |
| | | #endif | |
| #else | | #else | |
| boost::object_pool<policy::ipv4_peer> m_ipv4_peer_po
ol; | | boost::object_pool<policy::ipv4_peer> m_ipv4_peer_po
ol; | |
|
| # if TORRENT_USE_IPV6 | | #if TORRENT_USE_IPV6 | |
| boost::object_pool<policy::ipv6_peer> m_ipv6_peer_po
ol; | | boost::object_pool<policy::ipv6_peer> m_ipv6_peer_po
ol; | |
|
| # endif | | #endif | |
| | | #if TORRENT_USE_I2P | |
| | | boost::object_pool<policy::i2p_peer> m_i2p_peer_pool | |
| | | ; | |
| | | #endif | |
| #endif | | #endif | |
| | | | |
| // this vector is used to store the block_info | | // this vector is used to store the block_info | |
| // objects pointed to by partial_piece_info returned | | // objects pointed to by partial_piece_info returned | |
| // by torrent::get_download_queue. | | // by torrent::get_download_queue. | |
| std::vector<block_info> m_block_info_storage; | | std::vector<block_info> m_block_info_storage; | |
| | | | |
| #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | | #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | |
| // this pool is used to allocate and recycle send | | // this pool is used to allocate and recycle send | |
| // buffers from. | | // buffers from. | |
| boost::pool<> m_send_buffers; | | boost::pool<> m_send_buffers; | |
| #endif | | #endif | |
|
| boost::mutex m_send_buffer_mutex; | | | |
| | | | |
| // the file pool that all storages in this session's | | // the file pool that all storages in this session's | |
| // torrents uses. It sets a limit on the number of | | // torrents uses. It sets a limit on the number of | |
| // open files by this session. | | // open files by this session. | |
| // file pool must be destructed after the torrents | | // file pool must be destructed after the torrents | |
| // since they will still have references to it | | // since they will still have references to it | |
| // when they are destructed. | | // when they are destructed. | |
| file_pool m_files; | | file_pool m_files; | |
| | | | |
| // this is where all active sockets are stored. | | // this is where all active sockets are stored. | |
| // the selector can sleep while there's no activity
on | | // the selector can sleep while there's no activity
on | |
| // them | | // them | |
| mutable io_service m_io_service; | | mutable io_service m_io_service; | |
| | | | |
|
| tcp::resolver m_host_resolver; | | #ifdef TORRENT_USE_OPENSSL | |
| | | // this is a generic SSL context used when talking t | |
| | | o | |
| | | // unauthenticated HTTPS servers | |
| | | asio::ssl::context m_ssl_ctx; | |
| | | #endif | |
| | | | |
| // handles delayed alerts | | // handles delayed alerts | |
| alert_manager m_alerts; | | alert_manager m_alerts; | |
| | | | |
| // handles disk io requests asynchronously | | // handles disk io requests asynchronously | |
| // peers have pointers into the disk buffer | | // peers have pointers into the disk buffer | |
| // pool, and must be destructed before this | | // pool, and must be destructed before this | |
| // object. The disk thread relies on the file | | // object. The disk thread relies on the file | |
| // pool object, and must be destructed before | | // pool object, and must be destructed before | |
| // m_files. The disk io thread posts completion | | // m_files. The disk io thread posts completion | |
| | | | |
| skipping to change at line 469 | | skipping to change at line 638 | |
| // this is a list of half-open tcp connections | | // this is a list of half-open tcp connections | |
| // (only outgoing connections) | | // (only outgoing connections) | |
| // this has to be one of the last | | // this has to be one of the last | |
| // members to be destructed | | // members to be destructed | |
| connection_queue m_half_open; | | connection_queue m_half_open; | |
| | | | |
| // the bandwidth manager is responsible for | | // the bandwidth manager is responsible for | |
| // handing out bandwidth to connections that | | // handing out bandwidth to connections that | |
| // asks for it, it can also throttle the | | // asks for it, it can also throttle the | |
| // rate. | | // rate. | |
|
| bandwidth_manager<peer_connection> m_download_rate; | | bandwidth_manager m_download_rate; | |
| bandwidth_manager<peer_connection> m_upload_rate; | | bandwidth_manager m_upload_rate; | |
| | | | |
| // the global rate limiter bandwidth channels | | // the global rate limiter bandwidth channels | |
| bandwidth_channel m_download_channel; | | bandwidth_channel m_download_channel; | |
| bandwidth_channel m_upload_channel; | | bandwidth_channel m_upload_channel; | |
| | | | |
| // bandwidth channels for local peers when | | // bandwidth channels for local peers when | |
| // rate limits are ignored. They are only | | // rate limits are ignored. They are only | |
| // throttled by these global rate limiters | | // throttled by these global rate limiters | |
| // and they don't have a rate limit set by | | // and they don't have a rate limit set by | |
| // default | | // default | |
| bandwidth_channel m_local_download_channel; | | bandwidth_channel m_local_download_channel; | |
| bandwidth_channel m_local_upload_channel; | | bandwidth_channel m_local_upload_channel; | |
| | | | |
|
| | | // all tcp peer connections are subject to these | |
| | | // bandwidth limits. Local peers are excempted | |
| | | // from this limit. The purpose is to be able to | |
| | | // throttle TCP that passes over the internet | |
| | | // bottleneck (i.e. modem) to avoid starving out | |
| | | // uTP connections. | |
| | | bandwidth_channel m_tcp_download_channel; | |
| | | bandwidth_channel m_tcp_upload_channel; | |
| | | | |
| bandwidth_channel* m_bandwidth_channel[2]; | | bandwidth_channel* m_bandwidth_channel[2]; | |
| | | | |
|
| | | // the number of peer connections that are waiting | |
| | | // for the disk. one for each channel. | |
| | | // upload_channel means waiting to read from disk | |
| | | // and download_channel is waiting to write to disk | |
| | | int m_disk_queues[2]; | |
| | | | |
| tracker_manager m_tracker_manager; | | tracker_manager m_tracker_manager; | |
| torrent_map m_torrents; | | torrent_map m_torrents; | |
|
| | | std::map<std::string, boost::shared_ptr<torrent> > m | |
| | | _uuids; | |
| | | | |
| typedef std::list<boost::shared_ptr<torrent> > check
_queue_t; | | typedef std::list<boost::shared_ptr<torrent> > check
_queue_t; | |
| | | | |
| // this has all torrents that wants to be checked in
it | | // this has all torrents that wants to be checked in
it | |
| check_queue_t m_queued_for_checking; | | check_queue_t m_queued_for_checking; | |
| | | | |
| // this maps sockets to their peer_connection | | // this maps sockets to their peer_connection | |
| // object. It is the complete list of all connected | | // object. It is the complete list of all connected | |
| // peers. | | // peers. | |
| connection_map m_connections; | | connection_map m_connections; | |
| | | | |
| | | | |
| skipping to change at line 530 | | skipping to change at line 716 | |
| // that we should let the os decide which | | // that we should let the os decide which | |
| // interface to listen on | | // interface to listen on | |
| tcp::endpoint m_listen_interface; | | tcp::endpoint m_listen_interface; | |
| | | | |
| // if we're listening on an IPv6 interface | | // if we're listening on an IPv6 interface | |
| // this is one of the non local IPv6 interfaces | | // this is one of the non local IPv6 interfaces | |
| // on this machine | | // on this machine | |
| tcp::endpoint m_ipv6_interface; | | tcp::endpoint m_ipv6_interface; | |
| tcp::endpoint m_ipv4_interface; | | tcp::endpoint m_ipv4_interface; | |
| | | | |
|
| struct listen_socket_t | | | |
| { | | | |
| listen_socket_t(): external_port(0) {} | | | |
| // this is typically set to the same as the | | | |
| local | | | |
| // listen port. In case a NAT port forward w | | | |
| as | | | |
| // successfully opened, this will be set to | | | |
| the | | | |
| // port that is open on the external (NAT) i | | | |
| nterface | | | |
| // on the NAT box itself. This is the port t | | | |
| hat has | | | |
| // to be published to peers, since this is t | | | |
| he port | | | |
| // the client is reachable through. | | | |
| int external_port; | | | |
| | | | |
| // the actual socket | | | |
| boost::shared_ptr<socket_acceptor> sock; | | | |
| }; | | | |
| // since we might be listening on multiple interface
s | | // since we might be listening on multiple interface
s | |
| // we might need more than one listen socket | | // we might need more than one listen socket | |
| std::list<listen_socket_t> m_listen_sockets; | | std::list<listen_socket_t> m_listen_sockets; | |
| | | | |
|
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | void ssl_handshake(error_code const& ec, boost::shar | |
| | | ed_ptr<socket_type> s); | |
| | | #endif | |
| | | | |
| // when as a socks proxy is used for peers, also | | // when as a socks proxy is used for peers, also | |
| // listen for incoming connections on a socks connec
tion | | // listen for incoming connections on a socks connec
tion | |
| 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(); | |
| | | | |
|
| listen_socket_t setup_listener(tcp::endpoint ep, int | | #if TORRENT_USE_I2P | |
| retries, bool v6_only = false); | | i2p_connection m_i2p_conn; | |
| | | boost::shared_ptr<socket_type> m_i2p_listen_socket; | |
| // the settings for the client | | | |
| session_settings m_settings; | | | |
| // the proxy settings for different | | | |
| // kinds of connections | | | |
| proxy_settings m_peer_proxy; | | | |
| proxy_settings m_web_seed_proxy; | | | |
| proxy_settings m_tracker_proxy; | | | |
| #ifndef TORRENT_DISABLE_DHT | | | |
| proxy_settings m_dht_proxy; | | | |
| #endif | | #endif | |
| | | | |
|
| | | void setup_listener(listen_socket_t* s, tcp::endpoin | |
| | | t ep, int retries | |
| | | , bool v6_only, int flags, error_code& ec); | |
| | | | |
| | | // the proxy used for bittorrent | |
| | | proxy_settings m_proxy; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| entry m_dht_state; | | entry m_dht_state; | |
| #endif | | #endif | |
| // set to true when the session object | | // set to true when the session object | |
| // is being destructed and the thread | | // is being destructed and the thread | |
| // should exit | | // should exit | |
| bool m_abort; | | bool m_abort; | |
| | | | |
| // is true if the session is paused | | // is true if the session is paused | |
| bool m_paused; | | bool m_paused; | |
| | | | |
|
| // the max number of unchoked peers as set by the us | | | |
| er | | | |
| int m_max_uploads; | | | |
| | | | |
| // the number of unchoked peers as set by the auto-u
nchoker | | // the number of unchoked peers as set by the auto-u
nchoker | |
| // this should always be >= m_max_uploads | | // this should always be >= m_max_uploads | |
| int m_allowed_upload_slots; | | int m_allowed_upload_slots; | |
| | | | |
|
| // the max number of connections, as set by the user | | | |
| int m_max_connections; | | | |
| | | | |
| // the number of unchoked peers | | // the number of unchoked peers | |
| int m_num_unchoked; | | int m_num_unchoked; | |
| | | | |
| // this is initialized to the unchoke_interval | | // this is initialized to the unchoke_interval | |
| // session_setting and decreased every second. | | // session_setting and decreased every second. | |
| // when it reaches zero, it is reset to the | | // when it reaches zero, it is reset to the | |
| // unchoke_interval and the unchoke set is | | // unchoke_interval and the unchoke set is | |
| // recomputed. | | // recomputed. | |
| int m_unchoke_time_scaler; | | int m_unchoke_time_scaler; | |
| | | | |
| | | | |
| skipping to change at line 620 | | skipping to change at line 788 | |
| // it reaches 0, and all the connections are | | // it reaches 0, and all the connections are | |
| // used, the worst connection will be disconnected | | // used, the worst connection will be disconnected | |
| // from the torrent with the most peers | | // from the torrent with the most peers | |
| int m_disconnect_time_scaler; | | int m_disconnect_time_scaler; | |
| | | | |
| // when this scaler reaches zero, it will | | // when this scaler reaches zero, it will | |
| // scrape one of the auto managed, paused, | | // scrape one of the auto managed, paused, | |
| // torrents. | | // torrents. | |
| int m_auto_scrape_time_scaler; | | int m_auto_scrape_time_scaler; | |
| | | | |
|
| | | // the index of the torrent that we'll | |
| | | // refresh the next time | |
| | | int m_next_explicit_cache_torrent; | |
| | | | |
| | | // this is a counter of the number of seconds until | |
| | | // the next time the read cache is rotated, if we're | |
| | | // using an explicit read read cache. | |
| | | int m_cache_rotation_timer; | |
| | | | |
| // statistics gathered from all torrents. | | // statistics gathered from all torrents. | |
| stat m_stat; | | stat m_stat; | |
| | | | |
|
| | | int m_peak_up_rate; | |
| | | int m_peak_down_rate; | |
| | | | |
| // is false by default and set to true when | | // is false by default and set to true when | |
| // the first incoming connection is established | | // the first incoming connection is established | |
| // this is used to know if the client is behind | | // this is used to know if the client is behind | |
| // NAT or not. | | // NAT or not. | |
| bool m_incoming_connection; | | bool m_incoming_connection; | |
| | | | |
| void on_disk_queue(); | | void on_disk_queue(); | |
| void on_tick(error_code const& e); | | void on_tick(error_code const& e); | |
| | | | |
|
| int auto_manage_torrents(std::vector<torrent*>& list | | void auto_manage_torrents(std::vector<torrent*>& lis | |
| , int hard_limit, int type_limit); | | t | |
| | | , int& dht_limit, int& tracker_limit, int& l | |
| | | sd_limit | |
| | | , int& hard_limit, int type_limit); | |
| void recalculate_auto_managed_torrents(); | | void recalculate_auto_managed_torrents(); | |
| void recalculate_unchoke_slots(int congested_torrent
s | | void recalculate_unchoke_slots(int congested_torrent
s | |
| , int uncongested_torrents); | | , int uncongested_torrents); | |
|
| void recalculate_optimistic_unchoke_slot(); | | void recalculate_optimistic_unchoke_slots(); | |
| | | | |
| ptime m_created; | | ptime m_created; | |
| int session_time() const { return total_seconds(time
_now() - m_created); } | | int session_time() const { return total_seconds(time
_now() - m_created); } | |
| | | | |
| ptime m_last_tick; | | ptime m_last_tick; | |
| ptime m_last_second_tick; | | ptime m_last_second_tick; | |
|
| | | // used to limit how often disk warnings are generat | |
| | | ed | |
| | | ptime m_last_disk_performance_warning; | |
| | | ptime m_last_disk_queue_performance_warning; | |
| | | | |
| // the last time we went through the peers | | // the last time we went through the peers | |
| // to decide which ones to choke/unchoke | | // to decide which ones to choke/unchoke | |
| ptime m_last_choke; | | ptime m_last_choke; | |
| | | | |
|
| | | // the time when the next rss feed needs updating | |
| | | ptime m_next_rss_update; | |
| | | | |
| | | // update any rss feeds that need updating and | |
| | | // recalculate m_next_rss_update | |
| | | void update_rss_feeds(); | |
| | | | |
| // when outgoing_ports is configured, this is the | | // when outgoing_ports is configured, this is the | |
| // port we'll bind the next outgoing socket to | | // port we'll bind the next outgoing socket to | |
| int m_next_port; | | int m_next_port; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| boost::intrusive_ptr<dht::dht_tracker> m_dht; | | boost::intrusive_ptr<dht::dht_tracker> m_dht; | |
| dht_settings m_dht_settings; | | dht_settings m_dht_settings; | |
|
| // if this is set to true, the dht listen port | | | |
| // will be set to the same as the tcp listen port | | | |
| // and will be synchronlized with it as it changes | | | |
| // it defaults to true | | | |
| bool m_dht_same_port; | | | |
| | | | |
| // see m_external_listen_port. This is the same | | | |
| // but for the udp port used by the DHT. | | | |
| int m_external_udp_port; | | | |
| | | | |
| boost::intrusive_ptr<rate_limited_udp_socket> m_dht_ | | | |
| socket; | | | |
| | | | |
| // these are used when starting the DHT | | // these are used when starting the DHT | |
| // (and bootstrapping it), and then erased | | // (and bootstrapping it), and then erased | |
| std::list<udp::endpoint> m_dht_router_nodes; | | std::list<udp::endpoint> m_dht_router_nodes; | |
| | | | |
|
| | | // this announce timer is used | |
| | | // by the DHT. | |
| | | deadline_timer m_dht_announce_timer; | |
| | | #endif | |
| | | | |
| void on_receive_udp(error_code const& e | | void on_receive_udp(error_code const& e | |
| , udp::endpoint const& ep, char const* buf,
int len); | | , udp::endpoint const& ep, char const* buf,
int len); | |
|
| #endif | | | |
| | | void on_receive_udp_hostname(error_code const& e | |
| | | , char const* hostname, char const* buf, int | |
| | | len); | |
| | | | |
| | | // see m_external_listen_port. This is the same | |
| | | // but for the udp port used by the DHT. | |
| | | int m_external_udp_port; | |
| | | | |
| | | rate_limited_udp_socket m_udp_socket; | |
| | | | |
| | | utp_socket_manager m_utp_socket_manager; | |
| | | | |
| | | // the number of torrent connection boosts | |
| | | // connections that have been made this second | |
| | | // this is deducted from the connect speed | |
| | | int m_boost_connections; | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| pe_settings m_pe_settings; | | pe_settings m_pe_settings; | |
| #endif | | #endif | |
| | | | |
| boost::intrusive_ptr<natpmp> m_natpmp; | | boost::intrusive_ptr<natpmp> m_natpmp; | |
| boost::intrusive_ptr<upnp> m_upnp; | | boost::intrusive_ptr<upnp> m_upnp; | |
| boost::intrusive_ptr<lsd> m_lsd; | | boost::intrusive_ptr<lsd> m_lsd; | |
| | | | |
|
| | | // mask is a bitmask of which protocols to remap on: | |
| | | // 1: NAT-PMP | |
| | | // 2: UPnP | |
| | | void remap_tcp_ports(boost::uint32_t mask, int tcp_p | |
| | | ort, int ssl_port); | |
| | | | |
| // 0 is natpmp 1 is upnp | | // 0 is natpmp 1 is upnp | |
| int m_tcp_mapping[2]; | | int m_tcp_mapping[2]; | |
| int m_udp_mapping[2]; | | int m_udp_mapping[2]; | |
|
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | int m_ssl_mapping[2]; | |
| | | #endif | |
| | | | |
| // the timer used to fire the tick | | // the timer used to fire the tick | |
| deadline_timer m_timer; | | deadline_timer m_timer; | |
| | | | |
| // torrents are announced on the local network in a | | // torrents are announced on the local network in a | |
| // round-robin fashion. All torrents are cycled thro
ugh | | // round-robin fashion. All torrents are cycled thro
ugh | |
| // within the LSD announce interval (which defaults
to | | // within the LSD announce interval (which defaults
to | |
| // 5 minutes) | | // 5 minutes) | |
| torrent_map::iterator m_next_lsd_torrent; | | torrent_map::iterator m_next_lsd_torrent; | |
| | | | |
|
| | | #ifndef TORRENT_DISABLE_DHT | |
| | | // torrents are announced on the DHT in a | |
| | | // round-robin fashion. All torrents are cycled thro | |
| | | ugh | |
| | | // within the DHT announce interval (which defaults | |
| | | to | |
| | | // 15 minutes) | |
| | | torrent_map::iterator m_next_dht_torrent; | |
| | | #endif | |
| | | | |
| // this announce timer is used | | // this announce timer is used | |
| // by Local service discovery | | // by Local service discovery | |
| deadline_timer m_lsd_announce_timer; | | deadline_timer m_lsd_announce_timer; | |
| | | | |
|
| | | tcp::resolver m_host_resolver; | |
| | | | |
| // the index of the torrent that will be offered to | | // the index of the torrent that will be offered to | |
| // connect to a peer next time on_tick is called. | | // connect to a peer next time on_tick is called. | |
| // This implements a round robin. | | // This implements a round robin. | |
| torrent_map::iterator m_next_connect_torrent; | | torrent_map::iterator m_next_connect_torrent; | |
|
| | | | |
| | | // this is the round-robin cursor for peers that | |
| | | // get to download again after the disk has been | |
| | | // blocked | |
| | | connection_map::iterator m_next_disk_peer; | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
|
| #if defined TORRENT_STATS && defined TORRENT_DISK_STATS | | #ifdef TORRENT_DISK_STATS | |
| void log_buffer_usage(); | | void log_buffer_usage(); | |
|
| #endif | | | |
| | | | |
| #if defined TORRENT_STATS | | | |
| // logger used to write bandwidth usage statistics | | | |
| std::ofstream m_stats_logger; | | | |
| int m_second_counter; | | | |
| // used to log send buffer usage statistics | | // used to log send buffer usage statistics | |
| std::ofstream m_buffer_usage_logger; | | std::ofstream m_buffer_usage_logger; | |
| // the number of send buffers that are allocated | | // the number of send buffers that are allocated | |
| int m_buffer_allocations; | | int m_buffer_allocations; | |
|
| | | #endif | |
| | | | |
| | | #ifdef TORRENT_REQUEST_LOGGING | |
| | | // used to log all requests from peers | |
| | | FILE* m_request_log; | |
| | | #endif | |
| | | | |
| | | #ifdef TORRENT_STATS | |
| | | void rotate_stats_log(); | |
| | | void print_log_line(int tick_interval_ms, ptime now) | |
| | | ; | |
| | | void reset_stat_counters(); | |
| | | void enable_stats_logging(bool s); | |
| | | | |
| | | bool m_stats_logging_enabled; | |
| | | | |
| | | // the last time we rotated the log file | |
| | | ptime m_last_log_rotation; | |
| | | | |
| | | // logger used to write bandwidth usage statistics | |
| | | FILE* m_stats_logger; | |
| | | // sequence number for log file. Log files are | |
| | | // rotated every hour and the sequence number is | |
| | | // incremented by one | |
| | | int m_log_seq; | |
| | | // the number of peers that were disconnected this | |
| | | // tick due to protocol error | |
| | | int m_error_peers; | |
| | | int m_disconnected_peers; | |
| | | int m_eof_peers; | |
| | | int m_connreset_peers; | |
| | | int m_connrefused_peers; | |
| | | int m_connaborted_peers; | |
| | | int m_perm_peers; | |
| | | int m_buffer_peers; | |
| | | int m_unreachable_peers; | |
| | | int m_broken_pipe_peers; | |
| | | int m_addrinuse_peers; | |
| | | int m_no_access_peers; | |
| | | int m_invalid_arg_peers; | |
| | | int m_aborted_peers; | |
| | | | |
|
| | | int m_piece_requests; | |
| | | int m_max_piece_requests; | |
| | | int m_invalid_piece_requests; | |
| | | int m_choked_piece_requests; | |
| | | int m_cancelled_piece_requests; | |
| | | int m_piece_rejects; | |
| | | | |
| | | int m_error_incoming_peers; | |
| | | int m_error_outgoing_peers; | |
| | | int m_error_rc4_peers; | |
| | | int m_error_encrypted_peers; | |
| | | int m_error_tcp_peers; | |
| | | int m_error_utp_peers; | |
| | | // the number of times the piece picker fell through | |
| | | // to the end-game mode | |
| | | int m_end_game_piece_picker_blocks; | |
| | | int m_piece_picker_blocks; | |
| | | int m_piece_picks; | |
| | | int m_reject_piece_picks; | |
| | | int m_unchoke_piece_picks; | |
| | | int m_incoming_redundant_piece_picks; | |
| | | int m_incoming_piece_picks; | |
| | | int m_end_game_piece_picks; | |
| | | int m_snubbed_piece_picks; | |
| | | int m_connect_timeouts; | |
| | | int m_uninteresting_peers; | |
| | | int m_timeout_peers; | |
| | | int m_no_memory_peers; | |
| | | int m_too_many_peers; | |
| | | int m_transport_timeout_peers; | |
| | | cache_status m_last_cache_status; | |
| | | size_type m_last_failed; | |
| | | size_type m_last_redundant; | |
| | | size_type m_last_uploaded; | |
| | | size_type m_last_downloaded; | |
| | | int m_connection_attempts; | |
| | | int m_num_banned_peers; | |
| | | int m_banned_for_hash_failure; | |
| | | vm_statistics_data_t m_last_vm_stat; | |
| | | thread_cpu_usage m_network_thread_cpu_usage; | |
| | | sliding_average<20> m_read_ops; | |
| | | sliding_average<20> m_write_ops;; | |
| enum | | enum | |
| { | | { | |
| on_read_counter, | | on_read_counter, | |
| on_write_counter, | | on_write_counter, | |
| on_tick_counter, | | on_tick_counter, | |
| on_lsd_counter, | | on_lsd_counter, | |
| on_lsd_peer_counter, | | on_lsd_peer_counter, | |
| on_udp_counter, | | on_udp_counter, | |
| on_accept_counter, | | on_accept_counter, | |
| on_disk_queue_counter, | | on_disk_queue_counter, | |
| on_disk_read_counter, | | on_disk_read_counter, | |
| on_disk_write_counter, | | on_disk_write_counter, | |
| max_messages | | max_messages | |
| }; | | }; | |
| int m_num_messages[max_messages]; | | int m_num_messages[max_messages]; | |
| // 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8
192, | | // 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8
192, | |
| // 16384, 32768, 65536, 131072, 262144, 524288, 1048
576 | | // 16384, 32768, 65536, 131072, 262144, 524288, 1048
576 | |
| int m_send_buffer_sizes[18]; | | int m_send_buffer_sizes[18]; | |
| int m_recv_buffer_sizes[18]; | | int m_recv_buffer_sizes[18]; | |
| #endif | | #endif | |
|
| | | | |
| | | // each second tick the timer takes a little | |
| | | // bit longer than one second to trigger. The | |
| | | // extra time it took is accumulated into this | |
| | | // counter. Every time it exceeds 1000, torrents | |
| | | // will tick their timers 2 seconds instead of one. | |
| | | // this keeps the timers more accurate over time | |
| | | // as a kind of "leap second" to adjust for the | |
| | | // accumulated error | |
| | | boost::uint16_t m_tick_residual; | |
| | | | |
| | | // the number of torrents that have apply_ip_filter | |
| | | // set to false. This is typically 0 | |
| | | int m_non_filtered_torrents; | |
| | | | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| boost::shared_ptr<logger> create_log(std::string con
st& name | | boost::shared_ptr<logger> create_log(std::string con
st& name | |
| , int instance, bool append = true); | | , int instance, bool append = true); | |
| | | | |
| // this list of tracker loggers serves as tracker_ca
llbacks when | | // this list of tracker loggers serves as tracker_ca
llbacks when | |
| // shutting down. This list is just here to keep the
m alive during | | // shutting down. This list is just here to keep the
m alive during | |
| // whe shutting down process | | // whe shutting down process | |
| std::list<boost::shared_ptr<tracker_logger> > m_trac
ker_loggers; | | std::list<boost::shared_ptr<tracker_logger> > m_trac
ker_loggers; | |
| | | | |
|
| fs::path m_logpath; | | std::string m_logpath; | |
| public: | | | |
| boost::shared_ptr<logger> m_logger; | | | |
| private: | | private: | |
| | | | |
| #endif | | #endif | |
| #ifdef TORRENT_UPNP_LOGGING | | #ifdef TORRENT_UPNP_LOGGING | |
| std::ofstream m_upnp_log; | | std::ofstream m_upnp_log; | |
| #endif | | #endif | |
|
| | | struct external_ip_t | |
| | | { | |
| | | external_ip_t(): sources(0), num_votes(0) {} | |
| | | | |
| | | bool add_vote(sha1_hash const& k, int type); | |
| | | bool operator<(external_ip_t const& rhs) con | |
| | | st | |
| | | { | |
| | | if (num_votes < rhs.num_votes) retur | |
| | | n true; | |
| | | if (num_votes > rhs.num_votes) retur | |
| | | n false; | |
| | | return sources < rhs.sources; | |
| | | } | |
| | | | |
| | | // this is a bloom filter of the IPs that ha | |
| | | ve | |
| | | // reported this address | |
| | | bloom_filter<16> voters; | |
| | | // this is the actual external address | |
| | | address addr; | |
| | | // a bitmask of sources the reporters have c | |
| | | ome from | |
| | | boost::uint16_t sources; | |
| | | // the total number of votes for this IP | |
| | | boost::uint16_t num_votes; | |
| | | }; | |
| | | | |
| | | // this is a bloom filter of all the IPs that have | |
| | | // been the first to report an external address. Eac | |
| | | h | |
| | | // IP only gets to add a new item once. | |
| | | bloom_filter<32> m_external_address_voters; | |
| | | std::vector<external_ip_t> m_external_addresses; | |
| address m_external_address; | | address m_external_address; | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| typedef std::list<boost::function<boost::shared_ptr< | | typedef std::list<boost::function<boost::shared_ptr< | |
| torrent_plugin>(torrent*, void*)> > extensio
n_list_t; | | torrent_plugin>(torrent*, void*)> > extensio
n_list_t; | |
| | | | |
| extension_list_t m_extensions; | | extension_list_t m_extensions; | |
|
| | | | |
| | | typedef std::list<boost::shared_ptr<plugin> > ses_ex | |
| | | tension_list_t; | |
| | | ses_extension_list_t m_ses_extensions; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| GeoIP* m_asnum_db; | | GeoIP* m_asnum_db; | |
| GeoIP* m_country_db; | | GeoIP* m_country_db; | |
| | | | |
| // maps AS number to the peak download rate | | // maps AS number to the peak download rate | |
| // we've seen from it. Entries are never removed | | // we've seen from it. Entries are never removed | |
| // from this map. Pointers to its elements | | // from this map. Pointers to its elements | |
| // are kept in the policy::peer structures. | | // are kept in the policy::peer structures. | |
| std::map<int, int> m_as_peak; | | std::map<int, int> m_as_peak; | |
| #endif | | #endif | |
| | | | |
| // total redundant and failed bytes | | // total redundant and failed bytes | |
| size_type m_total_failed_bytes; | | size_type m_total_failed_bytes; | |
| size_type m_total_redundant_bytes; | | size_type m_total_redundant_bytes; | |
| | | | |
|
| | | // redundant bytes per category | |
| | | size_type m_redundant_bytes[7]; | |
| | | | |
| | | std::vector<boost::shared_ptr<feed> > m_feeds; | |
| | | | |
| | | // this is the set of (subscribed) torrents that hav | |
| | | e changed | |
| | | // their states since the last time the user request | |
| | | ed updates. | |
| | | std::vector<boost::weak_ptr<torrent> > m_state_updat | |
| | | es; | |
| | | | |
| // the main working thread | | // the main working thread | |
|
| boost::scoped_ptr<boost::thread> m_thread; | | boost::scoped_ptr<thread> m_thread; | |
| | | | |
| | | #if (defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS) && defined BOOST_HAS | |
| | | _PTHREADS | |
| | | pthread_t m_network_thread; | |
| | | #endif | |
| }; | | }; | |
| | | | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| struct tracker_logger : request_callback | | struct tracker_logger : request_callback | |
| { | | { | |
| tracker_logger(session_impl& ses): m_ses(ses) {} | | tracker_logger(session_impl& ses): m_ses(ses) {} | |
| void tracker_warning(tracker_request const& req | | void tracker_warning(tracker_request const& req | |
| , std::string const& str) | | , std::string const& str) | |
| { | | { | |
| debug_log("*** tracker warning: " + str); | | debug_log("*** tracker warning: " + str); | |
| } | | } | |
| | | | |
| void tracker_response(tracker_request const& | | void tracker_response(tracker_request const& | |
| , libtorrent::address const& tracker_ip | | , libtorrent::address const& tracker_ip | |
| , std::list<address> const& ip_list | | , std::list<address> const& ip_list | |
| , std::vector<peer_entry>& peers | | , std::vector<peer_entry>& peers | |
| , int interval | | , int interval | |
| , int min_interval | | , int min_interval | |
| , int complete | | , int complete | |
| , int incomplete | | , int incomplete | |
|
| , address const& external_ip) | | , address const& external_ip | |
| | | , std::string const& tracker_id) | |
| { | | { | |
| std::string s; | | std::string s; | |
| s = "TRACKER RESPONSE:\n"; | | s = "TRACKER RESPONSE:\n"; | |
| char tmp[200]; | | char tmp[200]; | |
| snprintf(tmp, 200, "interval: %d\nmin_interv
al: %d\npeers:\n", interval, min_interval); | | snprintf(tmp, 200, "interval: %d\nmin_interv
al: %d\npeers:\n", interval, min_interval); | |
| s += tmp; | | s += tmp; | |
| for (std::vector<peer_entry>::const_iterator
i = peers.begin(); | | for (std::vector<peer_entry>::const_iterator
i = peers.begin(); | |
| i != peers.end(); ++i) | | i != peers.end(); ++i) | |
| { | | { | |
| char pid[41]; | | char pid[41]; | |
| | | | |
| skipping to change at line 834 | | skipping to change at line 1192 | |
| s += tmp; | | s += tmp; | |
| debug_log(s); | | debug_log(s); | |
| } | | } | |
| | | | |
| void tracker_request_timed_out( | | void tracker_request_timed_out( | |
| tracker_request const&) | | tracker_request const&) | |
| { | | { | |
| debug_log("*** tracker timed out"); | | debug_log("*** tracker timed out"); | |
| } | | } | |
| | | | |
|
| void tracker_request_error( | | void tracker_request_error(tracker_request const& r | |
| tracker_request const& | | , int response_code, error_code const& ec, c | |
| , int response_code | | onst std::string& str | |
| , const std::string& str | | | |
| , int retry_interval) | | , int retry_interval) | |
| { | | { | |
| char msg[256]; | | char msg[256]; | |
|
| snprintf(msg, sizeof(msg), "*** tracker erro | | snprintf(msg, sizeof(msg), "*** tracker erro | |
| r: %d: %s", response_code, str.c_str()); | | r: %d: %s %s" | |
| | | , response_code, ec.message().c_str( | |
| | | ), str.c_str()); | |
| debug_log(msg); | | debug_log(msg); | |
| } | | } | |
| | | | |
| void debug_log(const std::string& line) | | void debug_log(const std::string& line) | |
| { | | { | |
| (*m_ses.m_logger) << time_now_string() << "
" << line << "\n"; | | (*m_ses.m_logger) << time_now_string() << "
" << line << "\n"; | |
| } | | } | |
| session_impl& m_ses; | | session_impl& m_ses; | |
| }; | | }; | |
| #endif | | #endif | |
| | | | |
End of changes. 100 change blocks. |
| 161 lines changed or deleted | | 557 lines changed or added | |
|
| session_settings.hpp | | session_settings.hpp | |
| | | | |
| skipping to change at line 38 | | skipping to change at line 38 | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_SESSION_SETTINGS_HPP_INCLUDED | | #ifndef TORRENT_SESSION_SETTINGS_HPP_INCLUDED | |
| #define TORRENT_SESSION_SETTINGS_HPP_INCLUDED | | #define TORRENT_SESSION_SETTINGS_HPP_INCLUDED | |
| | | | |
| #include "libtorrent/version.hpp" | | #include "libtorrent/version.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
|
| | | #include "libtorrent/version.hpp" | |
| | | | |
| | | #include <string> | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| | | | |
| struct TORRENT_EXPORT proxy_settings | | struct TORRENT_EXPORT proxy_settings | |
| { | | { | |
|
| proxy_settings() : port(0), type(none) {} | | proxy_settings() : port(0), type(none) | |
| | | , proxy_hostnames(true) | |
| | | , proxy_peer_connections(true) | |
| | | {} | |
| | | | |
| std::string hostname; | | std::string hostname; | |
| int port; | | int port; | |
| | | | |
| std::string username; | | std::string username; | |
| std::string password; | | std::string password; | |
| | | | |
| enum proxy_type | | enum proxy_type | |
| { | | { | |
| // a plain tcp socket is used, and | | // a plain tcp socket is used, and | |
| | | | |
| skipping to change at line 74 | | skipping to change at line 80 | |
| // connect to the proxy. the username | | // connect to the proxy. the username | |
| // and password are used to authenticate | | // and password are used to authenticate | |
| // with the proxy server. | | // with the proxy server. | |
| socks5_pw, | | socks5_pw, | |
| // the http proxy is only available for | | // the http proxy is only available for | |
| // tracker and web seed traffic | | // tracker and web seed traffic | |
| // assumes anonymous access to proxy | | // assumes anonymous access to proxy | |
| http, | | http, | |
| // http proxy with basic authentication | | // http proxy with basic authentication | |
| // uses username and password | | // uses username and password | |
|
| http_pw | | http_pw, | |
| | | // route through a i2p SAM proxy | |
| | | i2p_proxy | |
| }; | | }; | |
| | | | |
| proxy_type type; | | proxy_type type; | |
| | | | |
|
| | | // when set to true, hostname are resolved | |
| | | // through the proxy (if supported) | |
| | | bool proxy_hostnames; | |
| | | | |
| | | // if true, use this proxy for peers too | |
| | | bool proxy_peer_connections; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT session_settings | | struct TORRENT_EXPORT session_settings | |
| { | | { | |
| session_settings(std::string const& user_agent_ = "libtorren
t/" | | session_settings(std::string const& user_agent_ = "libtorren
t/" | |
|
| LIBTORRENT_VERSION) | | LIBTORRENT_VERSION); | |
| : user_agent(user_agent_) | | ~session_settings(); | |
| , tracker_completion_timeout(60) | | | |
| , tracker_receive_timeout(40) | | // libtorrent version. Used for forward binary compatibility | |
| , stop_tracker_timeout(5) | | int version; | |
| , tracker_maximum_response_length(1024*1024) | | | |
| , piece_timeout(20) | | | |
| , request_timeout(50) | | | |
| , request_queue_time(3) | | | |
| , max_allowed_in_request_queue(250) | | | |
| , max_out_request_queue(200) | | | |
| , whole_pieces_threshold(20) | | | |
| , peer_timeout(120) | | | |
| , urlseed_timeout(20) | | | |
| , urlseed_pipeline_size(5) | | | |
| , urlseed_wait_retry(30) | | | |
| , file_pool_size(40) | | | |
| , allow_multiple_connections_per_ip(false) | | | |
| , max_failcount(3) | | | |
| , min_reconnect_time(60) | | | |
| , peer_connect_timeout(7) | | | |
| , ignore_limits_on_local_network(true) | | | |
| , connection_speed(10) | | | |
| , send_redundant_have(false) | | | |
| , lazy_bitfields(true) | | | |
| , inactivity_timeout(600) | | | |
| , unchoke_interval(15) | | | |
| , optimistic_unchoke_interval(30) | | | |
| , num_want(200) | | | |
| , initial_picker_threshold(4) | | | |
| , allowed_fast_set_size(10) | | | |
| , max_queued_disk_bytes(256 * 1024) | | | |
| , handshake_timeout(10) | | | |
| #ifndef TORRENT_DISABLE_DHT | | | |
| , use_dht_as_fallback(false) | | | |
| #endif | | | |
| , free_torrent_hashes(true) | | | |
| , upnp_ignore_nonrouters(false) | | | |
| , send_buffer_watermark(100 * 1024) | | | |
| , auto_upload_slots(true) | | | |
| , auto_upload_slots_rate_based(false) | | | |
| , use_parole_mode(true) | | | |
| , cache_size(1024) | | | |
| , cache_buffer_chunk_size(16) | | | |
| , cache_expiry(60) | | | |
| , use_read_cache(true) | | | |
| , disk_io_write_mode(0) | | | |
| , disk_io_read_mode(0) | | | |
| , coalesce_reads(false) | | | |
| , coalesce_writes(false) | | | |
| , outgoing_ports(0,0) | | | |
| , peer_tos(0) | | | |
| , active_downloads(8) | | | |
| , active_seeds(5) | | | |
| , active_limit(15) | | | |
| , auto_manage_prefer_seeds(false) | | | |
| , dont_count_slow_torrents(true) | | | |
| , auto_manage_interval(30) | | | |
| , share_ratio_limit(2.f) | | | |
| , seed_time_ratio_limit(7.f) | | | |
| , seed_time_limit(24 * 60 * 60) // 24 hours | | | |
| , peer_turnover(2 / 50.f) | | | |
| , peer_turnover_cutoff(.9f) | | | |
| , close_redundant_connections(true) | | | |
| , auto_scrape_interval(1800) | | | |
| , auto_scrape_min_interval(300) | | | |
| , max_peerlist_size(4000) | | | |
| , max_paused_peerlist_size(4000) | | | |
| , min_announce_interval(5 * 60) | | | |
| , prioritize_partial_pieces(false) | | | |
| , auto_manage_startup(120) | | | |
| , rate_limit_ip_overhead(true) | | | |
| , announce_to_all_trackers(false) | | | |
| , announce_to_all_tiers(false) | | | |
| , prefer_udp_trackers(true) | | | |
| , strict_super_seeding(false) | | | |
| , seeding_piece_quota(20) | | | |
| #ifdef TORRENT_WINDOWS | | | |
| , max_sparse_regions(30000) | | | |
| #else | | | |
| , max_sparse_regions(0) | | | |
| #endif | | | |
| #ifndef TORRENT_DISABLE_MLOCK | | | |
| , lock_disk_cache(false) | | | |
| #endif | | | |
| , max_rejects(50) | | | |
| , recv_socket_buffer_size(0) | | | |
| , send_socket_buffer_size(0) | | | |
| , optimize_hashing_for_speed(true) | | | |
| , file_checks_delay_per_block(0) | | | |
| , disk_cache_algorithm(largest_contiguous) | | | |
| , read_cache_line_size(16) | | | |
| , write_cache_line_size(32) | | | |
| , optimistic_disk_retry(10 * 60) | | | |
| , disable_hash_checks(false) | | | |
| , allow_reordered_disk_operations(true) | | | |
| , max_suggest_pieces(10) | | | |
| , drop_skipped_requests(false) | | | |
| , low_prio_disk(true) | | | |
| , local_service_announce_interval(5 * 60) | | | |
| , udp_tracker_token_expiry(60) | | | |
| , report_true_downloaded(false) | | | |
| , strict_end_game_mode(true) | | | |
| , broadcast_lsd(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 | |
| // when doing requests. It is used to identify the client. | | // when doing requests. It is used to identify the client. | |
| // It cannot contain \r or \n | | // It cannot contain \r or \n | |
| std::string user_agent; | | std::string user_agent; | |
| | | | |
| // the number of seconds to wait until giving up on a | | // the number of seconds to wait until giving up on a | |
| // tracker request if it hasn't finished | | // tracker request if it hasn't finished | |
| int tracker_completion_timeout; | | int tracker_completion_timeout; | |
| | | | |
| | | | |
| skipping to change at line 331 | | skipping to change at line 245 | |
| | | | |
| // the number of seconds between chokes/unchokes | | // the number of seconds between chokes/unchokes | |
| int unchoke_interval; | | int unchoke_interval; | |
| | | | |
| // the number of seconds between | | // the number of seconds between | |
| // optimistic unchokes | | // optimistic unchokes | |
| int optimistic_unchoke_interval; | | int optimistic_unchoke_interval; | |
| | | | |
| // if this is set, this IP will be reported do the | | // if this is set, this IP will be reported do the | |
| // tracker in the ip= parameter. | | // tracker in the ip= parameter. | |
|
| address announce_ip; | | std::string announce_ip; | |
| | | | |
| // the num want sent to trackers | | // the num want sent to trackers | |
| int num_want; | | int num_want; | |
| | | | |
| // while we have fewer pieces than this, pick | | // while we have fewer pieces than this, pick | |
| // random pieces instead of rarest first. | | // random pieces instead of rarest first. | |
| int initial_picker_threshold; | | int initial_picker_threshold; | |
| | | | |
| // the number of allowed pieces to send to peers | | // the number of allowed pieces to send to peers | |
| // that supports the fast extensions | | // that supports the fast extensions | |
| int allowed_fast_set_size; | | int allowed_fast_set_size; | |
| | | | |
|
| | | // this determines which pieces will be suggested to peers | |
| | | // suggest read cache will make libtorrent suggest pieces | |
| | | // that are fresh in the disk read cache, to potentially | |
| | | // lower disk access and increase the cache hit ratio | |
| | | enum { no_piece_suggestions = 0, suggest_read_cache = 1 }; | |
| | | int suggest_mode; | |
| | | | |
| // the maximum number of bytes a connection may have | | // the maximum number of bytes a connection may have | |
| // pending in the disk write queue before its download | | // pending in the disk write queue before its download | |
| // rate is being throttled. This prevents fast downloads | | // rate is being throttled. This prevents fast downloads | |
| // to slow medias to allocate more and more memory | | // to slow medias to allocate more and more memory | |
| // indefinitely. This should be set to at least 16 kB | | // indefinitely. This should be set to at least 16 kB | |
| // to not completely disrupt normal downloads. If it's | | // to not completely disrupt normal downloads. If it's | |
| // set to 0, you will be starving the disk thread and | | // set to 0, you will be starving the disk thread and | |
| // nothing will be written to disk. | | // nothing will be written to disk. | |
| // this is a per session setting. | | // this is a per session setting. | |
| int max_queued_disk_bytes; | | int max_queued_disk_bytes; | |
| | | | |
|
| | | // this is the low watermark for the disk buffer queue. | |
| | | // whenever the number of queued bytes exceed the | |
| | | // max_queued_disk_bytes, libtorrent will wait for | |
| | | // it to drop below this value before issuing more | |
| | | // reads from the sockets. If set to 0, the | |
| | | // low watermark will be half of the max queued disk bytes | |
| | | int max_queued_disk_bytes_low_watermark; | |
| | | | |
| // the number of seconds to wait for a handshake | | // the number of seconds to wait for a handshake | |
| // response from a peer. If no response is received | | // response from a peer. If no response is received | |
| // within this time, the peer is disconnected. | | // within this time, the peer is disconnected. | |
| int handshake_timeout; | | int handshake_timeout; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| // while this is true, the dht will not be used unless the | | // while this is true, the dht will not be used unless the | |
| // tracker is online | | // tracker is online | |
| bool use_dht_as_fallback; | | bool use_dht_as_fallback; | |
| #endif | | #endif | |
| | | | |
| skipping to change at line 377 | | skipping to change at line 306 | |
| // to save memory, once the torrent is seeding. This will | | // to save memory, once the torrent is seeding. This will | |
| // make the get_torrent_info() function to return an incompl
ete | | // make the get_torrent_info() function to return an incompl
ete | |
| // torrent object that cannot be passed back to add_torrent(
) | | // torrent object that cannot be passed back to add_torrent(
) | |
| bool free_torrent_hashes; | | bool free_torrent_hashes; | |
| | | | |
| // when this is true, the upnp port mapper will ignore | | // when this is true, the upnp port mapper will ignore | |
| // any upnp devices that don't have an address that matches | | // any upnp devices that don't have an address that matches | |
| // our currently configured router. | | // our currently configured router. | |
| bool upnp_ignore_nonrouters; | | bool upnp_ignore_nonrouters; | |
| | | | |
|
| | | // This is the minimum send buffer target size (send buffer | |
| | | // includes bytes pending being read from disk). For good | |
| | | // and snappy seeding performance, set this fairly high, to | |
| | | // at least fit a few blocks. This is essentially the initia | |
| | | l | |
| | | // window size which will determine how fast we can ramp up | |
| | | // the send rate | |
| | | int send_buffer_low_watermark; | |
| | | | |
| // if the send buffer has fewer bytes than this, we'll | | // if the send buffer has fewer bytes than this, we'll | |
| // read another 16kB block onto it. If set too small, | | // read another 16kB block onto it. If set too small, | |
| // upload rate capacity will suffer. If set too high, | | // upload rate capacity will suffer. If set too high, | |
| // memory will be wasted. | | // memory will be wasted. | |
| // The actual watermark may be lower than this in case | | // The actual watermark may be lower than this in case | |
| // the upload rate is low, this is the upper limit. | | // the upload rate is low, this is the upper limit. | |
| int send_buffer_watermark; | | int send_buffer_watermark; | |
| | | | |
|
| // if auto_upload_slots is true, and a global upload | | // the current upload rate to a peer is multiplied by | |
| // limit is set and the upload rate is less than 90% | | // this factor to get the send buffer watermark. The | |
| // of the upload limit, on new slot is opened up. If | | // factor is specified as a percentage. i.e. 50 -> 0.5 | |
| // the upload rate is >= upload limit for an extended | | // This product is clamped to the send_buffer_watermark | |
| // period of time, one upload slot is closed. The | | // setting to not exceed the max. For high speed | |
| // upload slots are never automatically decreased below | | // upload, this should be set to a greater value than | |
| // the manual settings, through max_uploads. | | // 100. The default is 50. | |
| bool auto_upload_slots; | | int send_buffer_watermark_factor; | |
| | | | |
|
| // this only affects the auto upload slots mechanism. | | #ifndef TORRENT_NO_DEPRECATE | |
| // if auto_upload_slots is false, this field is not | | // deprecated in 0.16 | |
| // considered. | | bool auto_upload_slots; | |
| bool auto_upload_slots_rate_based; | | bool auto_upload_slots_rate_based; | |
|
| | | #endif | |
| | | | |
| | | enum choking_algorithm_t | |
| | | { | |
| | | fixed_slots_choker, | |
| | | auto_expand_choker, | |
| | | rate_based_choker, | |
| | | bittyrant_choker | |
| | | }; | |
| | | | |
| | | int choking_algorithm; | |
| | | | |
| | | enum seed_choking_algorithm_t | |
| | | { | |
| | | round_robin, | |
| | | fastest_upload, | |
| | | anti_leech | |
| | | }; | |
| | | | |
| | | // the choking algorithm to use for seeding torrents | |
| | | int seed_choking_algorithm; | |
| | | | |
| // if set to true, peers that participate in a failing | | // if set to true, peers that participate in a failing | |
| // piece is put in parole mode. i.e. They will only | | // piece is put in parole mode. i.e. They will only | |
| // download whole pieces until they either fail or pass. | | // download whole pieces until they either fail or pass. | |
| // they are taken out of parole mode as soon as they | | // they are taken out of parole mode as soon as they | |
| // participate in a piece that passes. | | // participate in a piece that passes. | |
| bool use_parole_mode; | | bool use_parole_mode; | |
| | | | |
| // the disk write cache, specified in 16 KiB blocks. | | // the disk write cache, specified in 16 KiB blocks. | |
| // default is 1024 (= 16 MiB). -1 means automatic, which | | // default is 1024 (= 16 MiB). -1 means automatic, which | |
| | | | |
| skipping to change at line 420 | | skipping to change at line 378 | |
| int cache_size; | | int cache_size; | |
| | | | |
| // this is the number of disk buffer blocks (16 kiB) | | // this is the number of disk buffer blocks (16 kiB) | |
| // that should be allocated at a time. It must be | | // that should be allocated at a time. It must be | |
| // at least 1. Lower number saves memory at the expense | | // at least 1. Lower number saves memory at the expense | |
| // of more heap allocations | | // of more heap allocations | |
| int cache_buffer_chunk_size; | | int cache_buffer_chunk_size; | |
| | | | |
| // the number of seconds a write cache entry sits | | // the number of seconds a write cache entry sits | |
| // idle in the cache before it's forcefully flushed | | // idle in the cache before it's forcefully flushed | |
|
| // to disk. Default is 60 seconds. | | // to disk. Default is 5 minutes. | |
| int cache_expiry; | | int cache_expiry; | |
| | | | |
| // when true, the disk I/O thread uses the disk | | // when true, the disk I/O thread uses the disk | |
| // cache for caching blocks read from disk too | | // cache for caching blocks read from disk too | |
| bool use_read_cache; | | bool use_read_cache; | |
| | | | |
|
| | | // don't implicitly cache pieces in the read cache, | |
| | | // only cache pieces that are explicitly asked to be | |
| | | // cached. | |
| | | bool explicit_read_cache; | |
| | | | |
| | | // the number of seconds between refreshes of | |
| | | // explicit caches | |
| | | int explicit_cache_interval; | |
| | | | |
| enum io_buffer_mode_t | | enum io_buffer_mode_t | |
| { | | { | |
| enable_os_cache = 0, | | enable_os_cache = 0, | |
| disable_os_cache_for_aligned_files = 1, | | disable_os_cache_for_aligned_files = 1, | |
| disable_os_cache = 2 | | disable_os_cache = 2 | |
| }; | | }; | |
| int disk_io_write_mode; | | int disk_io_write_mode; | |
| int disk_io_read_mode; | | int disk_io_read_mode; | |
| | | | |
| bool coalesce_reads; | | bool coalesce_reads; | |
| | | | |
| skipping to change at line 456 | | skipping to change at line 423 | |
| // web seeds) is set to this value. The default | | // web seeds) is set to this value. The default | |
| // is the QBSS scavenger service | | // is the QBSS scavenger service | |
| // http://qbone.internet2.edu/qbss/ | | // http://qbone.internet2.edu/qbss/ | |
| // For unmarked packets, set to 0 | | // For unmarked packets, set to 0 | |
| char peer_tos; | | char peer_tos; | |
| | | | |
| // for auto managed torrents, these are the limits | | // for auto managed torrents, these are the limits | |
| // they are subject to. If there are too many torrents | | // they are subject to. If there are too many torrents | |
| // some of the auto managed ones will be paused until | | // some of the auto managed ones will be paused until | |
| // some slots free up. | | // some slots free up. | |
|
| | | // active_dht_limit and active_tracker_limit limits the | |
| | | // number of torrents that will be active on the DHT | |
| | | // versus the tracker. If the active limit is set higher | |
| | | // than these numbers, some torrents will be "active" in | |
| | | // the sense that they will accept incoming connections, | |
| | | // but not announce on the DHT or the tracker | |
| int active_downloads; | | int active_downloads; | |
| int active_seeds; | | int active_seeds; | |
|
| | | int active_dht_limit; | |
| | | int active_tracker_limit; | |
| | | int active_lsd_limit; | |
| int active_limit; | | int active_limit; | |
| | | | |
| // prefer seeding torrents when determining which torrents t
o give | | // prefer seeding torrents when determining which torrents t
o give | |
| // active slots to, the default is false which gives prefere
nce to | | // active slots to, the default is false which gives prefere
nce to | |
| // downloading torrents | | // downloading torrents | |
| bool auto_manage_prefer_seeds; | | bool auto_manage_prefer_seeds; | |
| | | | |
| // if this is true, torrents that don't have any significant | | // if this is true, torrents that don't have any significant | |
| // transfers are not counted as active when determining whic
h | | // transfers are not counted as active when determining whic
h | |
| // auto managed torrents to pause and resume | | // auto managed torrents to pause and resume | |
| | | | |
| skipping to change at line 486 | | skipping to change at line 462 | |
| // (seconds as seed / seconds as downloader) or the seed | | // (seconds as seed / seconds as downloader) or the seed | |
| // time limit (seconds as seed) it is considered | | // time limit (seconds as seed) it is considered | |
| // done, and it will leave room for other torrents | | // done, and it will leave room for other torrents | |
| // the default value for share ratio is 2 | | // the default value for share ratio is 2 | |
| // the default seed time ratio is 7, because that's a common | | // the default seed time ratio is 7, because that's a common | |
| // asymmetry ratio on connections | | // asymmetry ratio on connections | |
| float share_ratio_limit; | | float share_ratio_limit; | |
| float seed_time_ratio_limit; | | float seed_time_ratio_limit; | |
| int seed_time_limit; | | int seed_time_limit; | |
| | | | |
|
| | | // the interval (in seconds) between optimistic disconnects | |
| | | // if the disconnects happen and how many peers are disconne | |
| | | cted | |
| | | // is controlled by peer_turnover and peer_turnover_cutoff | |
| | | int peer_turnover_interval; | |
| | | | |
| // the percentage of peers to disconnect every | | // the percentage of peers to disconnect every | |
|
| // 90 seconds (if we're at the peer limit) | | // turnoever interval (if we're at the peer limit) | |
| // defaults to 1/50:th | | // defaults to 2/50:th | |
| float peer_turnover; | | float peer_turnover; | |
| | | | |
| // when we are connected to more than | | // when we are connected to more than | |
| // limit * peer_turnover_cutoff peers | | // limit * peer_turnover_cutoff peers | |
| // disconnect peer_turnover fraction | | // disconnect peer_turnover fraction | |
| // of the peers | | // of the peers | |
| float peer_turnover_cutoff; | | float peer_turnover_cutoff; | |
| | | | |
| // if this is true (default) connections where both | | // if this is true (default) connections where both | |
| // ends have no utility in keeping the connection open | | // ends have no utility in keeping the connection open | |
| | | | |
| skipping to change at line 611 | | skipping to change at line 592 | |
| // delay between disk operations, to make it | | // delay between disk operations, to make it | |
| // less intrusive on the system as a whole | | // less intrusive on the system as a whole | |
| // blocking the disk. This delay is specified | | // blocking the disk. This delay is specified | |
| // in milliseconds and the delay will be this | | // in milliseconds and the delay will be this | |
| // long per 16kiB block | | // long per 16kiB block | |
| // the default of 10 ms/16kiB will limit | | // the default of 10 ms/16kiB will limit | |
| // the checking rate to 1.6 MiB per second | | // the checking rate to 1.6 MiB per second | |
| int file_checks_delay_per_block; | | int file_checks_delay_per_block; | |
| | | | |
| enum disk_cache_algo_t | | enum disk_cache_algo_t | |
|
| { lru, largest_contiguous }; | | { lru, largest_contiguous, avoid_readback }; | |
| | | | |
| disk_cache_algo_t disk_cache_algorithm; | | disk_cache_algo_t disk_cache_algorithm; | |
| | | | |
| // the number of blocks that will be read ahead | | // the number of blocks that will be read ahead | |
| // when reading a block into the read cache | | // when reading a block into the read cache | |
| int read_cache_line_size; | | int read_cache_line_size; | |
| | | | |
| // whenever a contiguous range of this many | | // whenever a contiguous range of this many | |
| // blocks is found in the write cache, it | | // blocks is found in the write cache, it | |
| // is flushed immediately | | // is flushed immediately | |
| | | | |
| skipping to change at line 646 | | skipping to change at line 627 | |
| // if this is true, disk read operations may | | // if this is true, disk read operations may | |
| // be re-ordered based on their physical disk | | // be re-ordered based on their physical disk | |
| // read offset. This greatly improves throughput | | // read offset. This greatly improves throughput | |
| // when uploading to many peers. This assumes | | // when uploading to many peers. This assumes | |
| // a traditional hard drive with a read head | | // a traditional hard drive with a read head | |
| // and spinning platters. If your storage medium | | // and spinning platters. If your storage medium | |
| // is a solid state drive, this optimization | | // is a solid state drive, this optimization | |
| // doesn't give you an benefits | | // doesn't give you an benefits | |
| bool allow_reordered_disk_operations; | | bool allow_reordered_disk_operations; | |
| | | | |
|
| | | // if this is true, i2p torrents are allowed | |
| | | // to also get peers from other sources than | |
| | | // the tracker, and connect to regular IPs, | |
| | | // not providing any anonymization. This may | |
| | | // be useful if the user is not interested in | |
| | | // the anonymization of i2p, but still wants to | |
| | | // be able to connect to i2p peers. | |
| | | bool allow_i2p_mixed; | |
| | | | |
| // the max number of pieces that a peer can | | // the max number of pieces that a peer can | |
| // suggest to use before we start dropping | | // suggest to use before we start dropping | |
| // previous suggested piece | | // previous suggested piece | |
| int max_suggest_pieces; | | int max_suggest_pieces; | |
| | | | |
| // if set to true, requests that have have not been | | // if set to true, requests that have have not been | |
| // satisfied after the equivalence of the entire | | // satisfied after the equivalence of the entire | |
| // request queue has been received, will be considered lost | | // request queue has been received, will be considered lost | |
| bool drop_skipped_requests; | | bool drop_skipped_requests; | |
| | | | |
| | | | |
| skipping to change at line 667 | | skipping to change at line 657 | |
| // run at lower-than-normal priority. This is | | // run at lower-than-normal priority. This is | |
| // intended to make the machine more responsive | | // intended to make the machine more responsive | |
| // to foreground tasks, while bittorrent runs | | // to foreground tasks, while bittorrent runs | |
| // in the background | | // in the background | |
| bool low_prio_disk; | | bool low_prio_disk; | |
| | | | |
| // number of seconds between local service announces for | | // number of seconds between local service announces for | |
| // torrents. Defaults to 5 minutes | | // torrents. Defaults to 5 minutes | |
| int local_service_announce_interval; | | int local_service_announce_interval; | |
| | | | |
|
| | | // number of seconds between DHT announces for | |
| | | // torrents. Defaults to 15 minutes | |
| | | int dht_announce_interval; | |
| | | | |
| // the number of seconds a connection ID received | | // the number of seconds a connection ID received | |
| // from a UDP tracker is valid for. This is specified | | // from a UDP tracker is valid for. This is specified | |
| // as 60 seconds | | // as 60 seconds | |
| int udp_tracker_token_expiry; | | int udp_tracker_token_expiry; | |
| | | | |
|
| | | // if this is set to true, any block read from the | |
| | | // disk cache will be dropped from the cache immediately | |
| | | // following. This may be useful if the block is not | |
| | | // expected to be hit again. It would save some memory | |
| | | bool volatile_read_cache; | |
| | | | |
| | | // if this is set to true, the size of the cache line | |
| | | // generated by a particular read request depends on the | |
| | | // rate you're sending to that peer. This optimizes the | |
| | | // memory usage of the disk read cache by reading | |
| | | // further ahead for peers that you're uploading at high | |
| | | // rates to | |
| | | bool guided_read_cache; | |
| | | | |
| | | // this is the default minimum time any read cache line | |
| | | // is kept in the cache. | |
| | | int default_cache_min_age; | |
| | | | |
| | | // the global number of optimistic unchokes | |
| | | // 0 means automatic | |
| | | int num_optimistic_unchoke_slots; | |
| | | | |
| | | // if set to true, files won't have their atime updated | |
| | | // on disk reads. This works on linux | |
| | | bool no_atime_storage; | |
| | | | |
| | | // === BitTyrant unchoker settings == | |
| | | | |
| | | // when using BitTyrant choker, this is the default | |
| | | // assumed reciprocation rate. This is where each peer start | |
| | | s | |
| | | int default_est_reciprocation_rate; | |
| | | | |
| | | // this is the increase of the estimated reciprocation rate | |
| | | // in percent. We increase by this amount once every unchoke | |
| | | // interval that we are choked by the other peer and we have | |
| | | // unchoked them | |
| | | int increase_est_reciprocation_rate; | |
| | | | |
| | | // each unchoke interval that we stay unchoked by the other | |
| | | // peer, and we have unchoked this peer as well, we decrease | |
| | | // our estimate of the reciprocation rate, since we might ha | |
| | | ve | |
| | | // over-estimated it | |
| | | int decrease_est_reciprocation_rate; | |
| | | | |
| | | // if set to true, an incoming connection to a torrent that' | |
| | | s | |
| | | // paused and auto-managed will make the torrent start. | |
| | | bool incoming_starts_queued_torrents; | |
| | | | |
| // when set to true, the downloaded counter sent to trackers | | // when set to true, the downloaded counter sent to trackers | |
| // will include the actual number of payload bytes donwnload
ed | | // will include the actual number of payload bytes donwnload
ed | |
| // including redundant bytes. If set to false, it will not i
nclude | | // including redundant bytes. If set to false, it will not i
nclude | |
| // any redundany bytes | | // any redundany bytes | |
| bool report_true_downloaded; | | bool report_true_downloaded; | |
| | | | |
| // if set to true, libtorrent won't request a piece multiple
times | | // if set to true, libtorrent won't request a piece multiple
times | |
| // until every piece is requested | | // until every piece is requested | |
| bool strict_end_game_mode; | | bool strict_end_game_mode; | |
| | | | |
| // if this is true, the broadcast socket will not only use I
P multicast | | // if this is true, the broadcast socket will not only use I
P multicast | |
| // but also send the messages on the broadcast address. This
is false by | | // but also send the messages on the broadcast address. This
is false by | |
| // default in order to avoid flooding networks for no good r
eason. If | | // default in order to avoid flooding networks for no good r
eason. If | |
| // a network is known not to support multicast, this can be
enabled | | // a network is known not to support multicast, this can be
enabled | |
| bool broadcast_lsd; | | bool broadcast_lsd; | |
|
| | | | |
| | | // when set to true, libtorrent will try to make outgoing ut | |
| | | p connections | |
| | | bool enable_outgoing_utp; | |
| | | | |
| | | // if set to false, libtorrent will reject incoming utp conn | |
| | | ections | |
| | | bool enable_incoming_utp; | |
| | | | |
| | | // when set to false, no outgoing TCP connections will be ma | |
| | | de | |
| | | bool enable_outgoing_tcp; | |
| | | | |
| | | // if set to false, libtorrent will reject incoming tcp conn | |
| | | ections | |
| | | bool enable_incoming_tcp; | |
| | | | |
| | | // the max number of peers we accept from pex messages from | |
| | | a single peer. | |
| | | // this limits the number of concurrent peers any of our pee | |
| | | rs claims to | |
| | | // be connected to. If they clain to be connected to more th | |
| | | an this, we'll | |
| | | // ignore any peer that exceeds this limit | |
| | | int max_pex_peers; | |
| | | | |
| | | // when set to true, the file modification time is ignored w | |
| | | hen loading | |
| | | // resume data. The resume data includes the expected timest | |
| | | amp of each | |
| | | // file and is typically compared to make sure the files hav | |
| | | en't changed | |
| | | // since the last session | |
| | | bool ignore_resume_timestamps; | |
| | | | |
| | | // normally, if a resume file is incomplete (typically there | |
| | | 's no | |
| | | // "file sizes" field) the torrent is queued for a full chec | |
| | | k. If | |
| | | // this settings is set to true, instead libtorrent will ass | |
| | | ume | |
| | | // we have none of the files and go straight to download | |
| | | bool no_recheck_incomplete_resume; | |
| | | | |
| | | // when this is true, libtorrent will take actions to make s | |
| | | ure any | |
| | | // privacy sensitive information is leaked out from the clie | |
| | | nt. 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; | |
| | | | |
| | | // the number of milliseconds between internal ticks. Should | |
| | | be no | |
| | | // more than one second (i.e. 1000). | |
| | | int tick_interval; | |
| | | | |
| | | // specifies whether downloads from web seeds is reported to | |
| | | the | |
| | | // tracker or not. Defaults to on | |
| | | bool report_web_seed_downloads; | |
| | | | |
| | | // this is the target share ratio for share-mode torrents | |
| | | int share_mode_target; | |
| | | | |
| | | // max upload rate in bytes per second for the session | |
| | | int upload_rate_limit; | |
| | | | |
| | | // max download rate in bytes per second for the session | |
| | | int download_rate_limit; | |
| | | | |
| | | // max upload rate in bytes per second for peers on the loca | |
| | | l | |
| | | // network, in the session | |
| | | int local_upload_rate_limit; | |
| | | | |
| | | // max download rate in bytes per second for peers on the lo | |
| | | cal | |
| | | // network, in the session | |
| | | int local_download_rate_limit; | |
| | | | |
| | | // max upload rate used by the DHT in bytes per second | |
| | | int dht_upload_rate_limit; | |
| | | | |
| | | // the max number of unchoke slots in the session (might be | |
| | | // overridden by unchoke algorithm) | |
| | | int unchoke_slots_limit; | |
| | | | |
| | | // the max number of half-open TCP connections | |
| | | int half_open_limit; | |
| | | | |
| | | // the max number of connections in the session | |
| | | int connections_limit; | |
| | | | |
| | | // target delay, milliseconds | |
| | | int utp_target_delay; | |
| | | | |
| | | // max number of bytes to increase cwnd per rtt in uTP | |
| | | // congestion controller | |
| | | int utp_gain_factor; | |
| | | | |
| | | // the shortest allowed uTP connection timeout in millisecon | |
| | | ds | |
| | | // defaults to 500 milliseconds. The shorter timeout, the | |
| | | // faster the connection recovers from a loss of an entire w | |
| | | indow | |
| | | int utp_min_timeout; | |
| | | | |
| | | // the number of SYN packets that are sent before giving up | |
| | | int utp_syn_resends; | |
| | | | |
| | | // the number of resent packets sent on a closed socket befo | |
| | | re giving up | |
| | | int utp_fin_resends; | |
| | | | |
| | | // the number of times to send a packet before giving up | |
| | | int utp_num_resends; | |
| | | | |
| | | // initial timeout for uTP SYN packets | |
| | | int utp_connect_timeout; | |
| | | | |
| | | // number of milliseconds of delaying ACKing packets the mos | |
| | | t | |
| | | int utp_delayed_ack; | |
| | | | |
| | | // set to true if the uTP socket buffer size is allowed to i | |
| | | ncrease | |
| | | // dynamically based on the NIC MTU setting. This is true by | |
| | | default | |
| | | // and improves uTP performance for networks with larger fra | |
| | | me sizes | |
| | | // including loopback | |
| | | bool utp_dynamic_sock_buf; | |
| | | | |
| | | // what to multiply the congestion window by on packet loss. | |
| | | // it's specified as a percent. The default is 50, i.e. cut | |
| | | // in half | |
| | | int utp_loss_multiplier; | |
| | | | |
| | | enum bandwidth_mixed_algo_t | |
| | | { | |
| | | // disables the mixed mode bandwidth balancing | |
| | | prefer_tcp = 0, | |
| | | | |
| | | // does not throttle uTP, throttles TCP to the same | |
| | | proportion | |
| | | // of throughput as there are TCP connections | |
| | | peer_proportional = 1 | |
| | | | |
| | | }; | |
| | | // the algorithm to use to balance bandwidth between tcp | |
| | | // connections and uTP connections | |
| | | int mixed_mode_algorithm; | |
| | | | |
| | | // set to true if uTP connections should be rate limited | |
| | | // defaults to false | |
| | | bool rate_limit_utp; | |
| | | | |
| | | // this is the number passed in to listen(). i.e. | |
| | | // the number of connections to accept while we're | |
| | | // not waiting in an accept() call. | |
| | | int listen_queue_size; | |
| | | | |
| | | // if this is true, the &ip= argument in tracker requests | |
| | | // (unless otherwise specified) will be set to the intermedi | |
| | | ate | |
| | | // IP address if the user is double NATed. If ther user is n | |
| | | ot | |
| | | // double NATed, this option does not have an affect | |
| | | bool announce_double_nat; | |
| | | | |
| | | // the first tracker response after a torrent is started | |
| | | // will cause this many connections to be made immediately. | |
| | | // instead of waiting for the connection scheduler which | |
| | | // triggeres every second | |
| | | int torrent_connect_boost; | |
| | | | |
| | | // this controls whether or not seeding (and complete) torre | |
| | | nts | |
| | | // attempt to make outgoing connections or not. It defaults | |
| | | to | |
| | | // true, but can be set to zero for specific applications wh | |
| | | ere | |
| | | // making outgoing connections is costly and known to not | |
| | | // add any benefits | |
| | | bool seeding_outgoing_connections; | |
| | | | |
| | | // when this is true, libtorrent will not attempt to make ou | |
| | | tgoing | |
| | | // connections to peers whose port is < 1024. This is a safe | |
| | | ty | |
| | | // precaution to avoid being part of a DDoS attack | |
| | | bool no_connect_privileged_ports; | |
| | | | |
| | | // the max alert queue size | |
| | | int alert_queue_size; | |
| | | | |
| | | // the max allowed size for metadata received by the | |
| | | // ut_metadata extension (i.e. magnet links) | |
| | | int max_metadata_size; | |
| | | | |
| | | // attempt to smooth out connects to avoid getting spikes in | |
| | | // opening connections and timing out connections | |
| | | bool smooth_connects; | |
| | | | |
| | | // always send user-agent | |
| | | bool always_send_user_agent; | |
| | | | |
| | | // if true, trackers will also be filtered by the IP | |
| | | // filter, otherwise they are exempt | |
| | | bool apply_ip_filter_to_trackers; | |
| | | | |
| | | // to avoid write jobs starving read jobs, if this many | |
| | | // write jobs have been taking priority in a row, service | |
| | | // one read job | |
| | | int read_job_every; | |
| | | | |
| | | // issue posix_fadvise() or fcntl(F_RDADVISE) for disk reads | |
| | | // ahead of time | |
| | | bool use_disk_read_ahead; | |
| | | | |
| | | // if set to true, files will be locked when opened. | |
| | | // preventing any other process from modifying them | |
| | | bool lock_files; | |
| | | | |
| | | // open an ssl listen socket for ssl torrents on this port | |
| | | int ssl_listen; | |
| | | | |
| | | // this is the factor X in the formula to calculate the | |
| | | // next tracker timeout: | |
| | | // delay = 5 + X/100 * fails^2 | |
| | | // so, it's an exponential back-off, and this factor | |
| | | // determines how fast the back-off happens. Default | |
| | | // is 250 | |
| | | int tracker_backoff; | |
| | | | |
| | | // when true, web seeds sending bad data will be banned | |
| | | bool ban_web_seeds; | |
| }; | | }; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| struct dht_settings | | struct dht_settings | |
| { | | { | |
| dht_settings() | | dht_settings() | |
| : max_peers_reply(100) | | : max_peers_reply(100) | |
| , search_branching(5) | | , search_branching(5) | |
|
| | | #ifndef TORRENT_NO_DEPRECATE | |
| , service_port(0) | | , service_port(0) | |
|
| | | #endif | |
| , max_fail_count(20) | | , max_fail_count(20) | |
|
| | | , max_torrents(2000) | |
| | | , max_dht_items(700) | |
| | | , max_torrent_search_reply(20) | |
| | | , restrict_routing_ips(true) | |
| | | , restrict_search_ips(true) | |
| {} | | {} | |
| | | | |
| // the maximum number of peers to send in a | | // the maximum number of peers to send in a | |
| // reply to get_peers | | // reply to get_peers | |
| int max_peers_reply; | | int max_peers_reply; | |
| | | | |
| // the number of simultanous "connections" when | | // the number of simultanous "connections" when | |
| // searching the DHT. | | // searching the DHT. | |
| int search_branching; | | int search_branching; | |
| | | | |
|
| | | #ifndef TORRENT_NO_DEPRECATE | |
| // the listen port for the dht. This is a UDP port. | | // the listen port for the dht. This is a UDP port. | |
| // zero means use the same as the tcp interface | | // zero means use the same as the tcp interface | |
| int service_port; | | int service_port; | |
|
| | | #endif | |
| | | | |
| // the maximum number of times a node can fail | | // the maximum number of times a node can fail | |
| // in a row before it is removed from the table. | | // in a row before it is removed from the table. | |
| int max_fail_count; | | int max_fail_count; | |
|
| | | | |
| | | // this is the max number of torrents the DHT will track | |
| | | int max_torrents; | |
| | | | |
| | | // max number of items the DHT will store | |
| | | int max_dht_items; | |
| | | | |
| | | // the max number of torrents to return in a | |
| | | // torrent search query to the DHT | |
| | | int max_torrent_search_reply; | |
| | | | |
| | | // when set, nodes whose IP address that's in | |
| | | // the same /24 (or /64 for IPv6) range in the | |
| | | // same routing table bucket. This is an attempt | |
| | | // to mitigate node ID spoofing attacks | |
| | | // also restrict any IP to only have a single | |
| | | // entry in the whole routing table | |
| | | bool restrict_routing_ips; | |
| | | | |
| | | // applies the same IP restrictions on nodes | |
| | | // received during a DHT search (traversal algorithm) | |
| | | bool restrict_search_ips; | |
| }; | | }; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| | | | |
| struct pe_settings | | struct pe_settings | |
| { | | { | |
| pe_settings() | | pe_settings() | |
| : out_enc_policy(enabled) | | : out_enc_policy(enabled) | |
| , in_enc_policy(enabled) | | , in_enc_policy(enabled) | |
| | | | |
| skipping to change at line 737 | | skipping to change at line 1014 | |
| | | | |
| enum enc_policy | | enum enc_policy | |
| { | | { | |
| forced, // disallow non encrypted connections | | forced, // disallow non encrypted connections | |
| enabled, // allow encrypted and non encrypted connec
tions | | enabled, // allow encrypted and non encrypted connec
tions | |
| disabled // disallow encrypted connections | | disabled // disallow encrypted connections | |
| }; | | }; | |
| | | | |
| enum enc_level | | enum enc_level | |
| { | | { | |
|
| plaintext, // use only plaintext encryption | | plaintext = 1, // use only plaintext encryption | |
| rc4, // use only rc4 encryption | | rc4 = 2, // use only rc4 encryption | |
| both // allow both | | both = 3 // allow both | |
| }; | | }; | |
| | | | |
| enc_policy out_enc_policy; | | enc_policy out_enc_policy; | |
| enc_policy in_enc_policy; | | enc_policy in_enc_policy; | |
| | | | |
| enc_level allowed_enc_level; | | enc_level allowed_enc_level; | |
| // if the allowed encryption level is both, setting this to | | // if the allowed encryption level is both, setting this to | |
| // true will prefer rc4 if both methods are offered, plainte
xt | | // true will prefer rc4 if both methods are offered, plainte
xt | |
| // otherwise | | // otherwise | |
| bool prefer_rc4; | | bool prefer_rc4; | |
| | | | |
End of changes. 30 change blocks. |
| 126 lines changed or deleted | | 444 lines changed or added | |
|
| stat.hpp | | stat.hpp | |
| | | | |
| skipping to change at line 46 | | skipping to change at line 46 | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| #include <assert.h> | | #include <assert.h> | |
| #include <cstring> | | #include <cstring> | |
| | | | |
| #include "libtorrent/size_type.hpp" | | #include "libtorrent/size_type.hpp" | |
| #include "libtorrent/invariant_check.hpp" | | #include "libtorrent/invariant_check.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| | | | |
|
| | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | |
| | | ORRENT_ERROR_LOGGING | |
| | | #include "libtorrent/debug.hpp" // for logger | |
| | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| class TORRENT_EXPORT stat_channel | | class TORRENT_EXTRA_EXPORT stat_channel | |
| { | | { | |
|
| friend class invariant_access; | | | |
| public: | | public: | |
|
| enum { history = 10 }; | | | |
| | | | |
| stat_channel() | | stat_channel() | |
| : m_counter(0) | | : m_counter(0) | |
|
| | | , m_5_sec_average(0) | |
| | | , m_30_sec_average(0) | |
| , m_total_counter(0) | | , m_total_counter(0) | |
|
| , m_rate_sum(0) | | {} | |
| { | | | |
| std::memset(m_rate_history, 0, sizeof(m_rate_history | | | |
| )); | | | |
| } | | | |
| | | | |
| void operator+=(stat_channel const& s) | | void operator+=(stat_channel const& s) | |
| { | | { | |
| TORRENT_ASSERT(m_counter >= 0); | | TORRENT_ASSERT(m_counter >= 0); | |
| TORRENT_ASSERT(m_total_counter >= 0); | | TORRENT_ASSERT(m_total_counter >= 0); | |
| TORRENT_ASSERT(s.m_counter >= 0); | | TORRENT_ASSERT(s.m_counter >= 0); | |
| m_counter += s.m_counter; | | m_counter += s.m_counter; | |
| m_total_counter += s.m_counter; | | m_total_counter += s.m_counter; | |
| TORRENT_ASSERT(m_counter >= 0); | | TORRENT_ASSERT(m_counter >= 0); | |
| TORRENT_ASSERT(m_total_counter >= 0); | | TORRENT_ASSERT(m_total_counter >= 0); | |
| | | | |
| skipping to change at line 85 | | skipping to change at line 86 | |
| TORRENT_ASSERT(count >= 0); | | TORRENT_ASSERT(count >= 0); | |
| | | | |
| m_counter += count; | | m_counter += count; | |
| TORRENT_ASSERT(m_counter >= 0); | | TORRENT_ASSERT(m_counter >= 0); | |
| m_total_counter += count; | | m_total_counter += count; | |
| TORRENT_ASSERT(m_total_counter >= 0); | | TORRENT_ASSERT(m_total_counter >= 0); | |
| } | | } | |
| | | | |
| // should be called once every second | | // should be called once every second | |
| void second_tick(int tick_interval_ms); | | void second_tick(int tick_interval_ms); | |
|
| int rate() const { return m_rate_sum / history; } | | int rate() const { return m_5_sec_average; } | |
| size_type rate_sum() const { return m_rate_sum; } | | int low_pass_rate() const { return m_30_sec_average; } | |
| size_type total() const { return m_total_counter; } | | size_type total() const { return m_total_counter; } | |
| | | | |
| void offset(size_type c) | | void offset(size_type c) | |
| { | | { | |
| TORRENT_ASSERT(c >= 0); | | TORRENT_ASSERT(c >= 0); | |
| TORRENT_ASSERT(m_total_counter >= 0); | | TORRENT_ASSERT(m_total_counter >= 0); | |
| m_total_counter += c; | | m_total_counter += c; | |
| TORRENT_ASSERT(m_total_counter >= 0); | | TORRENT_ASSERT(m_total_counter >= 0); | |
| } | | } | |
| | | | |
|
| size_type counter() const { return m_counter; } | | int counter() const { return m_counter; } | |
| | | | |
| void clear() | | void clear() | |
| { | | { | |
|
| std::memset(m_rate_history, 0, sizeof(m_rate_history
)); | | | |
| m_counter = 0; | | m_counter = 0; | |
|
| | | m_5_sec_average = 0; | |
| | | m_30_sec_average = 0; | |
| m_total_counter = 0; | | m_total_counter = 0; | |
|
| m_rate_sum = 0; | | | |
| } | | } | |
| | | | |
| private: | | private: | |
| | | | |
|
| #ifdef TORRENT_DEBUG | | | |
| void check_invariant() const | | | |
| { | | | |
| size_type sum = 0; | | | |
| for (int i = 0; i < history; ++i) sum += m_rate_hist | | | |
| ory[i]; | | | |
| TORRENT_ASSERT(m_rate_sum == sum); | | | |
| TORRENT_ASSERT(m_total_counter >= 0); | | | |
| } | | | |
| #endif | | | |
| | | | |
| // history of rates a few seconds back | | | |
| int m_rate_history[history]; | | | |
| | | | |
| // the accumulator for this second. | | // the accumulator for this second. | |
| int m_counter; | | int m_counter; | |
| | | | |
|
| | | // sliding average | |
| | | int m_5_sec_average; | |
| | | int m_30_sec_average; | |
| | | | |
| // total counters | | // total counters | |
| size_type m_total_counter; | | size_type m_total_counter; | |
|
| | | | |
| // sum of all elements in m_rate_history | | | |
| size_type m_rate_sum; | | | |
| }; | | }; | |
| | | | |
|
| class TORRENT_EXPORT stat | | class TORRENT_EXTRA_EXPORT stat | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| public: | | public: | |
| void operator+=(const stat& s) | | void operator+=(const stat& s) | |
| { | | { | |
| for (int i = 0; i < num_channels; ++i) | | for (int i = 0; i < num_channels; ++i) | |
| m_stat[i] += s.m_stat[i]; | | m_stat[i] += s.m_stat[i]; | |
| } | | } | |
| | | | |
| void sent_syn(bool ipv6) | | void sent_syn(bool ipv6) | |
| { | | { | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| m_stat[upload_ip_protocol].add(ipv6 ? 60 : 40); | | m_stat[upload_ip_protocol].add(ipv6 ? 60 : 40); | |
|
| | | #endif | |
| } | | } | |
| | | | |
| void received_synack(bool ipv6) | | void received_synack(bool ipv6) | |
| { | | { | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| // we received SYN-ACK and also sent ACK back | | // we received SYN-ACK and also sent ACK back | |
| m_stat[download_ip_protocol].add(ipv6 ? 60 : 40); | | m_stat[download_ip_protocol].add(ipv6 ? 60 : 40); | |
| m_stat[upload_ip_protocol].add(ipv6 ? 60 : 40); | | m_stat[upload_ip_protocol].add(ipv6 ? 60 : 40); | |
|
| | | #endif | |
| } | | } | |
| | | | |
| void received_dht_bytes(int bytes) | | void received_dht_bytes(int bytes) | |
| { | | { | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| TORRENT_ASSERT(bytes >= 0); | | TORRENT_ASSERT(bytes >= 0); | |
| m_stat[download_dht_protocol].add(bytes); | | m_stat[download_dht_protocol].add(bytes); | |
|
| | | #endif | |
| } | | } | |
| | | | |
| void sent_dht_bytes(int bytes) | | void sent_dht_bytes(int bytes) | |
| { | | { | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| TORRENT_ASSERT(bytes >= 0); | | TORRENT_ASSERT(bytes >= 0); | |
| m_stat[upload_dht_protocol].add(bytes); | | m_stat[upload_dht_protocol].add(bytes); | |
|
| | | #endif | |
| } | | } | |
| | | | |
| void received_tracker_bytes(int bytes) | | void received_tracker_bytes(int bytes) | |
| { | | { | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| TORRENT_ASSERT(bytes >= 0); | | TORRENT_ASSERT(bytes >= 0); | |
| m_stat[download_tracker_protocol].add(bytes); | | m_stat[download_tracker_protocol].add(bytes); | |
|
| | | #endif | |
| } | | } | |
| | | | |
| void sent_tracker_bytes(int bytes) | | void sent_tracker_bytes(int bytes) | |
| { | | { | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| TORRENT_ASSERT(bytes >= 0); | | TORRENT_ASSERT(bytes >= 0); | |
| m_stat[upload_tracker_protocol].add(bytes); | | m_stat[upload_tracker_protocol].add(bytes); | |
|
| | | #endif | |
| } | | } | |
| | | | |
| void received_bytes(int bytes_payload, int bytes_protocol) | | void received_bytes(int bytes_payload, int bytes_protocol) | |
| { | | { | |
| TORRENT_ASSERT(bytes_payload >= 0); | | TORRENT_ASSERT(bytes_payload >= 0); | |
| TORRENT_ASSERT(bytes_protocol >= 0); | | TORRENT_ASSERT(bytes_protocol >= 0); | |
| | | | |
| m_stat[download_payload].add(bytes_payload); | | m_stat[download_payload].add(bytes_payload); | |
| m_stat[download_protocol].add(bytes_protocol); | | m_stat[download_protocol].add(bytes_protocol); | |
| } | | } | |
| | | | |
| skipping to change at line 200 | | skipping to change at line 201 | |
| TORRENT_ASSERT(bytes_protocol >= 0); | | TORRENT_ASSERT(bytes_protocol >= 0); | |
| | | | |
| m_stat[upload_payload].add(bytes_payload); | | m_stat[upload_payload].add(bytes_payload); | |
| m_stat[upload_protocol].add(bytes_protocol); | | m_stat[upload_protocol].add(bytes_protocol); | |
| } | | } | |
| | | | |
| // and IP packet was received or sent | | // and IP packet was received or sent | |
| // account for the overhead caused by it | | // account for the overhead caused by it | |
| void trancieve_ip_packet(int bytes_transferred, bool ipv6) | | void trancieve_ip_packet(int bytes_transferred, bool ipv6) | |
| { | | { | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| // one TCP/IP packet header for the packet | | // one TCP/IP packet header for the packet | |
| // sent or received, and one for the ACK | | // sent or received, and one for the ACK | |
| // The IPv4 header is 20 bytes | | // The IPv4 header is 20 bytes | |
| // and IPv6 header is 40 bytes | | // and IPv6 header is 40 bytes | |
| const int header = (ipv6 ? 40 : 20) + 20; | | const int header = (ipv6 ? 40 : 20) + 20; | |
| const int mtu = 1500; | | const int mtu = 1500; | |
| const int packet_size = mtu - header; | | const int packet_size = mtu - header; | |
| const int overhead = (std::max)(1, (bytes_transferre
d + packet_size - 1) / packet_size) * header; | | const int overhead = (std::max)(1, (bytes_transferre
d + packet_size - 1) / packet_size) * header; | |
| m_stat[download_ip_protocol].add(overhead); | | m_stat[download_ip_protocol].add(overhead); | |
| m_stat[upload_ip_protocol].add(overhead); | | m_stat[upload_ip_protocol].add(overhead); | |
|
| | | #endif | |
| } | | } | |
| | | | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| int upload_ip_overhead() const { return m_stat[upload_ip_pro
tocol].counter(); } | | int upload_ip_overhead() const { return m_stat[upload_ip_pro
tocol].counter(); } | |
| int download_ip_overhead() const { return m_stat[download_ip
_protocol].counter(); } | | int download_ip_overhead() const { return m_stat[download_ip
_protocol].counter(); } | |
| int upload_dht() const { return m_stat[upload_dht_protocol].
counter(); } | | int upload_dht() const { return m_stat[upload_dht_protocol].
counter(); } | |
| int download_dht() const { return m_stat[download_dht_protoc
ol].counter(); } | | int download_dht() const { return m_stat[download_dht_protoc
ol].counter(); } | |
| int download_tracker() const { return m_stat[download_tracke
r_protocol].counter(); } | | int download_tracker() const { return m_stat[download_tracke
r_protocol].counter(); } | |
| int upload_tracker() const { return m_stat[upload_tracker_pr
otocol].counter(); } | | int upload_tracker() const { return m_stat[upload_tracker_pr
otocol].counter(); } | |
|
| | | #else | |
| | | int upload_ip_overhead() const { return 0; } | |
| | | int download_ip_overhead() const { return 0; } | |
| | | int upload_dht() const { return 0; } | |
| | | int download_dht() const { return 0; } | |
| | | int download_tracker() const { return 0; } | |
| | | int upload_tracker() const { return 0; } | |
| | | #endif | |
| | | | |
| // should be called once every second | | // should be called once every second | |
| void second_tick(int tick_interval_ms) | | void second_tick(int tick_interval_ms) | |
| { | | { | |
| for (int i = 0; i < num_channels; ++i) | | for (int i = 0; i < num_channels; ++i) | |
| m_stat[i].second_tick(tick_interval_ms); | | m_stat[i].second_tick(tick_interval_ms); | |
| } | | } | |
| | | | |
|
| | | int low_pass_upload_rate() const | |
| | | { | |
| | | return m_stat[upload_payload].low_pass_rate() | |
| | | + m_stat[upload_protocol].low_pass_rate() | |
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| | | + m_stat[upload_ip_protocol].low_pass_rate() | |
| | | + m_stat[upload_dht_protocol].low_pass_rate( | |
| | | ) | |
| | | + m_stat[upload_tracker_protocol].low_pass_r | |
| | | ate() | |
| | | #endif | |
| | | ; | |
| | | } | |
| | | | |
| | | int low_pass_download_rate() const | |
| | | { | |
| | | return m_stat[download_payload].low_pass_rate() | |
| | | + m_stat[download_protocol].low_pass_rate() | |
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| | | + m_stat[download_ip_protocol].low_pass_rate | |
| | | () | |
| | | + m_stat[download_dht_protocol].low_pass_rat | |
| | | e() | |
| | | + m_stat[download_tracker_protocol].low_pass | |
| | | _rate() | |
| | | #endif | |
| | | ; | |
| | | } | |
| | | | |
| int upload_rate() const | | int upload_rate() const | |
| { | | { | |
|
| return (m_stat[upload_payload].rate_sum() | | return m_stat[upload_payload].rate() | |
| + m_stat[upload_protocol].rate_sum() | | + m_stat[upload_protocol].rate() | |
| + m_stat[upload_ip_protocol].rate_sum() | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| + m_stat[upload_dht_protocol].rate_sum()) | | + m_stat[upload_ip_protocol].rate() | |
| / stat_channel::history; | | + m_stat[upload_dht_protocol].rate() | |
| | | + m_stat[upload_tracker_protocol].rate() | |
| | | #endif | |
| | | ; | |
| } | | } | |
| | | | |
| int download_rate() const | | int download_rate() const | |
| { | | { | |
|
| return (m_stat[download_payload].rate_sum() | | return m_stat[download_payload].rate() | |
| + m_stat[download_protocol].rate_sum() | | + m_stat[download_protocol].rate() | |
| + m_stat[download_ip_protocol].rate_sum() | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| + m_stat[download_dht_protocol].rate_sum()) | | + m_stat[download_ip_protocol].rate() | |
| / stat_channel::history; | | + m_stat[download_dht_protocol].rate() | |
| | | + m_stat[download_tracker_protocol].rate() | |
| | | #endif | |
| | | ; | |
| } | | } | |
| | | | |
| size_type total_upload() const | | size_type total_upload() const | |
| { | | { | |
| return m_stat[upload_payload].total() | | return m_stat[upload_payload].total() | |
| + m_stat[upload_protocol].total() | | + m_stat[upload_protocol].total() | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| + m_stat[upload_ip_protocol].total() | | + m_stat[upload_ip_protocol].total() | |
| + m_stat[upload_dht_protocol].total() | | + m_stat[upload_dht_protocol].total() | |
|
| + m_stat[upload_tracker_protocol].total(); | | + m_stat[upload_tracker_protocol].total() | |
| | | #endif | |
| | | ; | |
| } | | } | |
| | | | |
| size_type total_download() const | | size_type total_download() const | |
| { | | { | |
| return m_stat[download_payload].total() | | return m_stat[download_payload].total() | |
| + m_stat[download_protocol].total() | | + m_stat[download_protocol].total() | |
|
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| + m_stat[download_ip_protocol].total() | | + m_stat[download_ip_protocol].total() | |
| + m_stat[download_dht_protocol].total() | | + m_stat[download_dht_protocol].total() | |
|
| + m_stat[download_tracker_protocol].total(); | | + m_stat[download_tracker_protocol].total() | |
| | | #endif | |
| | | ; | |
| } | | } | |
| | | | |
| int upload_payload_rate() const | | int upload_payload_rate() const | |
| { return m_stat[upload_payload].rate(); } | | { return m_stat[upload_payload].rate(); } | |
| int download_payload_rate() const | | int download_payload_rate() const | |
| { return m_stat[download_payload].rate(); } | | { return m_stat[download_payload].rate(); } | |
| | | | |
| size_type total_payload_upload() const | | size_type total_payload_upload() const | |
| { return m_stat[upload_payload].total(); } | | { return m_stat[upload_payload].total(); } | |
| size_type total_payload_download() const | | size_type total_payload_download() const | |
| | | | |
| skipping to change at line 291 | | skipping to change at line 339 | |
| | | | |
| // this is used to offset the statistics when a | | // this is used to offset the statistics when a | |
| // peer_connection is opened and have some previous | | // peer_connection is opened and have some previous | |
| // transfers from earlier connections. | | // transfers from earlier connections. | |
| void add_stat(size_type downloaded, size_type uploaded) | | void add_stat(size_type downloaded, size_type uploaded) | |
| { | | { | |
| m_stat[download_payload].offset(downloaded); | | m_stat[download_payload].offset(downloaded); | |
| m_stat[upload_payload].offset(uploaded); | | m_stat[upload_payload].offset(uploaded); | |
| } | | } | |
| | | | |
|
| size_type last_payload_downloaded() const | | int last_payload_downloaded() const | |
| { return m_stat[download_payload].counter(); } | | { return m_stat[download_payload].counter(); } | |
|
| size_type last_payload_uploaded() const | | int last_payload_uploaded() const | |
| { return m_stat[upload_payload].counter(); } | | { return m_stat[upload_payload].counter(); } | |
|
| size_type last_protocol_downloaded() const | | int last_protocol_downloaded() const | |
| { return m_stat[download_protocol].counter(); } | | { return m_stat[download_protocol].counter(); } | |
|
| size_type last_protocol_uploaded() const | | int last_protocol_uploaded() const | |
| { return m_stat[upload_protocol].counter(); } | | { return m_stat[upload_protocol].counter(); } | |
| | | | |
| // these are the channels we keep stats for | | // these are the channels we keep stats for | |
| enum | | enum | |
| { | | { | |
| upload_payload, | | upload_payload, | |
| upload_protocol, | | upload_protocol, | |
|
| | | download_payload, | |
| | | download_protocol, | |
| | | #ifndef TORRENT_DISABLE_FULL_STATS | |
| upload_ip_protocol, | | upload_ip_protocol, | |
| upload_dht_protocol, | | upload_dht_protocol, | |
| upload_tracker_protocol, | | upload_tracker_protocol, | |
|
| download_payload, | | | |
| download_protocol, | | | |
| download_ip_protocol, | | download_ip_protocol, | |
| download_dht_protocol, | | download_dht_protocol, | |
| download_tracker_protocol, | | download_tracker_protocol, | |
|
| | | #endif | |
| num_channels | | num_channels | |
| }; | | }; | |
| | | | |
| void clear() | | void clear() | |
| { | | { | |
| for (int i = 0; i < num_channels; ++i) | | for (int i = 0; i < num_channels; ++i) | |
| m_stat[i].clear(); | | m_stat[i].clear(); | |
| } | | } | |
| | | | |
| stat_channel const& operator[](int i) const | | stat_channel const& operator[](int i) const | |
| | | | |
End of changes. 45 change blocks. |
| 49 lines changed or deleted | | 103 lines changed or added | |
|
| storage.hpp | | storage.hpp | |
| | | | |
| skipping to change at line 37 | | skipping to change at line 37 | |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_STORAGE_HPP_INCLUDE | | #ifndef TORRENT_STORAGE_HPP_INCLUDE | |
| #define TORRENT_STORAGE_HPP_INCLUDE | | #define TORRENT_STORAGE_HPP_INCLUDE | |
| | | | |
| #include <vector> | | #include <vector> | |
|
| #include <bitset> | | #include <sys/types.h> | |
| | | #include <sys/stat.h> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
|
| #include <boost/function.hpp> | | #include <boost/function/function2.hpp> | |
| #include <boost/limits.hpp> | | #include <boost/limits.hpp> | |
|
| #include <boost/thread.hpp> | | | |
| #include <boost/shared_ptr.hpp> | | #include <boost/shared_ptr.hpp> | |
|
| | | #include <boost/scoped_ptr.hpp> | |
| #include <boost/intrusive_ptr.hpp> | | #include <boost/intrusive_ptr.hpp> | |
|
| #include <boost/filesystem/path.hpp> | | | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/torrent_info.hpp" | | #include "libtorrent/torrent_info.hpp" | |
| #include "libtorrent/piece_picker.hpp" | | #include "libtorrent/piece_picker.hpp" | |
| #include "libtorrent/intrusive_ptr_base.hpp" | | #include "libtorrent/intrusive_ptr_base.hpp" | |
| #include "libtorrent/peer_request.hpp" | | #include "libtorrent/peer_request.hpp" | |
| #include "libtorrent/hasher.hpp" | | #include "libtorrent/hasher.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/file.hpp" | | #include "libtorrent/file.hpp" | |
| #include "libtorrent/disk_buffer_holder.hpp" | | #include "libtorrent/disk_buffer_holder.hpp" | |
|
| | | #include "libtorrent/thread.hpp" | |
| | | #include "libtorrent/storage_defs.hpp" | |
| | | #include "libtorrent/allocator.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| namespace aux | | | |
| { | | | |
| struct piece_checker_data; | | | |
| } | | | |
| | | | |
| namespace fs = boost::filesystem; | | | |
| | | | |
| class session; | | class session; | |
| struct file_pool; | | struct file_pool; | |
| struct disk_io_job; | | struct disk_io_job; | |
| struct disk_buffer_pool; | | struct disk_buffer_pool; | |
| struct session_settings; | | struct session_settings; | |
| | | | |
|
| enum storage_mode_t | | TORRENT_EXTRA_EXPORT std::vector<std::pair<size_type, std::time_t> > | |
| { | | get_filesizes( | |
| storage_mode_allocate = 0, | | | |
| storage_mode_sparse, | | | |
| storage_mode_compact | | | |
| }; | | | |
| | | | |
| TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_f | | | |
| ilesizes( | | | |
| file_storage const& t | | file_storage const& t | |
|
| , fs::path p); | | , std::string const& p); | |
| | | | |
|
| TORRENT_EXPORT bool match_filesizes( | | TORRENT_EXTRA_EXPORT bool match_filesizes( | |
| file_storage const& t | | file_storage const& t | |
|
| , fs::path p | | , std::string const& p | |
| , std::vector<std::pair<size_type, std::time_t> > const& siz
es | | , std::vector<std::pair<size_type, std::time_t> > const& siz
es | |
| , bool compact_mode | | , bool compact_mode | |
| , std::string* error = 0); | | , std::string* error = 0); | |
|
| | | /* | |
| struct TORRENT_EXPORT file_allocation_failed: std::exception | | struct TORRENT_EXTRA_EXPORT file_allocation_failed: std::exception | |
| { | | { | |
| file_allocation_failed(const char* error_msg): m_msg(error_m
sg) {} | | file_allocation_failed(const char* error_msg): m_msg(error_m
sg) {} | |
| virtual const char* what() const throw() { return m_msg.c_st
r(); } | | virtual const char* what() const throw() { return m_msg.c_st
r(); } | |
| virtual ~file_allocation_failed() throw() {} | | virtual ~file_allocation_failed() throw() {} | |
| std::string m_msg; | | std::string m_msg; | |
| }; | | }; | |
|
| | | */ | |
| struct TORRENT_EXPORT partial_hash | | struct TORRENT_EXTRA_EXPORT partial_hash | |
| { | | { | |
| partial_hash(): offset(0) {} | | partial_hash(): offset(0) {} | |
| // the number of bytes in the piece that has been hashed | | // the number of bytes in the piece that has been hashed | |
| int offset; | | int offset; | |
| // the sha-1 context | | // the sha-1 context | |
| hasher h; | | hasher h; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT storage_interface | | struct TORRENT_EXPORT storage_interface | |
| { | | { | |
| | | | |
| skipping to change at line 128 | | skipping to change at line 117 | |
| // allocate_files is true if allocation mode | | // allocate_files is true if allocation mode | |
| // is set to full and sparse files are supported | | // is set to full and sparse files are supported | |
| // false return value indicates an error | | // false return value indicates an error | |
| virtual bool initialize(bool allocate_files) = 0; | | virtual bool initialize(bool allocate_files) = 0; | |
| | | | |
| virtual bool has_any_file() = 0; | | virtual bool has_any_file() = 0; | |
| | | | |
| virtual int readv(file::iovec_t const* bufs, int slot, int o
ffset, int num_bufs); | | virtual int readv(file::iovec_t const* bufs, int slot, int o
ffset, int num_bufs); | |
| virtual int writev(file::iovec_t const* bufs, int slot, int
offset, int num_bufs); | | virtual int writev(file::iovec_t const* bufs, int slot, int
offset, int num_bufs); | |
| | | | |
|
| | | virtual void hint_read(int slot, int offset, int len) {} | |
| // negative return value indicates an error | | // negative return value indicates an error | |
| virtual int read(char* buf, int slot, int offset, int size)
= 0; | | virtual int read(char* buf, int slot, int offset, int size)
= 0; | |
| | | | |
| // negative return value indicates an error | | // negative return value indicates an error | |
| virtual int write(const char* buf, int slot, int offset, int
size) = 0; | | virtual int write(const char* buf, int slot, int offset, int
size) = 0; | |
| | | | |
| virtual size_type physical_offset(int slot, int offset) = 0; | | virtual size_type physical_offset(int slot, int offset) = 0; | |
| | | | |
| // returns the end of the sparse region the slot 'start' | | // returns the end of the sparse region the slot 'start' | |
| // resides in i.e. the next slot with content. If start | | // resides in i.e. the next slot with content. If start | |
| // is not in a sparse region, start itself is returned | | // is not in a sparse region, start itself is returned | |
| virtual int sparse_end(int start) const { return start; } | | virtual int sparse_end(int start) const { return start; } | |
| | | | |
| // non-zero return value indicates an error | | // non-zero return value indicates an error | |
|
| virtual bool move_storage(fs::path save_path) = 0; | | virtual bool move_storage(std::string const& save_path) = 0; | |
| | | | |
| // verify storage dependent fast resume entries | | // verify storage dependent fast resume entries | |
| virtual bool verify_resume_data(lazy_entry const& rd, error_
code& error) = 0; | | virtual bool verify_resume_data(lazy_entry const& rd, error_
code& error) = 0; | |
| | | | |
| // write storage dependent fast resume entries | | // write storage dependent fast resume entries | |
| virtual bool write_resume_data(entry& rd) const = 0; | | virtual bool write_resume_data(entry& rd) const = 0; | |
| | | | |
| // moves (or copies) the content in src_slot to dst_slot | | // moves (or copies) the content in src_slot to dst_slot | |
| virtual bool move_slot(int src_slot, int dst_slot) = 0; | | virtual bool move_slot(int src_slot, int dst_slot) = 0; | |
| | | | |
| | | | |
| skipping to change at line 173 | | skipping to change at line 163 | |
| // non-zero return value indicates an error | | // non-zero return value indicates an error | |
| virtual bool release_files() = 0; | | virtual bool release_files() = 0; | |
| | | | |
| // this will rename the file specified by index. | | // this will rename the file specified by index. | |
| virtual bool rename_file(int index, std::string const& new_f
ilename) = 0; | | virtual bool rename_file(int index, std::string const& new_f
ilename) = 0; | |
| | | | |
| // this will close all open files and delete them | | // this will close all open files and delete them | |
| // non-zero return value indicates an error | | // non-zero return value indicates an error | |
| virtual bool delete_files() = 0; | | virtual bool delete_files() = 0; | |
| | | | |
|
| | | virtual void finalize_file(int file) {} | |
| | | | |
| disk_buffer_pool* disk_pool() { return m_disk_pool; } | | disk_buffer_pool* disk_pool() { return m_disk_pool; } | |
| session_settings const& settings() const { return *m_setting
s; } | | session_settings const& settings() const { return *m_setting
s; } | |
| | | | |
|
| void set_error(boost::filesystem::path const& file, error_co | | void set_error(std::string const& file, error_code const& ec | |
| de const& ec) const | | ) const; | |
| { | | | |
| m_error_file = file.string(); | | | |
| m_error = ec; | | | |
| } | | | |
| | | | |
| error_code const& error() const { return m_error; } | | error_code const& error() const { return m_error; } | |
| std::string const& error_file() const { return m_error_file;
} | | std::string const& error_file() const { return m_error_file;
} | |
|
| void clear_error() { m_error = error_code(); m_error_file.cl
ear(); } | | virtual void clear_error() { m_error = error_code(); m_error
_file.resize(0); } | |
| | | | |
| mutable error_code m_error; | | mutable error_code m_error; | |
| mutable std::string m_error_file; | | mutable std::string m_error_file; | |
| | | | |
| virtual ~storage_interface() {} | | virtual ~storage_interface() {} | |
| | | | |
| disk_buffer_pool* m_disk_pool; | | disk_buffer_pool* m_disk_pool; | |
| session_settings* m_settings; | | session_settings* m_settings; | |
| }; | | }; | |
| | | | |
|
| typedef storage_interface* (*storage_constructor_type)( | | class TORRENT_EXPORT default_storage : public storage_interface, boo | |
| file_storage const&, file_storage const*, fs::path const&, f | | st::noncopyable | |
| ile_pool&); | | { | |
| | | public: | |
| | | default_storage(file_storage const& fs, file_storage const* | |
| | | mapped, std::string const& path | |
| | | , file_pool& fp, std::vector<boost::uint8_t> const& | |
| | | file_prio); | |
| | | ~default_storage(); | |
| | | | |
|
| TORRENT_EXPORT storage_interface* default_storage_constructor( | | void finalize_file(int file); | |
| file_storage const&, file_storage const* mapped, fs::path co | | bool has_any_file(); | |
| nst&, file_pool&); | | bool rename_file(int index, std::string const& new_filename) | |
| | | ; | |
| | | bool release_files(); | |
| | | bool delete_files(); | |
| | | bool initialize(bool allocate_files); | |
| | | bool move_storage(std::string const& save_path); | |
| | | int read(char* buf, int slot, int offset, int size); | |
| | | int write(char const* buf, int slot, int offset, int size); | |
| | | int sparse_end(int start) const; | |
| | | void hint_read(int slot, int offset, int len); | |
| | | int readv(file::iovec_t const* bufs, int slot, int offset, i | |
| | | nt num_bufs); | |
| | | int writev(file::iovec_t const* buf, int slot, int offset, i | |
| | | nt num_bufs); | |
| | | size_type physical_offset(int slot, int offset); | |
| | | bool move_slot(int src_slot, int dst_slot); | |
| | | bool swap_slots(int slot1, int slot2); | |
| | | bool swap_slots3(int slot1, int slot2, int slot3); | |
| | | bool verify_resume_data(lazy_entry const& rd, error_code& er | |
| | | ror); | |
| | | bool write_resume_data(entry& rd) const; | |
| | | | |
|
| TORRENT_EXPORT storage_interface* disabled_storage_constructor( | | // this identifies a read or write operation | |
| file_storage const&, file_storage const* mapped, fs::path co | | // so that default_storage::readwritev() knows what to | |
| nst&, file_pool&); | | // do when it's actually touching the file | |
| | | struct fileop | |
| | | { | |
| | | size_type (file::*regular_op)(size_type file_offset | |
| | | , file::iovec_t const* bufs, int num_bufs, e | |
| | | rror_code& ec); | |
| | | size_type (default_storage::*unaligned_op)(boost::in | |
| | | trusive_ptr<file> const& f | |
| | | , size_type file_offset, file::iovec_t const | |
| | | * bufs, int num_bufs | |
| | | , error_code& ec); | |
| | | int cache_setting; | |
| | | int mode; | |
| | | }; | |
| | | | |
| | | void delete_one_file(std::string const& p); | |
| | | int readwritev(file::iovec_t const* bufs, int slot, int offs | |
| | | et | |
| | | , int num_bufs, fileop const&); | |
| | | | |
| | | size_type read_unaligned(boost::intrusive_ptr<file> const& f | |
| | | ile_handle | |
| | | , size_type file_offset, file::iovec_t const* bufs, | |
| | | int num_bufs, error_code& ec); | |
| | | size_type write_unaligned(boost::intrusive_ptr<file> const& | |
| | | file_handle | |
| | | , size_type file_offset, file::iovec_t const* bufs, | |
| | | int num_bufs, error_code& ec); | |
| | | | |
| | | file_storage const& files() const { return m_mapped_files?*m | |
| | | _mapped_files:m_files; } | |
| | | | |
| | | boost::scoped_ptr<file_storage> m_mapped_files; | |
| | | file_storage const& m_files; | |
| | | | |
| | | // helper function to open a file in the file pool with the | |
| | | right mode | |
| | | boost::intrusive_ptr<file> open_file(file_storage::iterator | |
| | | fe, int mode | |
| | | , error_code& ec) const; | |
| | | | |
| | | std::vector<boost::uint8_t> m_file_priority; | |
| | | std::string m_save_path; | |
| | | // the file pool is typically stored in | |
| | | // the session, to make all storage | |
| | | // instances use the same pool | |
| | | file_pool& m_pool; | |
| | | | |
| | | int m_page_size; | |
| | | bool m_allocate_files; | |
| | | }; | |
| | | | |
| | | // this storage implementation does not write anything to disk | |
| | | // and it pretends to read, and just leaves garbage in the buffers | |
| | | // this is useful when simulating many clients on the same machine | |
| | | // or when running stress tests and want to take the cost of the | |
| | | // disk I/O out of the picture. This cannot be used for any kind | |
| | | // of normal bittorrent operation, since it will just send garbage | |
| | | // to peers and throw away all the data it downloads. It would end | |
| | | // up being banned immediately | |
| | | class disabled_storage : public storage_interface, boost::noncopyabl | |
| | | e | |
| | | { | |
| | | public: | |
| | | disabled_storage(int piece_size) : m_piece_size(piece_size) | |
| | | {} | |
| | | bool has_any_file() { return false; } | |
| | | bool rename_file(int index, std::string const& new_filename) | |
| | | { return false; } | |
| | | bool release_files() { return false; } | |
| | | bool delete_files() { return false; } | |
| | | bool initialize(bool allocate_files) { return false; } | |
| | | bool move_storage(std::string const& save_path) { return tru | |
| | | e; } | |
| | | int read(char* buf, int slot, int offset, int size) { return | |
| | | size; } | |
| | | int write(char const* buf, int slot, int offset, int size) { | |
| | | return size; } | |
| | | size_type physical_offset(int slot, int offset) { return 0; | |
| | | } | |
| | | int readv(file::iovec_t const* bufs, int slot, int offset, i | |
| | | nt num_bufs); | |
| | | int writev(file::iovec_t const* bufs, int slot, int offset, | |
| | | int num_bufs); | |
| | | bool move_slot(int src_slot, int dst_slot) { return false; } | |
| | | bool swap_slots(int slot1, int slot2) { return false; } | |
| | | bool swap_slots3(int slot1, int slot2, int slot3) { return f | |
| | | alse; } | |
| | | bool verify_resume_data(lazy_entry const& rd, error_code& er | |
| | | ror) { return false; } | |
| | | bool write_resume_data(entry& rd) const { return false; } | |
| | | | |
| | | int m_piece_size; | |
| | | }; | |
| | | | |
| struct disk_io_thread; | | struct disk_io_thread; | |
| | | | |
|
| class TORRENT_EXPORT piece_manager | | class TORRENT_EXTRA_EXPORT piece_manager | |
| : public intrusive_ptr_base<piece_manager> | | : public intrusive_ptr_base<piece_manager> | |
| , boost::noncopyable | | , boost::noncopyable | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| friend struct disk_io_thread; | | friend struct disk_io_thread; | |
| public: | | public: | |
| | | | |
| piece_manager( | | piece_manager( | |
| boost::shared_ptr<void> const& torrent | | boost::shared_ptr<void> const& torrent | |
| , boost::intrusive_ptr<torrent_info const> info | | , boost::intrusive_ptr<torrent_info const> info | |
|
| , fs::path const& path | | , std::string const& path | |
| , file_pool& fp | | , file_pool& fp | |
| , disk_io_thread& io | | , disk_io_thread& io | |
| , storage_constructor_type sc | | , storage_constructor_type sc | |
|
| , storage_mode_t sm); | | , storage_mode_t sm | |
| | | , std::vector<boost::uint8_t> const& file_prio); | |
| | | | |
| ~piece_manager(); | | ~piece_manager(); | |
| | | | |
| boost::intrusive_ptr<torrent_info const> info() const { retu
rn m_info; } | | boost::intrusive_ptr<torrent_info const> info() const { retu
rn m_info; } | |
| void write_resume_data(entry& rd) const; | | void write_resume_data(entry& rd) const; | |
| | | | |
|
| | | void async_finalize_file(int file); | |
| | | | |
| void async_check_fastresume(lazy_entry const* resume_data | | void async_check_fastresume(lazy_entry const* resume_data | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler); | | , boost::function<void(int, disk_io_job const&)> con
st& handler); | |
| | | | |
| void async_check_files(boost::function<void(int, disk_io_job
const&)> const& handler); | | void async_check_files(boost::function<void(int, disk_io_job
const&)> const& handler); | |
| | | | |
|
| int queued_bytes() const; | | | |
| | | | |
| void async_rename_file(int index, std::string const& name | | void async_rename_file(int index, std::string const& name | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler); | | , boost::function<void(int, disk_io_job const&)> con
st& handler); | |
| | | | |
| void async_read( | | void async_read( | |
| peer_request const& r | | peer_request const& r | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler | | , boost::function<void(int, disk_io_job const&)> con
st& handler | |
|
| , int priority = 0); | | , int cache_line_size = 0 | |
| | | , int cache_expiry = 0); | |
| | | | |
| void async_read_and_hash( | | void async_read_and_hash( | |
| peer_request const& r | | peer_request const& r | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler | | , boost::function<void(int, disk_io_job const&)> con
st& handler | |
|
| , int priority = 0); | | , int cache_expiry = 0); | |
| | | | |
|
| void async_write( | | void async_cache(int piece | |
| | | , boost::function<void(int, disk_io_job const&)> con | |
| | | st& handler | |
| | | , int cache_expiry = 0); | |
| | | | |
| | | // returns the write queue size | |
| | | int async_write( | |
| peer_request const& r | | peer_request const& r | |
| , disk_buffer_holder& buffer | | , disk_buffer_holder& buffer | |
| , boost::function<void(int, disk_io_job const&)> con
st& f); | | , boost::function<void(int, disk_io_job const&)> con
st& f); | |
| | | | |
| void async_hash(int piece, boost::function<void(int, disk_io
_job const&)> const& f); | | void async_hash(int piece, boost::function<void(int, disk_io
_job const&)> const& f); | |
| | | | |
| void async_release_files( | | void async_release_files( | |
| boost::function<void(int, disk_io_job const&)> const
& handler | | boost::function<void(int, disk_io_job const&)> const
& handler | |
| = boost::function<void(int, disk_io_job const&)>()); | | = boost::function<void(int, disk_io_job const&)>()); | |
| | | | |
| void abort_disk_io(); | | void abort_disk_io(); | |
| | | | |
| void async_clear_read_cache( | | void async_clear_read_cache( | |
| boost::function<void(int, disk_io_job const&)> const
& handler | | boost::function<void(int, disk_io_job const&)> const
& handler | |
| = boost::function<void(int, disk_io_job const&)>()); | | = boost::function<void(int, disk_io_job const&)>()); | |
| | | | |
| void async_delete_files( | | void async_delete_files( | |
| boost::function<void(int, disk_io_job const&)> const
& handler | | boost::function<void(int, disk_io_job const&)> const
& handler | |
| = boost::function<void(int, disk_io_job const&)>()); | | = boost::function<void(int, disk_io_job const&)>()); | |
| | | | |
|
| void async_move_storage(fs::path const& p | | void async_move_storage(std::string const& p | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler); | | , boost::function<void(int, disk_io_job const&)> con
st& handler); | |
| | | | |
| void async_save_resume_data( | | void async_save_resume_data( | |
| boost::function<void(int, disk_io_job const&)> const
& handler); | | boost::function<void(int, disk_io_job const&)> const
& handler); | |
| | | | |
| enum return_t | | enum return_t | |
| { | | { | |
| // return values from check_fastresume and check_fil
es | | // return values from check_fastresume and check_fil
es | |
| no_error = 0, | | no_error = 0, | |
| need_full_check = -1, | | need_full_check = -1, | |
| fatal_disk_error = -2, | | fatal_disk_error = -2, | |
| disk_check_aborted = -3 | | disk_check_aborted = -3 | |
| }; | | }; | |
| | | | |
| storage_interface* get_storage_impl() { return m_storage.get
(); } | | storage_interface* get_storage_impl() { return m_storage.get
(); } | |
| | | | |
| private: | | private: | |
| | | | |
|
| fs::path save_path() const; | | std::string save_path() const; | |
| | | | |
| bool verify_resume_data(lazy_entry const& rd, error_code& e) | | bool verify_resume_data(lazy_entry const& rd, error_code& e) | |
| { return m_storage->verify_resume_data(rd, e); } | | { return m_storage->verify_resume_data(rd, e); } | |
| | | | |
| bool is_allocating() const | | bool is_allocating() const | |
| { return m_state == state_expand_pieces; } | | { return m_state == state_expand_pieces; } | |
| | | | |
| void mark_failed(int index); | | void mark_failed(int index); | |
| | | | |
| error_code const& error() const { return m_storage->error();
} | | error_code const& error() const { return m_storage->error();
} | |
| | | | |
| skipping to change at line 319 | | skipping to change at line 407 | |
| | | | |
| // if error is set and return value is 'no_error' or 'need_f
ull_check' | | // if error is set and return value is 'no_error' or 'need_f
ull_check' | |
| // the error message indicates that the fast resume data was
rejected | | // the error message indicates that the fast resume data was
rejected | |
| // if 'fatal_disk_error' is returned, the error message indi
cates what | | // if 'fatal_disk_error' is returned, the error message indi
cates what | |
| // when wrong in the disk access | | // when wrong in the disk access | |
| int check_fastresume(lazy_entry const& rd, error_code& error
); | | int check_fastresume(lazy_entry const& rd, error_code& error
); | |
| | | | |
| // this function returns true if the checking is complete | | // this function returns true if the checking is complete | |
| int check_files(int& current_slot, int& have_piece, error_co
de& error); | | int check_files(int& current_slot, int& have_piece, error_co
de& error); | |
| | | | |
|
| | | #ifndef TORRENT_NO_DEPRECATE | |
| bool compact_allocation() const | | bool compact_allocation() const | |
| { return m_storage_mode == storage_mode_compact; } | | { return m_storage_mode == storage_mode_compact; } | |
|
| | | #endif | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| std::string name() const { return m_info->name(); } | | std::string name() const { return m_info->name(); } | |
| #endif | | #endif | |
| | | | |
|
| bool allocate_slots(int num_slots, bool abort_on_disk = fals
e); | | bool allocate_slots_impl(int num_slots, mutex::scoped_lock&
l, bool abort_on_disk = false); | |
| | | | |
| // updates the ph.h hasher object with the data at the given
slot | | // updates the ph.h hasher object with the data at the given
slot | |
| // and optionally a 'small hash' as well, the hash for | | // and optionally a 'small hash' as well, the hash for | |
| // the partial slot. Returns the number of bytes read | | // the partial slot. Returns the number of bytes read | |
| int hash_for_slot(int slot, partial_hash& h, int piece_size | | int hash_for_slot(int slot, partial_hash& h, int piece_size | |
| , int small_piece_size = 0, sha1_hash* small_hash =
0); | | , int small_piece_size = 0, sha1_hash* small_hash =
0); | |
| | | | |
|
| | | void hint_read_impl(int piece_index, int offset, int size); | |
| | | | |
| int read_impl( | | int read_impl( | |
| file::iovec_t* bufs | | file::iovec_t* bufs | |
| , int piece_index | | , int piece_index | |
| , int offset | | , int offset | |
| , int num_bufs); | | , int num_bufs); | |
| | | | |
| int write_impl( | | int write_impl( | |
| file::iovec_t* bufs | | file::iovec_t* bufs | |
| , int piece_index | | , int piece_index | |
| , int offset | | , int offset | |
| , int num_bufs); | | , int num_bufs); | |
| | | | |
| size_type physical_offset(int piece_index, int offset); | | size_type physical_offset(int piece_index, int offset); | |
| | | | |
|
| | | void finalize_file(int index); | |
| | | | |
| // returns the number of pieces left in the | | // returns the number of pieces left in the | |
| // file currently being checked | | // file currently being checked | |
| int skip_file() const; | | int skip_file() const; | |
| // -1=error 0=ok >0=skip this many pieces | | // -1=error 0=ok >0=skip this many pieces | |
| int check_one_piece(int& have_piece); | | int check_one_piece(int& have_piece); | |
| int identify_data( | | int identify_data( | |
| sha1_hash const& large_hash | | sha1_hash const& large_hash | |
| , sha1_hash const& small_hash | | , sha1_hash const& small_hash | |
| , int current_slot); | | , int current_slot); | |
| | | | |
| void switch_to_full_mode(); | | void switch_to_full_mode(); | |
|
| sha1_hash hash_for_piece_impl(int piece); | | sha1_hash hash_for_piece_impl(int piece, int* readback = 0); | |
| | | | |
| int release_files_impl() { return m_storage->release_files()
; } | | int release_files_impl() { return m_storage->release_files()
; } | |
| int delete_files_impl() { return m_storage->delete_files();
} | | int delete_files_impl() { return m_storage->delete_files();
} | |
| int rename_file_impl(int index, std::string const& new_filen
ame) | | int rename_file_impl(int index, std::string const& new_filen
ame) | |
| { return m_storage->rename_file(index, new_filename); } | | { return m_storage->rename_file(index, new_filename); } | |
| | | | |
|
| int move_storage_impl(fs::path const& save_path); | | int move_storage_impl(std::string const& save_path); | |
| | | | |
| int allocate_slot_for_piece(int piece_index); | | int allocate_slot_for_piece(int piece_index); | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #ifdef TORRENT_STORAGE_DEBUG | | #ifdef TORRENT_STORAGE_DEBUG | |
| void debug_log() const; | | void debug_log() const; | |
| #endif | | #endif | |
| #endif | | #endif | |
| boost::intrusive_ptr<torrent_info const> m_info; | | boost::intrusive_ptr<torrent_info const> m_info; | |
| file_storage const& m_files; | | file_storage const& m_files; | |
| | | | |
| skipping to change at line 406 | | skipping to change at line 500 | |
| enum | | enum | |
| { | | { | |
| unallocated = -1, // the slot is unallocated | | unallocated = -1, // the slot is unallocated | |
| unassigned = -2 // the slot is allocated but not a
ssigned to a piece | | unassigned = -2 // the slot is allocated but not a
ssigned to a piece | |
| }; | | }; | |
| | | | |
| // maps slots to piece indices, if a slot doesn't have a pie
ce | | // maps slots to piece indices, if a slot doesn't have a pie
ce | |
| // it can either be 'unassigned' or 'unallocated' | | // it can either be 'unassigned' or 'unallocated' | |
| std::vector<int> m_slot_to_piece; | | std::vector<int> m_slot_to_piece; | |
| | | | |
|
| fs::path m_save_path; | | std::string m_save_path; | |
| | | | |
|
| mutable boost::recursive_mutex m_mutex; | | mutable mutex m_mutex; | |
| | | | |
| enum { | | enum { | |
| // the default initial state | | // the default initial state | |
| state_none, | | state_none, | |
| // the file checking is complete | | // the file checking is complete | |
| state_finished, | | state_finished, | |
| // checking the files | | // checking the files | |
| state_full_check, | | state_full_check, | |
| // move pieces to their final position | | // move pieces to their final position | |
| state_expand_pieces | | state_expand_pieces | |
| } m_state; | | } m_state; | |
| int m_current_slot; | | int m_current_slot; | |
| // used during check. If any piece is found | | // used during check. If any piece is found | |
| // that is not in its final position, this | | // that is not in its final position, this | |
| // is set to true | | // is set to true | |
| bool m_out_of_place; | | bool m_out_of_place; | |
| // used to move pieces while expanding | | // used to move pieces while expanding | |
| // the storage from compact allocation | | // the storage from compact allocation | |
| // to full allocation | | // to full allocation | |
|
| disk_buffer_holder m_scratch_buffer; | | aligned_holder m_scratch_buffer; | |
| disk_buffer_holder m_scratch_buffer2; | | aligned_holder m_scratch_buffer2; | |
| // the piece that is in the scratch buffer | | // the piece that is in the scratch buffer | |
| int m_scratch_piece; | | int m_scratch_piece; | |
| | | | |
| // the last piece we wrote to or read from | | // the last piece we wrote to or read from | |
| int m_last_piece; | | int m_last_piece; | |
| | | | |
| // this is saved in case we need to instantiate a new | | // this is saved in case we need to instantiate a new | |
| // storage (osed when remapping files) | | // storage (osed when remapping files) | |
| storage_constructor_type m_storage_constructor; | | storage_constructor_type m_storage_constructor; | |
| | | | |
| | | | |
End of changes. 41 change blocks. |
| 61 lines changed or deleted | | 182 lines changed or added | |
|
| torrent.hpp | | torrent.hpp | |
| | | | |
| skipping to change at line 46 | | skipping to change at line 46 | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| #include <set> | | #include <set> | |
| #include <list> | | #include <list> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/limits.hpp> | | #include <boost/limits.hpp> | |
|
| #include <boost/filesystem/path.hpp> | | | |
| #include <boost/tuple/tuple.hpp> | | #include <boost/tuple/tuple.hpp> | |
| #include <boost/enable_shared_from_this.hpp> | | #include <boost/enable_shared_from_this.hpp> | |
| #include <boost/scoped_ptr.hpp> | | #include <boost/scoped_ptr.hpp> | |
| #include <boost/intrusive_ptr.hpp> | | #include <boost/intrusive_ptr.hpp> | |
|
| | | #include <boost/version.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/torrent_handle.hpp" | | #include "libtorrent/torrent_handle.hpp" | |
| #include "libtorrent/entry.hpp" | | #include "libtorrent/entry.hpp" | |
| #include "libtorrent/torrent_info.hpp" | | #include "libtorrent/torrent_info.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
|
| | | #include "libtorrent/address.hpp" | |
| #include "libtorrent/policy.hpp" | | #include "libtorrent/policy.hpp" | |
| #include "libtorrent/tracker_manager.hpp" | | #include "libtorrent/tracker_manager.hpp" | |
| #include "libtorrent/stat.hpp" | | #include "libtorrent/stat.hpp" | |
| #include "libtorrent/alert.hpp" | | #include "libtorrent/alert.hpp" | |
| #include "libtorrent/piece_picker.hpp" | | #include "libtorrent/piece_picker.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/escape_string.hpp" | | #include "libtorrent/escape_string.hpp" | |
| #include "libtorrent/bandwidth_limit.hpp" | | #include "libtorrent/bandwidth_limit.hpp" | |
| #include "libtorrent/bandwidth_queue_entry.hpp" | | #include "libtorrent/bandwidth_queue_entry.hpp" | |
|
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage_defs.hpp" | |
| #include "libtorrent/hasher.hpp" | | #include "libtorrent/hasher.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/bitfield.hpp" | | #include "libtorrent/bitfield.hpp" | |
| #include "libtorrent/aux_/session_impl.hpp" | | #include "libtorrent/aux_/session_impl.hpp" | |
|
| | | #include "libtorrent/deadline_timer.hpp" | |
| | | #include "libtorrent/union_endpoint.hpp" | |
| | | | |
| #if TORRENT_COMPLETE_TYPES_REQUIRED | | #if TORRENT_COMPLETE_TYPES_REQUIRED | |
| #include "libtorrent/peer_connection.hpp" | | #include "libtorrent/peer_connection.hpp" | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) | | class http_parser; | |
| | | | |
| | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | |
| | | ORRENT_ERROR_LOGGING | |
| struct logger; | | struct logger; | |
| #endif | | #endif | |
| | | | |
| class piece_manager; | | class piece_manager; | |
| struct torrent_plugin; | | struct torrent_plugin; | |
| struct bitfield; | | struct bitfield; | |
| struct announce_entry; | | struct announce_entry; | |
| struct tracker_request; | | struct tracker_request; | |
| struct add_torrent_params; | | struct add_torrent_params; | |
|
| | | struct storage_interface; | |
| | | class bt_peer_connection; | |
| | | struct listen_socket_t; | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
|
| | | struct session_impl; | |
| struct piece_checker_data; | | struct piece_checker_data; | |
| } | | } | |
| | | | |
|
| struct web_seed_entry | | | |
| { | | | |
| std::string url; | | | |
| // http seeds are different from url seeds in the | | | |
| // protocol they use. http seeds follows the original | | | |
| // http seed spec. by John Hoffman | | | |
| enum type_t { url_seed, http_seed} type; | | | |
| | | | |
| web_seed_entry(std::string const& url_, type_t type_) | | | |
| : url(url_), type(type_) {} | | | |
| | | | |
| bool operator==(web_seed_entry const& e) const | | | |
| { return url == e.url && type == e.type; } | | | |
| | | | |
| bool operator<(web_seed_entry const& e) const | | | |
| { | | | |
| if (url < e.url) return true; | | | |
| if (url > e.url) return false; | | | |
| return type < e.type; | | | |
| } | | | |
| }; | | | |
| | | | |
| namespace fs = boost::filesystem; | | | |
| | | | |
| // a torrent is a class that holds information | | // a torrent is a class that holds information | |
| // for a specific download. It updates itself against | | // for a specific download. It updates itself against | |
| // the tracker | | // the tracker | |
|
| class TORRENT_EXPORT torrent: public request_callback | | class TORRENT_EXTRA_EXPORT torrent: public request_callback | |
| , public boost::enable_shared_from_this<torrent> | | , public boost::enable_shared_from_this<torrent> | |
| { | | { | |
| public: | | public: | |
| | | | |
| torrent(aux::session_impl& ses, tcp::endpoint const& net_int
erface | | torrent(aux::session_impl& ses, tcp::endpoint const& net_int
erface | |
|
| , int block_size, int seq, add_torrent_params const& | | , int block_size, int seq, add_torrent_params const& | |
| p); | | p | |
| | | , sha1_hash const& info_hash); | |
| ~torrent(); | | ~torrent(); | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| sha1_hash const& obfuscated_hash() const | | sha1_hash const& obfuscated_hash() const | |
| { return m_obfuscated_hash; } | | { return m_obfuscated_hash; } | |
| #endif | | #endif | |
| | | | |
| sha1_hash const& info_hash() const | | sha1_hash const& info_hash() const | |
| { return m_torrent_file->info_hash(); } | | { return m_torrent_file->info_hash(); } | |
| | | | |
| // starts the announce timer | | // starts the announce timer | |
| void start(); | | void start(); | |
| | | | |
|
| | | void start_download_url(); | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void add_extension(boost::shared_ptr<torrent_plugin>); | | void add_extension(boost::shared_ptr<torrent_plugin>); | |
| void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> const& ext | | void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> const& ext | |
| , void* userdata); | | , void* userdata); | |
|
| | | void notify_extension_add_peer(tcp::endpoint const& ip, int
src, int flags); | |
| #endif | | #endif | |
| | | | |
|
| #ifdef TORRENT_DEBUG | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| bool has_peer(peer_connection* p) const | | bool has_peer(peer_connection* p) const | |
| { return m_connections.find(p) != m_connections.end(); } | | { return m_connections.find(p) != m_connections.end(); } | |
| #endif | | #endif | |
| | | | |
| // this is called when the torrent has metadata. | | // this is called when the torrent has metadata. | |
| // it will initialize the storage and the piece-picker | | // it will initialize the storage and the piece-picker | |
| void init(); | | void init(); | |
| | | | |
|
| | | // find the peer that introduced us to the given endpoint. T | |
| | | his is | |
| | | // used when trying to holepunch. We need the introducer so | |
| | | that we | |
| | | // can send a rendezvous connect message | |
| | | bt_peer_connection* find_introducer(tcp::endpoint const& ep) | |
| | | const; | |
| | | | |
| | | // if we're connected to a peer at ep, return its peer conne | |
| | | ction | |
| | | // only count BitTorrent peers | |
| | | bt_peer_connection* find_peer(tcp::endpoint const& ep) const | |
| | | ; | |
| | | | |
| void on_resume_data_checked(int ret, disk_io_job const& j); | | void on_resume_data_checked(int ret, disk_io_job const& j); | |
| void on_force_recheck(int ret, disk_io_job const& j); | | void on_force_recheck(int ret, disk_io_job const& j); | |
| void on_piece_checked(int ret, disk_io_job const& j); | | void on_piece_checked(int ret, disk_io_job const& j); | |
|
| void files_checked_lock(); | | void files_checked(); | |
| void files_checked(boost::mutex::scoped_lock const&); | | | |
| void start_checking(); | | void start_checking(); | |
| | | | |
| void start_announcing(); | | void start_announcing(); | |
| void stop_announcing(); | | void stop_announcing(); | |
| | | | |
|
| | | void send_share_mode(); | |
| void send_upload_only(); | | void send_upload_only(); | |
| | | | |
|
| | | void set_share_mode(bool s); | |
| | | bool share_mode() const { return m_share_mode; } | |
| | | | |
| | | bool graceful_pause() const { return m_graceful_pause_mode; | |
| | | } | |
| | | | |
| void set_upload_mode(bool b); | | void set_upload_mode(bool b); | |
|
| bool upload_mode() const { return m_upload_mode; } | | bool upload_mode() const { return m_upload_mode || m_gracefu | |
| bool is_upload_only() const | | l_pause_mode; } | |
| { return (is_finished() || upload_mode()) && !super_seeding( | | bool is_upload_only() const { return is_finished() || upload | |
| ); } | | _mode(); } | |
| | | | |
| int seed_rank(session_settings const& s) const; | | int seed_rank(session_settings const& s) const; | |
| | | | |
| enum flags_t { overwrite_existing = 1 }; | | enum flags_t { overwrite_existing = 1 }; | |
| void add_piece(int piece, char const* data, int flags = 0); | | void add_piece(int piece, char const* data, int flags = 0); | |
| void on_disk_write_complete(int ret, disk_io_job const& j | | void on_disk_write_complete(int ret, disk_io_job const& j | |
| , peer_request p); | | , peer_request p); | |
|
| | | void on_disk_cache_complete(int ret, disk_io_job const& j); | |
| | | | |
|
| | | void set_progress_ppm(int p) { m_progress_ppm = p; } | |
| struct read_piece_struct | | struct read_piece_struct | |
| { | | { | |
| boost::shared_array<char> piece_data; | | boost::shared_array<char> piece_data; | |
| int blocks_left; | | int blocks_left; | |
| bool fail; | | bool fail; | |
| }; | | }; | |
| void read_piece(int piece); | | void read_piece(int piece); | |
| void on_disk_read_complete(int ret, disk_io_job const& j, pe
er_request r, read_piece_struct* rp); | | void on_disk_read_complete(int ret, disk_io_job const& j, pe
er_request r, read_piece_struct* rp); | |
| | | | |
|
| storage_mode_t storage_mode() const { return m_storage_mode;
} | | storage_mode_t storage_mode() const { return (storage_mode_t
)m_storage_mode; } | |
| storage_interface* get_storage() | | storage_interface* get_storage() | |
| { | | { | |
| if (!m_owning_storage) return 0; | | if (!m_owning_storage) return 0; | |
| return m_owning_storage->get_storage_impl(); | | return m_owning_storage->get_storage_impl(); | |
| } | | } | |
| | | | |
| // this will flag the torrent as aborted. The main | | // this will flag the torrent as aborted. The main | |
| // loop in session_impl will check for this state | | // loop in session_impl will check for this state | |
| // on all torrents once every second, and take | | // on all torrents once every second, and take | |
| // the necessary actions then. | | // the necessary actions then. | |
| void abort(); | | void abort(); | |
| bool is_aborted() const { return m_abort; } | | bool is_aborted() const { return m_abort; } | |
| | | | |
|
| torrent_status::state_t state() const { return m_state; } | | torrent_status::state_t state() const { return (torrent_stat
us::state_t)m_state; } | |
| void set_state(torrent_status::state_t s); | | void set_state(torrent_status::state_t s); | |
| | | | |
| session_settings const& settings() const; | | session_settings const& settings() const; | |
| | | | |
| aux::session_impl& session() { return m_ses; } | | aux::session_impl& session() { return m_ses; } | |
| | | | |
| void set_sequential_download(bool sd); | | void set_sequential_download(bool sd); | |
| bool is_sequential_download() const | | bool is_sequential_download() const | |
| { return m_sequential_download; } | | { return m_sequential_download; } | |
| | | | |
|
| | | void queue_up(); | |
| | | void queue_down(); | |
| void set_queue_position(int p); | | void set_queue_position(int p); | |
| int queue_position() const { return m_sequence_number; } | | int queue_position() const { return m_sequence_number; } | |
| | | | |
| void second_tick(stat& accumulator, int tick_interval_ms); | | void second_tick(stat& accumulator, int tick_interval_ms); | |
| | | | |
| std::string name() const; | | std::string name() const; | |
| | | | |
| stat statistics() const { return m_stat; } | | stat statistics() const { return m_stat; } | |
| void add_stats(stat const& s); | | void add_stats(stat const& s); | |
| size_type bytes_left() const; | | size_type bytes_left() const; | |
| int block_bytes_wanted(piece_block const& p) const; | | int block_bytes_wanted(piece_block const& p) const; | |
|
| void bytes_done(torrent_status& st) const; | | void bytes_done(torrent_status& st, bool accurate) const; | |
| size_type quantized_bytes_done() const; | | size_type quantized_bytes_done() const; | |
| | | | |
| void ip_filter_updated() { m_policy.ip_filter_updated(); } | | void ip_filter_updated() { m_policy.ip_filter_updated(); } | |
| | | | |
| void handle_disk_error(disk_io_job const& j, peer_connection
* c = 0); | | void handle_disk_error(disk_io_job const& j, peer_connection
* c = 0); | |
| void clear_error(); | | void clear_error(); | |
| void set_error(error_code const& ec, std::string const& file
); | | void set_error(error_code const& ec, std::string const& file
); | |
|
| bool has_error() const { return m_error; } | | bool has_error() const { return !!m_error; } | |
| | | error_code error() const { return m_error; } | |
| | | | |
| void flush_cache(); | | void flush_cache(); | |
|
| void pause(); | | void pause(bool graceful = false); | |
| void resume(); | | void resume(); | |
|
| | | void set_allow_peers(bool b, bool graceful_pause = false); | |
| | | void set_announce_to_dht(bool b) { m_announce_to_dht = b; } | |
| | | void set_announce_to_trackers(bool b) { m_announce_to_tracke | |
| | | rs = b; } | |
| | | void set_announce_to_lsd(bool b) { m_announce_to_lsd = b; } | |
| | | | |
| ptime started() const { return m_started; } | | ptime started() const { return m_started; } | |
| void do_pause(); | | void do_pause(); | |
| void do_resume(); | | void do_resume(); | |
| | | | |
| bool is_paused() const; | | bool is_paused() const; | |
|
| bool is_torrent_paused() const { return m_paused; } | | bool allows_peers() const { return m_allow_peers; } | |
| | | bool is_torrent_paused() const { return !m_allow_peers || m_ | |
| | | graceful_pause_mode; } | |
| void force_recheck(); | | void force_recheck(); | |
|
| void save_resume_data(); | | void save_resume_data(int flags); | |
| | | | |
| | | bool need_save_resume_data() const | |
| | | { | |
| | | // save resume data every 15 minutes regardless, jus | |
| | | t to | |
| | | // keep stats up to date | |
| | | return m_need_save_resume_data || time(0) - m_last_s | |
| | | aved_resume > 15 * 60; | |
| | | } | |
| | | | |
| bool is_auto_managed() const { return m_auto_managed; } | | bool is_auto_managed() const { return m_auto_managed; } | |
| void auto_managed(bool a); | | void auto_managed(bool a); | |
| | | | |
| bool should_check_files() const; | | bool should_check_files() const; | |
| | | | |
| void delete_files(); | | void delete_files(); | |
| | | | |
| // ============ start deprecation ============= | | // ============ start deprecation ============= | |
| void filter_piece(int index, bool filter); | | void filter_piece(int index, bool filter); | |
| | | | |
| skipping to change at line 275 | | skipping to change at line 294 | |
| void file_progress(std::vector<float>& fp) const; | | void file_progress(std::vector<float>& fp) const; | |
| #endif | | #endif | |
| // ============ end deprecation ============= | | // ============ end deprecation ============= | |
| | | | |
| void piece_availability(std::vector<int>& avail) const; | | void piece_availability(std::vector<int>& avail) const; | |
| | | | |
| void set_piece_priority(int index, int priority); | | void set_piece_priority(int index, int priority); | |
| int piece_priority(int index) const; | | int piece_priority(int index) const; | |
| | | | |
| void prioritize_pieces(std::vector<int> const& pieces); | | void prioritize_pieces(std::vector<int> const& pieces); | |
|
| void piece_priorities(std::vector<int>&) const; | | void piece_priorities(std::vector<int>*) const; | |
| | | | |
| void set_file_priority(int index, int priority); | | void set_file_priority(int index, int priority); | |
| int file_priority(int index) const; | | int file_priority(int index) const; | |
| | | | |
| void prioritize_files(std::vector<int> const& files); | | void prioritize_files(std::vector<int> const& files); | |
|
| void file_priorities(std::vector<int>&) const; | | void file_priorities(std::vector<int>*) const; | |
| | | | |
| void set_piece_deadline(int piece, int t, int flags); | | void set_piece_deadline(int piece, int t, int flags); | |
| void reset_piece_deadline(int piece); | | void reset_piece_deadline(int piece); | |
| void update_piece_priorities(); | | void update_piece_priorities(); | |
| | | | |
|
| torrent_status status() const; | | void status(torrent_status* st, boost::uint32_t flags); | |
| | | | |
| | | // this torrent changed state, if the user is subscribing to | |
| | | // it, add it to the m_state_updates list in session_impl | |
| | | void state_updated(); | |
| | | | |
| void file_progress(std::vector<size_type>& fp, int flags = 0
) const; | | void file_progress(std::vector<size_type>& fp, int flags = 0
) const; | |
| | | | |
|
| void use_interface(const char* net_interface); | | void use_interface(std::string net_interface); | |
| tcp::endpoint const& get_interface() const { return m_net_in | | tcp::endpoint get_interface() const; | |
| terface; } | | | |
| | | | |
|
| void connect_to_url_seed(web_seed_entry const& url); | | void connect_to_url_seed(std::list<web_seed_entry>::iterator | |
| bool connect_to_peer(policy::peer* peerinfo); | | url); | |
| | | bool connect_to_peer(policy::peer* peerinfo, bool ignore_lim | |
| | | it = false); | |
| | | | |
| void set_ratio(float r) | | void set_ratio(float r) | |
| { TORRENT_ASSERT(r >= 0.0f); m_ratio = r; } | | { TORRENT_ASSERT(r >= 0.0f); m_ratio = r; } | |
| | | | |
| float ratio() const | | float ratio() const | |
| { return m_ratio; } | | { return m_ratio; } | |
| | | | |
| int priority() const { return m_priority; } | | int priority() const { return m_priority; } | |
| void set_priority(int prio) | | void set_priority(int prio) | |
| { | | { | |
| TORRENT_ASSERT(prio <= 255 && prio >= 0); | | TORRENT_ASSERT(prio <= 255 && prio >= 0); | |
| if (prio > 255) prio = 255; | | if (prio > 255) prio = 255; | |
| else if (prio < 0) prio = 0; | | else if (prio < 0) prio = 0; | |
| m_priority = prio; | | m_priority = prio; | |
|
| | | state_updated(); | |
| } | | } | |
| | | | |
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| void resolve_countries(bool r) | | void resolve_countries(bool r) | |
| { m_resolve_countries = r; } | | { m_resolve_countries = r; } | |
| | | | |
|
| bool resolving_countries() const { return m_resolve_countrie | | bool resolving_countries() const | |
| s; } | | { | |
| | | return m_resolve_countries && !m_ses.settings().anon | |
| | | ymous_mode; | |
| | | } | |
| #endif | | #endif | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // BANDWIDTH MANAGEMENT | | // BANDWIDTH MANAGEMENT | |
| | | | |
| bandwidth_channel m_bandwidth_channel[2]; | | bandwidth_channel m_bandwidth_channel[2]; | |
| | | | |
| int bandwidth_throttle(int channel) const; | | int bandwidth_throttle(int channel) const; | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // PEER MANAGEMENT | | // PEER MANAGEMENT | |
| | | | |
|
| | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || def | |
| | | ined TORRENT_LOGGING | |
| | | void log_to_all_peers(char const* message); | |
| | | #endif | |
| | | | |
| // add or remove a url that will be attempted for | | // add or remove a url that will be attempted for | |
| // finding the file(s) in this torrent. | | // finding the file(s) in this torrent. | |
| void add_web_seed(std::string const& url, web_seed_entry::ty
pe_t type) | | void add_web_seed(std::string const& url, web_seed_entry::ty
pe_t type) | |
|
| { m_web_seeds.insert(web_seed_entry(url, type)); } | | { | |
| | | m_web_seeds.push_back(web_seed_entry(url, type)); | |
| | | } | |
| | | | |
|
| void remove_web_seed(std::string const& url, web_seed_entry: | | void add_web_seed(std::string const& url, web_seed_entry::ty | |
| :type_t type) | | pe_t type | |
| { m_web_seeds.erase(web_seed_entry(url, type)); } | | , std::string const& auth, web_seed_entry::headers_t | |
| | | const& extra_headers) | |
| | | { | |
| | | m_web_seeds.push_back(web_seed_entry(url, type, auth | |
| | | , extra_headers)); | |
| | | } | |
| | | | |
|
| void retry_web_seed(std::string const& url, web_seed_entry:: | | void remove_web_seed(std::string const& url, web_seed_entry: | |
| type_t type, int retry = 0); | | :type_t type); | |
| | | void disconnect_web_seed(peer_connection* p); | |
| | | | |
|
| std::set<web_seed_entry> web_seeds() const | | void retry_web_seed(peer_connection* p, int retry = 0); | |
| | | | |
| | | void remove_web_seed(peer_connection* p); | |
| | | | |
| | | std::list<web_seed_entry> web_seeds() const | |
| { return m_web_seeds; } | | { return m_web_seeds; } | |
| | | | |
| std::set<std::string> web_seeds(web_seed_entry::type_t type)
const; | | std::set<std::string> web_seeds(web_seed_entry::type_t type)
const; | |
| | | | |
| bool free_upload_slots() const | | bool free_upload_slots() const | |
| { return m_num_uploads < m_max_uploads; } | | { return m_num_uploads < m_max_uploads; } | |
| | | | |
| bool choke_peer(peer_connection& c); | | bool choke_peer(peer_connection& c); | |
| bool unchoke_peer(peer_connection& c, bool optimistic = fals
e); | | bool unchoke_peer(peer_connection& c, bool optimistic = fals
e); | |
| | | | |
| | | | |
| skipping to change at line 365 | | skipping to change at line 406 | |
| | | | |
| // this will remove the peer and make sure all | | // this will remove the peer and make sure all | |
| // the pieces it had have their reference counter | | // the pieces it had have their reference counter | |
| // decreased in the piece_picker | | // decreased in the piece_picker | |
| void remove_peer(peer_connection* p); | | void remove_peer(peer_connection* p); | |
| | | | |
| void cancel_block(piece_block block); | | void cancel_block(piece_block block); | |
| | | | |
| bool want_more_peers() const; | | bool want_more_peers() const; | |
| bool try_connect_peer(); | | bool try_connect_peer(); | |
|
| void give_connect_points(int points); | | void add_peer(tcp::endpoint const& adr, int source); | |
| | | | |
| // the number of peers that belong to this torrent | | // the number of peers that belong to this torrent | |
| int num_peers() const { return (int)m_connections.size(); } | | int num_peers() const { return (int)m_connections.size(); } | |
| int num_seeds() const; | | int num_seeds() const; | |
| | | | |
| typedef std::set<peer_connection*>::iterator peer_iterator; | | typedef std::set<peer_connection*>::iterator peer_iterator; | |
| typedef std::set<peer_connection*>::const_iterator const_pee
r_iterator; | | typedef std::set<peer_connection*>::const_iterator const_pee
r_iterator; | |
| | | | |
| const_peer_iterator begin() const { return m_connections.beg
in(); } | | const_peer_iterator begin() const { return m_connections.beg
in(); } | |
| const_peer_iterator end() const { return m_connections.end()
; } | | const_peer_iterator end() const { return m_connections.end()
; } | |
| | | | |
| peer_iterator begin() { return m_connections.begin(); } | | peer_iterator begin() { return m_connections.begin(); } | |
| peer_iterator end() { return m_connections.end(); } | | peer_iterator end() { return m_connections.end(); } | |
| | | | |
| void resolve_peer_country(boost::intrusive_ptr<peer_connecti
on> const& p) const; | | void resolve_peer_country(boost::intrusive_ptr<peer_connecti
on> const& p) const; | |
| | | | |
| void get_full_peer_list(std::vector<peer_list_entry>& v) con
st; | | void get_full_peer_list(std::vector<peer_list_entry>& v) con
st; | |
| void get_peer_info(std::vector<peer_info>& v); | | void get_peer_info(std::vector<peer_info>& v); | |
|
| void get_download_queue(std::vector<partial_piece_info>& que | | void get_download_queue(std::vector<partial_piece_info>* que | |
| ue); | | ue); | |
| | | | |
| | | void refresh_explicit_cache(int cache_size); | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // TRACKER MANAGEMENT | | // TRACKER MANAGEMENT | |
| | | | |
| // these are callbacks called by the tracker_connection inst
ance | | // these are callbacks called by the tracker_connection inst
ance | |
| // (either http_tracker_connection or udp_tracker_connection
) | | // (either http_tracker_connection or udp_tracker_connection
) | |
| // when this torrent got a response from its tracker request | | // when this torrent got a response from its tracker request | |
| // or when a failure occured | | // or when a failure occured | |
| virtual void tracker_response( | | virtual void tracker_response( | |
| tracker_request const& r | | tracker_request const& r | |
| , address const& tracker_ip | | , address const& tracker_ip | |
| , std::list<address> const& ip_list | | , std::list<address> const& ip_list | |
| , std::vector<peer_entry>& e, int interval, int min_
interval | | , std::vector<peer_entry>& e, int interval, int min_
interval | |
|
| , int complete, int incomplete, address const& exter | | , int complete, int incomplete, address const& exter | |
| nal_ip); | | nal_ip | |
| virtual void tracker_request_timed_out( | | , std::string const& trackerid); | |
| tracker_request const& r); | | | |
| virtual void tracker_request_error(tracker_request const& r | | virtual void tracker_request_error(tracker_request const& r | |
|
| , int response_code, const std::string& str, int ret | | , int response_code, error_code const& ec, const std | |
| ry_interval); | | ::string& msg | |
| | | , int retry_interval); | |
| virtual void tracker_warning(tracker_request const& req | | virtual void tracker_warning(tracker_request const& req | |
| , std::string const& msg); | | , std::string const& msg); | |
| virtual void tracker_scrape_response(tracker_request const&
req | | virtual void tracker_scrape_response(tracker_request const&
req | |
|
| , int complete, int incomplete, int downloaded); | | , int complete, int incomplete, int downloaded, int
downloaders); | |
| | | | |
| // if no password and username is set | | // if no password and username is set | |
| // this will return an empty string, otherwise | | // this will return an empty string, otherwise | |
| // it will concatenate the login and password | | // it will concatenate the login and password | |
| // ready to be sent over http (but without | | // ready to be sent over http (but without | |
| // base64 encoding). | | // base64 encoding). | |
| std::string tracker_login() const; | | std::string tracker_login() const; | |
| | | | |
| // returns the absolute time when the next tracker | | // returns the absolute time when the next tracker | |
| // announce will take place. | | // announce will take place. | |
| ptime next_announce() const; | | ptime next_announce() const; | |
| | | | |
| // forcefully sets next_announce to the current time | | // forcefully sets next_announce to the current time | |
| void force_tracker_request(); | | void force_tracker_request(); | |
| void force_tracker_request(ptime); | | void force_tracker_request(ptime); | |
| void scrape_tracker(); | | void scrape_tracker(); | |
| void announce_with_tracker(tracker_request::event_t e | | void announce_with_tracker(tracker_request::event_t e | |
| = tracker_request::none | | = tracker_request::none | |
| , address const& bind_interface = address_v4::any())
; | | , address const& bind_interface = address_v4::any())
; | |
|
| ptime const& last_scrape() const { return m_last_scrape; } | | int seconds_since_last_scrape() const { return m_last_scrape
; } | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
|
| void force_dht_announce(); | | void dht_announce(); | |
| #endif | | #endif | |
| | | | |
| // sets the username and password that will be sent to | | // sets the username and password that will be sent to | |
| // the tracker | | // the tracker | |
| void set_tracker_login(std::string const& name, std::string
const& pw); | | void set_tracker_login(std::string const& name, std::string
const& pw); | |
| | | | |
| // the tcp::endpoint of the tracker that we managed to | | // the tcp::endpoint of the tracker that we managed to | |
| // announce ourself at the last time we tried to announce | | // announce ourself at the last time we tried to announce | |
|
| const tcp::endpoint& current_tracker() const; | | tcp::endpoint current_tracker() const; | |
| | | | |
| announce_entry* find_tracker(tracker_request const& r); | | announce_entry* find_tracker(tracker_request const& r); | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // PIECE MANAGEMENT | | // PIECE MANAGEMENT | |
| | | | |
|
| | | void recalc_share_mode(); | |
| | | | |
| void update_sparse_piece_prio(int piece, int cursor, int rev
erse_cursor); | | void update_sparse_piece_prio(int piece, int cursor, int rev
erse_cursor); | |
| | | | |
|
| | | void get_suggested_pieces(std::vector<int>& s) const; | |
| | | | |
| bool super_seeding() const | | bool super_seeding() const | |
| { return m_super_seeding; } | | { return m_super_seeding; } | |
| | | | |
| void super_seeding(bool on); | | void super_seeding(bool on); | |
| int get_piece_to_super_seed(bitfield const&); | | int get_piece_to_super_seed(bitfield const&); | |
| | | | |
| // returns true if we have downloaded the given piece | | // returns true if we have downloaded the given piece | |
| bool have_piece(int index) const | | bool have_piece(int index) const | |
| { | | { | |
|
| return has_picker()?m_picker->have_piece(index):true | | if (!valid_metadata()) return false; | |
| ; | | if (!has_picker()) return true; | |
| | | return m_picker->have_piece(index); | |
| } | | } | |
| | | | |
| // called when we learn that we have a piece | | // called when we learn that we have a piece | |
| // only once per piece | | // only once per piece | |
| void we_have(int index); | | void we_have(int index); | |
| | | | |
| int num_have() const | | int num_have() const | |
| { | | { | |
| return has_picker() | | return has_picker() | |
|
| ?m_picker->num_have() | | ? m_picker->num_have() | |
| :m_torrent_file->num_pieces(); | | : m_torrent_file->num_pieces(); | |
| } | | } | |
| | | | |
| // when we get a have message, this is called for that piece | | // when we get a have message, this is called for that piece | |
| void peer_has(int index) | | void peer_has(int index) | |
| { | | { | |
| if (m_picker.get()) | | if (m_picker.get()) | |
| { | | { | |
| TORRENT_ASSERT(!is_seed()); | | TORRENT_ASSERT(!is_seed()); | |
| m_picker->inc_refcount(index); | | m_picker->inc_refcount(index); | |
| } | | } | |
| | | | |
| skipping to change at line 532 | | skipping to change at line 581 | |
| m_picker->dec_refcount(index); | | m_picker->dec_refcount(index); | |
| } | | } | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| else | | else | |
| { | | { | |
| TORRENT_ASSERT(is_seed()); | | TORRENT_ASSERT(is_seed()); | |
| } | | } | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| int block_size() const { TORRENT_ASSERT(m_block_size > 0); r
eturn m_block_size; } | | int block_size() const { TORRENT_ASSERT(m_block_size_shift >
0); return 1 << m_block_size_shift; } | |
| peer_request to_req(piece_block const& p) const; | | peer_request to_req(piece_block const& p) const; | |
| | | | |
| void disconnect_all(error_code const& ec); | | void disconnect_all(error_code const& ec); | |
|
| int disconnect_peers(int num); | | int disconnect_peers(int num, error_code const& ec); | |
| | | | |
| // this is called wheh the torrent has completed | | // this is called wheh the torrent has completed | |
| // the download. It will post an event, disconnect | | // the download. It will post an event, disconnect | |
| // all seeds and let the tracker know we're finished. | | // all seeds and let the tracker know we're finished. | |
| void completed(); | | void completed(); | |
| | | | |
|
| | | #if TORRENT_USE_I2P | |
| | | void on_i2p_resolve(error_code const& ec, char const* dest); | |
| | | #endif | |
| | | | |
| // this is the asio callback that is called when a name | | // this is the asio callback that is called when a name | |
| // lookup for a PEER is completed. | | // lookup for a PEER is completed. | |
| void on_peer_name_lookup(error_code const& e, tcp::resolver:
:iterator i | | void on_peer_name_lookup(error_code const& e, tcp::resolver:
:iterator i | |
| , peer_id pid); | | , peer_id pid); | |
| | | | |
| // this is the asio callback that is called when a name | | // this is the asio callback that is called when a name | |
| // lookup for a WEB SEED is completed. | | // lookup for a WEB SEED is completed. | |
| void on_name_lookup(error_code const& e, tcp::resolver::iter
ator i | | void on_name_lookup(error_code const& e, tcp::resolver::iter
ator i | |
|
| , web_seed_entry url, tcp::endpoint proxy); | | , std::list<web_seed_entry>::iterator url, tcp::endp | |
| | | oint proxy); | |
| | | | |
| | | void connect_web_seed(std::list<web_seed_entry>::iterator we | |
| | | b, tcp::endpoint a); | |
| | | | |
| // this is the asio callback that is called when a name | | // this is the asio callback that is called when a name | |
| // lookup for a proxy for a web seed is completed. | | // lookup for a proxy for a web seed is completed. | |
| void on_proxy_name_lookup(error_code const& e, tcp::resolver
::iterator i | | void on_proxy_name_lookup(error_code const& e, tcp::resolver
::iterator i | |
|
| , web_seed_entry url); | | , std::list<web_seed_entry>::iterator url); | |
| | | | |
| | | // remove a web seed, or schedule it for removal in case the | |
| | | re | |
| | | // are outstanding operations on it | |
| | | void remove_web_seed(std::list<web_seed_entry>::iterator web | |
| | | ); | |
| | | | |
| // this is called when the torrent has finished. i.e. | | // this is called when the torrent has finished. i.e. | |
| // all the pieces we have not filtered have been downloaded. | | // all the pieces we have not filtered have been downloaded. | |
| // If no pieces are filtered, this is called first and then | | // If no pieces are filtered, this is called first and then | |
| // completed() is called immediately after it. | | // completed() is called immediately after it. | |
| void finished(); | | void finished(); | |
| | | | |
| // This is the opposite of finished. It is called if we used | | // This is the opposite of finished. It is called if we used | |
| // to be finished but enabled some files for download so tha
t | | // to be finished but enabled some files for download so tha
t | |
| // we wasn't finished anymore. | | // we wasn't finished anymore. | |
| | | | |
| skipping to change at line 591 | | skipping to change at line 650 | |
| | | | |
| // piece_failed is called when a piece fails the hash check | | // piece_failed is called when a piece fails the hash check | |
| void piece_failed(int index); | | void piece_failed(int index); | |
| | | | |
| // this will restore the piece picker state for a piece | | // this will restore the piece picker state for a piece | |
| // by re marking all the requests to blocks in this piece | | // by re marking all the requests to blocks in this piece | |
| // that are still outstanding in peers' download queues. | | // that are still outstanding in peers' download queues. | |
| // this is done when a piece fails | | // this is done when a piece fails | |
| void restore_piece_state(int index); | | void restore_piece_state(int index); | |
| | | | |
|
| void add_redundant_bytes(int b); | | enum wasted_reason_t | |
| | | { | |
| | | piece_timed_out, piece_cancelled, piece_unknown, pie | |
| | | ce_seed, piece_end_game, piece_closing | |
| | | , waste_reason_max | |
| | | }; | |
| | | void add_redundant_bytes(int b, wasted_reason_t reason); | |
| void add_failed_bytes(int b); | | void add_failed_bytes(int b); | |
| | | | |
| // this is true if we have all the pieces | | // this is true if we have all the pieces | |
| bool is_seed() const | | bool is_seed() const | |
| { | | { | |
| return valid_metadata() | | return valid_metadata() | |
| && (!m_picker | | && (!m_picker | |
| || m_state == torrent_status::seeding | | || m_state == torrent_status::seeding | |
| || m_picker->num_have() == m_picker->num_pie
ces()); | | || m_picker->num_have() == m_picker->num_pie
ces()); | |
| } | | } | |
| | | | |
| // this is true if we have all the pieces that we want | | // this is true if we have all the pieces that we want | |
| bool is_finished() const | | bool is_finished() const | |
| { | | { | |
| if (is_seed()) return true; | | if (is_seed()) return true; | |
| return valid_metadata() && m_torrent_file->num_piece
s() | | return valid_metadata() && m_torrent_file->num_piece
s() | |
| - m_picker->num_have() - m_picker->num_filte
red() == 0; | | - m_picker->num_have() - m_picker->num_filte
red() == 0; | |
| } | | } | |
| | | | |
|
| fs::path save_path() const; | | std::string save_path() const; | |
| alert_manager& alerts() const; | | alert_manager& alerts() const; | |
| piece_picker& picker() | | piece_picker& picker() | |
| { | | { | |
| TORRENT_ASSERT(m_picker.get()); | | TORRENT_ASSERT(m_picker.get()); | |
| return *m_picker; | | return *m_picker; | |
| } | | } | |
| bool has_picker() const | | bool has_picker() const | |
| { | | { | |
| return m_picker.get() != 0; | | return m_picker.get() != 0; | |
| } | | } | |
| policy& get_policy() { return m_policy; } | | policy& get_policy() { return m_policy; } | |
| piece_manager& filesystem(); | | piece_manager& filesystem(); | |
| torrent_info const& torrent_file() const | | torrent_info const& torrent_file() const | |
| { return *m_torrent_file; } | | { return *m_torrent_file; } | |
| | | | |
|
| | | std::string const& uuid() const { return m_uuid; } | |
| | | void set_uuid(std::string const& s) { m_uuid = s; } | |
| | | std::string const& url() const { return m_url; } | |
| | | void set_url(std::string const& s) { m_url = s; } | |
| | | std::string const& source_feed_url() const { return m_source | |
| | | _feed_url; } | |
| | | void set_source_feed_url(std::string const& s) { m_source_fe | |
| | | ed_url = s; } | |
| | | | |
| std::vector<announce_entry> const& trackers() const | | std::vector<announce_entry> const& trackers() const | |
| { return m_trackers; } | | { return m_trackers; } | |
| | | | |
| void replace_trackers(std::vector<announce_entry> const& url
s); | | void replace_trackers(std::vector<announce_entry> const& url
s); | |
| void add_tracker(announce_entry const& url); | | void add_tracker(announce_entry const& url); | |
| | | | |
| torrent_handle get_handle(); | | torrent_handle get_handle(); | |
| | | | |
| void write_resume_data(entry& rd) const; | | void write_resume_data(entry& rd) const; | |
| void read_resume_data(lazy_entry const& rd); | | void read_resume_data(lazy_entry const& rd); | |
| | | | |
|
| | | void seen_complete() { m_last_seen_complete = time(0); } | |
| | | int time_since_complete() const { return int(time(0) - m_las | |
| | | t_seen_complete); } | |
| | | time_t last_seen_complete() const { return m_last_seen_compl | |
| | | ete; } | |
| | | | |
| // LOGGING | | // LOGGING | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| virtual void debug_log(const std::string& line); | | virtual void debug_log(const std::string& line); | |
| #endif | | #endif | |
| | | | |
| // DEBUG | | // DEBUG | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // RESOURCE MANAGEMENT | | // RESOURCE MANAGEMENT | |
| | | | |
|
| void add_free_upload(int diff) { m_available_free_upload += | | void add_free_upload(size_type diff) | |
| diff; } | | { | |
| | | TORRENT_ASSERT(diff >= 0); | |
| | | if (UINT_MAX - m_available_free_upload > diff) | |
| | | m_available_free_upload += boost::uint32_t(d | |
| | | iff); | |
| | | else | |
| | | m_available_free_upload = UINT_MAX; | |
| | | } | |
| | | | |
|
| | | int get_peer_upload_limit(tcp::endpoint ip) const; | |
| | | int get_peer_download_limit(tcp::endpoint ip) const; | |
| void set_peer_upload_limit(tcp::endpoint ip, int limit); | | void set_peer_upload_limit(tcp::endpoint ip, int limit); | |
| void set_peer_download_limit(tcp::endpoint ip, int limit); | | void set_peer_download_limit(tcp::endpoint ip, int limit); | |
| | | | |
| void set_upload_limit(int limit); | | void set_upload_limit(int limit); | |
| int upload_limit() const; | | int upload_limit() const; | |
| void set_download_limit(int limit); | | void set_download_limit(int limit); | |
| int download_limit() const; | | int download_limit() const; | |
| | | | |
| void set_max_uploads(int limit); | | void set_max_uploads(int limit); | |
| int max_uploads() const { return m_max_uploads; } | | int max_uploads() const { return m_max_uploads; } | |
| void set_max_connections(int limit); | | void set_max_connections(int limit); | |
| int max_connections() const { return m_max_connections; } | | int max_connections() const { return m_max_connections; } | |
| | | | |
|
| void move_storage(fs::path const& save_path); | | void move_storage(std::string const& save_path); | |
| | | | |
| // renames the file with the given index to the new name | | // renames the file with the given index to the new name | |
| // the name may include a directory path | | // the name may include a directory path | |
| // returns false on failure | | // returns false on failure | |
| bool rename_file(int index, std::string const& name); | | bool rename_file(int index, std::string const& name); | |
| | | | |
| // unless this returns true, new connections must wait | | // unless this returns true, new connections must wait | |
| // with their initialization. | | // with their initialization. | |
| bool ready_for_connections() const | | bool ready_for_connections() const | |
| { return m_connections_initialized; } | | { return m_connections_initialized; } | |
| | | | |
| skipping to change at line 689 | | skipping to change at line 773 | |
| bool are_files_checked() const | | bool are_files_checked() const | |
| { return m_files_checked; } | | { return m_files_checked; } | |
| | | | |
| // parses the info section from the given | | // parses the info section from the given | |
| // bencoded tree and moves the torrent | | // bencoded tree and moves the torrent | |
| // to the checker thread for initial checking | | // to the checker thread for initial checking | |
| // of the storage. | | // of the storage. | |
| // a return value of false indicates an error | | // a return value of false indicates an error | |
| bool set_metadata(char const* metadata_buf, int metadata_siz
e); | | bool set_metadata(char const* metadata_buf, int metadata_siz
e); | |
| | | | |
|
| | | void on_torrent_download(error_code const& ec, http_parser c | |
| | | onst& parser | |
| | | , char const* data, int size); | |
| | | | |
| int sequence_number() const { return m_sequence_number; } | | int sequence_number() const { return m_sequence_number; } | |
| | | | |
| bool seed_mode() const { return m_seed_mode; } | | bool seed_mode() const { return m_seed_mode; } | |
| void leave_seed_mode(bool seed) | | void leave_seed_mode(bool seed) | |
| { | | { | |
| if (!m_seed_mode) return; | | if (!m_seed_mode) return; | |
| m_seed_mode = false; | | m_seed_mode = false; | |
| // seed is false if we turned out not | | // seed is false if we turned out not | |
| // to be a seed after all | | // to be a seed after all | |
| if (!seed) force_recheck(); | | if (!seed) force_recheck(); | |
| | | | |
| skipping to change at line 725 | | skipping to change at line 812 | |
| ++m_num_verified; | | ++m_num_verified; | |
| m_verified.set_bit(piece); | | m_verified.set_bit(piece); | |
| } | | } | |
| | | | |
| bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int
piece); | | bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int
piece); | |
| | | | |
| // this is called once periodically for torrents | | // this is called once periodically for torrents | |
| // that are not private | | // that are not private | |
| void lsd_announce(); | | void lsd_announce(); | |
| | | | |
|
| | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | |
| | | ORRENT_ERROR_LOGGING | |
| | | static void print_size(logger& l); | |
| | | #endif | |
| | | | |
| | | void update_last_upload() { m_last_upload = 0; } | |
| | | | |
| | | void set_apply_ip_filter(bool b); | |
| | | bool apply_ip_filter() const { return m_apply_ip_filter; } | |
| | | | |
| | | void queue_torrent_check(); | |
| | | void dequeue_torrent_check(); | |
| | | | |
| | | void clear_in_state_update() | |
| | | { m_in_state_updates = false; } | |
| | | | |
| | | void inc_num_connecting() | |
| | | { ++m_num_connecting; } | |
| | | void dec_num_connecting() | |
| | | { | |
| | | TORRENT_ASSERT(m_num_connecting > 0); | |
| | | --m_num_connecting; | |
| | | } | |
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | void set_ssl_cert(std::string const& certificate | |
| | | , std::string const& private_key | |
| | | , std::string const& dh_params | |
| | | , std::string const& passphrase); | |
| | | bool is_ssl_torrent() const { return m_ssl_ctx; } | |
| | | boost::asio::ssl::context* ssl_ctx() const { return m_ssl_ct | |
| | | x.get(); } | |
| | | #endif | |
| | | | |
| private: | | private: | |
| | | | |
| void on_files_deleted(int ret, disk_io_job const& j); | | void on_files_deleted(int ret, disk_io_job const& j); | |
| void on_files_released(int ret, disk_io_job const& j); | | void on_files_released(int ret, disk_io_job const& j); | |
|
| void on_torrent_aborted(int ret, disk_io_job const& j); | | | |
| void on_torrent_paused(int ret, disk_io_job const& j); | | void on_torrent_paused(int ret, disk_io_job const& j); | |
| void on_storage_moved(int ret, disk_io_job const& j); | | void on_storage_moved(int ret, disk_io_job const& j); | |
| void on_save_resume_data(int ret, disk_io_job const& j); | | void on_save_resume_data(int ret, disk_io_job const& j); | |
| void on_file_renamed(int ret, disk_io_job const& j); | | void on_file_renamed(int ret, disk_io_job const& j); | |
| void on_cache_flushed(int ret, disk_io_job const& j); | | void on_cache_flushed(int ret, disk_io_job const& j); | |
| | | | |
| void on_piece_verified(int ret, disk_io_job const& j | | void on_piece_verified(int ret, disk_io_job const& j | |
| , boost::function<void(int)> f); | | , boost::function<void(int)> f); | |
| | | | |
| int prioritize_tracker(int tracker_index); | | int prioritize_tracker(int tracker_index); | |
| int deprioritize_tracker(int tracker_index); | | int deprioritize_tracker(int tracker_index); | |
| | | | |
| void on_country_lookup(error_code const& error, tcp::resolve
r::iterator i | | void on_country_lookup(error_code const& error, tcp::resolve
r::iterator i | |
| , boost::intrusive_ptr<peer_connection> p) const; | | , boost::intrusive_ptr<peer_connection> p) const; | |
| bool request_bandwidth_from_session(int channel) const; | | bool request_bandwidth_from_session(int channel) const; | |
| | | | |
| void update_peer_interest(bool was_finished); | | void update_peer_interest(bool was_finished); | |
| void prioritize_udp_trackers(); | | void prioritize_udp_trackers(); | |
| | | | |
|
| void queue_torrent_check(); | | void parse_response(const entry& e, std::vector<peer_entry>& | |
| void dequeue_torrent_check(); | | peer_list); | |
| | | | |
|
| policy m_policy; | | void update_tracker_timer(ptime now); | |
| | | | |
|
| // total time we've been available on this torrent | | static void on_tracker_announce_disp(boost::weak_ptr<torrent | |
| // does not count when the torrent is stopped or paused | | > p | |
| time_duration m_active_time; | | , error_code const& e); | |
| | | | |
|
| // total time we've been finished with this torrent | | void on_tracker_announce(); | |
| // does not count when the torrent is stopped or paused | | | |
| time_duration m_finished_time; | | | |
| | | | |
|
| // total time we've been available as a seed on this torrent | | #ifndef TORRENT_DISABLE_DHT | |
| // does not count when the torrent is stopped or paused | | static void on_dht_announce_response_disp(boost::weak_ptr<to | |
| time_duration m_seeding_time; | | rrent> t | |
| | | , std::vector<tcp::endpoint> const& peers); | |
| | | void on_dht_announce_response(std::vector<tcp::endpoint> con | |
| | | st& peers); | |
| | | bool should_announce_dht() const; | |
| | | #endif | |
| | | | |
| | | void remove_time_critical_piece(int piece, bool finished = f | |
| | | alse); | |
| | | void remove_time_critical_pieces(std::vector<int> const& pri | |
| | | ority); | |
| | | void request_time_critical_pieces(); | |
| | | | |
| | | policy m_policy; | |
| | | | |
| // all time totals of uploaded and downloaded payload | | // all time totals of uploaded and downloaded payload | |
| // stored in resume data | | // stored in resume data | |
| size_type m_total_uploaded; | | size_type m_total_uploaded; | |
| size_type m_total_downloaded; | | size_type m_total_downloaded; | |
| | | | |
| // if this torrent is running, this was the time | | // if this torrent is running, this was the time | |
| // when it was started. This is used to have a | | // when it was started. This is used to have a | |
| // bias towards keeping seeding torrents that | | // bias towards keeping seeding torrents that | |
| // recently was started, to avoid oscillation | | // recently was started, to avoid oscillation | |
| ptime m_started; | | ptime m_started; | |
| | | | |
|
| // the last time we initiated a scrape request to | | | |
| // one of the trackers in this torrent | | | |
| ptime m_last_scrape; | | | |
| | | | |
| // the time when we switched to upload mode | | | |
| ptime m_upload_mode_time; | | | |
| | | | |
| boost::intrusive_ptr<torrent_info> m_torrent_file; | | boost::intrusive_ptr<torrent_info> m_torrent_file; | |
| | | | |
|
| void parse_response(const entry& e, std::vector<peer_entry>& | | | |
| peer_list); | | | |
| | | | |
| // if this pointer is 0, the torrent is in | | // if this pointer is 0, the torrent is in | |
| // a state where the metadata hasn't been | | // a state where the metadata hasn't been | |
| // received yet. | | // received yet. | |
| // the piece_manager keeps the torrent object | | // the piece_manager keeps the torrent object | |
| // alive by holding a shared_ptr to it and | | // alive by holding a shared_ptr to it and | |
| // the torrent keeps the piece manager alive | | // the torrent keeps the piece manager alive | |
| // with this intrusive_ptr. This cycle is | | // with this intrusive_ptr. This cycle is | |
| // broken when torrent::abort() is called | | // broken when torrent::abort() is called | |
| // Then the torrent releases the piece_manager | | // Then the torrent releases the piece_manager | |
| // and when the piece_manager is complete with all | | // and when the piece_manager is complete with all | |
| | | | |
| skipping to change at line 813 | | skipping to change at line 926 | |
| // torrent, so the torrent cannot destruct | | // torrent, so the torrent cannot destruct | |
| // before the piece_manager. | | // before the piece_manager. | |
| boost::intrusive_ptr<piece_manager> m_owning_storage; | | boost::intrusive_ptr<piece_manager> m_owning_storage; | |
| | | | |
| // this is a weak (non owninig) pointer to | | // this is a weak (non owninig) pointer to | |
| // the piece_manager. This is used after the torrent | | // the piece_manager. This is used after the torrent | |
| // has been aborted, and it can no longer own | | // has been aborted, and it can no longer own | |
| // the object. | | // the object. | |
| piece_manager* m_storage; | | piece_manager* m_storage; | |
| | | | |
|
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | boost::shared_ptr<asio::ssl::context> m_ssl_ctx; | |
| | | | |
| | | #if BOOST_VERSION >= 104700 | |
| | | bool verify_peer_cert(bool preverified, boost::asio::ssl::ve | |
| | | rify_context& ctx); | |
| | | #endif | |
| | | | |
| | | void init_ssl(std::string const& cert); | |
| | | #endif | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| public: | | public: | |
| #endif | | #endif | |
| std::set<peer_connection*> m_connections; | | std::set<peer_connection*> m_connections; | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| private: | | private: | |
| #endif | | #endif | |
| | | | |
|
| | | // of all peers in m_connections, this is the number | |
| | | // of peers that are outgoing and still waiting to | |
| | | // complete the connection. This is used to possibly | |
| | | // kick out these connections when we get incoming | |
| | | // connections (if we've reached the connection limit) | |
| | | int m_num_connecting; | |
| | | | |
| // The list of web seeds in this torrent. Seeds | | // The list of web seeds in this torrent. Seeds | |
| // with fatal errors are removed from the set | | // with fatal errors are removed from the set | |
|
| std::set<web_seed_entry> m_web_seeds; | | std::list<web_seed_entry> m_web_seeds; | |
| | | | |
| // a list of web seeds that have failed and are | | | |
| // waiting to be retried | | | |
| std::map<web_seed_entry, ptime> m_web_seeds_next_retry; | | | |
| | | | |
| // urls of the web seeds that we are currently | | | |
| // resolving the address for | | | |
| std::set<web_seed_entry> m_resolving_web_seeds; | | | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| typedef std::list<boost::shared_ptr<torrent_plugin> > extens
ion_list_t; | | typedef std::list<boost::shared_ptr<torrent_plugin> > extens
ion_list_t; | |
| extension_list_t m_extensions; | | extension_list_t m_extensions; | |
| #endif | | #endif | |
| | | | |
|
| // used to resolve the names of web seeds | | | |
| mutable tcp::resolver m_host_resolver; | | | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | | |
| // this announce timer is used both | | | |
| // by Local service discovery and | | | |
| // by the DHT. | | | |
| deadline_timer m_dht_announce_timer; | | | |
| #endif | | | |
| | | | |
| // used for tracker announces | | // used for tracker announces | |
| deadline_timer m_tracker_timer; | | deadline_timer m_tracker_timer; | |
| | | | |
|
| void update_tracker_timer(ptime now); | | | |
| | | | |
| static void on_tracker_announce_disp(boost::weak_ptr<torrent | | | |
| > p | | | |
| , error_code const& e); | | | |
| | | | |
| void on_tracker_announce(); | | | |
| | | | |
| void dht_announce(); | | | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | | |
| static void on_dht_announce_post(boost::weak_ptr<libtorrent: | | | |
| :torrent> t | | | |
| , std::vector<tcp::endpoint> const& peers); | | | |
| static void on_dht_announce_response_disp(boost::weak_ptr<to | | | |
| rrent> t | | | |
| , std::vector<tcp::endpoint> const& peers); | | | |
| void on_dht_announce_response(std::vector<tcp::endpoint> con | | | |
| st& peers); | | | |
| bool should_announce_dht() const; | | | |
| void on_dht_announce(error_code const& e); | | | |
| | | | |
| // the time when the DHT was last announced of our | | | |
| // presence on this torrent | | | |
| ptime m_last_dht_announce; | | | |
| #endif | | | |
| | | | |
| // this is the upload and download statistics for the whole
torrent. | | // this is the upload and download statistics for the whole
torrent. | |
| // it's updated from all its peers once every second. | | // it's updated from all its peers once every second. | |
| libtorrent::stat m_stat; | | libtorrent::stat m_stat; | |
| | | | |
| // ----------------------------- | | // ----------------------------- | |
| | | | |
| // a back reference to the session | | // a back reference to the session | |
| // this torrent belongs to. | | // this torrent belongs to. | |
| aux::session_impl& m_ses; | | aux::session_impl& m_ses; | |
| | | | |
| | | | |
| skipping to change at line 914 | | skipping to change at line 1003 | |
| // 1 = send alert with piece data when available | | // 1 = send alert with piece data when available | |
| int flags; | | int flags; | |
| // how many peers it's been requested from | | // how many peers it's been requested from | |
| int peers; | | int peers; | |
| // the piece index | | // the piece index | |
| int piece; | | int piece; | |
| bool operator<(time_critical_piece const& rhs) const | | bool operator<(time_critical_piece const& rhs) const | |
| { return deadline < rhs.deadline; } | | { return deadline < rhs.deadline; } | |
| }; | | }; | |
| | | | |
|
| void remove_time_critical_piece(int piece, bool finished = f | | | |
| alse); | | | |
| void remove_time_critical_pieces(std::vector<int> const& pri | | | |
| ority); | | | |
| void request_time_critical_pieces(); | | | |
| | | | |
| // this list is sorted by time_critical_piece::deadline | | // this list is sorted by time_critical_piece::deadline | |
| std::list<time_critical_piece> m_time_critical_pieces; | | std::list<time_critical_piece> m_time_critical_pieces; | |
| | | | |
|
| // the average time it takes to download one time critical p | | std::string m_trackerid; | |
| iece | | std::string m_username; | |
| time_duration m_average_piece_time; | | std::string m_password; | |
| // the average piece download time deviation | | | |
| time_duration m_piece_time_deviation; | | | |
| | | | |
|
| // the number of bytes that has been | | // the network interfaces outgoing connections | |
| // downloaded that failed the hash-test | | // are opened through. If there is more then one, | |
| size_type m_total_failed_bytes; | | // they are used in a round-robin fasion | |
| size_type m_total_redundant_bytes; | | std::vector<union_endpoint> m_net_interfaces; | |
| | | | |
|
| // the number of bytes of padding files | | std::string m_save_path; | |
| int m_padding; | | | |
| | | | |
|
| std::string m_username; | | // if we don't have the metadata, this is a url to | |
| std::string m_password; | | // the torrent file | |
| | | std::string m_url; | |
| | | | |
|
| // the network interface all outgoing connections | | // if this was added from an RSS feed, this is the unique | |
| // are opened through | | // identifier in the feed. | |
| tcp::endpoint m_net_interface; | | std::string m_uuid; | |
| | | | |
|
| fs::path m_save_path; | | // if this torrent was added by an RSS feed, this is the | |
| | | // URL to that feed | |
| | | std::string m_source_feed_url; | |
| | | | |
| | | // this is used as temporary storage while downloading | |
| | | // the .torrent file from m_url | |
| | | std::vector<char> m_torrent_file_buf; | |
| | | | |
| // each bit represents a piece. a set bit means | | // each bit represents a piece. a set bit means | |
| // the piece has had its hash verified. This | | // the piece has had its hash verified. This | |
| // is only used in seed mode (when m_seed_mode | | // is only used in seed mode (when m_seed_mode | |
| // is true) | | // is true) | |
| bitfield m_verified; | | bitfield m_verified; | |
|
| // m_num_verified = m_verified.count() | | | |
| int m_num_verified; | | | |
| | | | |
| // free download we have got that hasn't | | | |
| // been distributed yet. | | | |
| size_type m_available_free_upload; | | | |
| | | | |
| // determines the storage state for this torrent. | | | |
| storage_mode_t m_storage_mode; | | | |
| | | | |
| // the state of this torrent (queued, checking, downloading, | | | |
| etc.) | | | |
| torrent_status::state_t m_state; | | | |
| | | | |
| // set if there's an error on this torrent | | // set if there's an error on this torrent | |
| error_code m_error; | | error_code m_error; | |
| // if the error ocurred on a file, this is the file | | // if the error ocurred on a file, this is the file | |
| std::string m_error_file; | | std::string m_error_file; | |
| | | | |
| // used if there is any resume data | | // used if there is any resume data | |
| std::vector<char> m_resume_data; | | std::vector<char> m_resume_data; | |
| lazy_entry m_resume_entry; | | lazy_entry m_resume_entry; | |
| | | | |
| // if the torrent is started without metadata, it may | | // if the torrent is started without metadata, it may | |
| // still be given a name until the metadata is received | | // still be given a name until the metadata is received | |
| // once the metadata is received this field will no | | // once the metadata is received this field will no | |
| // longer be used and will be reset | | // longer be used and will be reset | |
| boost::scoped_ptr<std::string> m_name; | | boost::scoped_ptr<std::string> m_name; | |
| | | | |
|
| | | storage_constructor_type m_storage_constructor; | |
| | | | |
| | | // the posix time this torrent was added and when | |
| | | // it was completed. If the torrent isn't yet | |
| | | // completed, m_completed_time is 0 | |
| | | time_t m_added_time; | |
| | | time_t m_completed_time; | |
| | | time_t m_last_seen_complete; | |
| | | time_t m_last_saved_resume; | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| // this is SHA1("req2" + info-hash), used for | | // this is SHA1("req2" + info-hash), used for | |
| // encrypted hand shakes | | // encrypted hand shakes | |
| sha1_hash m_obfuscated_hash; | | sha1_hash m_obfuscated_hash; | |
| #endif | | #endif | |
|
| session_settings const& m_settings; | | | |
| | | | |
| storage_constructor_type m_storage_constructor; | | | |
| | | | |
| int m_progress_ppm; | | | |
| | | | |
| // the upload/download ratio that each peer | | // the upload/download ratio that each peer | |
| // tries to maintain. | | // tries to maintain. | |
| // 0 is infinite | | // 0 is infinite | |
| float m_ratio; | | float m_ratio; | |
| | | | |
|
| // the maximum number of uploads for this torrent | | // free download we have got that hasn't | |
| int m_max_uploads; | | // been distributed yet. | |
| | | boost::uint32_t m_available_free_upload; | |
| // the number of unchoked peers in this torrent | | | |
| int m_num_uploads; | | | |
| | | | |
| // the maximum number of connections for this torrent | | | |
| int m_max_connections; | | | |
| | | | |
| // the size of a request block | | | |
| // each piece is divided into these | | | |
| // blocks when requested | | | |
| int m_block_size; | | | |
| | | | |
| // ----------------------------- | | | |
| // DATA FROM TRACKER RESPONSE | | | |
| | | | |
|
| // the scrape data from the tracker response, this | | // the average time it takes to download one time critical p | |
| // is optional and may be -1. | | iece | |
| int m_complete; | | boost::uint32_t m_average_piece_time; | |
| int m_incomplete; | | // the average piece download time deviation | |
| | | boost::uint32_t m_piece_time_deviation; | |
| | | | |
|
| #ifdef TORRENT_DEBUG | | // the number of bytes that has been | |
| // this is the amount downloaded when this torrent | | // downloaded that failed the hash-test | |
| // is started. i.e. | | boost::uint32_t m_total_failed_bytes; | |
| // total_done - m_initial_done <= total_payload_download | | boost::uint32_t m_total_redundant_bytes; | |
| size_type m_initial_done; | | | |
| #endif | | | |
| // this is the deficit counter in the Deficit Round Robin | | | |
| // used to determine which torrent gets the next | | | |
| // connection attempt. See: | | | |
| // http://www.ecs.umass.edu/ece/wolf/courses/ECE697J/papers/ | | | |
| DRR.pdf | | | |
| // The quanta assigned to each torrent depends on the torren | | | |
| ts | | | |
| // priority, whether it's seed and the number of connected | | | |
| // peers it has. This has the effect that some torrents | | | |
| // will have more connection attempts than other. Each | | | |
| // connection attempt costs 100 points from the deficit | | | |
| // counter. points are deducted in try_connect_peer and | | | |
| // increased in give_connect_points. Outside of the | | | |
| // torrent object, these points are called connect_points. | | | |
| int m_deficit_counter; | | | |
| | | | |
| // the sequence number for this torrent, this is a | | // the sequence number for this torrent, this is a | |
| // monotonically increasing number for each added torrent | | // monotonically increasing number for each added torrent | |
|
| boost::int16_t m_sequence_number; | | int m_sequence_number; | |
| | | | |
|
| // the index to the last tracker that worked | | // ============================== | |
| boost::int8_t m_last_working_tracker; | | // The following members are specifically | |
| | | // ordered to make the 24 bit members | |
| | | // properly 32 bit aligned by inserting | |
| | | // 8 bits after each one | |
| | | // ============================== | |
| | | | |
|
| // the number of connection attempts that has | | // the number of seconds we've been in upload mode | |
| // failed in a row, this is currently used to | | unsigned int m_upload_mode_time:24; | |
| // determine the timeout until next try. | | | |
| boost::int8_t m_failed_trackers; | | | |
| | | | |
|
| // this is a counter that is decreased every | | // the state of this torrent (queued, checking, downloading, | |
| // second, and when it reaches 0, the policy::pulse() | | etc.) | |
| // is called and the time scaler is reset to 10. | | unsigned int m_state:3; | |
| boost::int8_t m_time_scaler; | | | |
| | | | |
|
| // this is the priority of the torrent. The higher | | // determines the storage state for this torrent. | |
| // the value is, the more bandwidth is assigned to | | unsigned int m_storage_mode:2; | |
| // the torrent's peers | | | |
| boost::uint8_t m_priority; | | | |
| | | | |
|
| // is set to true when the torrent has | | // this is true while tracker announcing is enabled | |
| // been aborted. | | // is is disabled while paused and checking files | |
| bool m_abort:1; | | bool m_announcing:1; | |
| | | | |
|
| // is true if this torrent has been paused | | // this is true while the tracker deadline timer | |
| bool m_paused:1; | | // is in use. i.e. one or more trackers are waiting | |
| | | // for a reannounce | |
| | | bool m_waiting_tracker:1; | |
| | | | |
|
| // set to true when this torrent may not download anything | | // this means we haven't verified the file content | |
| bool m_upload_mode:1; | | // of the files we're seeding. the m_verified bitfield | |
| | | // indicates which pieces have been verified and which | |
| | | // haven't | |
| | | bool m_seed_mode:1; | |
| | | | |
|
| // if this is true, libtorrent may pause and resume | | // total time we've been available on this torrent | |
| // this torrent depending on queuing rules. Torrents | | // does not count when the torrent is stopped or paused | |
| // started with auto_managed flag set may be added in | | // in seconds | |
| // a paused state in case there are no available | | unsigned int m_active_time:24; | |
| // slots. | | | |
| bool m_auto_managed:1; | | | |
| | | | |
|
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | // the index to the last tracker that worked | |
| // this is true while there is a country | | boost::int8_t m_last_working_tracker; | |
| // resolution in progress. To avoid flodding | | | |
| // the DNS request queue, only one ip is resolved | | | |
| // at a time. | | | |
| mutable bool m_resolving_country:1; | | | |
| | | | |
|
| // this is true if the user has enabled | | // total time we've been finished with this torrent | |
| // country resolution in this torrent | | // does not count when the torrent is stopped or paused | |
| bool m_resolve_countries:1; | | unsigned int m_finished_time:24; | |
| #endif | | | |
| | | | |
| // in case the piece picker hasn't been constructed | | // in case the piece picker hasn't been constructed | |
| // when this settings is set, this variable will keep | | // when this settings is set, this variable will keep | |
| // its value until the piece picker is created | | // its value until the piece picker is created | |
| bool m_sequential_download:1; | | bool m_sequential_download:1; | |
| | | | |
| // is false by default and set to | | // is false by default and set to | |
| // true when the first tracker reponse | | // true when the first tracker reponse | |
| // is received | | // is received | |
| bool m_got_tracker_response:1; | | bool m_got_tracker_response:1; | |
| | | | |
| skipping to change at line 1110 | | skipping to change at line 1161 | |
| // valid_resume_data() will return false as long as | | // valid_resume_data() will return false as long as | |
| // the connections aren't initialized, to avoid | | // the connections aren't initialized, to avoid | |
| // them from altering the piece-picker before it | | // them from altering the piece-picker before it | |
| // has been initialized with files_checked(). | | // has been initialized with files_checked(). | |
| bool m_connections_initialized:1; | | bool m_connections_initialized:1; | |
| | | | |
| // if this is true, we're currently super seeding this | | // if this is true, we're currently super seeding this | |
| // torrent. | | // torrent. | |
| bool m_super_seeding:1; | | bool m_super_seeding:1; | |
| | | | |
|
| | | // this is set when we don't want to load seed_mode, | |
| | | // paused or auto_managed from the resume data | |
| | | bool m_override_resume_data:1; | |
| | | | |
| | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| | | // this is true while there is a country | |
| | | // resolution in progress. To avoid flodding | |
| | | // the DNS request queue, only one ip is resolved | |
| | | // at a time. | |
| | | mutable bool m_resolving_country:1; | |
| | | | |
| | | // this is true if the user has enabled | |
| | | // country resolution in this torrent | |
| | | bool m_resolve_countries:1; | |
| | | #else | |
| | | unsigned int m_dummy_padding_bits_to_align:2; | |
| | | #endif | |
| | | | |
| | | // set to false when saving resume data. Set to true | |
| | | // whenever something is downloaded | |
| | | bool m_need_save_resume_data:1; | |
| | | | |
| | | // total time we've been available as a seed on this torrent | |
| | | // does not count when the torrent is stopped or paused | |
| | | unsigned int m_seeding_time:24; | |
| | | | |
| | | // this is a counter that is decreased every | |
| | | // second, and when it reaches 0, the policy::pulse() | |
| | | // is called and the time scaler is reset to 10. | |
| | | boost::int8_t m_time_scaler; | |
| | | | |
| | | // the maximum number of uploads for this torrent | |
| | | unsigned int m_max_uploads:24; | |
| | | | |
| | | // these are the flags sent in on a call to save_resume_data | |
| | | // we need to save them to check them in write_resume_data | |
| | | boost::uint8_t m_save_resume_flags; | |
| | | | |
| | | // the number of unchoked peers in this torrent | |
| | | unsigned int m_num_uploads:24; | |
| | | | |
| | | // the size of a request block | |
| | | // each piece is divided into these | |
| | | // blocks when requested. The block size is | |
| | | // 1 << m_block_size_shift | |
| | | unsigned int m_block_size_shift:5; | |
| | | | |
| // is set to true every time there is an incoming | | // is set to true every time there is an incoming | |
| // connection to this torrent | | // connection to this torrent | |
| bool m_has_incoming:1; | | bool m_has_incoming:1; | |
| | | | |
| // this is set to true when the files are checked | | // this is set to true when the files are checked | |
| // before the files are checked, we don't try to | | // before the files are checked, we don't try to | |
| // connect to peers | | // connect to peers | |
| bool m_files_checked:1; | | bool m_files_checked:1; | |
| | | | |
| // this is true if the torrent has been added to | | // this is true if the torrent has been added to | |
| // checking queue in the session | | // checking queue in the session | |
| bool m_queued_for_checking:1; | | bool m_queued_for_checking:1; | |
| | | | |
|
| // this is true while tracker announcing is enabled | | // the maximum number of connections for this torrent | |
| // is is disabled while paused and checking files | | unsigned int m_max_connections:24; | |
| bool m_announcing:1; | | | |
| | | | |
|
| // this is true while the tracker deadline timer | | // the number of bytes of padding files | |
| // is in use. i.e. one or more trackers are waiting | | unsigned int m_padding:24; | |
| // for a reannounce | | | |
| bool m_waiting_tracker:1; | | | |
| | | | |
|
| // this means we haven't verified the file content | | // the scrape data from the tracker response, this | |
| // of the files we're seeding. the m_verified bitfield | | // is optional and may be 0xffffff | |
| // indicates which pieces have been verified and which | | unsigned int m_complete:24; | |
| // haven't | | | |
| bool m_seed_mode:1; | | | |
| | | | |
|
| // this is set when we don't want to load seed_mode, | | // this is the priority of the torrent. The higher | |
| // paused or auto_managed from the resume data | | // the value is, the more bandwidth is assigned to | |
| bool m_override_resume_data:1; | | // the torrent's peers | |
| | | boost::uint8_t m_priority; | |
| | | | |
| | | // the scrape data from the tracker response, this | |
| | | // is optional and may be 0xffffff | |
| | | unsigned int m_incomplete:24; | |
| | | | |
| | | // progress parts per million (the number of | |
| | | // millionths of completeness) | |
| | | unsigned int m_progress_ppm:20; | |
| | | | |
| | | // is set to true when the torrent has | |
| | | // been aborted. | |
| | | bool m_abort:1; | |
| | | | |
| | | // true when the torrent should announce to | |
| | | // the DHT | |
| | | bool m_announce_to_dht:1; | |
| | | | |
| | | // true when this torrent should anncounce to | |
| | | // trackers | |
| | | bool m_announce_to_trackers:1; | |
| | | | |
| | | // true when this torrent should anncounce to | |
| | | // the local network | |
| | | bool m_announce_to_lsd:1; | |
| | | | |
| | | // is true if this torrent has allows having peers | |
| | | bool m_allow_peers:1; | |
| | | | |
| | | // set to true when this torrent may not download anything | |
| | | bool m_upload_mode:1; | |
| | | | |
| | | // if this is true, libtorrent may pause and resume | |
| | | // this torrent depending on queuing rules. Torrents | |
| | | // started with auto_managed flag set may be added in | |
| | | // a paused state in case there are no available | |
| | | // slots. | |
| | | bool m_auto_managed:1; | |
| | | | |
| | | // this is set when the torrent is in share-mode | |
| | | bool m_share_mode:1; | |
| | | | |
| | | // m_num_verified = m_verified.count() | |
| | | boost::uint16_t m_num_verified; | |
| | | | |
| | | // the number of seconds since the last scrape request to | |
| | | // one of the trackers in this torrent | |
| | | boost::uint16_t m_last_scrape; | |
| | | | |
| | | // the number of seconds since the last piece passed for | |
| | | // this torrent | |
| | | boost::uint16_t m_last_download; | |
| | | | |
| | | // the number of seconds since the last byte was uploaded | |
| | | // from this torrent | |
| | | boost::uint16_t m_last_upload; | |
| | | | |
| | | // the scrape data from the tracker response, this | |
| | | // is optional and may be 0xffffff | |
| | | unsigned int m_downloaders:24; | |
| | | | |
| | | // round-robin index into m_interfaces | |
| | | mutable boost::uint8_t m_interface_index; | |
| | | | |
| | | // set to true when this torrent has been paused but | |
| | | // is waiting to finish all current download requests | |
| | | // before actually closing all connections | |
| | | bool m_graceful_pause_mode:1; | |
| | | | |
| | | // this is set to true when the torrent starts up | |
| | | // The first tracker response, when this is true, | |
| | | // will attempt to connect to a bunch of peers immediately | |
| | | // and set this to false. We only do this once to get | |
| | | // the torrent kick-started | |
| | | bool m_need_connect_boost:1; | |
| | | | |
| | | // rotating sequence number for LSD announces sent out. | |
| | | // used to only use IP broadcast for every 8th lsd announce | |
| | | boost::uint8_t m_lsd_seq:3; | |
| | | | |
| | | // this is set to true if the torrent was started without | |
| | | // metadata. It is used to save metadata in the resume file | |
| | | // by default for such torrents. It does not necessarily | |
| | | // have to be a magnet link. | |
| | | bool m_magnet_link:1; | |
| | | | |
| | | // set to true if the session IP filter applies to this | |
| | | // torrent or not. Defaults to true. | |
| | | bool m_apply_ip_filter:1; | |
| | | | |
| | | // if set to true, add tracker URLs loaded from resume | |
| | | // data into this torrent instead of replacing them | |
| | | bool m_merge_resume_trackers:1; | |
| | | | |
| | | // state subscription. If set, a pointer to this torrent | |
| | | // will be added to the m_state_updates set in session_impl | |
| | | // whenever this torrent's state changes (any state). | |
| | | bool m_state_subscription:1; | |
| | | | |
| | | // in state_updates list. When adding a torrent to the | |
| | | // session_impl's m_state_update list, this bit is set | |
| | | // to never add the same torrent twice | |
| | | bool m_in_state_updates:1; | |
| | | | |
| | | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |
| | | public: | |
| | | // set to false until we've loaded resume data | |
| | | bool m_resume_data_loaded; | |
| | | #endif | |
| }; | | }; | |
| } | | } | |
| | | | |
| #endif // TORRENT_TORRENT_HPP_INCLUDED | | #endif // TORRENT_TORRENT_HPP_INCLUDED | |
| | | | |
End of changes. 110 change blocks. |
| 291 lines changed or deleted | | 518 lines changed or added | |
|
| torrent_handle.hpp | | torrent_handle.hpp | |
| | | | |
| skipping to change at line 43 | | skipping to change at line 43 | |
| #ifndef TORRENT_TORRENT_HANDLE_HPP_INCLUDED | | #ifndef TORRENT_TORRENT_HANDLE_HPP_INCLUDED | |
| #define TORRENT_TORRENT_HANDLE_HPP_INCLUDED | | #define TORRENT_TORRENT_HANDLE_HPP_INCLUDED | |
| | | | |
| #include <vector> | | #include <vector> | |
| #include <set> | | #include <set> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
|
| #include <boost/date_time/posix_time/posix_time_types.hpp> | | #include <boost/assert.hpp> | |
| | | #include <boost/date_time/posix_time/posix_time_duration.hpp> | |
| #include <boost/shared_ptr.hpp> | | #include <boost/shared_ptr.hpp> | |
| #include <boost/weak_ptr.hpp> | | #include <boost/weak_ptr.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
|
| #include "libtorrent/peer_info.hpp" | | | |
| #include "libtorrent/piece_picker.hpp" | | #include "libtorrent/piece_picker.hpp" | |
| #include "libtorrent/torrent_info.hpp" | | #include "libtorrent/torrent_info.hpp" | |
|
| #include "libtorrent/time.hpp" | | #include "libtorrent/ptime.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
|
| | | #include "libtorrent/address.hpp" | |
| | | #include "libtorrent/bitfield.hpp" | |
| | | #include "libtorrent/socket.hpp" // tcp::endpoint | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| namespace fs = boost::filesystem; | | | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
| struct session_impl; | | struct session_impl; | |
|
| struct checker_impl; | | | |
| } | | } | |
| | | | |
| struct torrent_plugin; | | struct torrent_plugin; | |
|
| | | struct peer_info; | |
| | | struct peer_list_entry; | |
| | | struct torrent_status; | |
| | | | |
| | | TORRENT_EXPORT std::size_t hash_value(torrent_status const& ts); | |
| | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
| // for compatibility with 0.14 | | // for compatibility with 0.14 | |
| typedef libtorrent_exception duplicate_torrent; | | typedef libtorrent_exception duplicate_torrent; | |
| typedef libtorrent_exception invalid_handle; | | typedef libtorrent_exception invalid_handle; | |
| void throw_invalid_handle(); | | void throw_invalid_handle(); | |
| #endif | | #endif | |
| | | | |
|
| struct TORRENT_EXPORT torrent_status | | | |
| { | | | |
| torrent_status() | | | |
| : state(checking_resume_data) | | | |
| , paused(false) | | | |
| , progress(0.f) | | | |
| , progress_ppm(0) | | | |
| , total_download(0) | | | |
| , total_upload(0) | | | |
| , total_payload_download(0) | | | |
| , total_payload_upload(0) | | | |
| , total_failed_bytes(0) | | | |
| , total_redundant_bytes(0) | | | |
| , download_rate(0) | | | |
| , upload_rate(0) | | | |
| , download_payload_rate(0) | | | |
| , upload_payload_rate(0) | | | |
| , num_seeds(0) | | | |
| , num_peers(0) | | | |
| , num_complete(-1) | | | |
| , num_incomplete(-1) | | | |
| , list_seeds(0) | | | |
| , list_peers(0) | | | |
| , connect_candidates(0) | | | |
| , num_pieces(0) | | | |
| , total_done(0) | | | |
| , total_wanted_done(0) | | | |
| , total_wanted(0) | | | |
| , distributed_full_copies(0) | | | |
| , distributed_fraction(0) | | | |
| , distributed_copies(0.f) | | | |
| , block_size(0) | | | |
| , num_uploads(0) | | | |
| , num_connections(0) | | | |
| , uploads_limit(0) | | | |
| , connections_limit(0) | | | |
| , storage_mode(storage_mode_sparse) | | | |
| , up_bandwidth_queue(0) | | | |
| , down_bandwidth_queue(0) | | | |
| , all_time_upload(0) | | | |
| , all_time_download(0) | | | |
| , active_time(0) | | | |
| , finished_time(0) | | | |
| , seeding_time(0) | | | |
| , seed_rank(0) | | | |
| , last_scrape(0) | | | |
| , has_incoming(false) | | | |
| , sparse_regions(0) | | | |
| , seed_mode(false) | | | |
| , upload_mode(false) | | | |
| , priority(0) | | | |
| {} | | | |
| | | | |
| enum state_t | | | |
| { | | | |
| queued_for_checking, | | | |
| checking_files, | | | |
| downloading_metadata, | | | |
| downloading, | | | |
| finished, | | | |
| seeding, | | | |
| allocating, | | | |
| checking_resume_data | | | |
| }; | | | |
| | | | |
| state_t state; | | | |
| bool paused; | | | |
| float progress; | | | |
| // progress parts per million (progress * 1000000) | | | |
| // when disabling floating point operations, this is | | | |
| // the only option to query progress | | | |
| int progress_ppm; | | | |
| std::string error; | | | |
| | | | |
| boost::posix_time::time_duration next_announce; | | | |
| boost::posix_time::time_duration announce_interval; | | | |
| | | | |
| std::string current_tracker; | | | |
| | | | |
| // transferred this session! | | | |
| // total, payload plus protocol | | | |
| size_type total_download; | | | |
| size_type total_upload; | | | |
| | | | |
| // payload only | | | |
| size_type total_payload_download; | | | |
| size_type total_payload_upload; | | | |
| | | | |
| // the amount of payload bytes that | | | |
| // has failed their hash test | | | |
| size_type total_failed_bytes; | | | |
| | | | |
| // the number of payload bytes that | | | |
| // has been received redundantly. | | | |
| size_type total_redundant_bytes; | | | |
| | | | |
| // current transfer rate | | | |
| // payload plus protocol | | | |
| int download_rate; | | | |
| int upload_rate; | | | |
| | | | |
| // the rate of payload that is | | | |
| // sent and received | | | |
| int download_payload_rate; | | | |
| int upload_payload_rate; | | | |
| | | | |
| // the number of peers this torrent is connected to | | | |
| // that are seeding. | | | |
| int num_seeds; | | | |
| | | | |
| // the number of peers this torrent | | | |
| // is connected to (including seeds). | | | |
| int num_peers; | | | |
| | | | |
| // if the tracker sends scrape info in its | | | |
| // announce reply, these fields will be | | | |
| // set to the total number of peers that | | | |
| // have the whole file and the total number | | | |
| // of peers that are still downloading | | | |
| int num_complete; | | | |
| int num_incomplete; | | | |
| | | | |
| // this is the number of seeds whose IP we know | | | |
| // but are not necessarily connected to | | | |
| int list_seeds; | | | |
| | | | |
| // this is the number of peers whose IP we know | | | |
| // (including seeds), but are not necessarily | | | |
| // connected to | | | |
| int list_peers; | | | |
| | | | |
| // the number of peers in our peerlist that | | | |
| // we potentially could connect to | | | |
| int connect_candidates; | | | |
| | | | |
| bitfield pieces; | | | |
| | | | |
| // this is the number of pieces the client has | | | |
| // downloaded. it is equal to: | | | |
| // std::accumulate(pieces->begin(), pieces->end()); | | | |
| int num_pieces; | | | |
| | | | |
| // the number of bytes of the file we have | | | |
| // including pieces that may have been filtered | | | |
| // after we downloaded them | | | |
| size_type total_done; | | | |
| | | | |
| // the number of bytes we have of those that we | | | |
| // want. i.e. not counting bytes from pieces that | | | |
| // are filtered as not wanted. | | | |
| size_type total_wanted_done; | | | |
| | | | |
| // the total number of bytes we want to download | | | |
| // this may be smaller than the total torrent size | | | |
| // in case any pieces are filtered as not wanted | | | |
| size_type total_wanted; | | | |
| | | | |
| // the number of distributed copies of the file. | | | |
| // note that one copy may be spread out among many peers. | | | |
| // | | | |
| // the integer part tells how many copies | | | |
| // there are of the rarest piece(s) | | | |
| // | | | |
| // the fractional part tells the fraction of pieces that | | | |
| // have more copies than the rarest piece(s). | | | |
| | | | |
| // the number of full distributed copies (i.e. the number | | | |
| // of peers that have the rarest piece) | | | |
| int distributed_full_copies; | | | |
| | | | |
| // the fraction of pieces that more peers has than the | | | |
| // rarest pieces. This indicates how close the swarm is | | | |
| // to have one more full distributed copy | | | |
| int distributed_fraction; | | | |
| | | | |
| float distributed_copies; | | | |
| | | | |
| // the block size that is used in this torrent. i.e. | | | |
| // the number of bytes each piece request asks for | | | |
| // and each bit in the download queue bitfield represents | | | |
| int block_size; | | | |
| | | | |
| int num_uploads; | | | |
| int num_connections; | | | |
| int uploads_limit; | | | |
| int connections_limit; | | | |
| | | | |
| // true if the torrent is saved in compact mode | | | |
| // false if it is saved in full allocation mode | | | |
| storage_mode_t storage_mode; | | | |
| | | | |
| int up_bandwidth_queue; | | | |
| int down_bandwidth_queue; | | | |
| | | | |
| // number of bytes downloaded since torrent was started | | | |
| // saved and restored from resume data | | | |
| size_type all_time_upload; | | | |
| size_type all_time_download; | | | |
| | | | |
| // the number of seconds of being active | | | |
| // and as being a seed, saved and restored | | | |
| // from resume data | | | |
| int active_time; | | | |
| int finished_time; | | | |
| int seeding_time; | | | |
| | | | |
| // higher value means more important to seed | | | |
| int seed_rank; | | | |
| | | | |
| // number of seconds since last scrape, or -1 if | | | |
| // there hasn't been a scrape | | | |
| int last_scrape; | | | |
| | | | |
| // true if there are incoming connections to this | | | |
| // torrent | | | |
| bool has_incoming; | | | |
| | | | |
| // the number of "holes" in the torrent | | | |
| int sparse_regions; | | | |
| | | | |
| // is true if this torrent is (still) in seed_mode | | | |
| bool seed_mode; | | | |
| | | | |
| // this is set to true when the torrent is blocked | | | |
| // from downloading, typically caused by a file | | | |
| // write operation failing | | | |
| bool upload_mode; | | | |
| | | | |
| // the priority of this torrent | | | |
| int priority; | | | |
| }; | | | |
| | | | |
| struct TORRENT_EXPORT block_info | | struct TORRENT_EXPORT block_info | |
| { | | { | |
| enum block_state_t | | enum block_state_t | |
| { none, requested, writing, finished }; | | { none, requested, writing, finished }; | |
| | | | |
| private: | | private: | |
|
| #ifdef __SUNPRO_CC | | TORRENT_UNION addr_t | |
| // sunpro is strict about POD types in unions | | | |
| struct | | | |
| #else | | | |
| union | | | |
| #endif | | | |
| { | | { | |
| address_v4::bytes_type v4; | | address_v4::bytes_type v4; | |
|
| | | #if TORRENT_USE_IPV6 | |
| address_v6::bytes_type v6; | | address_v6::bytes_type v6; | |
|
| | | #endif | |
| } addr; | | } addr; | |
| | | | |
| boost::uint16_t port; | | boost::uint16_t port; | |
| public: | | public: | |
| | | | |
| void set_peer(tcp::endpoint const& ep) | | void set_peer(tcp::endpoint const& ep) | |
| { | | { | |
|
| | | #if TORRENT_USE_IPV6 | |
| is_v6_addr = ep.address().is_v6(); | | is_v6_addr = ep.address().is_v6(); | |
| if (is_v6_addr) | | if (is_v6_addr) | |
| addr.v6 = ep.address().to_v6().to_bytes(); | | addr.v6 = ep.address().to_v6().to_bytes(); | |
| else | | else | |
|
| | | #endif | |
| addr.v4 = ep.address().to_v4().to_bytes(); | | addr.v4 = ep.address().to_v4().to_bytes(); | |
| port = ep.port(); | | port = ep.port(); | |
| } | | } | |
| | | | |
| tcp::endpoint peer() const | | tcp::endpoint peer() const | |
| { | | { | |
|
| | | #if TORRENT_USE_IPV6 | |
| if (is_v6_addr) | | if (is_v6_addr) | |
| return tcp::endpoint(address_v6(addr.v6), po
rt); | | return tcp::endpoint(address_v6(addr.v6), po
rt); | |
| else | | else | |
|
| | | #endif | |
| return tcp::endpoint(address_v4(addr.v4), po
rt); | | return tcp::endpoint(address_v4(addr.v4), po
rt); | |
| } | | } | |
| | | | |
| // number of bytes downloaded in this block | | // number of bytes downloaded in this block | |
| unsigned bytes_progress:15; | | unsigned bytes_progress:15; | |
| // the total number of bytes in this block | | // the total number of bytes in this block | |
| unsigned block_size:15; | | unsigned block_size:15; | |
| private: | | private: | |
| // the type of the addr union | | // the type of the addr union | |
| unsigned is_v6_addr:1; | | unsigned is_v6_addr:1; | |
| | | | |
| skipping to change at line 384 | | skipping to change at line 158 | |
| int requested; | | int requested; | |
| block_info* blocks; | | block_info* blocks; | |
| enum state_t { none, slow, medium, fast }; | | enum state_t { none, slow, medium, fast }; | |
| state_t piece_state; | | state_t piece_state; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_handle | | struct TORRENT_EXPORT torrent_handle | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| friend struct aux::session_impl; | | friend struct aux::session_impl; | |
|
| | | friend struct feed; | |
| friend class torrent; | | friend class torrent; | |
|
| | | friend std::size_t hash_value(torrent_handle const& th); | |
| | | | |
| torrent_handle() {} | | torrent_handle() {} | |
| | | | |
| enum flags_t { overwrite_existing = 1 }; | | enum flags_t { overwrite_existing = 1 }; | |
| void add_piece(int piece, char const* data, int flags = 0) c
onst; | | void add_piece(int piece, char const* data, int flags = 0) c
onst; | |
| void read_piece(int piece) const; | | void read_piece(int piece) const; | |
|
| | | bool have_piece(int piece) const; | |
| | | | |
| void get_full_peer_list(std::vector<peer_list_entry>& v) con
st; | | void get_full_peer_list(std::vector<peer_list_entry>& v) con
st; | |
| void get_peer_info(std::vector<peer_info>& v) const; | | void get_peer_info(std::vector<peer_info>& v) const; | |
|
| torrent_status status() const; | | | |
| | | enum status_flags_t | |
| | | { | |
| | | query_distributed_copies = 1, | |
| | | query_accurate_download_counters = 2, | |
| | | query_last_seen_complete = 4, | |
| | | query_pieces = 8, | |
| | | query_verified_pieces = 16 | |
| | | }; | |
| | | | |
| | | // the flags specify which fields are calculated. By default | |
| | | everything | |
| | | // is included, you may save CPU by not querying fields you | |
| | | don't need | |
| | | torrent_status status(boost::uint32_t flags = 0xffffffff) co | |
| | | nst; | |
| void get_download_queue(std::vector<partial_piece_info>& que
ue) const; | | void get_download_queue(std::vector<partial_piece_info>& que
ue) const; | |
| | | | |
| enum deadline_flags { alert_when_available = 1 }; | | enum deadline_flags { alert_when_available = 1 }; | |
| void set_piece_deadline(int index, int deadline, int flags =
0) const; | | void set_piece_deadline(int index, int deadline, int flags =
0) const; | |
| void reset_piece_deadline(int index) const; | | void reset_piece_deadline(int index) const; | |
| | | | |
| void set_priority(int prio) const; | | void set_priority(int prio) const; | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| #if !TORRENT_NO_FPU | | #if !TORRENT_NO_FPU | |
| | | | |
| skipping to change at line 438 | | skipping to change at line 227 | |
| | | | |
| void add_http_seed(std::string const& url) const; | | void add_http_seed(std::string const& url) const; | |
| void remove_http_seed(std::string const& url) const; | | void remove_http_seed(std::string const& url) const; | |
| std::set<std::string> http_seeds() const; | | std::set<std::string> http_seeds() const; | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> const& ext | | void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> const& ext | |
| , void* userdata = 0); | | , void* userdata = 0); | |
| #endif | | #endif | |
| | | | |
|
| bool has_metadata() const; | | | |
| bool set_metadata(char const* metadata, int size) const; | | bool set_metadata(char const* metadata, int size) const; | |
| const torrent_info& get_torrent_info() const; | | const torrent_info& get_torrent_info() const; | |
| bool is_valid() const; | | bool is_valid() const; | |
| | | | |
|
| bool is_seed() const; | | enum pause_flags_t { graceful_pause = 1 }; | |
| bool is_finished() const; | | void pause(int flags = 0) const; | |
| bool is_paused() const; | | | |
| void pause() const; | | | |
| void resume() const; | | void resume() const; | |
| void set_upload_mode(bool b) const; | | void set_upload_mode(bool b) const; | |
|
| | | void set_share_mode(bool b) const; | |
| void flush_cache() const; | | void flush_cache() const; | |
| | | | |
|
| | | void apply_ip_filter(bool b) const; | |
| | | | |
| void force_recheck() const; | | void force_recheck() const; | |
|
| void save_resume_data() const; | | | |
| | | | |
|
| bool is_auto_managed() const; | | enum save_resume_flags_t { flush_disk_cache = 1, save_info_d | |
| | | ict = 2 }; | |
| | | void save_resume_data(int flags = 0) const; | |
| | | bool need_save_resume_data() const; | |
| | | | |
| void auto_managed(bool m) const; | | void auto_managed(bool m) const; | |
| | | | |
| int queue_position() const; | | int queue_position() const; | |
| void queue_position_up() const; | | void queue_position_up() const; | |
| void queue_position_down() const; | | void queue_position_down() const; | |
| void queue_position_top() const; | | void queue_position_top() const; | |
| void queue_position_bottom() const; | | void queue_position_bottom() const; | |
| | | | |
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| void resolve_countries(bool r); | | void resolve_countries(bool r); | |
| bool resolve_countries() const; | | bool resolve_countries() const; | |
| #endif | | #endif | |
| | | | |
|
| | | void set_ssl_certificate(std::string const& certificate | |
| | | , std::string const& private_key | |
| | | , std::string const& dh_params | |
| | | , std::string const& passphrase = ""); | |
| | | | |
| storage_interface* get_storage_impl() const; | | storage_interface* get_storage_impl() const; | |
| | | | |
| // all these are deprecated, use piece | | // all these are deprecated, use piece | |
| // priority functions instead | | // priority functions instead | |
| | | | |
| // ================ start deprecation ============ | | // ================ start deprecation ============ | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
|
| | | // deprecated in 0.16, feature will be removed | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int get_peer_upload_limit(tcp::endpoint ip) const TORRENT_DE | |
| | | PRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | int get_peer_download_limit(tcp::endpoint ip) const TORRENT_ | |
| | | DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_peer_upload_limit(tcp::endpoint ip, int limit) cons | |
| | | t TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_peer_download_limit(tcp::endpoint ip, int limit) co | |
| | | nst TORRENT_DEPRECATED; | |
| | | | |
| | | // deprecated in 0.16, feature will be removed | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void set_ratio(float up_down_ratio) const TORRENT_DEPRECATED | |
| | | ; | |
| | | | |
| | | // deprecated in 0.16. use status() instead | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | bool is_seed() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | bool is_finished() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | bool is_paused() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | bool is_auto_managed() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | bool is_sequential_download() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | bool has_metadata() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | bool super_seeding() const TORRENT_DEPRECATED; | |
| | | | |
| // deprecated in 0.13 | | // deprecated in 0.13 | |
| // marks the piece with the given index as filtered | | // marks the piece with the given index as filtered | |
| // it will not be downloaded | | // it will not be downloaded | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void filter_piece(int index, bool filter) const TORRENT_DEPR
ECATED; | | void filter_piece(int index, bool filter) const TORRENT_DEPR
ECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void filter_pieces(std::vector<bool> const& pieces) const TO
RRENT_DEPRECATED; | | void filter_pieces(std::vector<bool> const& pieces) const TO
RRENT_DEPRECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| bool is_piece_filtered(int index) const TORRENT_DEPRECATED; | | bool is_piece_filtered(int index) const TORRENT_DEPRECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| | | | |
| skipping to change at line 555 | | skipping to change at line 381 | |
| // TODO: add a feature where the user can tell the torrent | | // TODO: add a feature where the user can tell the torrent | |
| // to finish all pieces currently in the pipeline, and then | | // to finish all pieces currently in the pipeline, and then | |
| // abort the torrent. | | // abort the torrent. | |
| | | | |
| void set_upload_limit(int limit) const; | | void set_upload_limit(int limit) const; | |
| int upload_limit() const; | | int upload_limit() const; | |
| void set_download_limit(int limit) const; | | void set_download_limit(int limit) const; | |
| int download_limit() const; | | int download_limit() const; | |
| | | | |
| void set_sequential_download(bool sd) const; | | void set_sequential_download(bool sd) const; | |
|
| bool is_sequential_download() const; | | | |
| | | | |
| void set_peer_upload_limit(tcp::endpoint ip, int limit) cons | | | |
| t; | | | |
| void set_peer_download_limit(tcp::endpoint ip, int limit) co | | | |
| nst; | | | |
| | | | |
| // manually connect a peer | | // manually connect a peer | |
| void connect_peer(tcp::endpoint const& adr, int source = 0)
const; | | void connect_peer(tcp::endpoint const& adr, int source = 0)
const; | |
| | | | |
|
| // valid ratios are 0 (infinite ratio) or [ 1.0 , inf ) | | std::string save_path() const; | |
| // the ratio is uploaded / downloaded. less than 1 is not al | | | |
| lowed | | | |
| void set_ratio(float up_down_ratio) const; | | | |
| | | | |
| fs::path save_path() const; | | | |
| | | | |
| // -1 means unlimited unchokes | | // -1 means unlimited unchokes | |
| void set_max_uploads(int max_uploads) const; | | void set_max_uploads(int max_uploads) const; | |
| int max_uploads() const; | | int max_uploads() const; | |
| | | | |
| // -1 means unlimited connections | | // -1 means unlimited connections | |
| void set_max_connections(int max_connections) const; | | void set_max_connections(int max_connections) const; | |
| int max_connections() const; | | int max_connections() const; | |
| | | | |
| void set_tracker_login(std::string const& name | | void set_tracker_login(std::string const& name | |
| , std::string const& password) const; | | , std::string const& password) const; | |
| | | | |
| // post condition: save_path() == save_path if true is retur
ned | | // post condition: save_path() == save_path if true is retur
ned | |
|
| void move_storage(fs::path const& save_path) const; | | void move_storage(std::string const& save_path) const; | |
| void rename_file(int index, fs::path const& new_name) const; | | void rename_file(int index, std::string const& new_name) con | |
| | | st; | |
| | | | |
|
| #ifndef BOOST_FILESYSTEM_NARROW_ONLY | | #if TORRENT_USE_WSTRING | |
| void move_storage(fs::wpath const& save_path) const; | | void move_storage(std::wstring const& save_path) const; | |
| void rename_file(int index, fs::wpath const& new_name) const | | void rename_file(int index, std::wstring const& new_name) co | |
| ; | | nst; | |
| #endif | | #endif | |
| | | | |
|
| bool super_seeding() const; | | | |
| void super_seeding(bool on) const; | | void super_seeding(bool on) const; | |
| | | | |
| sha1_hash info_hash() const; | | sha1_hash info_hash() const; | |
| | | | |
| bool operator==(const torrent_handle& h) const | | bool operator==(const torrent_handle& h) const | |
| { return m_torrent.lock() == h.m_torrent.lock(); } | | { return m_torrent.lock() == h.m_torrent.lock(); } | |
| | | | |
| bool operator!=(const torrent_handle& h) const | | bool operator!=(const torrent_handle& h) const | |
| { return m_torrent.lock() != h.m_torrent.lock(); } | | { return m_torrent.lock() != h.m_torrent.lock(); } | |
| | | | |
| | | | |
| skipping to change at line 617 | | skipping to change at line 434 | |
| {} | | {} | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
| boost::weak_ptr<torrent> m_torrent; | | boost::weak_ptr<torrent> m_torrent; | |
| | | | |
| }; | | }; | |
| | | | |
|
| | | struct TORRENT_EXPORT torrent_status | |
| | | { | |
| | | torrent_status(); | |
| | | ~torrent_status(); | |
| | | | |
| | | bool operator==(torrent_status const& st) const | |
| | | { return handle == st.handle; } | |
| | | | |
| | | // handle to the torrent | |
| | | torrent_handle handle; | |
| | | | |
| | | enum state_t | |
| | | { | |
| | | queued_for_checking, | |
| | | checking_files, | |
| | | downloading_metadata, | |
| | | downloading, | |
| | | finished, | |
| | | seeding, | |
| | | allocating, | |
| | | checking_resume_data | |
| | | }; | |
| | | | |
| | | state_t state; | |
| | | bool paused; | |
| | | bool auto_managed; | |
| | | bool sequential_download; | |
| | | bool is_seeding; | |
| | | bool is_finished; | |
| | | bool has_metadata; | |
| | | | |
| | | float progress; | |
| | | // progress parts per million (progress * 1000000) | |
| | | // when disabling floating point operations, this is | |
| | | // the only option to query progress | |
| | | int progress_ppm; | |
| | | std::string error; | |
| | | | |
| | | boost::posix_time::time_duration next_announce; | |
| | | boost::posix_time::time_duration announce_interval; | |
| | | | |
| | | std::string current_tracker; | |
| | | | |
| | | // transferred this session! | |
| | | // total, payload plus protocol | |
| | | size_type total_download; | |
| | | size_type total_upload; | |
| | | | |
| | | // payload only | |
| | | size_type total_payload_download; | |
| | | size_type total_payload_upload; | |
| | | | |
| | | // the amount of payload bytes that | |
| | | // has failed their hash test | |
| | | size_type total_failed_bytes; | |
| | | | |
| | | // the number of payload bytes that | |
| | | // has been received redundantly. | |
| | | size_type total_redundant_bytes; | |
| | | | |
| | | // current transfer rate | |
| | | // payload plus protocol | |
| | | int download_rate; | |
| | | int upload_rate; | |
| | | | |
| | | // the rate of payload that is | |
| | | // sent and received | |
| | | int download_payload_rate; | |
| | | int upload_payload_rate; | |
| | | | |
| | | // the number of peers this torrent is connected to | |
| | | // that are seeding. | |
| | | int num_seeds; | |
| | | | |
| | | // the number of peers this torrent | |
| | | // is connected to (including seeds). | |
| | | int num_peers; | |
| | | | |
| | | // if the tracker sends scrape info in its | |
| | | // announce reply, these fields will be | |
| | | // set to the total number of peers that | |
| | | // have the whole file and the total number | |
| | | // of peers that are still downloading | |
| | | int num_complete; | |
| | | int num_incomplete; | |
| | | | |
| | | // this is the number of seeds whose IP we know | |
| | | // but are not necessarily connected to | |
| | | int list_seeds; | |
| | | | |
| | | // this is the number of peers whose IP we know | |
| | | // (including seeds), but are not necessarily | |
| | | // connected to | |
| | | int list_peers; | |
| | | | |
| | | // the number of peers in our peerlist that | |
| | | // we potentially could connect to | |
| | | int connect_candidates; | |
| | | | |
| | | bitfield pieces; | |
| | | bitfield verified_pieces; | |
| | | | |
| | | // this is the number of pieces the client has | |
| | | // downloaded. it is equal to: | |
| | | // std::accumulate(pieces->begin(), pieces->end()); | |
| | | int num_pieces; | |
| | | | |
| | | // the number of bytes of the file we have | |
| | | // including pieces that may have been filtered | |
| | | // after we downloaded them | |
| | | size_type total_done; | |
| | | | |
| | | // the number of bytes we have of those that we | |
| | | // want. i.e. not counting bytes from pieces that | |
| | | // are filtered as not wanted. | |
| | | size_type total_wanted_done; | |
| | | | |
| | | // the total number of bytes we want to download | |
| | | // this may be smaller than the total torrent size | |
| | | // in case any pieces are filtered as not wanted | |
| | | size_type total_wanted; | |
| | | | |
| | | // the number of distributed copies of the file. | |
| | | // note that one copy may be spread out among many peers. | |
| | | // | |
| | | // the integer part tells how many copies | |
| | | // there are of the rarest piece(s) | |
| | | // | |
| | | // the fractional part tells the fraction of pieces that | |
| | | // have more copies than the rarest piece(s). | |
| | | | |
| | | // the number of full distributed copies (i.e. the number | |
| | | // of peers that have the rarest piece) | |
| | | int distributed_full_copies; | |
| | | | |
| | | // the fraction of pieces that more peers has than the | |
| | | // rarest pieces. This indicates how close the swarm is | |
| | | // to have one more full distributed copy | |
| | | int distributed_fraction; | |
| | | | |
| | | float distributed_copies; | |
| | | | |
| | | // the block size that is used in this torrent. i.e. | |
| | | // the number of bytes each piece request asks for | |
| | | // and each bit in the download queue bitfield represents | |
| | | int block_size; | |
| | | | |
| | | int num_uploads; | |
| | | int num_connections; | |
| | | int uploads_limit; | |
| | | int connections_limit; | |
| | | | |
| | | // true if the torrent is saved in compact mode | |
| | | // false if it is saved in full allocation mode | |
| | | storage_mode_t storage_mode; | |
| | | | |
| | | int up_bandwidth_queue; | |
| | | int down_bandwidth_queue; | |
| | | | |
| | | // number of bytes downloaded since torrent was started | |
| | | // saved and restored from resume data | |
| | | size_type all_time_upload; | |
| | | size_type all_time_download; | |
| | | | |
| | | // the number of seconds of being active | |
| | | // and as being a seed, saved and restored | |
| | | // from resume data | |
| | | int active_time; | |
| | | int finished_time; | |
| | | int seeding_time; | |
| | | | |
| | | // higher value means more important to seed | |
| | | int seed_rank; | |
| | | | |
| | | // number of seconds since last scrape, or -1 if | |
| | | // there hasn't been a scrape | |
| | | int last_scrape; | |
| | | | |
| | | // true if there are incoming connections to this | |
| | | // torrent | |
| | | bool has_incoming; | |
| | | | |
| | | // the number of "holes" in the torrent | |
| | | int sparse_regions; | |
| | | | |
| | | // is true if this torrent is (still) in seed_mode | |
| | | bool seed_mode; | |
| | | | |
| | | // this is set to true when the torrent is blocked | |
| | | // from downloading, typically caused by a file | |
| | | // write operation failing | |
| | | bool upload_mode; | |
| | | | |
| | | // this is true if the torrent is in share-mode | |
| | | bool share_mode; | |
| | | | |
| | | // true if the torrent is in super seeding mode | |
| | | bool super_seeding; | |
| | | | |
| | | // the priority of this torrent | |
| | | int priority; | |
| | | | |
| | | // the time this torrent was added and completed | |
| | | time_t added_time; | |
| | | time_t completed_time; | |
| | | time_t last_seen_complete; | |
| | | | |
| | | // number of seconds since last upload or download activity | |
| | | int time_since_upload; | |
| | | int time_since_download; | |
| | | | |
| | | // the position in the download queue where this torrent is | |
| | | // this is -1 for seeds and finished torrents | |
| | | int queue_position; | |
| | | | |
| | | // true if this torrent has had changes since the last | |
| | | // time resume data was saved | |
| | | bool need_save_resume; | |
| | | | |
| | | // defaults to true. Determines whether the session | |
| | | // IP filter applies to this torrent or not | |
| | | bool ip_filter_applies; | |
| | | | |
| | | // the info-hash for this torrent | |
| | | sha1_hash info_hash; | |
| | | | |
| | | // if this torrent has its own listen socket, this is | |
| | | // the port it's listening on. Otherwise it's 0 | |
| | | int listen_port; | |
| | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED | | #endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED | |
| | | | |
End of changes. 33 change blocks. |
| 271 lines changed or deleted | | 326 lines changed or added | |
|
| torrent_info.hpp | | torrent_info.hpp | |
| | | | |
| skipping to change at line 38 | | skipping to change at line 38 | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_TORRENT_INFO_HPP_INCLUDED | | #ifndef TORRENT_TORRENT_INFO_HPP_INCLUDED | |
| #define TORRENT_TORRENT_INFO_HPP_INCLUDED | | #define TORRENT_TORRENT_INFO_HPP_INCLUDED | |
| | | | |
| #include <string> | | #include <string> | |
| #include <vector> | | #include <vector> | |
|
| //#include <iosfwd> | | | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/optional.hpp> | | #include <boost/optional.hpp> | |
|
| #include <boost/filesystem/path.hpp> | | | |
| #include <boost/shared_array.hpp> | | #include <boost/shared_array.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
|
| | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/entry.hpp" | | #include "libtorrent/entry.hpp" | |
| #include "libtorrent/lazy_entry.hpp" | | #include "libtorrent/lazy_entry.hpp" | |
|
| #include "libtorrent/socket.hpp" | | | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
| #include "libtorrent/size_type.hpp" | | #include "libtorrent/size_type.hpp" | |
|
| #include "libtorrent/config.hpp" | | #include "libtorrent/ptime.hpp" | |
| #include "libtorrent/time.hpp" | | | |
| #include "libtorrent/intrusive_ptr_base.hpp" | | #include "libtorrent/intrusive_ptr_base.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/file_storage.hpp" | | #include "libtorrent/file_storage.hpp" | |
|
| | | #include "libtorrent/copy_ptr.hpp" | |
| | | #include "libtorrent/socket.hpp" | |
| | | #include "libtorrent/policy.hpp" // for policy::peer | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| namespace pt = boost::posix_time; | | class peer_connection; | |
| namespace gr = boost::gregorian; | | struct session_settings; | |
| namespace fs = boost::filesystem; | | | |
| | | | |
| enum | | enum | |
| { | | { | |
|
| // wait 60 seconds before retrying a failed tracker | | // wait at least 5 seconds before retrying a failed tracker | |
| tracker_retry_delay_min = 10 | | tracker_retry_delay_min = 5 | |
| // when tracker_failed_max trackers | | // when tracker_failed_max trackers | |
| // has failed, wait 60 minutes instead | | // has failed, wait 60 minutes instead | |
| , tracker_retry_delay_max = 60 * 60 | | , tracker_retry_delay_max = 60 * 60 | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT announce_entry | | struct TORRENT_EXPORT announce_entry | |
| { | | { | |
|
| announce_entry(std::string const& u) | | announce_entry(std::string const& u); | |
| : url(u) | | ~announce_entry(); | |
| , next_announce(min_time()) | | | |
| , min_announce(min_time()) | | | |
| , tier(0) | | | |
| , fail_limit(0) | | | |
| , fails(0) | | | |
| , source(0) | | | |
| , verified(false) | | | |
| , updating(false) | | | |
| , start_sent(false) | | | |
| , complete_sent(false) | | | |
| , send_stats(true) | | | |
| {} | | | |
| | | | |
|
| | | // tracker URL as it appeared in the torrent file | |
| std::string url; | | std::string url; | |
|
| | | std::string trackerid; | |
| | | | |
| | | // if this tracker has returned an error or warning message | |
| | | // that message is stored here | |
| | | std::string message; | |
| | | | |
| | | // if this tracker failed the last time it was contacted | |
| | | // this error code specifies what error occurred | |
| | | error_code last_error; | |
| | | | |
| int next_announce_in() const; | | int next_announce_in() const; | |
| int min_announce_in() const; | | int min_announce_in() const; | |
| | | | |
| // the time of next tracker announce | | // the time of next tracker announce | |
| ptime next_announce; | | ptime next_announce; | |
| | | | |
| // no announces before this time | | // no announces before this time | |
| ptime min_announce; | | ptime min_announce; | |
| | | | |
|
| | | // the tier this tracker belongs to | |
| boost::uint8_t tier; | | boost::uint8_t tier; | |
|
| | | | |
| // the number of times this tracker can fail | | // the number of times this tracker can fail | |
| // in a row before it's removed. 0 means unlimited | | // in a row before it's removed. 0 means unlimited | |
| boost::uint8_t fail_limit; | | boost::uint8_t fail_limit; | |
| | | | |
| // the number of times in a row this tracker has failed | | // the number of times in a row this tracker has failed | |
|
| boost::uint8_t fails; | | boost::uint8_t fails:7; | |
| | | | |
| | | // true if we're currently trying to announce with | |
| | | // this tracker | |
| | | bool updating:1; | |
| | | | |
| enum tracker_source | | enum tracker_source | |
| { | | { | |
| source_torrent = 1, | | source_torrent = 1, | |
| source_client = 2, | | source_client = 2, | |
| source_magnet_link = 4, | | source_magnet_link = 4, | |
| source_tex = 8 | | source_tex = 8 | |
| }; | | }; | |
|
| | | | |
| // where did we get this tracker from | | // where did we get this tracker from | |
|
| boost::uint8_t source; | | boost::uint8_t source:4; | |
| | | | |
| // is set to true if we have ever received a response from | | // is set to true if we have ever received a response from | |
| // this tracker | | // this tracker | |
| bool verified:1; | | bool verified:1; | |
| | | | |
|
| // true if we're currently trying to announce with | | | |
| // this tracker | | | |
| bool updating:1; | | | |
| | | | |
| // this is true if event start has been sent to the tracker | | // this is true if event start has been sent to the tracker | |
| bool start_sent:1; | | bool start_sent:1; | |
| | | | |
| // this is true if event completed has been sent to the trac
ker | | // this is true if event completed has been sent to the trac
ker | |
| bool complete_sent:1; | | bool complete_sent:1; | |
| | | | |
| // this is false the stats sent to this tracker will be 0 | | // this is false the stats sent to this tracker will be 0 | |
| bool send_stats:1; | | bool send_stats:1; | |
| | | | |
| void reset() | | void reset() | |
| { | | { | |
| start_sent = false; | | start_sent = false; | |
| next_announce = min_time(); | | next_announce = min_time(); | |
| min_announce = min_time(); | | min_announce = min_time(); | |
| } | | } | |
| | | | |
|
| void failed(int retry_interval = 0) | | void failed(session_settings const& sett, int retry_interval | |
| { | | = 0); | |
| ++fails; | | | |
| int delay = (std::min)(tracker_retry_delay_min + int | | | |
| (fails) * int(fails) | | | |
| * tracker_retry_delay_min, int(tracker_retry | | | |
| _delay_max)); | | | |
| delay = (std::max)(delay, retry_interval); | | | |
| next_announce = time_now() + seconds(delay); | | | |
| updating = false; | | | |
| } | | | |
| | | | |
| bool will_announce(ptime now) const | | bool will_announce(ptime now) const | |
| { | | { | |
| return now <= next_announce | | return now <= next_announce | |
| && (fails < fail_limit || fail_limit == 0) | | && (fails < fail_limit || fail_limit == 0) | |
| && !updating; | | && !updating; | |
| } | | } | |
| | | | |
| bool can_announce(ptime now, bool is_seed) const; | | bool can_announce(ptime now, bool is_seed) const; | |
| | | | |
| bool is_working() const | | bool is_working() const | |
|
| { | | { return fails == 0; } | |
| return fails == 0; | | | |
| } | | | |
| | | | |
|
| void trim() | | void trim(); | |
| | | }; | |
| | | | |
| | | struct web_seed_entry | |
| | | { | |
| | | // http seeds are different from url seeds in the | |
| | | // protocol they use. http seeds follows the original | |
| | | // http seed spec. by John Hoffman | |
| | | enum type_t { url_seed, http_seed }; | |
| | | | |
| | | typedef std::vector<std::pair<std::string, std::string> > he | |
| | | aders_t; | |
| | | | |
| | | web_seed_entry(std::string const& url_, type_t type_ | |
| | | , std::string const& auth_ = std::string() | |
| | | , headers_t const& extra_headers_ = headers_t()); | |
| | | | |
| | | bool operator==(web_seed_entry const& e) const | |
| | | { return url == e.url && type == e.type; } | |
| | | | |
| | | bool operator<(web_seed_entry const& e) const | |
| { | | { | |
|
| while (!url.empty() && is_space(url[0])) | | if (url < e.url) return true; | |
| url.erase(url.begin()); | | if (url > e.url) return false; | |
| | | return type < e.type; | |
| } | | } | |
|
| | | | |
| | | std::string url; | |
| | | type_t type; | |
| | | std::string auth; | |
| | | headers_t extra_headers; | |
| | | | |
| | | // if this is > now, we can't reconnect yet | |
| | | ptime retry; | |
| | | | |
| | | // this indicates whether or not we're resolving the | |
| | | // hostname of this URL | |
| | | bool resolving; | |
| | | | |
| | | // if the user wanted to remove this while | |
| | | // we were resolving it. In this case, we set | |
| | | // the removed flag to true, to make the resolver | |
| | | // callback remove it | |
| | | bool removed; | |
| | | | |
| | | tcp::endpoint endpoint; | |
| | | | |
| | | // this is the peer_info field used for the | |
| | | // connection, just to count hash failures | |
| | | // it's also used to hold the peer_connection | |
| | | // pointer, when the web seed is connected | |
| | | policy::peer peer_info; | |
| }; | | }; | |
| | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
| // for backwards compatibility with 0.14 | | // for backwards compatibility with 0.14 | |
| typedef libtorrent_exception invalid_torrent_file; | | typedef libtorrent_exception invalid_torrent_file; | |
| #endif | | #endif | |
| | | | |
|
| int TORRENT_EXPORT load_file(fs::path const& filename, std::vector<c | | int TORRENT_EXPORT load_file(std::string const& filename | |
| har>& v, error_code& ec); | | , std::vector<char>& v, error_code& ec, int limit = 8000000) | |
| | | ; | |
| | | | |
| class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torren
t_info> | | class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torren
t_info> | |
| { | | { | |
| public: | | public: | |
|
| torrent_info(torrent_info const& t); | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifdef TORRENT_DEBUG | |
| torrent_info(lazy_entry const& torrent_file); | | void check_invariant() const; | |
| torrent_info(char const* buffer, int size); | | | |
| torrent_info(fs::path const& filename); | | | |
| #ifndef BOOST_FILESYSTEM_NARROW_ONLY | | | |
| torrent_info(fs::wpath const& filename); | | | |
| #endif | | | |
| #endif | | #endif | |
| | | | |
|
| torrent_info(sha1_hash const& info_hash); | | #ifndef BOOST_NO_EXCEPTIONS | |
| torrent_info(lazy_entry const& torrent_file, error_code& ec) | | torrent_info(lazy_entry const& torrent_file, int flags = 0); | |
| ; | | torrent_info(char const* buffer, int size, int flags = 0); | |
| torrent_info(char const* buffer, int size, error_code& ec); | | torrent_info(std::string const& filename, int flags = 0); | |
| torrent_info(fs::path const& filename, error_code& ec); | | #if TORRENT_USE_WSTRING | |
| #ifndef BOOST_FILESYSTEM_NARROW_ONLY | | torrent_info(std::wstring const& filename, int flags = 0); | |
| torrent_info(fs::wpath const& filename, error_code& ec); | | #endif // TORRENT_USE_WSTRING | |
| #endif | | #endif | |
| | | | |
|
| | | torrent_info(torrent_info const& t, int flags = 0); | |
| | | torrent_info(sha1_hash const& info_hash, int flags = 0); | |
| | | torrent_info(lazy_entry const& torrent_file, error_code& ec, | |
| | | int flags = 0); | |
| | | torrent_info(char const* buffer, int size, error_code& ec, i | |
| | | nt flags = 0); | |
| | | torrent_info(std::string const& filename, error_code& ec, in | |
| | | t flags = 0); | |
| | | #if TORRENT_USE_WSTRING | |
| | | torrent_info(std::wstring const& filename, error_code& ec, i | |
| | | nt flags = 0); | |
| | | #endif // TORRENT_USE_WSTRING | |
| | | | |
| ~torrent_info(); | | ~torrent_info(); | |
| | | | |
| file_storage const& files() const { return m_files; } | | file_storage const& files() const { return m_files; } | |
| file_storage const& orig_files() const { return m_orig_files
? *m_orig_files : m_files; } | | file_storage const& orig_files() const { return m_orig_files
? *m_orig_files : m_files; } | |
| | | | |
| void rename_file(int index, std::string const& new_filename) | | void rename_file(int index, std::string const& new_filename) | |
| { | | { | |
| copy_on_write(); | | copy_on_write(); | |
| m_files.rename_file(index, new_filename); | | m_files.rename_file(index, new_filename); | |
| } | | } | |
| | | | |
|
| #ifndef BOOST_FILESYSTEM_NARROW_ONLY | | #if TORRENT_USE_WSTRING | |
| void rename_file(int index, std::wstring const& new_filename
) | | void rename_file(int index, std::wstring const& new_filename
) | |
| { | | { | |
| copy_on_write(); | | copy_on_write(); | |
| m_files.rename_file(index, new_filename); | | m_files.rename_file(index, new_filename); | |
| } | | } | |
|
| #endif | | #endif // TORRENT_USE_WSTRING | |
| | | | |
| void remap_files(file_storage const& f); | | void remap_files(file_storage const& f); | |
| | | | |
| void add_tracker(std::string const& url, int tier = 0); | | void add_tracker(std::string const& url, int tier = 0); | |
| std::vector<announce_entry> const& trackers() const { return
m_urls; } | | std::vector<announce_entry> const& trackers() const { return
m_urls; } | |
| | | | |
|
| std::vector<std::string> const& url_seeds() const | | #ifndef TORRENT_NO_DEPRECATE | |
| { return m_url_seeds; } | | // deprecated in 0.16. Use web_seeds() instead | |
| void add_url_seed(std::string const& url) | | TORRENT_DEPRECATED_PREFIX | |
| { m_url_seeds.push_back(url); } | | std::vector<std::string> url_seeds() const TORRENT_DEPRECATE | |
| | | D; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | std::vector<std::string> http_seeds() const TORRENT_DEPRECAT | |
| | | ED; | |
| | | #endif // TORRENT_NO_DEPRECATE | |
| | | | |
|
| std::vector<std::string> const& http_seeds() const | | void add_url_seed(std::string const& url | |
| { return m_http_seeds; } | | , std::string const& extern_auth = std::string() | |
| void add_http_seed(std::string const& url) | | , web_seed_entry::headers_t const& extra_headers = w | |
| { m_http_seeds.push_back(url); } | | eb_seed_entry::headers_t()); | |
| | | | |
| | | void add_http_seed(std::string const& url | |
| | | , std::string const& extern_auth = std::string() | |
| | | , web_seed_entry::headers_t const& extra_headers = w | |
| | | eb_seed_entry::headers_t()); | |
| | | | |
| | | std::vector<web_seed_entry> const& web_seeds() const | |
| | | { return m_web_seeds; } | |
| | | | |
| size_type total_size() const { return m_files.total_size();
} | | size_type total_size() const { return m_files.total_size();
} | |
| int piece_length() const { return m_files.piece_length(); } | | int piece_length() const { return m_files.piece_length(); } | |
| int num_pieces() const { return m_files.num_pieces(); } | | int num_pieces() const { return m_files.num_pieces(); } | |
| const sha1_hash& info_hash() const { return m_info_hash; } | | const sha1_hash& info_hash() const { return m_info_hash; } | |
| const std::string& name() const { return m_files.name(); } | | const std::string& name() const { return m_files.name(); } | |
| | | | |
| typedef file_storage::iterator file_iterator; | | typedef file_storage::iterator file_iterator; | |
| typedef file_storage::reverse_iterator reverse_file_iterator
; | | typedef file_storage::reverse_iterator reverse_file_iterator
; | |
| | | | |
| file_iterator begin_files() const { return m_files.begin();
} | | file_iterator begin_files() const { return m_files.begin();
} | |
| file_iterator end_files() const { return m_files.end(); } | | file_iterator end_files() const { return m_files.end(); } | |
| reverse_file_iterator rbegin_files() const { return m_files.
rbegin(); } | | reverse_file_iterator rbegin_files() const { return m_files.
rbegin(); } | |
| reverse_file_iterator rend_files() const { return m_files.re
nd(); } | | reverse_file_iterator rend_files() const { return m_files.re
nd(); } | |
| int num_files() const { return m_files.num_files(); } | | int num_files() const { return m_files.num_files(); } | |
|
| file_entry const& file_at(int index) const { return m_files.
at(index); } | | file_entry file_at(int index) const { return m_files.at(inde
x); } | |
| | | | |
| file_iterator file_at_offset(size_type offset) const | | file_iterator file_at_offset(size_type offset) const | |
| { return m_files.file_at_offset(offset); } | | { return m_files.file_at_offset(offset); } | |
| std::vector<file_slice> map_block(int piece, size_type offse
t, int size) const | | std::vector<file_slice> map_block(int piece, size_type offse
t, int size) const | |
| { return m_files.map_block(piece, offset, size); } | | { return m_files.map_block(piece, offset, size); } | |
| peer_request map_file(int file, size_type offset, int size)
const | | peer_request map_file(int file, size_type offset, int size)
const | |
| { return m_files.map_file(file, offset, size); } | | { return m_files.map_file(file, offset, size); } | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // ------- start deprecation ------- | | // ------- start deprecation ------- | |
| // these functions will be removed in a future version | | // these functions will be removed in a future version | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| torrent_info(entry const& torrent_file) TORRENT_DEPRECATED; | | torrent_info(entry const& torrent_file) TORRENT_DEPRECATED; | |
| TORRENT_DEPRECATED_PREFIX | | TORRENT_DEPRECATED_PREFIX | |
| void print(std::ostream& os) const TORRENT_DEPRECATED; | | void print(std::ostream& os) const TORRENT_DEPRECATED; | |
| // ------- end deprecation ------- | | // ------- end deprecation ------- | |
| #endif | | #endif | |
| | | | |
|
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | std::string const& ssl_cert() const { return m_ssl_root_cert | |
| | | ; } | |
| | | #endif | |
| | | | |
| bool is_valid() const { return m_files.is_valid(); } | | bool is_valid() const { return m_files.is_valid(); } | |
| | | | |
| bool priv() const { return m_private; } | | bool priv() const { return m_private; } | |
| | | | |
|
| | | bool is_i2p() const { return m_i2p; } | |
| | | | |
| int piece_size(int index) const { return m_files.piece_size(
index); } | | int piece_size(int index) const { return m_files.piece_size(
index); } | |
| | | | |
| sha1_hash hash_for_piece(int index) const | | sha1_hash hash_for_piece(int index) const | |
| { return sha1_hash(hash_for_piece_ptr(index)); } | | { return sha1_hash(hash_for_piece_ptr(index)); } | |
| | | | |
| std::vector<sha1_hash> const& merkle_tree() const { return m
_merkle_tree; } | | std::vector<sha1_hash> const& merkle_tree() const { return m
_merkle_tree; } | |
| void set_merkle_tree(std::vector<sha1_hash>& h) | | void set_merkle_tree(std::vector<sha1_hash>& h) | |
| { TORRENT_ASSERT(h.size() == m_merkle_tree.size() ); m_merkl
e_tree.swap(h); } | | { TORRENT_ASSERT(h.size() == m_merkle_tree.size() ); m_merkl
e_tree.swap(h); } | |
| | | | |
| char const* hash_for_piece_ptr(int index) const | | char const* hash_for_piece_ptr(int index) const | |
| { | | { | |
| TORRENT_ASSERT(index >= 0); | | TORRENT_ASSERT(index >= 0); | |
| TORRENT_ASSERT(index < m_files.num_pieces()); | | TORRENT_ASSERT(index < m_files.num_pieces()); | |
| if (is_merkle_torrent()) | | if (is_merkle_torrent()) | |
| { | | { | |
|
| TORRENT_ASSERT(index < int(m_merkle_tree.siz
e()) - m_merkle_first_leaf); | | TORRENT_ASSERT(index < int(m_merkle_tree.siz
e() - m_merkle_first_leaf)); | |
| return (const char*)&m_merkle_tree[m_merkle_
first_leaf + index][0]; | | return (const char*)&m_merkle_tree[m_merkle_
first_leaf + index][0]; | |
| } | | } | |
| else | | else | |
| { | | { | |
| TORRENT_ASSERT(m_piece_hashes); | | TORRENT_ASSERT(m_piece_hashes); | |
| TORRENT_ASSERT(m_piece_hashes >= m_info_sect
ion.get()); | | TORRENT_ASSERT(m_piece_hashes >= m_info_sect
ion.get()); | |
| TORRENT_ASSERT(m_piece_hashes < m_info_secti
on.get() + m_info_section_size); | | TORRENT_ASSERT(m_piece_hashes < m_info_secti
on.get() + m_info_section_size); | |
|
| TORRENT_ASSERT(index < m_info_section_size /
20); | | TORRENT_ASSERT(index < int(m_info_section_si
ze / 20)); | |
| return &m_piece_hashes[index*20]; | | return &m_piece_hashes[index*20]; | |
| } | | } | |
| } | | } | |
| | | | |
|
| boost::optional<pt::ptime> creation_date() const; | | boost::optional<time_t> creation_date() const; | |
| | | | |
| const std::string& creator() const | | const std::string& creator() const | |
| { return m_created_by; } | | { return m_created_by; } | |
| | | | |
| const std::string& comment() const | | const std::string& comment() const | |
| { return m_comment; } | | { return m_comment; } | |
| | | | |
| // dht nodes to add to the routing table/bootstrap from | | // dht nodes to add to the routing table/bootstrap from | |
| typedef std::vector<std::pair<std::string, int> > nodes_t; | | typedef std::vector<std::pair<std::string, int> > nodes_t; | |
| | | | |
| nodes_t const& nodes() const | | nodes_t const& nodes() const | |
| { return m_nodes; } | | { return m_nodes; } | |
| void add_node(std::pair<std::string, int> const& node) | | void add_node(std::pair<std::string, int> const& node) | |
| { m_nodes.push_back(node); } | | { m_nodes.push_back(node); } | |
| | | | |
|
| bool parse_info_section(lazy_entry const& e, error_code& ex)
; | | bool parse_info_section(lazy_entry const& e, error_code& ec,
int flags); | |
| | | | |
| lazy_entry const* info(char const* key) const | | lazy_entry const* info(char const* key) const | |
| { | | { | |
| if (m_info_dict.type() == lazy_entry::none_t) | | if (m_info_dict.type() == lazy_entry::none_t) | |
|
| | | { | |
| | | error_code ec; | |
| lazy_bdecode(m_info_section.get(), m_info_se
ction.get() | | lazy_bdecode(m_info_section.get(), m_info_se
ction.get() | |
|
| + m_info_section_size, m_info_dict); | | + m_info_section_size, m_info_dict, | |
| | | ec); | |
| | | } | |
| return m_info_dict.dict_find(key); | | return m_info_dict.dict_find(key); | |
| } | | } | |
| | | | |
| void swap(torrent_info& ti); | | void swap(torrent_info& ti); | |
| | | | |
| boost::shared_array<char> metadata() const | | boost::shared_array<char> metadata() const | |
| { return m_info_section; } | | { return m_info_section; } | |
| | | | |
| int metadata_size() const { return m_info_section_size; } | | int metadata_size() const { return m_info_section_size; } | |
| | | | |
| bool add_merkle_nodes(std::map<int, sha1_hash> const& subtre
e | | bool add_merkle_nodes(std::map<int, sha1_hash> const& subtre
e | |
| , int piece); | | , int piece); | |
| std::map<int, sha1_hash> build_merkle_list(int piece) const; | | std::map<int, sha1_hash> build_merkle_list(int piece) const; | |
| bool is_merkle_torrent() const { return !m_merkle_tree.empty
(); } | | bool is_merkle_torrent() const { return !m_merkle_tree.empty
(); } | |
| | | | |
|
| | | // if we're logging member offsets, we need access to them | |
| | | #if defined TORRENT_DEBUG \ | |
| | | && !defined TORRENT_LOGGING \ | |
| | | && !defined TORRENT_VERBOSE_LOGGING \ | |
| | | && !defined TORRENT_ERROR_LOGGING | |
| private: | | private: | |
|
| | | #endif | |
| | | | |
| // not assignable | | // not assignable | |
| torrent_info const& operator=(torrent_info const&); | | torrent_info const& operator=(torrent_info const&); | |
| | | | |
| void copy_on_write(); | | void copy_on_write(); | |
|
| bool parse_torrent_file(lazy_entry const& libtorrent, error_ | | bool parse_torrent_file(lazy_entry const& libtorrent, error_ | |
| code& ec); | | code& ec, int flags); | |
| | | | |
| | | // the index to the first leaf. This is where the hash for t | |
| | | he | |
| | | // first piece is stored | |
| | | boost::uint32_t m_merkle_first_leaf; | |
| | | | |
| file_storage m_files; | | file_storage m_files; | |
| | | | |
| // if m_files is modified, it is first copied into | | // if m_files is modified, it is first copied into | |
| // m_orig_files so that the original name and | | // m_orig_files so that the original name and | |
| // filenames are preserved. | | // filenames are preserved. | |
|
| boost::shared_ptr<const file_storage> m_orig_files; | | copy_ptr<const file_storage> m_orig_files; | |
| | | | |
| // the urls to the trackers | | // the urls to the trackers | |
| std::vector<announce_entry> m_urls; | | std::vector<announce_entry> m_urls; | |
|
| std::vector<std::string> m_url_seeds; | | std::vector<web_seed_entry> m_web_seeds; | |
| std::vector<std::string> m_http_seeds; | | | |
| nodes_t m_nodes; | | nodes_t m_nodes; | |
| | | | |
|
| // the hash that identifies this torrent | | // if this is a merkle torrent, this is the merkle | |
| sha1_hash m_info_hash; | | // tree. It has space for merkle_num_nodes(merkle_num_leafs( | |
| | | num_pieces)) | |
| | | // hashes | |
| | | std::vector<sha1_hash> m_merkle_tree; | |
| | | | |
|
| // if a creation date is found in the torrent file | | // this is a copy of the info section from the torrent. | |
| // this will be set to that, otherwise it'll be | | // it use maintained in this flat format in order to | |
| // 1970, Jan 1 | | // make it available through the metadata extension | |
| pt::ptime m_creation_date; | | boost::shared_array<char> m_info_section; | |
| | | | |
| | | // this is a pointer into the m_info_section buffer | |
| | | // pointing to the first byte of the first sha-1 hash | |
| | | char const* m_piece_hashes; | |
| | | | |
| | | // TODO: these strings could be lazy_entry* to save memory | |
| | | | |
| // if a comment is found in the torrent file | | // if a comment is found in the torrent file | |
| // this will be set to that comment | | // this will be set to that comment | |
| std::string m_comment; | | std::string m_comment; | |
| | | | |
| // an optional string naming the software used | | // an optional string naming the software used | |
| // to create the torrent file | | // to create the torrent file | |
| std::string m_created_by; | | std::string m_created_by; | |
| | | | |
|
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | // for ssl-torrens, this contains the root | |
| | | // certificate, in .pem format (i.e. ascii | |
| | | // base64 encoded with head and tails) | |
| | | std::string m_ssl_root_cert; | |
| | | #endif | |
| | | | |
| | | // the info section parsed. points into m_info_section | |
| | | // parsed lazily | |
| | | mutable lazy_entry m_info_dict; | |
| | | | |
| | | // if a creation date is found in the torrent file | |
| | | // this will be set to that, otherwise it'll be | |
| | | // 1970, Jan 1 | |
| | | time_t m_creation_date; | |
| | | | |
| | | // the hash that identifies this torrent | |
| | | sha1_hash m_info_hash; | |
| | | | |
| | | // the number of bytes in m_info_section | |
| | | boost::uint32_t m_info_section_size:24; | |
| | | | |
| // this is used when creating a torrent. If there's | | // this is used when creating a torrent. If there's | |
| // only one file there are cases where it's impossible | | // only one file there are cases where it's impossible | |
| // to know if it should be written as a multifile torrent | | // to know if it should be written as a multifile torrent | |
| // or not. e.g. test/test there's one file and one director
y | | // or not. e.g. test/test there's one file and one director
y | |
| // and they have the same name. | | // and they have the same name. | |
|
| bool m_multifile; | | bool m_multifile:1; | |
| | | | |
| // this is true if the torrent is private. i.e., is should n
ot | | // this is true if the torrent is private. i.e., is should n
ot | |
| // be announced on the dht | | // be announced on the dht | |
|
| bool m_private; | | bool m_private:1; | |
| | | | |
| // this is a copy of the info section from the torrent. | | | |
| // it use maintained in this flat format in order to | | | |
| // make it available through the metadata extension | | | |
| boost::shared_array<char> m_info_section; | | | |
| int m_info_section_size; | | | |
| | | | |
| // this is a pointer into the m_info_section buffer | | | |
| // pointing to the first byte of the first sha-1 hash | | | |
| char const* m_piece_hashes; | | | |
| | | | |
| // if this is a merkle torrent, this is the merkle | | | |
| // tree. It has space for merkle_num_nodes(merkle_num_leafs( | | | |
| num_pieces)) | | | |
| // hashes | | | |
| std::vector<sha1_hash> m_merkle_tree; | | | |
| // the index to the first leaf. This is where the hash for t | | | |
| he | | | |
| // first piece is stored | | | |
| int m_merkle_first_leaf; | | | |
| | | | |
|
| // the info section parsed. points into m_info_section | | // this is true if one of the trackers has an .i2p top | |
| // parsed lazily | | // domain in its hostname. This means the DHT and LSD | |
| mutable lazy_entry m_info_dict; | | // features are disabled for this torrent (unless the | |
| | | // settings allows mixing i2p peers with regular peers) | |
| | | bool m_i2p:1; | |
| }; | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_TORRENT_INFO_HPP_INCLUDED | | #endif // TORRENT_TORRENT_INFO_HPP_INCLUDED | |
| | | | |
End of changes. 50 change blocks. |
| 116 lines changed or deleted | | 208 lines changed or added | |
|