From 0c79d1a10b257edaff45d00dbb11bb66d36119ec Mon Sep 17 00:00:00 2001 From: Andrew Resch Date: Sat, 23 Aug 2008 05:49:39 +0000 Subject: [PATCH] lt sync 2626 --- .../bindings/python/src/torrent_handle.cpp | 5 ++- libtorrent/include/libtorrent/alert.hpp | 1 + libtorrent/include/libtorrent/alert_types.hpp | 36 ++++++++++++++++ libtorrent/include/libtorrent/bencode.hpp | 6 +-- libtorrent/include/libtorrent/pe_crypto.hpp | 5 ++- libtorrent/include/libtorrent/torrent.hpp | 13 ++++++ libtorrent/src/bt_peer_connection.cpp | 42 ++++++------------- libtorrent/src/identify_client.cpp | 11 +++-- libtorrent/src/kademlia/dht_tracker.cpp | 3 +- libtorrent/src/lazy_bdecode.cpp | 2 +- libtorrent/src/natpmp.cpp | 32 ++++++++++---- libtorrent/src/pe_crypto.cpp | 13 +++--- libtorrent/src/peer_connection.cpp | 18 ++++++++ libtorrent/src/storage.cpp | 3 +- libtorrent/src/torrent.cpp | 24 ++++++++--- libtorrent/src/torrent_handle.cpp | 2 +- 16 files changed, 154 insertions(+), 62 deletions(-) diff --git a/libtorrent/bindings/python/src/torrent_handle.cpp b/libtorrent/bindings/python/src/torrent_handle.cpp index 343ef27bb..de9ba014c 100755 --- a/libtorrent/bindings/python/src/torrent_handle.cpp +++ b/libtorrent/bindings/python/src/torrent_handle.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "gil.hpp" @@ -170,6 +171,8 @@ void replace_trackers(torrent_handle& info, object trackers) list get_download_queue(torrent_handle& handle) { + using boost::python::make_tuple; + list ret; std::vector downloading; @@ -193,7 +196,7 @@ list get_download_queue(torrent_handle& handle) block_info["num_peers"] = i->blocks[k].num_peers; block_info["bytes_progress"] = i->blocks[k].bytes_progress; block_info["block_size"] = i->blocks[k].block_size; - block_info["peer"] = std::make_pair( + block_info["peer"] = make_tuple( boost::lexical_cast(i->blocks[k].peer.address()), i->blocks[k].peer.port()); block_list.append(block_info); } diff --git a/libtorrent/include/libtorrent/alert.hpp b/libtorrent/include/libtorrent/alert.hpp index f3df27742..9b2c0014f 100644 --- a/libtorrent/include/libtorrent/alert.hpp +++ b/libtorrent/include/libtorrent/alert.hpp @@ -82,6 +82,7 @@ namespace libtorrent { status_notification = 0x40, progress_notification = 0x80, ip_block_notification = 0x100, + performance_warning = 0x200, all_categories = 0xffffffff }; diff --git a/libtorrent/include/libtorrent/alert_types.hpp b/libtorrent/include/libtorrent/alert_types.hpp index ffa09bbf2..e85f3ed0d 100644 --- a/libtorrent/include/libtorrent/alert_types.hpp +++ b/libtorrent/include/libtorrent/alert_types.hpp @@ -151,6 +151,42 @@ namespace libtorrent int index; }; + struct TORRENT_EXPORT performance_alert: torrent_alert + { + enum performance_warning_t + { + outstanding_disk_buffer_limit_reached, + outstanding_request_limit_reached, + }; + + performance_alert(torrent_handle const& h + , performance_warning_t w) + : torrent_alert(h) + , warning_code(w) + {} + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new performance_alert(*this)); } + + virtual char const* what() const { return "performance warning"; } + virtual std::string message() const + { + static char const* warning_str[] = + { + "max outstanding disk writes reached", + "max outstanding piece requests reached", + }; + + return torrent_alert::message() + ": performance warning: " + + warning_str[warning_code]; + } + + const static int static_category = alert::performance_warning; + virtual int category() const { return static_category; } + + performance_warning_t warning_code; + }; + struct TORRENT_EXPORT state_changed_alert: torrent_alert { state_changed_alert(torrent_handle const& h diff --git a/libtorrent/include/libtorrent/bencode.hpp b/libtorrent/include/libtorrent/bencode.hpp index 9443e7a65..49b59e9da 100644 --- a/libtorrent/include/libtorrent/bencode.hpp +++ b/libtorrent/include/libtorrent/bencode.hpp @@ -105,12 +105,10 @@ namespace libtorrent template int write_string(OutIt& out, const std::string& val) { - int ret = val.length(); - std::string::const_iterator end = val.begin() + ret; for (std::string::const_iterator i = val.begin() - , end(val.begin() + ret); i != end; ++i) + , end(val.end()); i != end; ++i) *out++ = *i; - return ret; + return val.length(); } TORRENT_EXPORT char const* integer_to_str(char* buf, int size, entry::integer_type val); diff --git a/libtorrent/include/libtorrent/pe_crypto.hpp b/libtorrent/include/libtorrent/pe_crypto.hpp index dd1260497..05ee08ea1 100644 --- a/libtorrent/include/libtorrent/pe_crypto.hpp +++ b/libtorrent/include/libtorrent/pe_crypto.hpp @@ -58,7 +58,9 @@ namespace libtorrent // m_dh_secret. int compute_secret(const char* remote_pubkey); - const char* get_secret() const; + char const* get_secret() const { return m_dh_secret; } + + sha1_hash const& get_hash_xor_mask() const { return m_xor_mask; } private: int get_local_key_size() const @@ -71,6 +73,7 @@ namespace libtorrent char m_dh_local_key[96]; char m_dh_secret[96]; + sha1_hash m_xor_mask; }; class RC4_handler // Non copyable diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index d6a0f9dd3..c812aed33 100644 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -132,6 +132,14 @@ namespace libtorrent void parse_resume_data(std::vector* resume_data); +#ifndef TORRENT_DISABLE_ENCRYPTION + sha1_hash const& obfuscated_hash() const + { return m_obfuscated_hash; } +#endif + + sha1_hash const& info_hash() const + { return m_torrent_file->info_hash(); } + // starts the announce timer void start(); @@ -821,6 +829,11 @@ namespace libtorrent // longer be used and will be reset boost::scoped_ptr m_name; +#ifndef TORRENT_DISABLE_ENCRYPTION + // this is SHA1("req2" + info-hash), used for + // encrypted hand shakes + sha1_hash m_obfuscated_hash; +#endif session_settings const& m_settings; storage_constructor_type m_storage_constructor; diff --git a/libtorrent/src/bt_peer_connection.cpp b/libtorrent/src/bt_peer_connection.cpp index c68640d79..7e9fd43ce 100755 --- a/libtorrent/src/bt_peer_connection.cpp +++ b/libtorrent/src/bt_peer_connection.cpp @@ -1841,7 +1841,8 @@ namespace libtorrent return; } - cut_receive_buffer(bytes_processed, (std::min)(packet_size(), (512+20) - m_sync_bytes_read)); + cut_receive_buffer(bytes_processed, (std::min)(packet_size() + , (512+20) - m_sync_bytes_read)); TORRENT_ASSERT(!packet_finished()); return; @@ -1872,51 +1873,32 @@ namespace libtorrent recv_buffer = receive_buffer(); - // only calls info_hash() on the torrent_handle's, which - // never throws. - session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - - std::vector active_torrents = m_ses.get_torrents(); - std::vector::const_iterator i; - hasher h; - sha1_hash skey_hash, obfs_hash; + aux::session_impl::torrent_map::const_iterator i; - for (i = active_torrents.begin(); i != active_torrents.end(); ++i) + for (i = m_ses.m_torrents.begin(); i != m_ses.m_torrents.end(); ++i) { - torrent_handle const& t_h = *i; // TODO possible errors - sha1_hash const& info_hash = t_h.info_hash(); - // TODO Does info_hash need to be checked for validity? - - h.reset(); - h.update("req2", 4); - h.update((char*)info_hash.begin(), 20); - - skey_hash = h.final(); - - h.reset(); - h.update("req3", 4); - h.update(m_dh_key_exchange->get_secret(), dh_key_len); - - obfs_hash = h.final(); + torrent const& ti = *i->second; + sha1_hash const& skey_hash = ti.obfuscated_hash(); + sha1_hash obfs_hash = m_dh_key_exchange->get_hash_xor_mask(); obfs_hash ^= skey_hash; - if (std::equal (recv_buffer.begin, recv_buffer.begin + 20, - (char*)obfs_hash.begin())) + if (std::equal(recv_buffer.begin, recv_buffer.begin + 20, + (char*)&obfs_hash[0])) { if (!t) { - attach_to_torrent(info_hash); + attach_to_torrent(ti.info_hash()); if (is_disconnecting()) return; t = associated_torrent().lock(); TORRENT_ASSERT(t); } - init_pe_RC4_handler(m_dh_key_exchange->get_secret(), info_hash); + init_pe_RC4_handler(m_dh_key_exchange->get_secret(), ti.info_hash()); #ifdef TORRENT_VERBOSE_LOGGING (*m_logger) << " stream key found, torrent located.\n"; #endif - continue; // TODO Check flow control with multiple torrents + break; } } diff --git a/libtorrent/src/identify_client.cpp b/libtorrent/src/identify_client.cpp index 3ba57093e..ab0965d3f 100755 --- a/libtorrent/src/identify_client.cpp +++ b/libtorrent/src/identify_client.cpp @@ -59,6 +59,11 @@ namespace return unsigned(c) - 'A' + 10; } + bool isprint(char c) + { + return c >= 32 && c < 127; + } + // takes a peer id and returns a valid boost::optional // object if the peer id matched the azureus style encoding // the returned fingerprint contains information about the @@ -67,7 +72,7 @@ namespace { fingerprint ret("..", 0, 0, 0, 0); - if (id[0] != '-' || !std::isprint(id[1]) || (id[2] < '0') + if (id[0] != '-' || !isprint(id[1]) || (id[2] < '0') || (id[3] < '0') || (id[4] < '0') || (id[5] < '0') || (id[6] < '0') || id[7] != '-') @@ -129,7 +134,7 @@ namespace ret.tag_version = 0; if (sscanf(ids, "%c%d-%d-%d--", &ret.name[0], &ret.major_version, &ret.minor_version , &ret.revision_version) != 4 - || !std::isprint(ret.name[0])) + || !isprint(ret.name[0])) return boost::optional(); return boost::optional(ret); @@ -373,7 +378,7 @@ namespace libtorrent std::string unknown("Unknown ["); for (peer_id::const_iterator i = p.begin(); i != p.end(); ++i) { - unknown += std::isprint(*i)?*i:'.'; + unknown += isprint(*i)?*i:'.'; } unknown += "]"; return unknown; diff --git a/libtorrent/src/kademlia/dht_tracker.cpp b/libtorrent/src/kademlia/dht_tracker.cpp index 4c781b9e7..34d55bb69 100644 --- a/libtorrent/src/kademlia/dht_tracker.cpp +++ b/libtorrent/src/kademlia/dht_tracker.cpp @@ -448,8 +448,7 @@ namespace libtorrent { namespace dht { #ifdef TORRENT_DHT_VERBOSE_LOGGING std::string msg(buf, buf + bytes_transferred); - TORRENT_LOG(dht_tracker) << "invalid incoming packet: " - << e.what() << "\n" << msg << "\n"; + TORRENT_LOG(dht_tracker) << "invalid incoming packet\n"; #endif return; } diff --git a/libtorrent/src/lazy_bdecode.cpp b/libtorrent/src/lazy_bdecode.cpp index d53cbbb59..e823b07bc 100644 --- a/libtorrent/src/lazy_bdecode.cpp +++ b/libtorrent/src/lazy_bdecode.cpp @@ -376,7 +376,7 @@ namespace libtorrent for (int i = 0; i < e.string_length(); ++i) { using namespace std; - if (isprint(str[i])) continue; + if (isprint((unsigned char)str[i])) continue; printable = false; break; } diff --git a/libtorrent/src/natpmp.cpp b/libtorrent/src/natpmp.cpp index b751b083d..878cc6fbf 100644 --- a/libtorrent/src/natpmp.cpp +++ b/libtorrent/src/natpmp.cpp @@ -105,6 +105,9 @@ void natpmp::rebind(address const& listen_interface) return; } + m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16) + , m_remote, bind(&natpmp::on_reply, self(), _1, _2)); + for (std::vector::iterator i = m_mappings.begin() , end(m_mappings.end()); i != end; ++i) { @@ -237,8 +240,6 @@ void natpmp::update_mapping(int i) // send out a mapping request m_retry_count = 0; send_map_request(i); - m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16) - , m_remote, bind(&natpmp::on_reply, self(), _1, _2)); } } @@ -281,11 +282,12 @@ void natpmp::send_map_request(int i) void natpmp::resend_request(int i, error_code const& e) { if (e) return; - if (m_abort) return; - mutex_t::scoped_lock l(m_mutex); if (m_currently_mapping != i) return; - if (m_retry_count >= 9) + + // if we're shutting down, don't retry, just move on + // to the next mapping + if (m_retry_count >= 9 || m_abort) { m_currently_mapping = -1; m_mappings[i].action = mapping_t::action_none; @@ -301,12 +303,26 @@ void natpmp::on_reply(error_code const& e , std::size_t bytes_transferred) { using namespace libtorrent::detail; - if (e) return; + if (e) + { +#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) + m_log << time_now_string() + << " <== on_receive [" + " error: " << e.message() << " ]" << std::endl; +#endif + return; + } + + m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16) + , m_remote, bind(&natpmp::on_reply, self(), _1, _2)); if (m_remote != m_nat_endpoint) { - m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16) - , m_remote, bind(&natpmp::on_reply, self(), _1, _2)); +#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) + m_log << time_now_string() + << " <== received packet from the wrong IP [" + " ip: " << m_remote << " ]" << std::endl; +#endif return; } diff --git a/libtorrent/src/pe_crypto.cpp b/libtorrent/src/pe_crypto.cpp index f20535610..fe6ab6c81 100644 --- a/libtorrent/src/pe_crypto.cpp +++ b/libtorrent/src/pe_crypto.cpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "libtorrent/pe_crypto.hpp" +#include "libtorrent/hasher.hpp" #include "libtorrent/assert.hpp" namespace libtorrent @@ -144,12 +145,14 @@ namespace libtorrent } std::copy(dh_secret, dh_secret + secret_size, m_dh_secret + 96 - secret_size); BN_free(bn_remote_pubkey); - return 0; - } - char const* dh_key_exchange::get_secret() const - { - return m_dh_secret; + // calculate the xor mask for the obfuscated hash + hasher h; + h.update("req3", 4); + h.update(m_dh_secret, 96); + m_xor_mask = h.final(); + + return 0; } } // namespace libtorrent diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index e8451d036..4a62c0fc1 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -1643,6 +1643,13 @@ namespace libtorrent TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle); m_download_queue.erase(b); + if (m_outstanding_writing_bytes >= m_ses.settings().max_outstanding_disk_bytes_per_connection + && t->alerts().should_post()) + { + t->alerts().post_alert(performance_alert(t->get_handle() + , performance_alert::outstanding_disk_buffer_limit_reached)); + } + if (!m_download_queue.empty()) { m_timeout_extend = (std::max)(m_timeout_extend @@ -2765,6 +2772,13 @@ namespace libtorrent m_desired_queue_size = m_max_out_request_queue; if (m_desired_queue_size < min_request_queue) m_desired_queue_size = min_request_queue; + + if (m_desired_queue_size == m_max_out_request_queue + && t->alerts().should_post()) + { + t->alerts().post_alert(performance_alert(t->get_handle() + , performance_alert::outstanding_request_limit_reached)); + } } if (!m_download_queue.empty() @@ -3632,6 +3646,9 @@ namespace libtorrent TORRENT_ASSERT(m_ses.has_peer((peer_connection*)this)); } +/* + // this assertion correct most of the time, but sometimes right when the + // limit is changed it might break for (int i = 0; i < 2; ++i) { // this peer is in the bandwidth history iff max_assignable < limit @@ -3639,6 +3656,7 @@ namespace libtorrent == m_ses.m_bandwidth_manager[i]->is_in_history(this) || m_bandwidth_limit[i].throttle() == bandwidth_limit::inf); } +*/ if (m_channel_state[download_channel] == peer_info::bw_torrent || m_channel_state[download_channel] == peer_info::bw_global) diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index ed6546e23..750ecde1a 100755 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -528,7 +528,7 @@ namespace libtorrent #endif // don't allocate files with priority 0 int file_index = file_iter - files().begin(); - if (allocate_files && (m_file_priority.size() <= file_index + if (allocate_files && (int(m_file_priority.size()) <= file_index || m_file_priority[file_index] > 0)) { error_code ec; @@ -2169,6 +2169,7 @@ namespace libtorrent int skip_blocks = static_cast( (file_offset - current_offset + m_files.piece_length() - 1) / m_files.piece_length()); + TORRENT_ASSERT(skip_blocks >= 1); if (m_storage_mode == storage_mode_compact) { diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index a5e394c8c..555d48561 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -206,6 +206,13 @@ namespace libtorrent , m_complete_sent(false) { parse_resume_data(resume_data); + +#ifndef TORRENT_DISABLE_ENCRYPTION + hasher h; + h.update("req2", 4); + h.update((char*)&tf->info_hash()[0], 20); + m_obfuscated_hash = h.final(); +#endif } torrent::torrent( @@ -280,6 +287,14 @@ namespace libtorrent , m_complete_sent(false) { parse_resume_data(resume_data); + +#ifndef TORRENT_DISABLE_ENCRYPTION + hasher h; + h.update("req2", 4); + h.update((char*)&info_hash[0], 20); + m_obfuscated_hash = h.final(); +#endif + #ifndef NDEBUG m_files_checked = false; #endif @@ -1471,7 +1486,7 @@ namespace libtorrent // ban it. if (m_ses.m_alerts.should_post()) { - peer_id pid; + peer_id pid(0); if (p->connection) pid = p->connection->pid(); m_ses.m_alerts.post_alert(peer_ban_alert( get_handle(), p->ip(), pid)); @@ -2261,6 +2276,7 @@ namespace libtorrent if (!s) return; bool ret = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy(), *s); + (void)ret; TORRENT_ASSERT(ret); if (m_ses.web_seed_proxy().type == proxy_settings::http @@ -2775,6 +2791,7 @@ namespace libtorrent boost::shared_ptr s(new socket_type(m_ses.m_io_service)); bool ret = instantiate_connection(m_ses.m_io_service, m_ses.peer_proxy(), *s); + (void)ret; TORRENT_ASSERT(ret); std::pair const& out_ports = m_ses.settings().outgoing_ports; error_code ec; @@ -3523,14 +3540,11 @@ namespace libtorrent void torrent::set_sequential_download(bool sd) { + m_sequential_download = sd; if (has_picker()) { picker().sequential_download(sd); } - else - { - m_sequential_download = sd; - } } void torrent::set_queue_position(int p) diff --git a/libtorrent/src/torrent_handle.cpp b/libtorrent/src/torrent_handle.cpp index b1ee00296..b02da4a6d 100755 --- a/libtorrent/src/torrent_handle.cpp +++ b/libtorrent/src/torrent_handle.cpp @@ -250,7 +250,7 @@ namespace libtorrent bool torrent_handle::is_paused() const { INVARIANT_CHECK; - TORRENT_FORWARD_RETURN(is_paused(), false); + TORRENT_FORWARD_RETURN(is_torrent_paused(), false); } void torrent_handle::pause() const