From c5cf290f494f690a6e9054892001103b79fbcfa6 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 24 Nov 2006 14:22:52 +0000 Subject: [PATCH] more quota management fixes and more stats for web seeds --- ChangeLog | 3 + .../aux_/allocate_resources_impl.hpp | 8 +-- include/libtorrent/torrent.hpp | 5 ++ include/libtorrent/tracker_manager.hpp | 2 + src/http_tracker_connection.cpp | 6 ++ src/peer_connection.cpp | 58 +++++++++++-------- src/torrent.cpp | 43 +++++++++++++- 7 files changed, 95 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3779dd6a..1049f25cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ + * Modified the quota management to offer better bandwidth balancing + between peers. + * added XCode project files (maintained by Gregor Riepl) * logging now supports multiple sessions (different sessions now log to different directories). * fixed random number generator seed problem, generating the same diff --git a/include/libtorrent/aux_/allocate_resources_impl.hpp b/include/libtorrent/aux_/allocate_resources_impl.hpp index fb355081a..9eb3b4943 100644 --- a/include/libtorrent/aux_/allocate_resources_impl.hpp +++ b/include/libtorrent/aux_/allocate_resources_impl.hpp @@ -175,7 +175,7 @@ namespace libtorrent // the number of consumer that saturated their // quota last time slice int num_saturated = 0; - // the total resources those that saturated their + // the total resources that those saturated their // quota used. This is used to calculate the mean // of the saturating consumers, in order to // balance their quotas for the next time slice. @@ -238,7 +238,7 @@ namespace libtorrent { assert(num_saturated > 0); target = div_round_up(saturated_sum, num_saturated); - target += div_round_up(target, 10); + target += div_round_up(target, 6); } else { @@ -247,8 +247,8 @@ namespace libtorrent if (target > r.max) target = r.max; else if (target < r.min) target = r.min; - // move 50% towards the the target value - r.used = r.given + div_round_up(target - r.given, 2); + // move 12.5% towards the the target value + r.used = r.given + div_round_up(target - r.given, 8); r.given = r.min; } diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index cca75c972..a3e686b98 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -501,6 +501,10 @@ namespace libtorrent // it's updated from all its peers once every second. libtorrent::stat m_stat; + // this is the stats for web seeds in this torrent only. It is updated + // once every second. + libtorrent::stat m_web_stat; + // ----------------------------- boost::shared_ptr m_policy; @@ -614,6 +618,7 @@ namespace libtorrent #ifdef TORRENT_LOGGING boost::shared_ptr m_log; + boost::shared_ptr m_peer_log; int m_second_count; enum { debug_bw_history_size = 10 }; diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index c72b59016..c7734f414 100755 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -82,6 +82,7 @@ namespace libtorrent { tracker_request() : kind(announce_request) + , web_downloaded(0) , event(none) , key(0) , num_want(0) @@ -106,6 +107,7 @@ namespace libtorrent size_type downloaded; size_type uploaded; size_type left; + size_type web_downloaded; unsigned short listen_port; event_t event; std::string url; diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 65e947c75..7700a8d68 100755 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -322,6 +322,12 @@ namespace libtorrent m_send_buffer += "&left="; m_send_buffer += boost::lexical_cast(req.left); + if (req.web_downloaded > 0) + { + m_send_buffer += "&http_downloaded="; + m_send_buffer += boost::lexical_cast(req.web_downloaded); + } + if (req.event != tracker_request::none) { const char* event_string[] = {"completed", "started", "stopped"}; diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index c06ffd9c9..b3468d314 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -141,8 +141,22 @@ namespace libtorrent } else { - // just enough to get started with the handshake and bitmask - m_ul_bandwidth_quota.given = 400; + if (t->num_peers() == 0) + { + // just enough to get started with the handshake and bitmask + m_ul_bandwidth_quota.given = 400; + } + else + { + // set the limit of this new connection to the mean of the other connections + size_type total_ul_given = 0; + for (torrent::peer_iterator i = t->begin() + , end(t->end()); i != end; ++i) + { + total_ul_given += i->second->m_ul_bandwidth_quota.given; + } + m_ul_bandwidth_quota.given = total_ul_given / t->num_peers(); + } } m_dl_bandwidth_quota.min = 10; @@ -154,8 +168,22 @@ namespace libtorrent } else { - // just enough to get started with the handshake and bitmask - m_dl_bandwidth_quota.given = 400; + if (t->num_peers() == 0) + { + // just enough to get started with the handshake and bitmask + m_dl_bandwidth_quota.given = 400; + } + else + { + // set the limit of this new connection to the mean of the other connections + size_type total_dl_given = 0; + for (torrent::peer_iterator i = t->begin() + , end(t->end()); i != end; ++i) + { + total_dl_given += i->second->m_dl_bandwidth_quota.given; + } + m_dl_bandwidth_quota.given = total_dl_given / t->num_peers(); + } } std::fill(m_peer_id.begin(), m_peer_id.end(), 0); @@ -230,29 +258,11 @@ namespace libtorrent m_ul_bandwidth_quota.min = 10; m_ul_bandwidth_quota.max = resource_request::inf; - - if (m_ses.m_upload_rate == -1) - { - m_ul_bandwidth_quota.given = resource_request::inf; - } - else - { - // just enough to get started with the handshake and bitmask - m_ul_bandwidth_quota.given = 400; - } + m_ul_bandwidth_quota.given = 400; m_dl_bandwidth_quota.min = 10; m_dl_bandwidth_quota.max = resource_request::inf; - - if (m_ses.m_download_rate == -1) - { - m_dl_bandwidth_quota.given = resource_request::inf; - } - else - { - // just enough to get started with the handshake and bitmask - m_dl_bandwidth_quota.given = 400; - } + m_dl_bandwidth_quota.given = 400; std::fill(m_peer_id.begin(), m_peer_id.end(), 0); } diff --git a/src/torrent.cpp b/src/torrent.cpp index c21b8b77a..d3785bdc3 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -207,6 +207,8 @@ namespace << "14. bytes sent 10 seconds mean\n" << "15. bytes received\n" << "16. bytes received 10 seconds mean\n" + << "17. total payload download\n" + << "18. total web seed payload download\n" << "\n"; } #endif @@ -276,6 +278,11 @@ namespace libtorrent m_second_count = 0; std::fill_n(m_ul_history, 10, 0); std::fill_n(m_dl_history, 10, 0); + + m_peer_log = ses.create_log("torrent_peers_" + + boost::lexical_cast(tf.info_hash()) + , m_ses.listen_port(), false); + #endif INVARIANT_CHECK; @@ -1031,6 +1038,7 @@ namespace libtorrent req.info_hash = m_torrent_file.info_hash(); req.pid = m_ses.get_peer_id(); req.downloaded = m_stat.total_payload_download(); + req.web_downloaded = m_web_stat.total_payload_download(); req.uploaded = m_stat.total_payload_upload(); req.left = bytes_left(); if (req.left == -1) req.left = 16*1024; @@ -1170,6 +1178,12 @@ namespace libtorrent tcp::endpoint a(host->endpoint()); + if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) + { + // TODO: post alert: "web seed at " + a.address().to_string() + " blocked by ip filter"); + return; + } + boost::shared_ptr s(new stream_socket(m_ses.m_selector)); boost::intrusive_ptr c(new web_peer_connection( m_ses, shared_from_this(), s, a, url)); @@ -1225,6 +1239,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) + throw protocol_error(a.address().to_string() + " blocked by ip filter"); + if (m_connections.find(a) != m_connections.end()) throw protocol_error("already connected to peer"); @@ -1772,6 +1789,7 @@ namespace libtorrent { // let the stats fade out to 0 m_stat.second_tick(tick_interval); + m_web_stat.second_tick(tick_interval); return; } @@ -1812,6 +1830,10 @@ namespace libtorrent { peer_connection* p = i->second; m_stat += p->statistics(); + if (dynamic_cast(p)) + { + m_web_stat += p->statistics(); + } // updates the peer connection's ul/dl bandwidth // resource requests p->second_tick(tick_interval); @@ -1844,6 +1866,7 @@ namespace libtorrent accumulator += m_stat; m_stat.second_tick(tick_interval); + m_web_stat.second_tick(tick_interval); } void torrent::distribute_resources(float tick_interval) @@ -1890,9 +1913,9 @@ namespace libtorrent m_excess_dl = std::max(m_excess_dl, -10000); int ul_to_distribute = std::max(int((m_ul_bandwidth_quota.given - - m_excess_ul) * 1.6f), 0); + - m_excess_ul * 0.7f) * 1.6f), 0); int dl_to_distribute = std::max(int((m_dl_bandwidth_quota.given - - m_excess_dl) * 1.6f), 0); + - m_excess_dl * 0.7f) * 1.6f), 0); #ifdef TORRENT_LOGGING std::copy(m_ul_history + 1, m_ul_history + debug_bw_history_size, m_ul_history); @@ -1924,6 +1947,8 @@ namespace libtorrent << mean_ul << "\t" << dl_used << "\t" << mean_dl << "\t" + << m_stat.total_payload_download() << "\t" + << m_web_stat.total_payload_download() << "\t" << "\n"; (*m_log) @@ -1939,6 +1964,20 @@ namespace libtorrent << num_peers() << "\t" << ul_max << "\t" << dl_max << "\t"; + + (*m_peer_log) << m_second_count << "\t"; + for (peer_iterator i = m_connections.begin(); + i != m_connections.end(); ++i) + { + int given = i->second->m_dl_bandwidth_quota.given; + (*m_peer_log) << (given == resource_request::inf ? -1 : given) + << "\t" << i->second->m_dl_bandwidth_quota.used << "\t"; + } + for (int i = m_connections.size(); i < 10; ++i) + { + (*m_peer_log) << 0 << "\t" << 0 << "\t"; + } + (*m_peer_log) << "\n"; #endif