diff --git a/libtorrent/bindings/python/src/alert.cpp b/libtorrent/bindings/python/src/alert.cpp index 7249f58dc..fe34c6c27 100755 --- a/libtorrent/bindings/python/src/alert.cpp +++ b/libtorrent/bindings/python/src/alert.cpp @@ -95,6 +95,12 @@ void bind_alert() .def_readonly("url", &tracker_alert::url) ; + class_, noncopyable>( + "peer_alert", no_init + ) + .def_readonly("ip", &peer_alert::ip) + .def_readonly("pid", &peer_alert::pid) + ; class_, noncopyable>( "tracker_error_alert", tracker_error_alert_doc, no_init ) @@ -122,25 +128,18 @@ void bind_alert() .def_readonly("piece_index", &hash_failed_alert::piece_index) ; - class_, noncopyable>( + class_, noncopyable>( "peer_ban_alert", peer_ban_alert_doc, no_init - ) - .def_readonly("ip", &peer_ban_alert::ip) - ; + ); - class_, noncopyable>( + class_, noncopyable>( "peer_error_alert", peer_error_alert_doc, no_init - ) - .def_readonly("ip", &peer_error_alert::ip) - .def_readonly("pid", &peer_error_alert::pid) - ; + ); - class_, noncopyable>( + class_, noncopyable>( "invalid_request_alert", invalid_request_alert_doc, no_init ) - .def_readonly("ip", &invalid_request_alert::ip) .def_readonly("request", &invalid_request_alert::request) - .def_readonly("pid", &invalid_request_alert::pid) ; class_("peer_request", peer_request_doc) @@ -160,14 +159,14 @@ void bind_alert() .def_readonly("piece_index", &piece_finished_alert::piece_index) ; - class_, noncopyable>( + class_, noncopyable>( "block_finished_alert", block_finished_alert_doc, no_init ) .def_readonly("block_index", &block_finished_alert::block_index) .def_readonly("piece_index", &block_finished_alert::piece_index) ; - class_, noncopyable>( + class_, noncopyable>( "block_downloading_alert", block_downloading_alert_doc, no_init ) .def_readonly("peer_speedmsg", &block_downloading_alert::peer_speedmsg) @@ -281,6 +280,12 @@ void bind_alert() .def_readonly("name", &file_renamed_alert::name) ; + class_, noncopyable>( + "file_rename_failed_alert", no_init + ) + .def_readonly("index", &file_rename_failed_alert::index) + ; + class_, noncopyable>( "torrent_resumed_alert", no_init ); @@ -290,4 +295,56 @@ void bind_alert() ) .def_readonly("state", &state_changed_alert::state) ; + + class_, noncopyable>( + "dht_reply_alert", no_init + ) + .def_readonly("num_peers", &dht_reply_alert::num_peers) + ; + + class_, noncopyable>( + "peer_unsnubbed_alert", no_init + ); + + class_, noncopyable>( + "peer_snubbed_alert", no_init + ); + + class_, noncopyable>( + "peer_connect_alert", no_init + ); + + class_, noncopyable>( + "peer_disconnected_alert", no_init + ); + + class_, noncopyable>( + "request_dropped_alert", no_init + ) + .def_readonly("block_index", &request_dropped_alert::block_index) + .def_readonly("piece_index", &request_dropped_alert::piece_index) + ; + + class_, noncopyable>( + "block_timeout_alert", no_init + ) + .def_readonly("block_index", &block_timeout_alert::block_index) + .def_readonly("piece_index", &block_timeout_alert::piece_index) + ; + + class_, noncopyable>( + "unwanted_block_alert", no_init + ) + .def_readonly("block_index", &unwanted_block_alert::block_index) + .def_readonly("piece_index", &unwanted_block_alert::piece_index) + ; + + class_, noncopyable>( + "torrent_delete_failed_alert", no_init + ); + + class_, noncopyable>( + "save_resume_data_failed_alert", no_init + ); + } diff --git a/libtorrent/include/libtorrent/alert_types.hpp b/libtorrent/include/libtorrent/alert_types.hpp index 69f971f13..a1c556d82 100644 --- a/libtorrent/include/libtorrent/alert_types.hpp +++ b/libtorrent/include/libtorrent/alert_types.hpp @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/peer_connection.hpp" #include "libtorrent/config.hpp" #include "libtorrent/assert.hpp" +#include "libtorrent/identify_client.hpp" #include @@ -51,11 +52,51 @@ namespace libtorrent {} virtual std::string message() const - { return handle.is_valid()?handle.name():"- "; } + { return handle.is_valid()?handle.name():" - "; } torrent_handle handle; }; + struct TORRENT_EXPORT peer_alert: torrent_alert + { + peer_alert(torrent_handle const& h, tcp::endpoint const& ip_ + , peer_id const& pid_) + : torrent_alert(h) + , ip(ip_) + , pid(pid_) + {} + + const static int static_category = alert::peer_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + error_code ec; + return torrent_alert::message() + " peer (" + ip.address().to_string(ec) + + ", " + identify_client(pid) + ")"; + } + + tcp::endpoint ip; + peer_id pid; + }; + + struct TORRENT_EXPORT tracker_alert: torrent_alert + { + tracker_alert(torrent_handle const& h + , std::string const& url_) + : torrent_alert(h) + , url(url_) + { assert(!url.empty()); } + + const static int static_category = alert::tracker_notification; + virtual int category() const { return static_category; } + virtual std::string message() const + { + return torrent_alert::message() + " (" + url + ")"; + } + + std::string url; + }; + struct TORRENT_EXPORT file_renamed_alert: torrent_alert { file_renamed_alert(torrent_handle const& h @@ -139,25 +180,6 @@ namespace libtorrent torrent_status::state_t state; }; - struct TORRENT_EXPORT tracker_alert: torrent_alert - { - tracker_alert(torrent_handle const& h - , std::string const& url_) - : torrent_alert(h) - , url(url_) - { assert(!url.empty()); } - - const static int static_category = alert::tracker_notification; - virtual int category() const { return static_category; } - virtual std::string message() const - { - return torrent_alert::message() + " (" + url + ")"; - } - - - std::string url; - }; - struct TORRENT_EXPORT tracker_error_alert: tracker_alert { tracker_error_alert(torrent_handle const& h @@ -338,85 +360,60 @@ namespace libtorrent int piece_index; }; - struct TORRENT_EXPORT peer_ban_alert: torrent_alert + struct TORRENT_EXPORT peer_ban_alert: peer_alert { - peer_ban_alert(tcp::endpoint const& pip, torrent_handle h) - : torrent_alert(h) - , ip(pip) + peer_ban_alert(torrent_handle h, tcp::endpoint const& ip + , peer_id const& pid) + : peer_alert(h, ip, pid) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new peer_ban_alert(*this)); } virtual char const* what() const { return "peer banned"; } - const static int static_category = alert::peer_notification; - virtual int category() const { return static_category; } virtual std::string message() const { error_code ec; - return torrent_alert::message() + " banned peer " - + ip.address().to_string(ec); + return peer_alert::message() + " banned peer"; } - - tcp::endpoint ip; }; - struct TORRENT_EXPORT peer_unsnubbed_alert: torrent_alert + struct TORRENT_EXPORT peer_unsnubbed_alert: peer_alert { - peer_unsnubbed_alert(torrent_handle const& h, tcp::endpoint const& ip_ - , peer_id const& pid_) - : torrent_alert(h) - , ip(ip_) - , pid(pid_) + peer_unsnubbed_alert(torrent_handle h, tcp::endpoint const& ip + , peer_id const& pid) + : peer_alert(h, ip, pid) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new peer_unsnubbed_alert(*this)); } virtual char const* what() const { return "peer unsnubbed"; } - const static int static_category = alert::peer_notification; - virtual int category() const { return static_category; } virtual std::string message() const { - error_code ec; - return torrent_alert::message() + " peer unsnubbed: (" + ip.address().to_string(ec) - + ")"; + return peer_alert::message() + " peer unsnubbed"; } - - tcp::endpoint ip; - peer_id pid; }; - struct TORRENT_EXPORT peer_snubbed_alert: torrent_alert + struct TORRENT_EXPORT peer_snubbed_alert: peer_alert { - peer_snubbed_alert(torrent_handle const& h, tcp::endpoint const& ip_ - , peer_id const& pid_) - : torrent_alert(h) - , ip(ip_) - , pid(pid_) + peer_snubbed_alert(torrent_handle h, tcp::endpoint const& ip + , peer_id const& pid) + : peer_alert(h, ip, pid) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new peer_snubbed_alert(*this)); } virtual char const* what() const { return "peer snubbed"; } - const static int static_category = alert::peer_notification; - virtual int category() const { return static_category; } virtual std::string message() const { - error_code ec; - return torrent_alert::message() + " peer snubbed: (" + ip.address().to_string(ec) - + ")"; + return peer_alert::message() + " peer snubbed"; } - - tcp::endpoint ip; - peer_id pid; }; - struct TORRENT_EXPORT peer_error_alert: torrent_alert + struct TORRENT_EXPORT peer_error_alert: peer_alert { - peer_error_alert(torrent_handle const& h, tcp::endpoint const& ip_ - , peer_id const& pid_, std::string const& msg_) - : torrent_alert(h) - , ip(ip_) - , pid(pid_) + peer_error_alert(torrent_handle const& h, tcp::endpoint const& ip + , peer_id const& pid, std::string const& msg_) + : peer_alert(h, ip, pid) , msg(msg_) {} @@ -428,19 +425,17 @@ namespace libtorrent virtual std::string message() const { error_code ec; - return torrent_alert::message() + " peer error: (" + ip.address().to_string(ec) - + ") " + msg; + return peer_alert::message() + " peer error: " + msg; } - tcp::endpoint ip; - peer_id pid; std::string msg; }; - struct TORRENT_EXPORT peer_connect_alert: torrent_alert + struct TORRENT_EXPORT peer_connect_alert: peer_alert { - peer_connect_alert(torrent_handle const& h, tcp::endpoint const& ip_) - : torrent_alert(h), ip(ip_) + peer_connect_alert(torrent_handle h, tcp::endpoint const& ip + , peer_id const& pid) + : peer_alert(h, ip, pid) {} virtual std::auto_ptr clone() const @@ -450,21 +445,15 @@ namespace libtorrent virtual int category() const { return static_category; } virtual std::string message() const { - error_code ec; - return torrent_alert::message() + " connecting to peer " - + ip.address().to_string(ec); + return peer_alert::message() + " connecting to peer"; } - - tcp::endpoint ip; }; - struct TORRENT_EXPORT peer_disconnected_alert: torrent_alert + struct TORRENT_EXPORT peer_disconnected_alert: peer_alert { - peer_disconnected_alert(torrent_handle const& h, tcp::endpoint const& ip_ - , peer_id const& pid_, std::string const& msg_) - : torrent_alert(h) - , ip(ip_) - , pid(pid_) + peer_disconnected_alert(torrent_handle const& h, tcp::endpoint const& ip + , peer_id const& pid, std::string const& msg_) + : peer_alert(h, ip, pid) , msg(msg_) {} @@ -475,44 +464,32 @@ namespace libtorrent virtual int category() const { return static_category; } virtual std::string message() const { - error_code ec; - return torrent_alert::message() + " disconnecting " - + ip.address().to_string(ec) + ": " + msg; + return peer_alert::message() + " disconnecting: " + msg; } - tcp::endpoint ip; - peer_id pid; std::string msg; }; - struct TORRENT_EXPORT invalid_request_alert: torrent_alert + struct TORRENT_EXPORT invalid_request_alert: peer_alert { - invalid_request_alert( - peer_request const& r - , torrent_handle const& h - , tcp::endpoint const& sender - , peer_id const& pid_) - : torrent_alert(h) - , ip(sender) + invalid_request_alert(torrent_handle const& h, tcp::endpoint const& ip + , peer_id const& pid, peer_request const& r) + : peer_alert(h, ip, pid) , request(r) - , pid(pid_) {} virtual std::auto_ptr clone() const { return std::auto_ptr(new invalid_request_alert(*this)); } virtual char const* what() const { return "invalid piece request"; } - const static int static_category = alert::peer_notification; - virtual int category() const { return static_category; } virtual std::string message() const { - error_code ec; - return torrent_alert::message() + " peer " - + ip.address().to_string(ec) + " sent an invalid piece request"; + return peer_alert::message() + " peer sent an invalid piece request " + "( piece: " + boost::lexical_cast(request.piece) + + " start: " + boost::lexical_cast(request.start) + + " len: " + boost::lexical_cast(request.length) + ")"; } - tcp::endpoint ip; peer_request request; - peer_id pid; }; struct TORRENT_EXPORT torrent_finished_alert: torrent_alert @@ -556,13 +533,11 @@ namespace libtorrent } }; - struct TORRENT_EXPORT request_dropped_alert: torrent_alert + struct TORRENT_EXPORT request_dropped_alert: peer_alert { - request_dropped_alert( - const torrent_handle& h - , int block_num - , int piece_num) - : torrent_alert(h) + request_dropped_alert(const torrent_handle& h, tcp::endpoint const& ip + , peer_id const& pid, int block_num, int piece_num) + : peer_alert(h, ip, pid) , block_index(block_num) , piece_index(piece_num) { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} @@ -578,19 +553,17 @@ namespace libtorrent virtual int category() const { return static_category; } virtual std::string message() const { - return torrent_alert::message() + " block " - + boost::lexical_cast(block_index) + " in piece " - + boost::lexical_cast(piece_index) + " was dropped by remote peer"; + return peer_alert::message() + " peer dropped block ( piece: " + + boost::lexical_cast(piece_index) + " block: " + + boost::lexical_cast(block_index) + ")"; } }; - struct TORRENT_EXPORT block_timeout_alert: torrent_alert + struct TORRENT_EXPORT block_timeout_alert: peer_alert { - block_timeout_alert( - const torrent_handle& h - , int block_num - , int piece_num) - : torrent_alert(h) + block_timeout_alert(const torrent_handle& h, tcp::endpoint const& ip + , peer_id const& pid, int block_num, int piece_num) + : peer_alert(h, ip, pid) , block_index(block_num) , piece_index(piece_num) { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} @@ -606,19 +579,17 @@ namespace libtorrent virtual int category() const { return static_category; } virtual std::string message() const { - return torrent_alert::message() + " timed out block " - + boost::lexical_cast(block_index) + " in piece " - + boost::lexical_cast(piece_index); + return peer_alert::message() + " peer timed out request ( piece: " + + boost::lexical_cast(piece_index) + " block: " + + boost::lexical_cast(block_index) + ")"; } }; - struct TORRENT_EXPORT block_finished_alert: torrent_alert + struct TORRENT_EXPORT block_finished_alert: peer_alert { - block_finished_alert( - const torrent_handle& h - , int block_num - , int piece_num) - : torrent_alert(h) + block_finished_alert(const torrent_handle& h, tcp::endpoint const& ip + , peer_id const& pid, int block_num, int piece_num) + : peer_alert(h, ip, pid) , block_index(block_num) , piece_index(piece_num) { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} @@ -633,20 +604,17 @@ namespace libtorrent virtual int category() const { return static_category; } virtual std::string message() const { - return torrent_alert::message() + " block " - + boost::lexical_cast(block_index) + " in piece " - + boost::lexical_cast(piece_index) + " finished downloading"; + return peer_alert::message() + " block finished downloading ( piece: " + + boost::lexical_cast(piece_index) + " block: " + + boost::lexical_cast(block_index) + ")"; } }; - struct TORRENT_EXPORT block_downloading_alert: torrent_alert + struct TORRENT_EXPORT block_downloading_alert: peer_alert { - block_downloading_alert( - const torrent_handle& h - , char const* speedmsg - , int block_num - , int piece_num) - : torrent_alert(h) + block_downloading_alert(const torrent_handle& h, tcp::endpoint const& ip + , peer_id const& pid, char const* speedmsg, int block_num, int piece_num) + : peer_alert(h, ip, pid) , peer_speedmsg(speedmsg) , block_index(block_num) , piece_index(piece_num) @@ -663,9 +631,33 @@ namespace libtorrent virtual int category() const { return static_category; } virtual std::string message() const { - return torrent_alert::message() + " requested block " - + boost::lexical_cast(block_index) + " in piece " - + boost::lexical_cast(piece_index); + return peer_alert::message() + " requested block ( piece: " + + boost::lexical_cast(piece_index) + " block: " + + boost::lexical_cast(block_index) + ") " + + peer_speedmsg; + } + }; + + struct TORRENT_EXPORT unwanted_block_alert: peer_alert + { + unwanted_block_alert(const torrent_handle& h, tcp::endpoint const& ip + , peer_id const& pid, int block_num, int piece_num) + : peer_alert(h, ip, pid) + , block_index(block_num) + , piece_index(piece_num) + { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} + + int block_index; + int piece_index; + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new unwanted_block_alert(*this)); } + virtual char const* what() const { return "unwanted block received"; } + virtual std::string message() const + { + return peer_alert::message() + " received block not in download queue ( piece: " + + boost::lexical_cast(piece_index) + " block: " + + boost::lexical_cast(block_index) + ")"; } }; diff --git a/libtorrent/include/libtorrent/bt_peer_connection.hpp b/libtorrent/include/libtorrent/bt_peer_connection.hpp index c45f7cb31..a900bfc7e 100644 --- a/libtorrent/include/libtorrent/bt_peer_connection.hpp +++ b/libtorrent/include/libtorrent/bt_peer_connection.hpp @@ -275,7 +275,7 @@ public: // these functions encrypt the send buffer if m_rc4_encrypted // is true, otherwise it passes the call to the // peer_connection functions of the same names - void send_buffer(char* buf, int size); + void send_buffer(char* buf, int size, int flags = 0); buffer::interval allocate_send_buffer(int size); template void append_send_buffer(char* buffer, int size, Destructor const& destructor) diff --git a/libtorrent/include/libtorrent/file_storage.hpp b/libtorrent/include/libtorrent/file_storage.hpp index bbb606bf6..47fcb92eb 100644 --- a/libtorrent/include/libtorrent/file_storage.hpp +++ b/libtorrent/include/libtorrent/file_storage.hpp @@ -94,6 +94,7 @@ namespace libtorrent typedef std::vector::const_iterator iterator; typedef std::vector::const_reverse_iterator reverse_iterator; + iterator file_at_offset(size_type offset) const; iterator begin() const { return m_files.begin(); } iterator end() const { return m_files.end(); } reverse_iterator rbegin() const { return m_files.rbegin(); } diff --git a/libtorrent/include/libtorrent/peer_connection.hpp b/libtorrent/include/libtorrent/peer_connection.hpp index 8eebb113b..bfc45db5d 100644 --- a/libtorrent/include/libtorrent/peer_connection.hpp +++ b/libtorrent/include/libtorrent/peer_connection.hpp @@ -409,7 +409,8 @@ namespace libtorrent // these functions are virtual to let bt_peer_connection hook into them // and encrypt the content - virtual void send_buffer(char const* begin, int size); + enum message_type_flags { message_type_request = 1 }; + virtual void send_buffer(char const* begin, int size, int flags = 0); virtual buffer::interval allocate_send_buffer(int size); virtual void setup_send(); @@ -681,6 +682,10 @@ namespace libtorrent // downloaded from this peer std::vector m_suggested_pieces; + // a list of byte offsets inside the send buffer + // the piece requests + std::vector m_requests_in_buffer; + // the number of pieces this peer // has. Must be the same as // std::count(m_have_piece.begin(), diff --git a/libtorrent/include/libtorrent/peer_info.hpp b/libtorrent/include/libtorrent/peer_info.hpp index d447b51f8..83aa217cf 100644 --- a/libtorrent/include/libtorrent/peer_info.hpp +++ b/libtorrent/include/libtorrent/peer_info.hpp @@ -143,6 +143,10 @@ namespace libtorrent // for yet int download_queue_length; + // the number of request messages + // waiting to be sent inside the send buffer + int requests_in_buffer; + // the number of requests that is // tried to be maintained (this is // typically a function of download speed) diff --git a/libtorrent/include/libtorrent/torrent_info.hpp b/libtorrent/include/libtorrent/torrent_info.hpp index 0cc9b93b2..6c87b475a 100644 --- a/libtorrent/include/libtorrent/torrent_info.hpp +++ b/libtorrent/include/libtorrent/torrent_info.hpp @@ -118,6 +118,8 @@ namespace libtorrent int num_files() const { return m_files.num_files(); } file_entry const& file_at(int index) const { return m_files.at(index); } + file_iterator file_at_offset(size_type offset) const + { return m_files.file_at_offset(offset); } std::vector map_block(int piece, size_type offset, int size) const { return m_files.map_block(piece, offset, size); } peer_request map_file(int file, size_type offset, int size) const diff --git a/libtorrent/src/bt_peer_connection.cpp b/libtorrent/src/bt_peer_connection.cpp index cf9e3bc34..dbba0e407 100755 --- a/libtorrent/src/bt_peer_connection.cpp +++ b/libtorrent/src/bt_peer_connection.cpp @@ -601,7 +601,7 @@ namespace libtorrent #endif } - void bt_peer_connection::send_buffer(char* buf, int size) + void bt_peer_connection::send_buffer(char* buf, int size, int flags) { TORRENT_ASSERT(buf); TORRENT_ASSERT(size > 0); @@ -609,7 +609,7 @@ namespace libtorrent if (m_encrypted && m_rc4_encrypted) m_RC4_handler->encrypt(buf, size); - peer_connection::send_buffer(buf, size); + peer_connection::send_buffer(buf, size, flags); } buffer::interval bt_peer_connection::allocate_send_buffer(int size) @@ -1405,7 +1405,7 @@ namespace libtorrent detail::write_int32(r.piece, ptr); // index detail::write_int32(r.start, ptr); // begin detail::write_int32(r.length, ptr); // length - send_buffer(msg, sizeof(msg)); + send_buffer(msg, sizeof(msg), message_type_request); } void bt_peer_connection::write_bitfield() diff --git a/libtorrent/src/file_storage.cpp b/libtorrent/src/file_storage.cpp index 69e88d25d..e5b544dc3 100644 --- a/libtorrent/src/file_storage.cpp +++ b/libtorrent/src/file_storage.cpp @@ -64,6 +64,18 @@ namespace libtorrent m_files[index].path = new_filename; } + file_storage::iterator file_storage::file_at_offset(size_type offset) const + { + // TODO: do a binary search + std::vector::const_iterator i; + for (i = begin(); i != end(); ++i) + { + if (i->offset < offset && i->offset + i->size > offset) + return i; + } + return i; + } + std::vector file_storage::map_block(int piece, size_type offset , int size_) const { @@ -75,7 +87,7 @@ namespace libtorrent TORRENT_ASSERT(start + size <= m_total_size); // find the file iterator and file offset - // TODO: make a vector that can map piece -> file index in O(1) + // TODO: do a binary search on the file offsets size_type file_offset = start; std::vector::const_iterator file_iter; diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index 6c2b2eb88..43ec7b01a 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -902,12 +902,9 @@ namespace libtorrent m_suggested_pieces.erase(i); } - if (m_request_queue.empty()) + if (m_request_queue.empty() && m_download_queue.size() < 2) { - if (m_download_queue.size() < 2) - { - request_a_block(*t, *this); - } + request_a_block(*t, *this); send_block_requests(); } } @@ -1381,8 +1378,8 @@ namespace libtorrent if (t->alerts().should_post()) { - t->alerts().post_alert(invalid_request_alert(r - , t->get_handle(), m_remote, m_peer_id)); + t->alerts().post_alert(invalid_request_alert( + t->get_handle(), m_remote, m_peer_id, r)); } } } @@ -1523,8 +1520,8 @@ namespace libtorrent { if (t->alerts().should_post()) { - t->alerts().post_alert(peer_error_alert(t->get_handle(), m_remote - , m_peer_id, "got a block that was not in the request queue")); + t->alerts().post_alert(unwanted_block_alert(t->get_handle(), m_remote + , m_peer_id, block_finished.block_index, block_finished.piece_index)); } #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING (*m_logger) << " *** The block we just got was not in the " @@ -1542,8 +1539,8 @@ namespace libtorrent #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING (*m_logger) << time_now_string() - << " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | " - "b: " << i->block_index << " ] ***\n"; + << " *** SKIPPED_PIECE [ piece: " << i->block.piece_index << " | " + "b: " << i->block.block_index << " ] ***\n"; #endif ++i->skipped; @@ -1554,7 +1551,7 @@ namespace libtorrent { if (m_ses.m_alerts.should_post()) m_ses.m_alerts.post_alert(request_dropped_alert(t->get_handle() - , i->block.block_index, i->block.piece_index)); + , remote(), pid(), i->block.block_index, i->block.piece_index)); picker.abort_download(i->block); i = m_download_queue.erase(i); } @@ -1664,7 +1661,7 @@ namespace libtorrent if (t->alerts().should_post()) { t->alerts().post_alert(block_finished_alert(t->get_handle(), - block_finished.block_index, block_finished.piece_index)); + remote(), pid(), block_finished.block_index, block_finished.piece_index)); } // did we just finish the piece? @@ -1906,7 +1903,7 @@ namespace libtorrent void peer_connection::add_request(piece_block const& block) { - INVARIANT_CHECK; +// INVARIANT_CHECK; boost::shared_ptr t = m_torrent.lock(); TORRENT_ASSERT(t); @@ -1948,7 +1945,7 @@ namespace libtorrent if (t->alerts().should_post()) { t->alerts().post_alert(block_downloading_alert(t->get_handle(), - speedmsg, block.block_index, block.piece_index)); + remote(), pid(), speedmsg, block.block_index, block.piece_index)); } m_request_queue.push_back(block); @@ -2401,6 +2398,7 @@ namespace libtorrent p.load_balancing = total_free_upload(); p.download_queue_length = int(download_queue().size() + m_request_queue.size()); + p.requests_in_buffer = int(m_requests_in_buffer.size()); p.target_dl_queue_length = int(desired_queue_size()); p.upload_queue_length = int(upload_queue().size()); @@ -2765,6 +2763,8 @@ namespace libtorrent void peer_connection::snub_peer() { + INVARIANT_CHECK; + boost::shared_ptr t = m_torrent.lock(); TORRENT_ASSERT(t); @@ -2810,7 +2810,7 @@ namespace libtorrent if (m_ses.m_alerts.should_post()) { m_ses.m_alerts.post_alert(block_timeout_alert(t->get_handle() - , r.block_index, r.piece_index)); + , remote(), pid(), r.block_index, r.piece_index)); } m_download_queue.pop_back(); } @@ -2818,7 +2818,6 @@ namespace libtorrent m_timeout_extend += m_ses.settings().request_timeout; request_a_block(*t, *this); - send_block_requests(); // abort the block after the new one has // been requested in order to prevent it from @@ -2826,6 +2825,8 @@ namespace libtorrent // same piece indefinitely. if (r != piece_block(-1, -1)) picker.abort_download(r); + + send_block_requests(); } void peer_connection::fill_send_buffer() @@ -2955,15 +2956,16 @@ namespace libtorrent TORRENT_ASSERT(t); if (m_bandwidth_limit[upload_channel].max_assignable() > 0) { -#ifdef TORRENT_VERBOSE_LOGGING - (*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ upload ]\n"; -#endif - + int priority = is_interesting() * 2 + m_requests_in_buffer.size(); // peers that we are not interested in are non-prioritized m_channel_state[upload_channel] = peer_info::bw_torrent; t->request_bandwidth(upload_channel, self() - , m_send_buffer.size() - , is_interesting() * 2); + , m_send_buffer.size(), priority); +#ifdef TORRENT_VERBOSE_LOGGING + (*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ upload prio: " + << priority << "]\n"; +#endif + } return; } @@ -3146,8 +3148,11 @@ namespace libtorrent m_packet_size = packet_size; } - void peer_connection::send_buffer(char const* buf, int size) + void peer_connection::send_buffer(char const* buf, int size, int flags) { + if (flags == message_type_request) + m_requests_in_buffer.push_back(m_send_buffer.size() + size); + int free_space = m_send_buffer.space_in_last_buffer(); if (free_space > size) free_space = size; if (free_space > 0) @@ -3416,7 +3421,7 @@ namespace libtorrent if (t->alerts().should_post()) { t->alerts().post_alert(peer_connect_alert( - t->get_handle(), m_remote)); + t->get_handle(), remote(), pid())); } } @@ -3491,6 +3496,14 @@ namespace libtorrent TORRENT_ASSERT(m_channel_state[upload_channel] == peer_info::bw_network); m_send_buffer.pop_front(bytes_transferred); + + for (std::vector::iterator i = m_requests_in_buffer.begin() + , end(m_requests_in_buffer.end()); i != end; ++i) + *i -= bytes_transferred; + + while (!m_requests_in_buffer.empty() + && m_requests_in_buffer.front() <= 0) + m_requests_in_buffer.erase(m_requests_in_buffer.begin()); m_channel_state[upload_channel] = peer_info::bw_idle; diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index 944585a76..2567e2424 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -307,8 +307,6 @@ namespace libtorrent // that was free. If we couldn't find any busy // blocks as well, we cannot download anything // more from this peer. - - c.send_block_requests(); return; } @@ -329,7 +327,6 @@ namespace libtorrent TORRENT_ASSERT(p.is_requested(*i)); TORRENT_ASSERT(p.num_peers(*i) > 0); c.add_request(*i); - c.send_block_requests(); } policy::policy(torrent* t) @@ -864,6 +861,7 @@ namespace libtorrent if (c.is_interesting()) { request_a_block(*m_torrent, c); + c.send_block_requests(); } } @@ -1067,6 +1065,7 @@ namespace libtorrent && c.allowed_fast().empty()) return; request_a_block(*m_torrent, c); + c.send_block_requests(); } #ifndef NDEBUG diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index b9dea84f6..38d7113cb 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -1417,8 +1417,10 @@ namespace libtorrent // ban it. if (m_ses.m_alerts.should_post()) { + peer_id pid; + if (p->connection) pid = p->connection->pid(); m_ses.m_alerts.post_alert(peer_ban_alert( - p->ip, get_handle())); + get_handle(), p->ip, pid)); } // mark the peer as banned @@ -3980,6 +3982,7 @@ namespace libtorrent return; } + TORRENT_ASSERT(has_picker()); fp.resize(m_torrent_file->num_files(), 0.f); for (int i = 0; i < m_torrent_file->num_files(); ++i) @@ -4009,6 +4012,46 @@ namespace libtorrent fp[i] = static_cast(done) / m_torrent_file->files().at(i).size; } + + const std::vector& q + = m_picker->get_download_queue(); + + for (std::vector::const_iterator + i = q.begin(), end(q.end()); i != end; ++i) + { + size_type offset = size_type(i->index) * m_torrent_file->piece_length(); + torrent_info::file_iterator file = m_torrent_file->file_at_offset(offset); + int file_index = file - m_torrent_file->begin_files(); + int num_blocks = m_picker->blocks_in_piece(i->index); + piece_picker::block_info const* info = i->info; + for (int k = 0; k < num_blocks; ++k) + { + if (info[k].state != piece_picker::block_info::state_writing + && info[k].state != piece_picker::block_info::state_finished) + continue; + if (offset + m_block_size > file->offset + file->size) + { + // split the block on multiple files + size_type block_size = m_block_size; + while (offset + block_size > file->offset + file->size) + { + TORRENT_ASSERT(offset < file->offset + file->size); + size_type slice = file->offset + file->size - offset; + fp[file_index] += float(slice) / file->size; + offset += slice; + block_size -= slice; + ++file; + ++file_index; + if (file == m_torrent_file->end_files()) break; + } + } + else + { + fp[file_index] += float(m_block_size) / file->size; + offset += m_block_size; + } + } + } } void torrent::set_state(torrent_status::state_t s) diff --git a/libtorrent/src/web_peer_connection.cpp b/libtorrent/src/web_peer_connection.cpp index d31094f86..ab3b0bf64 100755 --- a/libtorrent/src/web_peer_connection.cpp +++ b/libtorrent/src/web_peer_connection.cpp @@ -303,7 +303,7 @@ namespace libtorrent (*m_logger) << request << "\n"; #endif - send_buffer(request.c_str(), request.size()); + send_buffer(request.c_str(), request.size(), message_type_request); } // --------------------------